1

When studying for an exam I stumbled upon some lines in java graphics that aren't really clear to me. So i started to glance and check some other programs and they were without those lines.

example:

public static void main(String[] args){
  SwingUtilities.invokeLater(new Runnable(){//unknown
  public void run(){                        //lines
  JPanel panel = new DrawingPanel();
  ...
}

now i know that Runnable and run have to deal with threads, but i don't know why and how do these two lines work

jabk
  • 1,388
  • 4
  • 25
  • 43
  • 2
    Have a look at this question: http://stackoverflow.com/questions/6567870/what-does-swingutilities-invokelater-do – Branislav Lazic Aug 25 '13 at 11:25
  • 1
    Please have a look at [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). Java Docs can explain this in a much better way :-) – nIcE cOw Aug 25 '13 at 11:26
  • 1
    One key with Swing is that all Swing calls should be made on a single thread, the event dispatch thread, including the code that starts the GUI. What you are doing (and what the API will tell you you are doing if you look up SwingUtilities) is queuing the Runnable onto this event thread. – Hovercraft Full Of Eels Aug 25 '13 at 11:27
  • 3
    This question is a duplicate of a duplicate which was already a duplicate. Search a little before asking! – Costis Aivalis Aug 25 '13 at 11:27
  • 1
    Yep, voting to close as a duplicate – Hovercraft Full Of Eels Aug 25 '13 at 11:28

2 Answers2

1

Swing objects can only be accessed from the Swing thread that runs in closed loop handling repaints, GUI events and so on. When you application starts, it starts in an ordinary thread (not a Swing thread). The lines that look strange to you use SwingUtilities to execute DrawingPanel constructor and probably more code in the Swing thread.

The code that instantiates the first GUI frame directly from the main thread may also work in practice if it is really the first method ever called (as expected). However it is "fundamentally wrong" approach that may not work later under different machine, if differently called and the like.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
1

Swing is a single threaded framework. All interactions and updates with the UI are expected to be executed from within the context of the Event Dispatching Thread.

Java makes no guarenttees that main is executed within the EDT (I believe they normally call this the main thread). Therefore, you are required to ensure that any of your UI code is synced to the Event Dispatching Thread first.

SwingUtilities.invokeLater, delegates to EventQueue.invokeLater. This basically posts the Runnable instance into the event queue, which is processed by the Event Dispatching Thread.

At some time in the future, the Runnable is popped off the queue and the run method is executed within the EDT

See Initial Threads for more details

You could also look at The Single Thread Rule in Swing, Event-Dispatching Thread Rules for Swing UIs for additional info

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 2
    "guaranteed not to be executed within the EDT"... unless you specify `-XstartOnFirstThread`, a requirement to run SWT on Cocoa. – Marko Topolnik Aug 25 '13 at 11:33
  • @MarkoTopolnik 1- The X parameters aren't guaranteed to be supported 2- I don't see `XstartOnFirstThread` in the available parameter list (admittly, I'm checking with a Windows version) 3- It's still safer not to assume anything about the state of the program (yes you could check `EventQueue#isEventDispatchingThread`, but you'd still need the `invokeLater` call anyway... – MadProgrammer Aug 25 '13 at 11:36
  • It's an OS X-specific issue, yes. However, this counterexample does impinge on the statement "guaranteed not to be executed within the EDT". Clearly, there cannot be any guarantee (if by "guarantee" you mean the JVM specification). – Marko Topolnik Aug 25 '13 at 11:38
  • @MarkoTopolnik There's no gurentee that the user executing the application will use the `-X` parameter or that the application is begin executed in an environment that supports it or that the `-X` parameter is available. As I said, yes, you can check for `isEventDispatchingThread`, but you'd still need to provide `invokeLater` anyway...IMHO, it's just simpler to assume the worst – MadProgrammer Aug 25 '13 at 11:41
  • Your edited wording definitely better reflects reality: there is no guarantee that `main` either will or won`t run on the EDT. Assume the worst, by all means, but don`t *rely* on the worst actually being guaranteed :) – Marko Topolnik Aug 25 '13 at 11:46
  • @MarkoTopolnik It's probably a nit-pick on my part, but I think you have to be defensive about it, because you have to write the code to allow for `invokeLater`, when starting the program, I would believe it would be simpler to just run it that way (IMHO), as you're execution process isn't reliant on a given state (other then not being initialised) - IMHO ;) – MadProgrammer Aug 25 '13 at 11:50
  • I completely agree, but if you say the main thread is guaranteed not to be the EDT, that belief can lead to broken code when run with -XstartOnFirstThread. – Marko Topolnik Aug 25 '13 at 12:13