Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use SwingWorker in Java?

Related to my previous question: Call repaint from another class in Java?

I'm new to Java and I've had a look at some tutorials on SwingWorker. Yet, I'm unsure how to implement it with the example code I gave in the previous question.

Can anyone please explain how to use SwingWorker with regards to my code snippet and/or point me towards a decent tutorial? I have looked but I'm not sure I understand yet.

like image 234
Relequestual Avatar asked Apr 23 '09 15:04

Relequestual


People also ask

What happens when SwingWorker task is not finished?

If the SwingWorker object has not finished executing the doInBackground() method, the call to this method blocks until the result is ready. It is not suggested to call this method on the event dispatch thread, as it will block all events until it returns. cancels the task if it is still running.

What is doInBackground () in Java?

doInBackground(Params...) , invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step.

Where is Swing used in Java?

Swing in java is part of Java foundation class which is lightweight and platform independent. It is used for creating window based applications. It includes components like button, scroll bar, text field etc. Putting together all these components makes a graphical user interface.


2 Answers

Generally, SwingWorker is used to perform long-running tasks in Swing.

Running long-running tasks on the Event Dispatch Thread (EDT) can cause the GUI to lock up, so one of the things which were done is to use SwingUtilities.invokeLater and invokeAndWait which keeps the GUI responsive by which prioritizing the other AWT events before running the desired task (in the form of a Runnable).

However, the problem with SwingUtilities is that it didn't allow returning data from the the executed Runnable to the original method. This is what SwingWorker was designed to address.

The Java Tutorial has a section on SwingWorker.

Here's an example where a SwingWorker is used to execute a time-consuming task on a separate thread, and displays a message box a second later with the answer.

First off, a class extending SwingWorker will be made:

class AnswerWorker extends SwingWorker<Integer, Integer> {     protected Integer doInBackground() throws Exception     {         // Do a time-consuming task.         Thread.sleep(1000);         return 42;     }      protected void done()     {         try         {             JOptionPane.showMessageDialog(f, get());         }         catch (Exception e)         {             e.printStackTrace();         }     } } 

The return type of the doInBackground and get methods are specified as the first type of the SwingWorker, and the second type is the type used to return for the publish and process methods, which are not used in this example.

Then, in order to invoke the SwingWorker, the execute method is called. In this example, we'll hook an ActionListener to a JButton to execute the AnswerWorker:

JButton b = new JButton("Answer!"); b.addActionListener(new ActionListener() {     public void actionPerformed(ActionEvent e)     {         new AnswerWorker().execute();     } }); 

The above button can be added to a JFrame, and clicked on to get a message box a second later. The following can be used to initialize the GUI for a Swing application:

private void makeGUI() {     final JFrame f = new JFrame();     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     f.getContentPane().setLayout(new FlowLayout());      // include: "class AnswerWorker" code here.     // include: "JButton" b code here.      f.getContentPane().add(b);     f.getContentPane().add(new JButton("Nothing"));     f.pack();     f.setVisible(true); } 

Once the application is run, there will be two buttons. One labeled "Answer!" and another "Nothing". When one clicks on the "Answer!" button, nothing will happen at first, but clicking on the "Nothing" button will work and demonstrate that the GUI is responsive.

And, one second later, the result of the AnswerWorker will appear in the message box.

like image 143
coobird Avatar answered Oct 13 '22 00:10

coobird


Agree:

Running long-running tasks on the Event Dispatch Thread (EDT) can cause the GUI to lock up.

Do not agree:

so one of the things which were done is to use SwingUtilities.invokeLater and invokeAndWait which keeps the GUI responsive..

invokeLater still runs the code on the EDT, and can freeze your UI!! Try this:

SwingUtilities.invokeLater(new Runnable() {             @Override             public void run() {                 try {                     Thread.sleep(100000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         }); 

At least I, cannot move my mouse once I click the button which triggers the actionPerformed with the above code. Am I missing something?

like image 31
dalvarezmartinez1 Avatar answered Oct 12 '22 23:10

dalvarezmartinez1