0

When I start my GUI interfaces, what can happen if I don't use invokeLater?

  1. Does that mean all rest of the GUI paints/updates/etc. will be in the main thread?
  2. Will calling a repaint outside of an invokeLater make all subsequent calls fall into the main thread?

Basically this:


void main()
{
    JFrame jmf();
    setVisible(jmf);
}

------------- VS -------------

void main()
{
    SwingUtilities.invokeLater(new Runnable(){
       run(){
          JFrame jmf();
          setVisible(jmf);
       }
    }
});

NOTE: In cases with small GUI, I if I don't put the invokeLater it seems to work fine. And in fact the application doesn't terminate although the last line of the main is executed.

I have read quite a few articles on why we should use it pertaining to the fact that Swing is not thread safe (it is single threaded and so on), but I really didn't read the repercussions of not calling invokeLater (partially because of my limited knowledge in Threads)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Mathew Kurian
  • 5,949
  • 5
  • 46
  • 73
  • 1
    It doesn't happen always, but you risk intermittent failure of your application. It's happened to me, especially when using some Look and Feel. – Hovercraft Full Of Eels Nov 29 '13 at 23:37
  • @Hovercraft Full Of Eels I am adding a bit more detail to the question. – Mathew Kurian Nov 29 '13 at 23:38
  • 2
    To be "really" honest, unless you are doing some really dynamic setups, until the a frame is made visible it "should" be okay not to do it within the context of the EDT. The problem comes down to the fact that different platforms are implemented differently. For example, the original requirement for using `invokeLater` when starting your UI seems to have come from deadlocks on the Sun OS many years back. I've also seen some issues with Java 7. The general advice is, use `invokeLater` to create and display your UI. Run all UI code within the context of the EDT – MadProgrammer Nov 29 '13 at 23:41
  • My first lockup was on using Nimbus L&F. My app just died. – Hovercraft Full Of Eels Nov 29 '13 at 23:43
  • It will also reduce the risk of you having to spend weeks trying to replicate and track down those weird anomalies (by running you all you UI code from within the EDT) – MadProgrammer Nov 29 '13 at 23:43
  • @MadProgrammer But if I call `repaint()` from the main thread won't the whole "repaint" process be in the main thread? Well atleast, until the component is refreshed. By the whole whole process as in "rasterization" and "drawing texture/quads" (Please ignore my DX terms, but you get the idea). – Mathew Kurian Nov 29 '13 at 23:44
  • 1
    `repaint()` I believe queues a request on the EDT. – Hovercraft Full Of Eels Nov 29 '13 at 23:48
  • 2
    It will only fail when you demo your program for the boss or for a customer. Otherwise it will work just fine. – Hovercraft Full Of Eels Nov 29 '13 at 23:49
  • `repaint` makes a request to the `RepaintManager`, that makes decisions about what and when something should be paint. It will actually post a "paint" event directly on to the Event Queue, which is then processed by the Event Dispatching Thread, so `repaint` is actually on (of the few) thread safe methods... – MadProgrammer Nov 29 '13 at 23:49
  • @MadProgrammer If you can put that as an answer, atleast I can atleast thank you with some points for the answer :P – Mathew Kurian Nov 29 '13 at 23:51
  • @MadProgrammer Can you expand on the concept of dirty region? You mean it doesn't rerender the whole screen like in DX for instance (esp. when you use a swap chain)? – Mathew Kurian Nov 29 '13 at 23:53
  • Not really what I mean. In the concept of a dirty update means that part of the view is updated with the part of the old model while part is update with the contents of the new model. This is more of a race condition, where the model state is updated from another thread WHILE a paint is in progress...never pretty, hard to replicate, harder to debug... – MadProgrammer Nov 29 '13 at 23:55
  • Remember, Swing employees (in part) the MVC paradigm. – MadProgrammer Nov 30 '13 at 00:08
  • Your main class won't cause any issues as it is, because even though you violate threading rules, there is nothing done in the other thread yet, because nothing has been created to handle, yet. But as soon as that JFrame is visible, doing the same again _could_ cause issues. – TwoThe Nov 30 '13 at 12:16

1 Answers1

4

The reality is, nothing might happen or the world will end. It's next to near impossible to predicate, this is the nature of multi-threaded environments...

Unless you are doing some really dynamic setups, until the a frame is made visible it "should" be okay not to do it within the context of the EDT.

The problem comes down to the fact that different platforms are implemented differently (at the native level). For example, the original requirement for using invokeLater when starting your UI seems to have come from deadlocks on the Sun OS many years back.

I've also seen some issues with Java 7 (but my predecessors idea of the thread was weird to say the least). The general advice is, use invokeLater to create and display your UI. Run all UI code within the context of the EDT

It will also reduce the risk of you having to spend weeks trying to replicate and track down those weird anomalies (by running you all you UI code from within the EDT)

Updated based on comments from the OP

repaint makes a request to the RepaintManager, that makes decisions about what and when something should be paint. It will actually post a "paint" event directly on to the Event Queue, which is then processed by the Event Dispatching Thread, so repaint is actually on (of the few) thread safe methods...

Take a look at

The general advice would be, you should use invokeLater because that's how the API has been designed, doing anything else is inviting problems...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366