3

良い一日、

他のいくつかのスタックオーバーフローの投稿や他のチュートリアルを読みましたが、ボタンが長いプロセスを開始した後、GUIを正しく更新することができません。私が抱えている問題の完全なコードを添付しました。コードを実行すると、forループが繰り返されるたびにではなく、最後にJListが一度に更新されることに注意してください。

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();
                }
            }
        }
    }
}

どんな助けでも大歓迎です。

4

2 に答える 2

4

このactionPerformedメソッドは、イベント ディスパッチ スレッドで呼び出されます。Thread.sleepEDTを呼び出すと、GUI の更新が停止します。GUI は更新できないため、JListアイテムが追加されても、ループが終了するまで再描画されません。

おそらくSwingWorker. (SwingWorkerチュートリアルです)

于 2012-06-13T04:31:52.137 に答える
4

invokeLaterここでの問題は、すでに EDT ( Event Dispatching Thread ) からメソッドを呼び出しているという事実です。

メソッドactionPerformedは EDT から呼び出されるため、sleep呼び出しによって EDT 自体が停止するだけです。これは本来の動作ではないことが想像できます。EDT が実行されていないということは、GUI が更新されていないことを意味します。

これは時間のかかるタスクであるため、並列に実行できるようにThread/で実装し、この他のスレッドから を呼び出す必要があります。RunnableinvokeLater

何かのようなもの:

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();
}
于 2012-06-13T04:33:05.227 に答える