ppelagh
ppelagh

Reputation: 21

How to stop continuous sound loop from another class?

I have a problem with a sound loop on my code. The sound itself is in another class, and I'd like to stop it by clicking a jbutton in another one.

Code in sound class:

public Sound() {
    try {
        URL sound = this.getClass().getClassLoader().getResource("sound.wav");
        AudioInputStream audioIn = AudioSystem.getAudioInputStream(sound);
        Clip clip = AudioSystem.getClip();
        clip.open(audioIn);
        clip.start();
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    } 
    catch (Exception e) {
        e.printStackTrace();
    }
}

I've tried a lot of things to get the sound to stop by clicking a jbutton in another class (ActionListener), but nothing seems to work. Any ideas?

Edit: I forgot to say I also tried to make a sound method into the same class with the jbutton, but didn't get that to work either. (following code)

public void sound() {
    try {
        URL sound = this.getClass().getClassLoader().getResource("sound.wav");
        AudioInputStream audioIn = AudioSystem.getAudioInputStream(sound);
        Clip clip = AudioSystem.getClip();
        clip.open(audioIn);
        clip.start();
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Edit 2:

JButton playB = new JButton("Play");
playB.setBounds(192, 350, 500, 100);
playB.setFont(new Font("Arial", Font.PLAIN, 80));
playB.setForeground(Color.GREEN);
menu.add(playB);
playB.setOpaque(false);
playB.setContentAreaFilled(false);
playB.setBorderPainted(false);
playB.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        clip.stop();
    }
});

clip.stop() is obviously not working there.

Upvotes: 2

Views: 79

Answers (1)

Phil Freihofner
Phil Freihofner

Reputation: 7910

First off, the Clip should be an instance variable. Don't declare it within your method. Declare it at the class level. Then, you can have a public, dedicated class method that references the Clip and stops it.

And when you do this (make it an instance variable), it would also be an improvement to make the playing of the Clip be its own individual method. When you initialize a Clip and then start it in a single method, the entire file has to be read into memory before the Clip will begin to play. This can lead to serious lag if the Clip is a large file.

The recommended practice is to first load the Clips and then hold them in memory until it is time to play them. If you don't want to hold this data in memory, you'd be better off using a SourceDataLine.

Upvotes: 1

Related Questions