Swing EDT and UIManager Initialization Question

We all know you are supposed to only interact with Swing GUI components on the event dispatch thread (EDT). Your main method might look like this:

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

But what about the first time you call UIManager.setLookAndFeel(...)? Does this one-time action have to go on the EDT?

Sun’s own examples are inconsistent.

First example:

public static void main(String[] args) {
  //Schedule a job for the event dispatch thread:
  //creating and showing this application's GUI.
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      createAndShowGUI();
    }
  });
}

private static void createAndShowGUI() {
  //Set the look and feel.
  initLookAndFeel();
  ...
}

private static void initLookAndFeel() {
  ....
  UIManager.setLookAndFeel(lookAndFeel);
  ...
}

So you see, in that example, they are careful to set the look and feel on the EDT.

But here is another example from the same web site:

public static void main(String[] args) {
  try {
    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
  } catch (...) {
    ...
  }

  //Schedule a job for the event-dispatching thread:
  //creating and showing this application's GUI.
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      createAndShowGUI();
    }
  });
}

I assume the second example is wrong. I believe you might be able to get away with it, maybe even thousands of times, but perhaps once in awhile you might see some weird threading issue or memory visibility problem. ???

What is the correct answer?


codepope Says:

From my intuition, there is no issue calling UIManager,setLookAndFeel() at startup; it only alters the default values in the library and doesn’t trigger any UI changes as there is at that point no UI to be changed. Now, when you do have a UI, then the UIManager.setLookAndFeel can still be done off the EDT, but SwingUtilities.updateComponentTreeUI(…) to redraw the UI should be on the EDT.

Both examples are therefore correct, as they both invoke before there’s any UI in existence.

Eric Burke Says:

But if UIManager is not designed for thread safety, isn’t there a possibility of memory visibility problems, since we are creating objects in the main thread and then accessing them from the event dispatch thread? Seems like UIManager (and everything it touches) would have to be explicitly synchronized, or use volatile, or some similar mechanism, to ensure visibility across threads.

Paranoid Says:

I know this article is very old, but can’t stay without replying.
As i understand, only operations with Graphics or Graphics2D need to be performed from EDT, because Graphics is not synchronized. Almost all other things, including JTable’s repaints (marking of dirty regions for repaint manager) and GUI creation can be done from elsewhere.