Jump to content




Recent Status Updates

  • Photo
      18 Aug
    KodeKool

    When faced with a wall of errors and no hope to fix them, remember the following "Programs always do what you tell them to, and seldom what you want them to, but eventually you'll run out of things that can go wrong and it'll just work. and that's the secret to good programming."

    Show comments (2)
  • Photo
      11 Aug
    Error

    Should I be practicing programming every day? I feel if I don't, I'll get instantly rusty or something.

    Show comments (4)
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
  • 156 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