![](/img/trans.png)
[英]GUI unable to update when executing process (SwingUtilities.invokeLater)
[英]SwingUtilities invokeLater GUI update with JList
美好的一天,
我已经阅读了其他一些堆栈溢出帖子和其他教程,但是在按钮启动一个漫长的过程后,我无法正确地更新GUI。 我附上了我遇到的问题的完整代码。 请注意,如果运行代码,JList会在结束时立即更新,而不是for循环的每次迭代。
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class theframe extends JFrame implements ActionListener
{
private JList list;
private DefaultListModel listmodel;
private JButton start;
public theframe()
{
listmodel = new DefaultListModel();
list = new JList(listmodel);
start = new JButton("Start");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,500);
setVisible(true);
list.setPreferredSize(new Dimension(200,200));
start.addActionListener(this);
JPanel p = new JPanel();
p.add(start);
p.add(list);
this.add(p);
}
public static void main(String[] args)
{
theframe frame = new theframe();
}
@Override
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource() == start)
{
for(int i=0;i<10;i++)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
// the JList should update one by one
listmodel.addElement("Start pushed ");
}
});
try
{
//This thread sleep simulates a long job
Thread.sleep(300);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
任何帮助将不胜感激。
将在Event Dispatch Thread上调用actionPerformed
方法。 在EDT上调用Thread.sleep
阻止它更新GUI。 由于您的GUI无法更新,因此在您的循环退出之前,在添加项目时,您的JList
不会重新绘制。
您可能应该使用SwingWorker
。 ( SwingWorker
教程。 )
你的问题是你已经从EDT( 事件调度线程 )调用了invokeLater
方法。
从EDT调用actionPerformed
方法,因此sleep
调用只会停止EDT本身:您可以想象这不是它应该如何工作,没有EDT运行意味着没有GUI更新。
由于这是一个耗时的任务,你应该在Thread
/ Runnable
实现它,这样你就可以并行执行它,然后从另一个线程调用invokeLater
。
就像是:
class LongProcess extends Thread {
public void run() {
for (int i = 0; i < 10; ++i) {
SwingUtilities.invokeLater(...);
Thread.sleep(300);
}
}
}
void actionPerformed(ActionEvent e) {
LongProcess process = new LongProcess();
process.start();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.