操作在Java中停止工作
这是我的第一篇文章,如果我的语法不好,我真的很抱歉(英语不是我的母语)。我最近开始用java编程,我对学习很感兴趣。所以我开始了一些小项目来帮助我理解更多的基本知识并改进我的编码 最近我读到了关于KeyListener、KeyBinding和所有这些东西的文章。所以我想我编写了一个非常基本的程序(几乎没有gui),它应该像一架简单的钢琴一样工作:操作在Java中停止工作,java,swing,action,key-bindings,keystroke,Java,Swing,Action,Key Bindings,Keystroke,这是我的第一篇文章,如果我的语法不好,我真的很抱歉(英语不是我的母语)。我最近开始用java编程,我对学习很感兴趣。所以我开始了一些小项目来帮助我理解更多的基本知识并改进我的编码 最近我读到了关于KeyListener、KeyBinding和所有这些东西的文章。所以我想我编写了一个非常基本的程序(几乎没有gui),它应该像一架简单的钢琴一样工作: import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; im
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.awt.*;
import java.io.File;
import javax.swing.*;
import java.awt.event.*;
public class pianl1 {
public static void main (String[] args){
int i= 0;
File C7 = new File("res/39191__jobro__piano-ff-044.wav");
File D7 = new File ("res/39194__jobro__piano-ff-046.wav");
JLabel lab1 =new JLabel("Hallo");
frame.add(lab1);
AbstractAction keyBindingReactorC7 = new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e){
Playsound(C7);
}
};
AbstractAction keyBindingReactorD7 = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Playsound(D7);
}
JPanel panel= new JPanel(new FlowLayout());
frame.getContentPane().add(panel);
frame.pack();
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("C"),
"cPressed");
panel.getActionMap().put("cPressed", keyBindingReactorC7);
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"),
"dPressed");
panel.getActionMap().put("dPressed", keyBindingReactorD7);
public static void Playsound(File Sound){
try{
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(Sound));
clip.start();
}catch(Exception e){}
}
}
它工作得很好。如果我按下按键,它就会播放声音,即使我敲击按键,声音也几乎没有延迟。这正是我想要的
但有一个小错误
如果我一直按一个键,或者同时按两个键(这样可以同时播放两个键),有时会出现完全没有声音的情况。我不能做任何事情让它再次工作,我所能做的就是重新启动整个程序。这是随机发生的,我不知道为什么。我知道有什么东西阻碍了我的行动持续工作。你的问题的答案围绕着你最终想要实现的目标,如果你只是想停止一个以上的声音播放,那么你需要某种可以监控的条件,如果你想停止播放“特定”的声音,然后,您需要维护某种类型的标记列表,您可以检查这些标记 因此,根据你的代码,假设你正在制作一架钢琴,所以你希望声音重叠,在这种情况下,我们需要一些方法来确定是否播放了特定的声音 实现这一点的方法有很多,但让我们先确定一个
集合
,它允许您维护唯一的项目列表(无重复项)
每次调用playSound
,我们都会检查此列表并确定声音是否已经播放过,如果没有,我们会将声音添加到列表并播放,当声音停止时,我们会将其从列表中删除
在核心。。。
我对你的代码做了一些修改,稍后我会详细解释,但本质上,这是这个想法的“核心”
private Set<File> playing = new HashSet<File>(25);
public void playsound(File sound) {
try {
// Is the been played or not?
if (!playing.contains(sound)) {
// And the sound to prevent it from been played again
playing.add(sound);
// Set up a new clip
Clip clip = AudioSystem.getClip();
// Monitor the clip's status, we want to know when it ends
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
// Clip has stopped
if (event.getType() == LineEvent.Type.STOP) {
// Release the resources
clip.close();
// Remove the sound from our list
// so it can be played again
playing.remove(sound);
}
}
});
// Play it again Sam
clip.open(AudioSystem.getAudioInputStream(sound));
clip.start();
}
} catch (Exception e) {
// Remove the sound if something goes wrong
playing.remove(sound);
e.printStackTrace();
}
}
好的,但是我如何使它一次只能播放一个声音呢?
啊,好问题
基本上,我们使用一个剪辑并检查它的状态
private Clip clip;
public void playsound(File sound) {
try {
if (clip == null) {
clip = AudioSystem.getClip();
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
clip.close();
}
}
});
}
// Is the clip active or running?
if (!clip.isActive() && !clip.isRunning()) {
if (clip.isOpen()) {
clip.close();
}
clip.open(AudioSystem.getAudioInputStream(sound));
clip.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
<>现在,我的java音频体验是不存在的,但是有些事情我可以考虑……
- 制作一个
AudioManager
或SoundManager
类,用于管理声音并提供播放声音的简单界面(如playC
,playD
)。为每个声音预加载剪辑。这将需要一些额外的管理,因为当剪辑结束时,您需要将其“重置”回开始。这“应该”会加快播放剪辑的速度,但可能会消耗更多的资源,哪种权衡对您更重要?您还可以创建某种缓存,如果某个剪辑在一段时间内没有播放,它将被关闭并处理
- 继续播放声音,直到释放钥匙……这对你来说是个不错的挑战;)李>
你的问题的答案围绕着你最终想要实现的目标,如果你只是想停止一个以上的声音播放,那么你需要某种你可以监控的条件,如果你想停止播放一个“特定”的声音,那么你需要维护一些你可以检查的标记的列表
因此,根据你的代码,假设你正在制作一架钢琴,所以你希望声音重叠,在这种情况下,我们需要一些方法来确定是否播放了特定的声音
实现这一点的方法有很多,但让我们先确定一个集合
,它允许您维护唯一的项目列表(无重复项)
每次调用playSound
,我们都会检查此列表并确定声音是否已经播放过,如果没有,我们会将声音添加到列表并播放,当声音停止时,我们会将其从列表中删除
在核心。。。
我对你的代码做了一些修改,稍后我会详细解释,但本质上,这是这个想法的“核心”
private Set<File> playing = new HashSet<File>(25);
public void playsound(File sound) {
try {
// Is the been played or not?
if (!playing.contains(sound)) {
// And the sound to prevent it from been played again
playing.add(sound);
// Set up a new clip
Clip clip = AudioSystem.getClip();
// Monitor the clip's status, we want to know when it ends
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
// Clip has stopped
if (event.getType() == LineEvent.Type.STOP) {
// Release the resources
clip.close();
// Remove the sound from our list
// so it can be played again
playing.remove(sound);
}
}
});
// Play it again Sam
clip.open(AudioSystem.getAudioInputStream(sound));
clip.start();
}
} catch (Exception e) {
// Remove the sound if something goes wrong
playing.remove(sound);
e.printStackTrace();
}
}
好的,但是我如何使它一次只能播放一个声音呢?
啊,好问题
基本上,我们使用一个剪辑并检查它的状态
private Clip clip;
public void playsound(File sound) {
try {
if (clip == null) {
clip = AudioSystem.getClip();
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
clip.close();
}
}
});
}
// Is the clip active or running?
if (!clip.isActive() && !clip.isRunning()) {
if (clip.isOpen()) {
clip.close();
}
clip.open(AudioSystem.getAudioInputStream(sound));
clip.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
<>现在,我的java音频体验是不存在的,但是有些事情我可以考虑……
- 制作一个
AudioManager
或SoundManager
类,用于管理声音并提供播放声音的简单界面(如playC
,playD
)。为每个声音预加载剪辑。这将需要一些额外的管理,因为当剪辑结束时,您需要将其“重置”回开始。这“应该”会加快播放剪辑的速度,但可能会消耗更多的资源,哪种权衡对您更重要?您还可以创建某种缓存,如果某个剪辑在一段时间内没有播放,它将被关闭并处理
- 继续播放声音,直到释放钥匙……这对你来说是个不错的挑战;)李>
除了@MadProgrammer的大力帮助,我还注意到了其他一些东西。我在Mac电脑上工作,但我也拥有Windows电脑。我最近刚切换到Mac,我没有注意到(直到现在),如果你按住一个键足够长的时间,OSX会自动显示更多的键选项(像ā、ć等等)。
所以我把所有的东西都换到了我的Windows机器上,瞧,它工作了。当然有一些小错误,但最终我对结果非常满意 除了@MadProgrammer的大力帮助,我还注意到了其他一些东西。我在Mac电脑上工作,但我也拥有Windows电脑。我最近刚切换到Mac,我没有注意到(直到现在),如果你按住一个键足够长的时间,OSX会自动显示更多的键选项(像ā、ć等等)。
所以我改变了一切