1

我正在开发一个由某个人作为研究项目的一部分开发的 Java 应用程序。以下是主要方法:

 public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                // Change the name of the application on a mac
                System.setProperty("com.apple.mrj.application.apple.menu.about.name",
                        "XX");

                // Use the top of the screen for the menu on a mac
                if( System.getProperty( "mrj.version" ) != null ) {
                    System.setProperty( "apple.laf.useScreenMenuBar", "true" );
                }

                try {
                    // Use system look and feel
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

                } catch (Exception e) {
                    System.out.println("Cannot use system's look and feel; using Java's default instead");
                }

                // Create a new instance of XX
                XX.getInstance();
            }
        });

    }

现在,我不明白为什么使用事件队列而不是仅仅使用

 public static void main(String[] args) {

        //the MAC stuff!!

        XX.getInstance();        //this line creates the UI and the event handlers
    }

使用EventQueue有什么意义吗?

4

3 回答 3

2

EventQueue.invokeLater()将在 GUI 线程(调度线程)上运行该 Runnable。您需要从调度线程运行对 GUI 的更新。不过,从您的代码来看,我认为您并不真正需要它,您只需要在后台线程中运行时使用它(例如,在事件的回调中)。

于 2012-04-30T20:10:05.540 回答
2

Swing(老实说,AWT)是线程敌对的。像绝大多数 GUI 库一样,它不是线程安全的,而且没有任何意义——微同步是不现实的。更糟糕的是,它使用有效的可变静态(实际上使用了一个奇怪的AppContext想法)在 AWT 事件调度线程 (EDT) 上运行工作。即使在“实现”之前设置 GUI 时也会发生这种情况。

应该不会有问题吧。也许在某些情况下,也许在 JRE 更新之后,它会带来一些问题。也许它只是一个不合适的插入符号。问题是,您是否甚至必须考虑冒这个风险,或者只是在标准的 Java 风格的冗长样板中拍打?

于 2012-04-30T22:24:24.133 回答
2

属性应该在初始线程上设置,然后 GUI 应该安排在事件分派线程上构建。此处显示了替代方法。

public static void main(String[] args) {
    // Change the name of the application on a mac
    System.setProperty(
        "com.apple.mrj.application.apple.menu.about.name", "XX");
    // Use the top of the screen for the menu on a mac
    if (System.getProperty("mrj.version") != null) {
        System.setProperty("apple.laf.useScreenMenuBar", "true");
    }

    java.awt.EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            // Create a new instance of XX
            XX.getInstance();
        }
    });
}
于 2012-05-01T00:38:34.333 回答