CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Dec 2008
    Posts
    87

    Repeating a SwingWorker

    I'm using a SwingWorker to seperate a loop in my code which plays a midi sound. However I need to use the SwingWorker more than once and there's no way of telling how many times it will need to be repeated as its executed on a button click.

    Here is the method which uses the SwingWorker:

    Code:
    public void playTune() {
    		//Play tune swing worker
    		SwingWorker<TunePlayer, Void> playWorker = new SwingWorker<TunePlayer, Void>() {
    			@Override
    			protected TunePlayer doInBackground() throws Exception {
    				while (!stopTune) {
    					if (!player.isPlaying()) {
    						player.play(tune);
    					}
    				}
    				
    				return null;
    			}
    		};
    		
    		playWorker.execute();
    	}
    I understand that doInBackground() can only be executed once but here I am making a new object every time that button is pressed (playTune() is fired when the button is clicked). Equally I should mention that there is a stop button which turn stopTune to true when it is clicked. Any help would be much appreciated

  2. #2
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    Why are you using SwingWorker to provide the background execution?

    The advantage of using a SwingWorker over creating your own background thread is it simplifies the task of updating the GUI from the background thread. You don't appear to be updating the GUI from the background thread so you probably don't need to use SwingWorker.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  3. #3
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    The program does use Swing for GUI and as said these are triggered on a button click. I've tried using ordinary threads with this but as soon as you press play the whole program freezes. The loop works as you can hear the sound looping round but obviously you can't do anything and you can't even press the stop button.

    SwingWorker seems to do fine as it does exactly what I want it to except for the fact that I can't run it more than once.

  4. #4
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    SwingWorker provides a mechanism for you to interact with the GUI from the background thread - you are not doing this hence you do not need a SwingWorker. What you are doing is running a time consuming task and don't want the GUI to freeze whilst the task it is running, therefore you need to run it on a background thread ie not the Event Dispatch Thread. You do not need a SwingWorker to do this, you just need to create your own thread and run the task on that.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  5. #5
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    I guess I understand that but I have already tried creating my own thread and running it from there and it still freezes the application. I've still got the code for the thread class if you need to see what I did?

  6. #6
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    Ok, by all means post the code so we can tell you what is wrong with it.

    What I would do is create a Runnable object to play the sound, create a single thread ExecutorService object by calling Executors.newSingleThreadExecutor() and then every time I wanted to play the sound submit the Runnable to the ExecutorService object.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  7. #7
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    Ok here is the thread class that I created a while back. In the other class where the SwingWorker is it was replaced with:

    Code:
    Thread playerThread = new Thread(new LoopsPlayer(tune, player));
    playerThread.run();
    The thread class code is:

    Code:
    public class LoopsPlayer implements Runnable {
    	private boolean stopTune;
    	private Tune tune;
    	private TunePlayer player;
    	
    	public LoopsPlayer(Tune tune, TunePlayer player) {
    		this.tune = tune;
    		this.player = player;
    	}
    	
    	public void setStopTune(boolean stop) {
    		stopTune = stop;
    	}
    	
    	@Override
    	public void run() {
    		while (!stopTune) {
    			if (!player.isPlaying()) {
    				player.play(tune);
    			}
    		}
    	}
    }

  8. #8
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    Your code is creating a background thread with a Runnable object but is then directly calling the run() method from the Event Dispatch Thread ie you aren't using the background thread the play the sound. To use the background thread you need to call it's start() method and not the run() method.

    This of course will still be a one shot object because you can't restart a thread once it has completed. That's why I suggested you create an ExecutorService.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  9. #9
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    So basically what you're saying is its going to be no different from what I'm trying to do now? I've never actually heard of an ExecutorService, looks like I'll need to look that one up

  10. #10
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    Look in the java.util.concurrent package
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  11. #11
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    You would use it as follows:

    Code:
    ExecutorService exec = Executors.newSingleThreadExecutor();
    
    Runnable player = new Runnable()
        {
        @Override
        public void run()
            {
            // play sound code
            }
        };
    
    ...
    
    
    // place this line in your action listener to play the sound every time it is executed
    exec.submit(player);
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  12. #12
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    Ok thanks I'll give this a try

  13. #13
    Join Date
    Dec 2008
    Posts
    87

    Re: Repeating a SwingWorker

    Worked perfectly and does everything I wanted, many thanks for your help! I only have one last question, when the loop ends and it exits the run() method is the thread cleared up as normal? In other words if I click start, stop then start again I'm not using 2 different threads am i? I don't want it to end up creating like 20 threads or anything silly

  14. #14
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Repeating a SwingWorker

    The thread stops when the run() method finishes. It's the approved way of stopping it.

    I think there is a world market for maybe five computers...
    T. J. Watson (IBM)
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  15. #15
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Repeating a SwingWorker

    If you are using an ExecutorService then a single thread (or pool of threads depending on the type of Executor service you have created), is kept alive by the ExecutorService object to run the tasks you submit to it, until you call one of its shutdown methods.

    So to answer your question, if you keep the same ExecutorService alive to play the sounds as and when you need them then it will reuse the thread(s) it has, it will not start new threads each time you submit a task to it.

    I didn't mention shutdown before but you should shutdown the service once you no longer need it to release its resources.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured