问题
public void playMet() {
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
if(Play.isSelected()) {
try {
FileInputStream in = new FileInputStream(new File("Click1.wav"));
AudioStream as = new AudioStream(in);
AudioPlayer.player.start(as);
Thread.sleep(tempo*1000);
playMet();
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
else
System.out.println("not playing");
}
Here's a section of my code, basically when a button is pressed it plays a click X times per minute.
I've tried the code with a while loop like this:
while(Play.isSelected()) {
.........
.........
}
and that didn't work either. In both cases the program runs like it should, but freezes and I have to close it down from the task manager.
How can I call a function when the button is pressed and be able to stop it if I deselect it?
P.S. Just saw the two posts below. Have to go to work, will check up on them later and see if they work. Thank you for the help.
回答1:
The recursive calls are blocking the Event Dispatch Thread. You have to create a new Thread to not block the EDT.
public void playMet()
{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
while(Play.isSelected()){
//Your code
}
}
};
t.start();
}
回答2:
You don't need Thread.sleep(), you don't need recursion or while loop. You need stateful player. And your UI should only change the state of the player.
See an example in https://stackoverflow.com/a/7524627/2078908
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> playingTask;
private FileInputStream playing;
public void playMet() {
stopPlaying();
playingTask = executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
playMet();
}
}, 0, 1000, TimeUnit.MILLISECONDS);
}
public void playMetOnce(){
try {
IOUtils.close(playing);
playing = new FileInputStream(new File("Click1.wav"));
AudioStream as = new AudioStream(playing);
AudioPlayer.player.start(as);
} catch (Exception e)
{
JOptionPane.showMessageDialog(null, e);
}
}
public void stopPlaying(){
try {
AudioPlayer.player.stop();
IOUtils.close(playing);
playing = null;
if (playingTask != null) {
playingTask.cancel(false);
}
playingTask = null;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
来源:https://stackoverflow.com/questions/27205368/java-jtogglebutton-freezes-in-while-loop