使用 Java Swing 时实现 Runnable

Implementing Runnable when using Java Swing

现在学习了一点 Swing,发现了两个使用不同方法制作简单 JFrame 的教程 window。

第一个实现 Runnable 并在 class:

中有一个 JFrame 对象变量
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());
    }
}

第二个教程没有实现Runnable,而是使用class构造函数初始化JFrame,并通过匿名内部调用构造函数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?

他们不是,不是真的,他们基本上是在以不同的方式实现同​​一件事。

第一种是更 "traditional" 的方法,而第二种是更 "modern" 或简写的方法,它利用了欢迎将 Anonymous Classes 引入语言.

And is there a more preferred choice?

这是一个见仁见智的问题,就我而言,第二种是首选,因为它不会在 class 上放置不必要的 Runnable 一致性,它还委托了设置的责任在调用者上向上 UI (正确地)并停止代码做出假设(即你可以在任何时候简单地构造框架 运行 它......只是在事件调度线程)。

此外,作为一种偏好,您不应直接从 JFrame 扩展,因为您实际上并没有向 class 添加新功能,而是像第二个示例中所做的那样,只需在需要时创建一个实例,然后在其上构建您的 UI

您可能还想查看 Concurrency in Swing 以了解有关为何应使用 EventQueue.invokeLater 启动 UI

的更多详细信息