缩短变量以使用路径
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);
}
}
这是我的完整代码,带有一些解释。
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);
}
}