3

I've been reading over the SwingUtilities.invokeLater() method, and I understand in large part its purpose. When dealing with GUI components, all actions on these components need to be done on the same Event thread to avoid races, etc.

However, and what I think many questions have failed to expand on, is how the code actually works? Looking at it:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        //method body code
    }
);

The question I have is, how is this working? We are passing the invokeLater() method a new Runnable obj (which I thought Runnable was an interface anyway, how are we instantiating a constructor new Runnable()?) and then attaching a whole method body with it inside a method call: {//Method body code});. How is that possible? I've never seen a method take in an entire method body as one of its parameters.

When I try to replicate this with my own methods, I get errors indicating that I cannot supply entire method bodies within a method parameter. Thus, I come back to my initial question of how this actually works. Perhaps I am overthinking/overlooking, but any help is greatly appreciated.

Thank you.

camickr
  • 321,443
  • 19
  • 166
  • 288
Matthew
  • 817
  • 1
  • 13
  • 39
  • 1
    https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html – shmosel Aug 01 '18 at 20:29
  • By using Anonymous Classes and here is one of my favorite [SO Answers](https://stackoverflow.com/questions/5107158/how-to-pass-parameters-to-anonymous-class) dealing with it. I use it all the time to pass parameters to the Anonymous class. – gtgaxiola Aug 01 '18 at 20:32

4 Answers4

3

Anonymous Classes. You can pass any class that implements Runnable, even an anonymous one.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thanks for the help. Never heard of Anonymous classes before. I guess I have more reading to do... – Matthew Aug 01 '18 at 20:31
2

I have is, how is this working?

You are implementing the run() method of the Runnable interface using an annonymous class.

You could also have done something like:

Runnable run = new Runnable()
{
    public void run()
    {
        //method body code
    }
};

SwingUtilities.invokeLater( run );
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks for the help camickr. As I said to Elliot above as well, never heard of Anonymous Classes before. Your explanations along with the javadocs have cleared that up – Matthew Aug 01 '18 at 20:54
2

In addition to other answers I'd like to add this.
For understanding your Java Code example

SwingUtilities.invokeLater(new Runnable() {
     public void run() {
         //method body code
     }
);

it is helpful to know how the Java-compiler actually handles it. The compiler does the following 2 things:

  • It creates an anonymous class (with a fancy class name ending with $1 or similar) implementing the Runnable interface:

    class YourEnclosingClass$1 implements Runnable {
         public void run() {
             //method body code
         }
    }
    
  • Then it uses this anonymous class with the new operator:

    SwingUtilities.invokeLater(new YourEnclosingClass$1());
    
Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
0

Because Runnableis an Interface, so only have the stub of the run method. When you create an instance of this interface, you have to provide the implementation of the interface.

And like Elliot said: Anonymous classes.

Rafael Palomino
  • 318
  • 2
  • 14