SwingUtilities.invokeLater()

4

在我的方法 doWork() 中,我调用了

SwingUtilities.invokeLater(new Runnable(){
public void run() {
button.setBackgroundColor(Color.red);
}
});

然后我调用。
SwingUtilities.invokeLater(new Runnable(){
public void run() {
button.setBackgroundColor(Color.blue);
}
});
问:按钮会先变成红色再变成蓝色,还是先变成蓝色再变成红色?
3个回答

11

invokeLater() 方法将其参数添加到 Swing 事件队列中,因此它们会按照添加的顺序执行,即先红色再蓝色。


请参见:https://groups.google.com/forum/m/?fromgroups#!topic/comp.lang.java.help/Tt1S9qEJqTc - assylias
@assylias:API文档显示,调用实际上由java.awt.EventQueue处理,其API文档明确指出事件按照“顺序排队”的方式依次分派。 - Michael Borgwardt
Javadoc 还说:“请注意,发布到 EventQueue 的事件可以进行合并”- 我有点困惑。 - assylias
4
聚合(coalescing)是一种特殊的机制,仅与鼠标移动事件、绘图事件以及源组件明确支持它的事件相关。请参阅java.awt.Component#coalesceEvents() - Michael Borgwardt

0
据我理解文档,应该是先red然后是blue,因为第一个事件被添加到事件队列中(嗯...)是最先的。

0

实际上,你可能会遇到按钮本身的重绘问题。

如果我没记错,setBackground() 只会改变背景字段,并触发一个重绘事件(通过调用 repaint())。但实际的重绘不会立即发生,即使在 EDT 中调用。相反,它会发送一个绘画事件,稍后会处理该事件(可能与其他绘画事件合并)。

因此,如果这两个 invokeLater() 之间的代码中没有“什么东西”,那么你可能只会看到最后设置的颜色,即蓝色,而从未看到红色背景,但这很大程度上取决于其中的代码。

例如,如果你在这两个方法之间放置了一个 sleep(),那么你可能会先看到红色再看到蓝色


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接