缩短变量以利用路径
这是我的完整代码,并附有一些解释。缩短变量以利用路径
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
声明来将声音放在不同的幻灯片中。
您可以在路径声音文件存储在一个列表,并使用当前幻灯片的索引选择正确的声音路径。我没有找到使用CardLayout
类的索引的方法;它有一个currentCard
字段,但它不可访问。
这些改变你原来的版本在下面的代码可见:
- 增加了
slideIndex
字段来跟踪当前幻灯片索引。该字段在启动时以及按Home键时被初始化为零。当按下下一个或上一个按钮时,它也会被修改。 - 增加了一个
soundPaths
列表与路径的声音文件。 - 按钮有一些文字,有一个
createIcon
方法。 - 当
slides
面板被填满时,soundPaths
列表太填补。 (我已经使用了带有图像和声音的目录。) - 原始声音代码在我的机器上无法使用;因此我使用了我在这个堆栈溢出回答中找到的代码:https://stackoverflow.com/a/30587573/1694043。循环应该很容易:如果您调用
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)
{
// 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'类型的音频 – user2781911
如果你调用'clip.loop',它应该能够循环。根据文档,Java Sound支持各种音频格式(如.au,.aif和.wav),但其可用性取决于操作系统。有关更多信息,请参阅http://stackoverflow.com/a/29713583/1694043或https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/sound.html#gdjzj信息。您还可以将声音文件转换为支持的格式。 –
好吧,现在的问题是,当我打开一个新的JFrame时,声音仍然存在,除非我关闭应用程序。从同一个包中的另一个文件更改为另一个JFrame后,如何停止声音? – user2781911
这是我自己的版本,有点不切实际,但至少我明白。基本上,我添加另一个变量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);
}
}
你的代码是很短的。你可以添加一些细节,比如框架和按钮的构造。 “幻灯片”是一个类似于“JTabbedPane”还是自定义数据结构的组件?当提问有关由代码引起的问题的问题时,如果您提供可用于重现问题的完整代码(有关更多信息,请参阅http://stackoverflow.com/help/mcve),您将得到更好的答案。 –
@FreekdeBruijn我编辑了我的代码 – user2781911
你可以加载所有的声音在stratup或只在运行时? – user1803551