簡體   English   中英

SwingUtilities使用JList調用更新GUI更新

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM