由java中的另一个线程刷新GUI(swing)
Posted
技术标签:
【中文标题】由java中的另一个线程刷新GUI(swing)【英文标题】:Refreshing GUI by another thread in java (swing) 【发布时间】:2011-11-05 22:55:56 【问题描述】:我有一个主程序,其中 GUI 基于摇摆,根据四种状态之一,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()。
如有任何提示,我将不胜感激。
【问题讨论】:
请看一下这个问题中关于事件和事件总线的答案:***.com/questions/7131484/… 为什么不能从其他线程调用updateGUI?除了对状态变量的非同步访问之外,我不明白为什么您不能从其他线程使用此方法。 如果我调用 Frame f = new Frame(); f.udpateGUI(..);然后当然什么也没发生。我还能如何调用该方法? 将要更新的框架传递给您的后台任务(例如在其构造函数中) 【参考方案1】:这里有一个小sn-p,您可以添加到方法中以确保它在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
...
【讨论】:
【参考方案2】:如果您使status
字段线程安全,那么您可以直接从后台线程调用setStatus
。要使状态线程安全,请将更改放在同步块中,并使变量 volatile 以便其他线程上的更新可见。
例如
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
。
【讨论】:
以上是关于由java中的另一个线程刷新GUI(swing)的主要内容,如果未能解决你的问题,请参考以下文章
怎样使用java swing画一个表格,把输出显示到表格上,而且每10秒自动刷新一次
Swing:关于Java界面编程的第一课,如何正确的处理界面中的线程