2

別のスレッドからJProgressBar.setValue(int)を更新するにはどうすればよいですか?私の第2の目標は、可能な限り少ないクラスでそれを行うことです。

これが私が今持っているコードです:

// Part of the main class....
pp.addActionListener(
        new ActionListener(){
            public void actionPerformed(ActionEvent event){
                new Thread(new Task(sd.getValue())).start(); 
            }
        });

public class Task implements Runnable {
    int val;
    public Task(int value){
        this.val = value;
    }

    @Override
    public void run() {
        for (int i = 0; i <= value; i++){ // Progressively increment variable i 
            pbar.setValue(i); // Set value 
            pbar.repaint(); // Refresh graphics 
            try{Thread.sleep(50);} // Sleep 50 milliseconds 
            catch (InterruptedException err){} 
        } 
    }
}

ppはJButtonであり、JButtonがクリックされると新しいスレッドを開始します。

pbarは、MainクラスのJProgressBarオブジェクトです。

どうすればその値を更新できますか?(進捗状況)

上記のrun()のコードは、pbarを認識できません。

4

3 に答える 3

3

常にスイングのルールに従う

Swingコンポーネントが実現されたら、そのコンポーネントの状態に影響を与える、または依存する可能性のあるすべてのコードを、イベントディスパッチスレッドで実行する必要があります。

あなたができることは、プログレスバーを更新するオブザーバーを作成することです-この場合、ボタンをクリックするだけでロードされているデータの進行状況を表示したいと思います。 DemoHelperクラスObservableは、データの特定の割合がロードされたときに、更新を実装してすべてのオブザーバーに送信します。プログレスバーは次の方法で更新されますpublic void update(Observable o, Object arg) {

class PopulateAction implements ActionListener, Observer {

    JTable tableToRefresh;
    JProgressBar progressBar;
    JButton sourceButton;
    DemoHelper helper;
    public PopulateAction(JTable tableToRefresh, JProgressBar progressBarToUpdate) {
        this.tableToRefresh = tableToRefresh;
        this.progressBar = progressBarToUpdate;
    }

    public void actionPerformed(ActionEvent e) {
        helper = DemoHelper.getDemoHelper();
        helper.addObserver(this);
        sourceButton = ((JButton) e.getSource());
        sourceButton.setEnabled(false);
        helper.insertData();
    }

    public void update(Observable o, Object arg) {
        progressBar.setValue(helper.getPercentage());
    }
}

恥知らずなプラグイン:これは私のデモプロジェクトのソースからのものです。詳細については、お 気軽に参照してください。

于 2010-04-28T00:41:51.840 に答える
0

イベントディスパッチスレッドの外でSwingを実行しないでください。これにアクセスするには、実行中のコードを使用してRunnableを作成し、それをSwingUtilities.invokeNow()またはSwingUtilities.invokeLater()に渡す必要があります。問題は、Swingスレッドの妨害を回避するために、JProgressBarチェックに遅延が必要なことです。これを行うには、独自のRunnableでinvokeNow以降を呼び出すタイマーが必要です。詳細については、http://www.javapractices.com/topic/TopicAction.do?Id=160をご覧ください。

于 2010-04-28T00:35:18.860 に答える
0
  • pbra.repaintを明示的に呼び出す必要はありません。
  • JProgressBarの更新は、GUIディスパッチスレッドを介して実行されます。

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // Remember to make pbar final variable.
        pbar.setValue(i);
    }
});
于 2010-04-28T00:35:50.167 に答える