Reputation: 113
I have a code with 2 classes MPlayer and Audio.
MPlayer has the GUI (JButtons, JPanel and JFrame etc), and Audio has the code to play audio.
The problem is when i call the pause method in class MPlayer, it does not pause the audio.
Can someone help me with it?
MPlayer.java:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MPlayer extends JFrame implements ActionListener {
ImageIcon icon1, icon2, icon3, icon4;
JPanel pan1;
JFrame frame;
JMenuBar bar;
JMenu menu;
JMenuItem menuItem;
JButton btn1, btn2;
public void initGUI() {
bar = new JMenuBar();
menu = new JMenu("Open");
bar.add(menu);
menuItem = new JMenuItem("Open");
menu.add(menuItem);
BorderLayout bl = new BorderLayout();
FlowLayout fl = new FlowLayout();
pan1 = new JPanel();
frame = new JFrame("Music Player");
frame.setLayout(bl);
pan1.setLayout(fl);
frame.setJMenuBar(bar);
icon1 = new ImageIcon("./play.jpg");
icon2 = new ImageIcon("./pause.png");
icon3 = new ImageIcon("./stop.jpg");
icon4 = new ImageIcon("./wallpaper.jpg");
frame.getContentPane().setBackground(Color.BLACK);
btn1 = new JButton(icon1);
btn1.setVisible(true);
btn2 = new JButton(icon3);
btn2.setVisible(true);
pan1.add(btn1);
pan1.add(btn2);
frame.add(new JLabel(icon4), BorderLayout.CENTER);
frame.add(pan1, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setFocusable(true);
btn1.addActionListener(this);
menuItem.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Audio aud = new Audio();
if (e.getSource() instanceof JMenuItem) {
if (((JMenuItem) (e.getSource())) == menuItem) {
aud.openFile();
}
}
if (btn1.getIcon() == icon1) {
btn1.setIcon(icon2);
aud.pause();
} else if (btn1.getIcon() == icon2) {
btn1.setIcon(icon1);
}
}
public static void main(String[] args) {
MPlayer gui = new MPlayer();
gui.initGUI();
}
}
Audio.java:
import javax.sound.sampled.*;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Audio {
File file;
AudioInputStream audio;
AudioFormat fmt;
DataLine.Info dli;
Clip c;
JFileChooser jfc;
public void openFile() {
try {
jfc = new JFileChooser();
jfc.showOpenDialog(null);
file = jfc.getSelectedFile();
audio = AudioSystem.getAudioInputStream(file);
fmt = audio.getFormat();
dli = new DataLine.Info(Clip.class, fmt);
c = (Clip) AudioSystem.getLine(dli);
c = AudioSystem.getClip();
c.open(audio);
c.start();
} catch (Exception ex) {
ex.getMessage();
}
}
public void pause() {
if (c.isRunning()) {
c.stop();
}
}
}
Upvotes: 4
Views: 812
Reputation: 7396
You are doing everything in the same thread. Swing applications start on what is called the Event Dispatch Thread - this is the thread that handles all UI interactions. You should not be performing long-running tasks (like playing audio) in this thread.
Spawn a new thread to play the audio, and I think you'll find things work better. You can do this manually or you can use something like a SwingWorker to do this, which would allow you to provide regular feedback on the "progress" of your playing (i.e. you can say you're X% done with the file etc, or that there are 3m25s left etc).
The class documentation for SwingWorker is quite good and I highly suggest you read it, regardless of whether or not you are going to use it, as it has some very good suggestions for threads in Swing in general.
Upvotes: 1