Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Swing is a single threaded environment. That is, there is a single thread responsible for managing all the interactions and updates to the Swing UI - the Event Dispatching Thread.</p> <p>Among the golden rules of Swing are...</p> <ul> <li>DON'T block the EDT (<code>Thread.sleep</code>, <code>Thread#join</code>, <code>Object#wait</code>, block IO and/or time consuming tasks (among others) should never be called from within the EDT), doing so will stop the EDT from dispatching events and paint updates (amongst other things)</li> <li>ONLY create/update Swing UI elements from within the EDT.</li> </ul> <p>This raises a question...how do you "wait" for a thread?</p> <p>The best way is use an Observer pattern. Basically, you provide the <code>Thread</code> with some kind of reference that it will call to provide notification of events, such as errors and completion...</p> <p>This will require you to think very carefully about the design of your applications, as you can not rely on a simple A to B execution of your code.</p> <p>For example...</p> <pre><code>public class TestThreadCallBack { public static void main(String[] args) { new TestThreadCallBack(); } public TestThreadCallBack() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public interface ThreadCallBack { public void threadCompleted(Runnable source); public void threadFailed(Runnable source); } public class TestPane extends JPanel implements ThreadCallBack { private JLabel message; private JLabel dots; private int count; private Timer timer; public TestPane() { setLayout(new GridBagLayout()); message = new JLabel("Running background task, please wait"); dots = new JLabel(" "); add(message); add(dots); timer = new Timer(250, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { count++; if (count &gt; 3) { count = 0; } StringBuilder sb = new StringBuilder(3); for (int index = 0; index &lt; count; index++) { sb.append("."); } for (int index = count; index &lt; 3; index++) { sb.append(" "); } dots.setText(sb.toString()); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); Thread thread = new Thread(new BackgroundTask(this)); thread.start(); } @Override public void threadCompleted(Runnable source) { timer.stop(); message.setText("Task completed successfully"); } @Override public void threadFailed(Runnable source) { timer.stop(); message.setText("Task failed"); } } public class BackgroundTask implements Runnable { private ThreadCallBack callBack; public BackgroundTask(ThreadCallBack callBack) { this.callBack = callBack; } @Override public void run() { System.out.println("Background task underway..."); try { Thread.sleep(2000); } catch (InterruptedException interruptedException) { } int result = (int) Math.round((Math.random() * 1)); if (result == 0) { callBack.threadCompleted(this); } else { callBack.threadFailed(this); } } } } </code></pre> <p>Updating the UI from within a <code>Thread</code> other then the EDT is, well, messy. An easier solution would actually be to use a <a href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html" rel="nofollow"><code>SwingWorker</code></a>. This has publish/process methods that make easy to update the UI and progress methods that can be used to provide feedback about the progress of the current task.</p> <p>You can use it's <code>done</code> method to notify interested parties when the worker has completed.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload