views:

224

answers:

5

I have trouble understanding this simple code:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
      createAndShowGUI();
   }
});

Can anybody please explain me how it works (in simple terms because I am a newbie)? This short code is a part of this larger code.

To be more specific, I have the following questions:

  1. Does "public void run" define a new method? If it is the case, why it is defined within another method (see "larger code" for reference)?
  2. If "public void run" defines a new methods, what is a reason to define a method containing only one line of code (createAndShowGUI)?
  3. What does "invokeLater" do? This is actually the most complicated question for me.

I would like to emphasize one more time that I am a newbie and usage of "special" and "technical" words will produce even more questions.

Thank you in advance, if you decide to help me!

+4  A: 

It's an anonymous inner class.

You are defining three things:

  • A new class
  • A method called run within that class
  • A new instance of that class

In this example some operation (createAndShowGUI()) needs to run in the Swing thread. You cannot "jump" into another thread in the middle of a method call, so instead you are placing an object (the new instance you created) in a queue. When the Swing thread is ready it will remove that object from the queue and call your run method, which in turn calls createAndShowGUI. Now everything happens in the correct thread.

finnw
It's not "the Swing thread". The AWT Event Dispatch Thread (EDT) does not depend on Swing at all. `java.awt.EventQueue.invokeLater` makes much more sense.
Tom Hawtin - tackline
(`SwingUtilities.invokeLater` is only there for compatibility with Java 1.1 (superseded by Java2 version 1.2 in 1998).
Tom Hawtin - tackline
`SwingUtilities.invokeLater` and `EventQueue.invokeLater` were both introduced in 1.2. They became equivalent in 1.3. Neither is deprecated. And the AWT-vs-Swing distinction is not really relevant to a beginner question, so yes the EDT can be called "the Swing thread."
finnw
+7  A: 

The shortest answer I can give is:

Runnable is an interface in Java representing a type that defines a run method. Any class that implements this interface must provide an implementation for run. Runnables represent tasks that are to be executed by other parts of your system. Thread is a well-known Runnable.

When you have code that looks like new InterfaceName() { //implementation }, that is called an anonymous class. The point of an anonymous class is to make a one-off class implementing the interface type. This class has no name, and as such we can never refer to it again. It is only used here.

Without knowing much about Swing, it looks like SwingUtilities.invokeLater() accepts a Runnable and...well, I would guess it invokes it later (how much later is probably described in the JavaDocs). But, the reason you would define run here as simply another method invocation is that some code inside SwingUtilities is going to be calling the run method on this Runnable; indeed, all it can possibly know about any Runnable is that it defines a method with signature public void run(), because that is the only method defined in the Runnable interface.

Well, I guess that wasn't too short after all.

danben
On invokeLater: Swing is a single-threaded GUI toolkit. There is a special thread called the Event Dispatch Thread (EDT) that is dedicated to displaying and updating Swing components. invokeLater is a helper method to ensure that any code that modifies the GUI in some way only ever does so while running on this special EDT. The invokeLater method will call the code in the "run" method at some point in the future on the Event Dispatch Thread. I would presume that the createAndShowGUI method will create, initialise and display components, hence it must only be run on the EDT.
Ash
Thanks, good explanation.
danben
A: 

When you call invokeLater you're passing it a Runnable type instance. Runnable is an interface that declares only one method "public void run()". What happens in line 1 of your short code, is called an "Annonymous Inner Class" - You're creating an instance of Runnable which is used only one time, you're not even naming it.

InvokeLater will receive your Runnable, and inside will do something like

public static void invokeLater(Runnable r) {
    // Wait for the correct time to run this
    r.run()
}

This means invokeLater will decide when to call the run method, thus running createAndShowGUI.

Because in Java you can't pass methods as parameters to run (yet), you are forced to create this one-use Runnable instance.

yulkes
+1  A: 

While this is how Swing typically creates a GUI, all they do is tell you "just do it like this, we will explain why later". And i guess they are right, because the details are somewhat complicated and non-helpful for a beginner. But anyway:

invokeLater launches a thread that will run a Runnable class later. The runnable class is created ad hoc as mentioned by finnw via new Runnable { [..] } and must specify a public void run() method according to the Runnable interface. In this case, all it does is execute the createAndShowGUI method.

LumpN
A: 

This code makes a function (createAndShowGUI()) be called in another thread. In case you don't know what a thread is, better read about it, but anyhow, think about it as code that is performed at the same time that other code is performed. The other code will be the lines that follow this Invoke() call. This is very common in graphic apps, code runs to update the graphic while other code respond to user actions. That said I haven't bothered to read the documentation about InvokeLater(), and haven't wrote too much Java in my life. As 'LumpN' said - 'this is how Swing typically creates a GUI'.

The weirder (for a newbie) thing is that the invokeLater() parameter is defined in an annonymous way - 'within the code'. It is actually a nice thing since this class is so nothing-new-simple. All other answers has explained the annonymous thing.

so: 1.yes. 2. You asked why and asked not to get too much technical details - but as said by 'yulkes' - because in Java you can't pass methods as parameters, so you must build this class, and its nice to build it like this. 3. With what I summed on my first paragraph, you can briefly read documentation (just search function name on Google), also get the to know 'Google code search'.

Hanan