我有一个主程序,其中GUI基于swing并且根据四种状态之一,GUI元素具有不同的参数。
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()。
我会感激任何提示。
答案 0 :(得分:19)
这是一个可以添加到方法的小片段,以确保它在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
...
}
答案 1 :(得分:9)
如果您使status
字段线程安全,那么您可以直接从后台线程调用setStatus
。要使状态是线程安全的,请将更改放在同步块中,并使变量变为volatile,以便其他线程上的更新变为可见。
E.g。
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
。