我有一个简单的groovy脚本,从它的主线程执行需要向用户显示一些对话框。
我的swing知识有限且生疏,但我记得我读过一篇文章,内容是需要小心地将GUI内容保存在事件分派线程(EDT)上。
如果我只是从我的主线程调用静态JOptionPane.showMessageDialog方法,我假设这将违反在EDT上保存图形用户界面的正确实践,对吗?
我真的应该像下面的示例代码那样使用swing.utils.invokeAndWait方法吗?
void showHelloThereDialog()
throws Exception {
Runnable showModalDialog = new
Runnable() {
public void run() {
JOptionPane.showMessageDialog(
myMainFrame, "Hello There");
}
};
SwingUtilities.invokeAndWait
(showModalDialog);
}现在,在invokeAndWait完成后,除了消息对话框之外,上面并没有做任何事情来使值可用。
想必groovy“闭包”实现Runnable的事实将使代码比上面的代码更简单。
是否需要invokeAndWait?如果是这样的话,请给出一个正确实现的例子,以便使用groovy获得类似于confirmDialog的结果?
发布于 2011-03-31 04:58:22
看看groovy.swing.SwingBuilder,它封装了invokeAndWait和invokeLater。你的例子可以写成:
import groovy.swing.SwingBuilder
import javax.swing.*
import java.awt.*
def swing = new SwingBuilder()
def myMainFrame = new Frame()
swing.edt {
JOptionPane.showMessageDialog(
myMainFrame, "Hello There");
}发布于 2012-07-21 12:59:34
对JOptionPane的showXXXDialog()的调用是阻塞的,直到用户选择ok/cancel/等。一般来说,您不会将如此缓慢的阻塞指令放在事件分派线程(EDT)上,因为其他所有的GUI组件都会冻结。因此,不把它放在EDT上的直觉是好的,但它也是错误的。原因是,正如其他一些人所说的那样,该方法创建GUI组件,而这应该始终在EDT上完成。但是阻塞又如何呢?您会注意到,即使您在EDT上运行它,它也工作得很好。原因可以在源代码中找到。JOptionPane类创建一个Dialog对象,然后调用show(),然后调用dispose(),第一个调用会阻塞线程。如果您阅读注释(或javadoc),您将看到它显示了关于该方法的以下内容:
如果对话框是模式对话框并且不可见,则此调用在通过调用hide或dispose隐藏对话框之前不会返回。允许从事件分派线程显示模式对话框,因为工具包将确保在调用此方法的事件泵被阻塞时运行另一个事件泵。
因此,在EDT上运行JOptionPane是完全安全的,尽管它是阻塞的。显然,在EDT之外调用Dialog的show()方法是安全的,但对于JOptionPane就不是这样了,因为它的方法包括创建图形用户界面组件、添加侦听器、在模式时访问其他容器以及阻塞对它们的输入等。诚然,我从未见过在EDT之外使用JOptionPane时出现的问题,因此这种可能性似乎很低,但它们肯定是有可能的。为对话框的容器传递一个null,并且只给字段提供不可变的对象(如String)作为参数,这将大大减少(据我所知甚至可以消除)发生糟糕事情的可能性,因为所有相关的图形用户界面组件都是在同一个线程中创建和访问的,而它们是不可见的。但是,你应该安全地把它放在EDT上。调用SwingUtilities.invokeAndWait()并不难。
发布于 2011-03-31 04:37:44
这应该在美国东部夏令时,所以invokeAndWait或invokeLater是必需的。你可以看出来,因为JOptionPane.showMessageDialog的代码最终会创建和修改Swing组件。从Java6开始,Sun表示Swing组件的所有操作(无论它们是否已经实现)都必须在EDT上完成。
http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html
http://www.velocityreviews.com/forums/t707173-why-does-jdk-1-6-recommend-creating-swing-components-on-the-edt.html
https://stackoverflow.com/questions/5491952
复制相似问题