【问题标题】:Shorten the variable to make use of the path缩短变量以使用路径
【发布时间】:2015-12-16 07:33:49
【问题描述】:

这是我的完整代码和一些解释。

public class SlideShow extends javax.swing.JFrame {

JPanel      slides;
CardLayout  layoutManager;
    private JButton btnPrev;
    private JButton btnNext;
    private JButton btnHome;
    private JButton btnSound;

public SlideShow() {
super();

setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

    btnPrev = new javax.swing.JButton();
    btnNext = new javax.swing.JButton();
    btnHome = new javax.swing.JButton();
    btnSound = new javax.swing.JButton();
    btnPrev.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/back+button.png")));
    btnNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/next2.png")));
    btnHome.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/home_icons.png")));
    btnSound.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/Media-Controls-Volume-Down-icon.png")));

slides = new JPanel();
slides.setBackground(Color.WHITE);
slides.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    slides.setLayout(layoutManager = new CardLayout(0,0));

    for(int i=2; i<=24; i++){
    slides.add(i+".png", new JLabel(new ImageIcon(getClass().getResource("/resources/"+i+".png"))));
    }
    add(slides);

    add(btnHome);
    add(btnPrev);
    add(btnNext);
    add(btnSound);

    btnPrev.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            layoutManager.previous(slides);
        }
    });

    btnNext.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            layoutManager.next(slides);
        }
    });

    btnHome.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            close();
            Frame fr = new Frame();
            fr.setVisible(true);
        }
    });

    btnSound.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            music("././build/classes/resources/test.wav");
        }
    });

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(700,530);
}

    public void close(){
    super.dispose();
}

    public static void music(String path) 
{
    AudioStream BGM;
    AudioData MD;
    AudioDataStream audiostream;

    try{
    BGM = new AudioStream (new FileInputStream(path));
    MD = BGM.getData();

    audiostream = new AudioDataStream(MD);
    AudioPlayer.player.start(audiostream);
    }catch(IOException error){}

}

public static void main(String args[]) {
    SlideShow frame =  new SlideShow();
    frame.setVisible(true);
}

}

我的JFrame 中有一个包含多张图片的幻灯片。每张幻灯片都有一个按钮,当它点击时会输出一些声音。这些幻灯片在同一个 JFrame 中调用。所以,我不必为每张幻灯片制作很多 JFrame。我想为每张幻灯片制作不同的声音。我所要做的就是调用幻灯片图像的路径来匹配声音。

我的情况是,基本上,我想缩短 ImageIcon 的变量,以便我可以返回一个特定的路径,如 5.png 来插入声音。但是,如果不调用 ImageIcon 中的完整路径,我就无法做到这一点,而且不知何故,即使我调用了完整路径,它也根本不起作用。

所以,如果我可以在slides 处获得特定路径作为变量或类似的东西,我可以使用它来使用相同的按钮调用不同的声音。如何缩短它? 或者,有没有办法从slides 获取特定变量?但是如何调用变量?这个应用程序中有 24 张幻灯片图像,如何区分它?

我在for loop 中测试了这段代码JOptionPane.showMessageDialog(null, "Test!");,看起来这段代码在实际幻灯片出现之前输出了24 次。所以,这意味着for loop 只输入图像,我不知道如何调用它,所以我可以做出类似if else 的语句来将声音放在不同的幻灯片上。

【问题讨论】:

  • 你的代码很短。您能否添加更多细节,例如框架和按钮的构造。 slides 是类似于 JTabbedPane 的组件还是自定义数据结构?当询问由您的代码引起的问题时,如果您提供人们可以用来重现问题的完整代码,您将获得更好的答案(有关更多信息,请参阅stackoverflow.com/help/mcve)。
  • @FreekdeBruijn 我编辑了我的代码
  • 你能在stratup加载所有声音还是只在运行时加载?
  • @user1803551 我只能在运行时加载,这意味着在我点击按钮期间
  • 好的,剩下的就是问你究竟你在做什么,因为你在问题中提到了许多不同的东西。

标签: java swing netbeans imageicon


【解决方案1】:

您可以将声音文件的路径存储在列表中,并使用当前幻灯片的索引来选择正确的声音路径。我没有找到使用CardLayout 类中的索引的方法;它有一个currentCard 字段,但无法访问。

对原始版本的这些更改在以下代码中可见:

代码如下:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import javax.sound.sampled.*;
import javax.swing.*;

public class SlideShow extends JFrame {

    private JPanel slides;
    private int slideIndex;
    private java.util.List<String> soundPaths;
    private CardLayout layoutManager;
    private JButton btnPrev;
    private JButton btnNext;
    private JButton btnHome;
    private JButton btnSound;

