Search code examples
javaswingrunnableevent-dispatch-thread

Implementing Runnable when using Java Swing


Learning a bit of Swing right now, came upon two tutorials which used different ways of making a simple JFrame window.

First one implements Runnable and has a JFrame object variable in the class:

class SwingDemo implements Runnable {
    private JFrame frame;

    @Override
    public void run() {
        frame = new JFrame("title");

        ... // setSize(), add components, etc

    }
}

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SwingDemo());
    }
}

The second tutorial didn't implement Runnable, instead it used the class constructor to initialize the JFrame and called the constructor through an anonymous inner class

class SwingDemoAlt {

    public SwingDemoAlt() {
        JFrame frame = new JFrame("title");

        ... // again some code here

    }
}

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SwingDemoAlt();
            }
        }
    }
}

How do the two ways differ? Is one way more preferable?


Solution

  • How do the two ways differ?

    They don't, not really, they are basically achieving the same thing in different ways.

    The first is a more "traditional" approach, while the second is a more "modern" or shorthanded approach, which takes advantage of the, welcome, introduction of Anonymous Classes into the language.

    And is there a more preferred choice?

    That's a matter of opinion, for my money, the second is is preferred because it doesn't put an otherwise unnecessary conformance of Runnable on the class, it also delegates responsibility for setting up the UI (correctly) on the caller and stops the code from making assumptions (ie you can simple construct the frame at any time an run it ... just do it from within the context of the Event Dispatching Thread).

    Also, as a preference, you should not extend directly from JFrame, as you're not actually adding a new functionality to the class, instead, as is done in the second example, simply create an instance when you need it and build your UI on top of it

    You might also like to have a look at Concurrency in Swing for more details about why you should use EventQueue.invokeLater to start your UI