1

need to make a music player as my simple java project. it opens up a file and loads the name in the text field.when play is pressed, the name is encircled in the textfield and when pause is pressed , the encircling suspends . play pause are JTogglebuttons and i have a button names stop. using multithreading, i m able to play and pause the string but after i press Stop once.. if again i open up a new music file and press play, it shows an illegalthreadstateexception.Please help me out here.. Note: i havent yet put in the code for playing music in it.. i will put it in once this problem is solved . thanks a lot for ur

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import sun.audio.*;

public class search extends Thread implements ActionListener
{
JFrame f;
JButton stop,open;
JToggleButton play;
JTextField tf,text;
JTextArea ta;
JLabel lab,lab1;
String str,dest;
JScrollPane scrol;
File fl;
int myfl=0,myfl1=0,myfl2=0;
search()
{
    f=new JFrame("Music Player");
    f.setLayout(null);
    f.setSize(620,300);

    play=new JToggleButton("play");
    play.setBounds(100,150,270,30);
    play.addActionListener(this);
    f.add(play);
    play.setEnabled(false);


    stop=new JButton("stop");
    stop.setBounds(400,150,120,30);
    stop.addActionListener(this);
    f.add(stop);
    stop.setEnabled(false);

    open=new JButton("open");
    open.setBounds(100,200,420,30);
    open.addActionListener(this);
    f.add(open);    


    tf=new JTextField();
    tf.setBounds(25,50,565,40);
    tf.setFont(new Font("DK BabySitter",Font.BOLD,20));
    tf.setHorizontalAlignment(JTextField.CENTER);
    f.add(tf);

    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


}

public void actionPerformed(ActionEvent ae)
{
   if(ae.getActionCommand().equals("open"))
    {
        FileDialog fd=new FileDialog(f,"Open Box",FileDialog.LOAD);
        fd.setSize(300,300);
        fd.setVisible(true);
    String s1="mp3";
    str=fd.getFile();
    dest=fd.getDirectory()+fd.getFile();
    if(str.toLowerCase().endsWith(s1))
    {

            tf.setText(str);
        //pause.setEnabled(true);
        play.setEnabled(true);
        stop.setEnabled(true);
    }
    else
    {
        JOptionPane.showMessageDialog(f, "Select a valid file format"); 
    }



    }

   if(ae.getActionCommand().equals("stop"))
    {   

    play.setLabel("play");
    myfl1=1;
        tf.setText(" "); 
    stop();

    }

   if(ae.getActionCommand().equals("play"))
    {   
    try
    {
        play.setLabel("pause");

        if(myfl==1 && myfl1==0)
        {
            resume();
        }

        if(myfl==0 || myfl1==1)
        {
            start();
        }
    }
    catch(IllegalThreadStateException e)
    {
        tf.setText("error a gya re");
        Thread newth= new Thread();
        newth.start();

    }
    }
   if(ae.getActionCommand().equals("pause"))
    {
    play.setLabel("play");
    myfl=1;
    suspend();
    }


} 

public void run()
{
    try
    {
        String rot=tf.getText();
    char rotn[]=new char[rot.length()];
    int flag=rot.length();
    int move=0;
    rotn=rot.toCharArray();
    tf.setText(" ");
    for(;;)
    {
        for(;;)
        {   
            sleep(100);
            tf.setText( tf.getText() + rotn[move]);
            move++;

            if(move==(flag-1))
            {   

                move=0;
                break;
            }

        }
    tf.setText(" ");    
    }
    }


    catch(Exception e)
    {
        tf.setText("error occured");
    }                 

}
    public static void main(String args[])
    {
      try {
            // Set System L&F
        UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }
        new search();
    }

}
  • 1
    Don't try to suspend or stop the thread! Code the thread to do what, and only what, you want it to do. Then you won't have to suspend or stop it. – David Schwartz Mar 07 '13 at 08:59
  • 1
    (i) a Thread can only be started once, so you can't start / stop / start for example (ii) stop and resume are both deprecated and should not be used – assylias Mar 07 '13 at 09:03
  • See also http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html – Andreas Fester Mar 07 '13 at 09:04
  • Possible duplicate of [How to start/stop/restart a thread in Java?](http://stackoverflow.com/questions/1881714/how-to-start-stop-restart-a-thread-in-java) – Raedwald Jan 23 '16 at 17:42

2 Answers2

0

You should not use Thread.stop(), Thread.suspend() or Thread.resume(). These methods are deprecated and explicitly documented to have severe implications (like potential deadlocks etc). See also Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

In this specific case the exception occurs because you cannot start() a Thread more than once. You need to code your thread (or better yet: don't extend Thread, but implement Runnable) so that it handles the pause, start, stop etc of your application correctly without using the deprecated and dangerous methods of Thread.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
0

The reason you're getting this error is that you're attempting to manually manipulate the state of the thread you're running in.

The methods you're using here are all deprecated - stop, resume, suspend - these should all be avoided.

A better way to think about how your program is running is that a thread is either alive or it isnt. It may not do anything within the actual run method while alive, but at no point are you pausing/suspending/stopping the actual thread - you're only pausing/stopping the application logic within.

A very quick fix to what you're seeing is to replace all stop/suspend/resume with the following:

private volatile boolean paused = false;
private void pausePlayer(boolean pause) {
    this.paused = pause;
}

then everywhere you need to pause the player use:
pausePlayer(true);

and when you want to resume it use:
pausePlayer(false);

In the run method replace the 2nd for loop with:

for (; ; ) {
    while(!paused) {
        // do your work

Note though that I believe there are larger structural issues with the program as it stands - mixing normal Threads with Swing can be problematic. I would suggest you investigate using a SwingWorker instead, as this is explicitly designed for the sort of thing you're trying to do.

Sean Landsman
  • 7,033
  • 2
  • 29
  • 33