![](/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.