There have been several questions asked, and suggestions posted, and sadly it was only by a great deal of reading and trial and error that I was able to make a simple test work correctly. Also, sometimes sample code that is associated with questions asked (and commented on) is too brief or specific to extrapolate a general solution. So I present here a complete little app that not only demonstrates a working example, it applies it in what should be a very common use.
Thanks for all the expertise posted on StackOverflow. It is an absolutely invaluable resource.
BTW, don't bother commenting on my formatting preferences - I believe clarity trumps tradition.
import java.lang.reflect.Method;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
// ========================================================================= //
public class TestCallable
{
// --------------------------------------------------------------------- //
public static void main( String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
// this runs on the EDT
new TestCallable();
}
} );
}
// --------------------------------------------------------------------- //
TestCallable()
{
// create a test environment (in the EDT)
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
final JTextArea textArea = new JTextArea( 10, 20 );
frame.add( textArea );
frame.pack();
frame.setLocation( 400, 400 );
frame.setVisible( true );
// go do something in a background worker thread
SwingWorker < Void, String > worker = new SwingWorker < Void, String >()
{
// ------------------------------------------------------------- //
@Override public Void doInBackground()
{
// this runs on a worker thread
Method publishMethod = null;
try {
publishMethod = this.getClass().getMethod( "myPublish",
new Class[] { String.class } );
} catch ( Exception ex ) {}
Worker ww = new Worker( this, publishMethod );
// this is the worker-bee method
ww.doSomething();
return null;
}
// ------------------------------------------------------------- //
@Override protected void process( List < String > msgs )
{
// is running in EDT
for ( String str : msgs )
textArea.append( str+"\n" );
}
// ------------------------------------------------------------- //
@SuppressWarnings( "unused" ) public void myPublish( String str )
{
// this wrapper seems to be necessary because publish()
// seems to be invisible to getMethod().
publish( str );
}
};
worker.execute();
}
// ===================================================================== //
class Worker
{
Object object;
Method publishMethod;
// ----------------------------------------------------------------- //
Worker( Object object, Method publishMethod )
{
// part of the infrastructure trick
this.object = object;
this.publishMethod = publishMethod;
}
// ----------------------------------------------------------------- //
public void publish( String message )
{
// part of the infrastructure trick
Object[] parameters = new Object[ 1 ];
parameters[ 0 ] = message;
try {
publishMethod.invoke( object, parameters );
} catch ( Exception ex ) {}
}
// ----------------------------------------------------------------- //
void doSomething()
{
// this is the worker method (or any additional methods in this class)
// that actually goes off and does something important
publish( "hello world" );
}
}
}
Aucun commentaire:
Enregistrer un commentaire