Jump to content




Recent Status Updates

  • Photo
      15 Sep
    Error

    Programming is something that I enjoy and want to make a career out of. But, I usually tend to start things and not finish them. Any advice on how I can finish what I start?

    Show comments (2)
View All Updates

Developed by Kemal Taskin
Photo
- - - - -

Swing Thread Safety - How to properly modify components.


  • Please log in to reply
No replies to this topic

#1 farrell2k

farrell2k

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 157 posts

Posted 18 June 2010 - 09:08 PM

Swing is not thread safe, so to avoid the possibility of deadlocks, all component realization and modification should be done in the event dispatch Thread (EDT) by invoking SwingUtilities.invokeLater(). It is likely, however, that your applications will work just fine 99% of the time without this. invokeLater adds your action to the EDT.

Example:

Creating a JFrame

package gooey;

import javax.swing.*;

public class Gooey {
    private JFrame frame;

    public Gooey() {
        initComponents();
    }

    private void initComponents() {
        frame = new JFrame("Thread Safety");
        frame.setSize(200,200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[]args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Gooey();
            }
        });
    }
}

This ensures that the EDT is the only thread realizing components. Can you imagine what would happen if new Gooey() was called at the same time from your main thread as well as the event dispatch Thread? A dealock.

The same goes for updating components under different threads. Lets say that you have a while loop in a main game that updates a jLabel via a seperate thread every couple of seconds.

while(!gameOver) {
    label.setText("Game is not over, yet!");
}

Now, if your while loop called on label.setText() at the same time the EDT was repainting that component, a deadlock would occur and your app would freeze. The way to fix this is to do your component updates via the EDT.

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        label.setText("Game not over, yet!");
    }
});
You do NOT have to uset Swingutilities.invokeLater while modifying a component via a gui event such as in an ActionEvent due to a button click, as all ActionEvents happen in the EDT already. Anything in actionPerformed, or any other Listener interface method is executed in the EDT and does not need SwingUtilities.invokeLater() It is also safe to call repaint() anywhere, as all repaint requests occur in the EDT.

Again, you may never use SwingUtilities, and may never have a problem, but you should use it whenever you're updating a component in a situation like the above.
  • 0