由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()。

我将不胜感激任何提示。

+0

请看看在这个问题上关于事件和事件总线的答案: http://stackoverflow.com/questions/7131484/how-to-pass-the-message-from-working-thread-to -gui-in-java/7131574#7131574 –

+0

为什么你不能从另一个线程调用updateGUI?除了对状态变量的非同步访问,我不明白为什么你不能从另一个线程使用这个方法。 –

+0

如果我调用Frame f = new Frame(); f.udpateGUI(..);那么当然没有事情发生。我还能如何调用这种方法? – galica

如果使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