Disabling main event from background thread in Java

My question is about multithreading in Java. I am rewriting an application I wrote in Visual Basic 2008 in Java. VB has a class called BackgroundWorker that allows the coder to perform a task on a different thread, much like SwingWorker

in Java. The only difference is that when threading, BackgroundWorker

run()

it fires an event called DoWork()

on the main line that contains code to execute in the background. In addition, after the code is executed, the event RunWorkerCompleted()

returns to the foreground thread to interpret the results.

I found the setup BackgroundWorker

quite useful and seems a little more flexible than SwingWorker

that, and I'm just wondering if it is possible (and valid) to trigger events in the same way in Java? And if so, how can I do it? Since I just looked quickly SwingWorker

, it is possible that it has similar functionality that would work just as well, in which case I would be happy to know about it.

Greetings,

hype

EDIT:

Kewl. Hi guys, thanks for the quick answers and apologies for my rather weak answer. I'll give you Oscar's idea, sorry coobird, I didn't quite follow - any further explanation would be appreciated (maybe an example).

Just for example: I want to have a runnable class that I instantiate in my code. The runnable class has two events, one of which is triggered from a background thread and contains code to run in the background ( DoWork()

), and the other event is triggered on the foreground thread after the background thread has completed the job ( RunWorkerCompleted()

).

And if I understand your advice correctly, I can fire the event DoWork()

from the 'runnable class' method run()

so that it runs on the background thread, and then I can use the method SwingUtilities.invokeLater()

to fire the event RunWorkerCompleted()

on the foreground thread as soon as the background thread finishes executing.

Yes?

+1


source to share


3 answers


The sole intention of the following code is to show what it looks like when the SwingUtilities.invokeLater method is used.

An effect is a task that runs on the AWT event thread (the one responsible for drawing the components).

The rest (creating a new thread, creating a gui, etc.) is just the scaffold code.



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InvokeLaterEffect {

    static JTextArea text = new JTextArea();


    // See the diff by commenting.
    static void done() {
        SwingUtilities.invokeLater( doneAction ); 
        //doneAction.run();
    }


    public static void main( String [] args ) {
        JFrame frame = new JFrame();
        frame.add( text );
        frame.pack();
        frame.setVisible( true );

        bacgroundTask.start();
    }
    // run a task in the background
    static Thread bacgroundTask = new Thread(){
        public void run(){
            try { 
                System.out.println( Thread.currentThread().getName() + " Started background task ");
                Thread.sleep( 5000 );
                System.out.println( Thread.currentThread().getName() + " Finished background task");
                done();
            } catch ( InterruptedException ie ){}
        }
    };

    // called whtn id done
    static Runnable doneAction = new Runnable(){
        public void run(){
            System.out.println( Thread.currentThread().getName() + " start setting text ");
            text.setText("Hello");
            System.out.println( Thread.currentThread().getName() + " finish setting text ");
        }
    };


}

      

The output looks like this:

Thread-2 Started background task
Thread-2 Finished background task
AWT-EventQueue-0 start setting text
AWT-EventQueue-0 finish setting text

      

0


source


What was the main line?

Let me make sure I am right.

The background thread fires an event that the GUI can intercept to know the data is ready.

Is it correct?

You can use SwingUtilities.invokeLater (Runnable r);



Inserts this executable instance into the AWT event dispatch thread (which I believe is the same as the main line) after all events occurring on that thread have been processed.

This way you can fire the ActionPerformed event and the registered listener will handle it correctly.

Let me say something very quickly and you will tell me if it was what you wanted.

In the meantime, look here

+1


source


Not really sure if that helps, but look at SwingWorker from Java 6 (which is new and different from previous releases) and Java tutorials on the subject, it might suggest something similar to what you might be after.

Taking a look at the Concurrency in Swing section in the Java Tutorials, it has a Related Properties and State Methods section that mentions how to register PropertyChangeListener

with SwingWorker

. This way, any events that you want to notify another thread can be executed by creating PropertyChangeEvent

with methods firePropertyChange

.

Also see the section on the SwingWorker Is Now section in Additional Enhancements in Java SE 6 for a quick description of the above.

So, if I understood the articles correctly, I first implement PropertyListener

in the stream to which the messages from the stream should be sent SwingWorker

. Then, to send a message back to the original thread, the firing property changes triggered from SwingWorker

in it doInBackground()

(using a method firePropertyChange

) can be used as a means of sending messages to another.

0


source







All Articles