[英]SwingUtilities invokeLater GUI update with JList
Good day, 美好的一天,
I've read a few other stack overflow postings and other tutorials, but I can't get my GUI to update correctly after a button starts a long process. 我已经阅读了其他一些堆栈溢出帖子和其他教程,但是在按钮启动一个漫长的过程后,我无法正确地更新GUI。 I've attached the full code of the problem that I am having.
我附上了我遇到的问题的完整代码。 Notice if you run the code, the JList gets updated all at once at the end instead of every iteration of the for loop.
请注意,如果运行代码,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();
}
}
}
}
}
Any help would be greatly appreciated. 任何帮助将不胜感激。
The actionPerformed
method will be called on the Event Dispatch Thread. 将在Event Dispatch Thread上调用
actionPerformed
方法。 Calling Thread.sleep
on the EDT stops it from updating your GUI. 在EDT上调用
Thread.sleep
阻止它更新GUI。 Since your GUI cannot update, your JList
will not repaint itself when items are added to it until after your loop exits. 由于您的GUI无法更新,因此在您的循环退出之前,在添加项目时,您的
JList
不会重新绘制。
You should probably be using a SwingWorker
. 您可能应该使用
SwingWorker
。 ( SwingWorker
tutorial. ) (
SwingWorker
教程。 )
Your problem here is the fact that you are calling the invokeLater
method already from the EDT ( Event Dispatching Thread ). 你的问题是你已经从EDT( 事件调度线程 )调用了
invokeLater
方法。
The method actionPerformed
is called from the EDT so what happens is that the sleep
call just stops the EDT itself: you can imagine that this is not how it should work, no EDT running means no GUI updates. 从EDT调用
actionPerformed
方法,因此sleep
调用只会停止EDT本身:您可以想象这不是它应该如何工作,没有EDT运行意味着没有GUI更新。
Since it's a time consuming task you should implement it in a Thread
/ Runnable
so that you can execute it in parallel and then call the invokeLater
from this other thread. 由于这是一个耗时的任务,你应该在
Thread
/ Runnable
实现它,这样你就可以并行执行它,然后从另一个线程调用invokeLater
。
Something like: 就像是:
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.