    public SlideShow() {
        super();

        setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

        btnPrev = new JButton("Previous");
        btnNext = new JButton("Next");
        btnHome = new JButton("Home");
        btnSound = new JButton("Sound");
        btnPrev.setIcon(createIcon("/resources/back+button.png"));
        btnNext.setIcon(createIcon("/resources/next2.png"));
        btnHome.setIcon(createIcon("/resources/home_icons.png"));
        btnSound.setIcon(createIcon("/resources/Media-Controls-Volume-Down-icon.png"));

        slides = new JPanel();
        slides.setBackground(Color.WHITE);
        slides.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        slides.setLayout(layoutManager = new CardLayout(0,0));

        soundPaths = new ArrayList<>();
        String directory = "resources/images-and-sounds/";
        for(int i=2; i<=24; i++){
            final String name = "/resources/" + i + ".png";
            slides.add(i + ".png", new JLabel(createIcon(name)));
            //slides.add(i+".png", new JLabel(new ImageIcon(directory + i + ".png")));
            soundPaths.add(directory + i + ".wav");
        }
        add(slides);

        add(btnHome);
        add(btnPrev);
        add(btnNext);
        add(btnSound);

        btnPrev.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                layoutManager.previous(slides);
                slideIndex = (slideIndex > 0)
                        ? slideIndex - 1
                        : slides.getComponentCount() - 1;
            }
        });

        btnNext.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                layoutManager.next(slides);
                slideIndex = (slideIndex + 1) % slides.getComponentCount();
            }
        });

        btnHome.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                close();
                Frame fr = new Frame();
                fr.setVisible(true);
                slideIndex = 0;
            }
        });

        btnSound.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //music("././build/classes/resources/test.wav");

                if (Files.exists(Paths.get(soundPaths.get(slideIndex)))) {
                    music(soundPaths.get(slideIndex));
                }
            }
        });

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(700,530);
    }

    private ImageIcon createIcon(String name) {
        return new ImageIcon(getClass().getResource(name));
    }

    public void close(){
        super.dispose();
    }

    public static void music(String path)
    {
        // https://stackoverflow.com/a/30587573/1694043
        try {
            Clip clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(new File(path)));
            clip.start();
            //clip.loop(Clip.LOOP_CONTINUOUSLY);
        } catch (LineUnavailableException | IOException
                | UnsupportedAudioFileException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        SlideShow frame = new SlideShow();
        frame.setVisible(true);
    }
}

【讨论】:

  • 这就是我之前一直在寻找的东西!但与你的相比,我的解决方案有点不切实际,也不是很好。无论如何,我可以问一下声音剪辑吗?代码是否使声音不断循环?因为我最终需要它。那么支持的类型呢?以前我的代码只支持.wav type audio only
  • 如果你调用clip.loop,它应该可以循环。根据文档,Java Sound 支持各种音频格式(如 .au、.aif 和 .wav),但它们的可用性取决于操作系统。参见例如stackoverflow.com/a/29713583/1694043docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/… 了解更多信息。您还可以将声音文件转换为支持的格式。
  • 好的,现在的问题是,当我打开一个新的 JFrame 时,声音仍然存在,除非我关闭应用程序。从同一个包中的另一个文件更改为另一个 JFrame 后如何停止声音?
  • 您可以将clip变量转换为字段并调用clip.stop方法,就在您创建新框架之前(在调用该方法之前检查clip是否不为空)。
  • 太好了,恭喜!祝你项目的其余部分好运。
【解决方案2】:

这是我自己的版本,有点不实用,但至少我理解了。基本上,我添加了另一个变量j 来替换页面幻灯片,因为我似乎无法返回它的路径。由于我的幻灯片从第 2 页开始,所以我将其声明为j=2。之后,我通过每次单击 Next/Previous 按钮来增加/减少变量 j。因此,我可以用j 的值替换幻灯片的编号。

为了防止过度点击超过我的幻灯片总数,我在每个按钮上都添加了.setVisible(false),然后回拨.setVisible(true) 以返回按钮。

通过j的声明,我可以使用if else语句,通过同一个按钮,定义任何页面,并根据页面添加任何声音。

public class SlideShow extends javax.swing.JFrame {

JPanel      slides;
CardLayout  layoutManager;
    private JButton btnPrev;
    private JButton btnNext;
    private JButton btnHome;
    private JButton btnSound;
    private int j=2;

public SlideShow() {
super();

setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

    btnPrev = new javax.swing.JButton();
    btnNext = new javax.swing.JButton();
    btnHome = new javax.swing.JButton();
    btnSound = new javax.swing.JButton();
    btnPrev.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/back+button.png")));
    btnNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/next2.png")));
    btnHome.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/home_icons.png")));
    btnSound.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/Media-Controls-Volume-Down-icon.png")));

slides = new JPanel();
slides.setBackground(Color.WHITE);
slides.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    slides.setLayout(layoutManager = new CardLayout(0,0));

            if(j==2)
                btnPrev.setVisible(false);

    for(int i=2; i<=24; i++){
    slides.add(i+".png", new JLabel(new ImageIcon(getClass().getResource("/resources/"+i+".png"))));
    }
    add(slides);

    add(btnHome);
    add(btnPrev);
    add(btnNext);
    add(btnSound);

    btnPrev.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            layoutManager.previous(slides);
            j--;
            if(j!=24)
                btnNext.setVisible(true);
            if(j==2)
                btnPrev.setVisible(false);
            //JOptionPane.showMessageDialog(null, "Slide "+j);
        }
    });

    btnNext.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            layoutManager.next(slides);
            j++;
            if(j==24)
                btnNext.setVisible(false);
            if(j!=2)
                btnPrev.setVisible(true);
            //JOptionPane.showMessageDialog(null, "Slide "+j);
        }
    });

    btnHome.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            close();
            Frame fr = new Frame();
            fr.setVisible(true);
        }
    });

    btnSound.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
                if(j==2)
                    music("././build/classes/resources/test1.wav");
                else if(j==3)
                    music("././build/classes/resources/test2.wav");
        }
    });

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(700,530);
}

    public void close(){
    super.dispose();
}

    public static void music(String path) 
{
    AudioStream BGM;
    AudioData MD;
    AudioDataStream audiostream;

    try{
    BGM = new AudioStream (new FileInputStream(path));
    MD = BGM.getData();

    audiostream = new AudioDataStream(MD);
    AudioPlayer.player.start(audiostream);
    }catch(IOException error){}

}

public static void main(String args[]) {
    SlideShow frame =  new SlideShow();
    frame.setVisible(true);
}

}

【讨论】:

    猜你喜欢
    • 2021-09-25
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多