简体   繁体   中英

Java program hangs on stopping audio

I have written this code for a simple music player, the problem is that when I click openLabel and open a song and then when I pause it by clicking playLabel the program stops execution (program hangs).

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Random;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;  

public class A extends MouseAdapter implements ChangeListener, Runnable {
    private ImageIcon playImage = new ImageIcon(getClass().getResource("Images/play.png"));
    private ImageIcon pauseImage = new ImageIcon(getClass().getResource("Images/pause.png"));
    private ImageIcon openImage = new ImageIcon(getClass().getResource("Images/open.png"));
    private JLabel playLabel = new JLabel(playImage);
    private JLabel openLabel = new JLabel(openImage);
    public JFrame frame = new JFrame();
    public JPanel colorPanel = new JPanel();
    private enum Status {ON,OFF,PAUSE,END};
    private Status playStatus=Status.OFF;
    private JSlider slider = new JSlider();
    public Clip songClip;   
    Thread screenThread = new Thread(this);

    public static void main(String arg[]) throws Exception {
        new A();
    }

    public A() throws Exception {
        setFrame();
        setComponents();
    }

    public void setFrame() {
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        frame.setCursor(new Cursor(Cursor.HAND_CURSOR));
        frame.getContentPane().setBackground(Color.BLACK);
        frame.setVisible(true);
    }

    public void setComponents() {
        slider.setBounds(0,640,1000,15);
        slider.setBackground(Color.BLACK);
        slider.addChangeListener(this);
        slider.setValue(0);
        playLabel.setBounds(450,665,100,100);
        playLabel.addMouseListener(this);
        openLabel.setBounds(540,690,60,60);
        openLabel.addMouseListener(this);
        colorPanel.setBackground(Color.BLACK);
        colorPanel.setBounds(0,100,1500,500);
        frame.add(openLabel);
        frame.add(playLabel);
        frame.add(colorPanel);
        frame.add(slider);
    }

    public void mouseClicked(MouseEvent clicked) {
        if (clicked.getSource() == openLabel) {
            openLabel.setIcon(openImage);
            open();
        }
        else if (clicked.getSource()==playLabel && playStatus != Status.OFF) {
            if (playStatus == Status.PAUSE) {
                songClip.start();
                screenThread.resume();
                playStatus=Status.ON;
                playLabel.setIcon(pauseImage);
            }
            else if (playStatus == Status.ON) {
                songClip.stop();
                screenThread.suspend();
                playStatus=Status.PAUSE;
                playLabel.setIcon(playImage);
            }
            else if (playStatus==Status.END) {
                songClip.setMicrosecondPosition(0);
                slider.setValue(0);
                songClip.start();
                screenThread.resume();
                playStatus = Status.ON;
                playLabel.setIcon(pauseImage);
            }
        }
    }

    public void stateChanged(ChangeEvent e) {
        if (playStatus != Status.OFF) {
            JSlider jslider = (JSlider)e.getSource();
            int position = jslider.getValue();
            songClip.setMicrosecondPosition(position * 1000000);
        }
    }

    public void open() {
        JFileChooser chooseSong = new JFileChooser();
        chooseSong.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooseSong.setFileFilter(new FileNameExtensionFilter(null, "wav"));
        int chooseButton = chooseSong.showOpenDialog(null);
        File songPath = chooseSong.getSelectedFile();

        if ( (chooseButton!=JFileChooser.CANCEL_OPTION) && (songPath!=null) && (songPath.getName() != null) ) {
            try {
                playLabel.setIcon(pauseImage);
                if (playStatus != Status.OFF)
                    songClip.close();

                AudioInputStream songFile = AudioSystem.getAudioInputStream(songPath);
                songClip = AudioSystem.getClip();
                songClip.open(songFile);

                int clipLength = (int)(songClip.getMicrosecondLength() / 1000000);
                slider.setMinimum(0);
                slider.setMaximum(clipLength);
                songClip.start();

                if (playStatus == Status.OFF)
                    screenThread.start();
                else if (playStatus != Status.OFF)
                    screenThread.resume();

                playStatus=Status.ON;
            }
            catch(Exception exp) {
                Toolkit.getDefaultToolkit().beep();
                JOptionPane.showMessageDialog(null, String.format("ERROR = %s",exp.getClass()));
                System.exit(0);
            }
        }
    }

    public void run() {
        while (true) {
            colorPanel.setBackground(new Color(new Random().nextInt(256), new Random().nextInt(256), new Random().nextInt(256)));           
            if (songClip.getMicrosecondPosition() == songClip.getMicrosecondLength()) {
                screenThread.suspend();
                playStatus=Status.END;
                playLabel.setIcon(playImage);
            }
        }
    }
}

You are calling screenThread.suspend(); in the block that responds to clicking the play/pause button. Thread methods suspend() and resume() are deadlock prone - that is, using them often causes hard-to-diagnose issues like the one you're having.

You need to remove the use of these methods by instead polling a variable, as described on this page .

This method has been deprecated, as it is inherently deadlock-prone.

This is the reason that is given for the deprecation of Thread.stop() , .suspend() and .resume() . As you are using these in your code it could be the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM