正确更新摆动组件

时间:2012-03-13 08:36:37

标签: java swing

我一直在设置swing组件的值就像我任何其他变量一样,但是我遇到了这个页面 - https://bitguru.wordpress.com/2007/03/21/will-the-real-swing-single-threading-rule-please-stand-up/ - 而且我似乎正在使用事件调度线程对swing组件进行所有更改 -

所以,这是否正确,我是否应该更改从此

更新swing组件的所有代码
    String name = this.getNameTextfield().getText();
    String password = new String(this.getPasswordField().getPassword());
    String confirmPassword = new String(this.getConfirmPasswordField().getPassword());

到此?

java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
               String name = this.getNameTextfield().getText();
               String password = new String(this.getPasswordField().getPassword());
               String confirmPassword = new String(this.getConfirmPasswordField().getPassword());
            }
        });

这是标准做法吗?

编辑:哎呀,只是复制并粘贴了一些与组件相关的代码,忽略了它没有更新组件这一事实。

4 个答案:

答案 0 :(得分:9)

Swing圣经有一个chapter on concurrency,底线:

  

所有使用Swing组件创建或交互的代码必须在事件派发线程上运行

(重点是我的)

所以是的,你必须确保所有访问,阅读或写作都在EDT上进行。

好的一面是:一旦在EDT上正确启动了应用程序,你已经 ,并且几乎所有访问都在EDT上自然发生。只有当您明确启动另一个线程(用于执行冗长的后台任务)并且需要向ui报告时,情况并非如此:那么您必须将访问调用包装到invokeLater中(或使用内部执行此操作的SwingWorker)< / p>

答案 1 :(得分:4)

字符串是不可变的 - 以下几行非常相似

String password = new String(this.getPasswordField().getPassword());
String password = this.getPasswordField().getPassword();

您没有修改组件。

如果您要更新它们,那么只有更新来自另一个线程。例如,如果您正在从附加到按钮的ActionListener更新文本字段,那么就没有必要,因为您已经在Event-Dispatch-Thread上。

为了获得最大的正确性,您应该先确定是否参加了EDT。

Runnable update = new Runnable() {
    @Override
    public void run() {
        getNameTextfield().setText("foo");
    }
};
if (SwingUtilities.isEventDispatchThread()) {
    update.run();
} else {
    SwingUtilities.invokeLater(update);
}

答案 2 :(得分:3)

在这种特定情况下,您不需要修改任何组件,因此您不需要在EDT上执行此操作,但是当您修改UI时,第二种方法是正确的。

答案 3 :(得分:1)

如果您只是从组件中读取数据,那么您可能不需要这样做。来自Swing组件属性的大多数读取都是线程安全的。

如果要在事件调度线程上运行代码,则应使用

invokeLater,这通常是您实际需要更新GUI时的情况。

short little tutorial here regarding the use of invokeLater

为了让您的生活更简单,并尽量减少出现问题的风险,我建议您确保在SWT上运行与Swing GUI交互的任何代码。正如kleopatra正确地指出的那样,好消息是,这种情况几乎会自动发生,因为所有的事件处理代码都将由EDT调用。