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:
- 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)?
- If "public void run" defines a new methods, what is a reason to define开发者_StackOverflow中文版 a method containing only one line of code (createAndShowGUI)?
- 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!
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
. Runnable
s 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.
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.
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.
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'.
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.
精彩评论