Re: [SWING] Join thread with SwingWorker objects
Here's what I came up with:
package swingthreads;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Main
{
public static void main( String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
createGui();
}
} );
}
private static void createGui()
{
final ExampleFrame frame = new ExampleFrame();
final Executor exe = Executors.newFixedThreadPool( 5 );
ActionListener batchKicker = new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
ExampleWorker worker = new ExampleWorker( exe, 5, frame.
getOutput() );
worker.execute();
}
};
frame.addButtonListener( batchKicker );
frame.setVisible( true );
}
}
class ExampleFrame
extends JFrame
{
JTextArea output;
JButton button;
public ExampleFrame()
{
super( "Example Batch Threads" );
output = new JTextArea();
JScrollPane sp = new JScrollPane( output );
add( sp );
button = new JButton( "Start" );
JPanel panel = new JPanel( new FlowLayout( FlowLayout.CENTER ) );
panel.add( button );
add( panel, BorderLayout.SOUTH );
setLocationRelativeTo( null );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize( 300, 300 );
}
public JTextArea getOutput()
{
return output;
}
public void addButtonListener( ActionListener a )
{
button.addActionListener( a );
}
}
class ExampleWorker
extends SwingWorker<Void, Void>
{
Executor exe;
JTextArea output;
int tasks;
public ExampleWorker( Executor exe,
int tasks, JTextArea output )
{
this.exe = exe;
this.tasks = tasks;
this.output = output;
}
@Override
protected Void doInBackground()
throws Exception
{
CountDownLatch latch = new CountDownLatch( tasks );
for( int i = 0; i < tasks; i++ ) {
ExampleBatchTask batch =
new ExampleBatchTask( output, latch );
exe.execute( batch );
}
latch.await();
return null;
}
@Override
public void done()
{
output.append( "All done!\n" );
}
}
class ExampleBatchTask
implements Runnable
{
JTextArea output;
CountDownLatch latch;
public ExampleBatchTask( JTextArea output, CountDownLatch latch )
{
this.output = output;
this.latch = latch;
}
public void run()
{
int interval = (int) (Math.random() * 4 + 1);
// append() is thread safe!
output.append( "Started: " + interval + "\n" );
for( int i = 0; i < 5; i++ ) {
try {
Thread.sleep( interval * 1000 );
} catch( InterruptedException ex ) {
break; // exit immediately if interrupted
}
output.append( "running " + interval + "\n" );
}
latch.countDown();
}
}