Java JToggleButton freezes in While loop

236 views Asked by At
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.

2

There are 2 answers

0
Lars On BEST ANSWER

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();
}
1
ursa On

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