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.
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.
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.
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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With