缩短变量以使用路径

Shorten the variable to make use of the path

这是我的完整代码,带有一些解释。

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 的变量,这样我就可以 return 像 5.png 这样的特定路径插入声音。但是,如果不在 ImageIcon 中调用完整路径,我就无法做到这一点,而且不知何故,即使我调用了完整路径,它也根本不起作用。

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

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

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

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

  • 添加了一个 slideIndex 字段来跟踪当前幻灯片索引。该字段在启动时和按下主页按钮时初始化为零。当按下下一个或上一个按钮时,它也会被修改。
  • 添加了包含声音文件路径的 soundPaths 列表。
  • 按钮有一些文本,并且有一个 createIcon 方法。
  • slides 面板被填满时,soundPaths 列表也会被填满。 (我使用了一个包含图像和声音的目录。)
  • 原来的声音代码在我的机器上不起作用;因此我使用了我在这个 Stack Overflow 答案中找到的代码:。循环应该很容易:如果你调用 clip.loop 方法,它应该能够循环。
  • 根据文档,Java 声音支持各种音频格式(如 .au、.aif 和 .wav),但它们的可用性取决于操作系统。有关更多信息,请参见示例:
  • 您还可以将原始声音文件转换为支持的格式。

代码如下:

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)
    {
        // 
        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);
    }
}

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

为了防止点击超过我的幻灯片总数,我在每个按钮上放置了 .setVisible(false) 并调用 .setVisible(true) 返回到 return 按钮。

通过声明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);
}

}