由java中的另一个线程刷新GUI(swing)
问题描述:
我有一个主程序,其中GUI基于swing,并且取决于四种状态之一GUI元素具有不同的参数。由java中的另一个线程刷新GUI(swing)
public class Frame extends JFrame implements Runnable {
Status status = 1;
...
@Override
public void run() {
switch (status) {
case 1:
...
case 2:
...
}
public void updateGUI(Status status) {
this.status = status;
SwingUtilities.invokeLater(this);
}
如果我想刷新GUI只调用具有适当参数的updateGUI,一切都很好。但该程序还创建了一个额外的线程,在处理完相关数据后,应该更改GUI主程序。不幸的是我不能在这个线程中调用updateGUI(..)方法。
我知道我可以使用invokeLater或SwingWorker来刷新,但有超过10个元素,所以我宁愿使用方法udpateGUI()。
我将不胜感激任何提示。
答
如果使status
场线程安全的,那么你可以直接从后台线程中调用setStatus
。要使状态成为线程安全的,请将更改置于同步块中,并使该变量易变,以便其他线程上的更新可见。
例如
public class Frame extends JFrame implements Runnable {
private volatile Status status = 1;
...
@Override
public void run() {
switch (status) {
case 1:
...
case 2:
...
}
public void updateGUI(Status status) {
setStatus(status);
SwingUtilities.invokeLater(this);
}
private synchronized void setStatus(Status status) {
this.status = status;
}
随着这些变化的地方,这是确定调用setStatus
从任何线程。
答
下面是一个小小的片段,您可以将其添加到方法中以确保它在GUI线程中执行。它依赖于isEventDispatchThread()
。
public void updateGUI(final Status status) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateGUI(status);
}
});
return;
}
//Now edit your gui objects
...
}
+0
谢谢,这也有帮助。 – galica
请看看在这个问题上关于事件和事件总线的答案: http://stackoverflow.com/questions/7131484/how-to-pass-the-message-from-working-thread-to -gui-in-java/7131574#7131574 –
为什么你不能从另一个线程调用updateGUI?除了对状态变量的非同步访问,我不明白为什么你不能从另一个线程使用这个方法。 –
如果我调用Frame f = new Frame(); f.udpateGUI(..);那么当然没有事情发生。我还能如何调用这种方法? – galica