4

この件はすでに多くの質問で見られ、回答されていることは知っていますが、それでも理解できません。

大きなxmlファイルの一部を抽出しながら、progressBarを更新したいだけです。時間のかかるループを別のスレッドに入れるだけで十分だと思いましたが、..私が取得できたのは、progressBar がまったく表示されないか、最後に更新されるか、閉じられる直前だけです。

アプリケーションの起動に近い場所でインスタンス化されたもの:

public class SomeClass {
    private SomeClass () {
        myXMLParser reader = new myXMLParser();
        CoolStuff fromXml = reader.readTheXml();
    }
}

JProgressBar を使用して JDialog を表示および更新している間:

public class LoadingDialog extends JDialog {
    private JProgressBar progressBar;
    /* ... */
    public void progress() {
        progressBar.setValue(progressBar.getValue() + 1);
    }
}

だから私はこのmyXMLParserを持っています:

public class myXMLParser {
    private LoadingDialog loadingDialog = new LoadingDialog();

    public CoolStuff readTheXml() {
        CoolStuff fromXml = new CoolStuff();
        while(manyIterations) {
            loadingDialog.progress();
            fromXml.add(some() + xml() + reading());
        }
        return fromXml;
    }
}

SwingWorkerイベントを使用してプログレスバーを更新する多くのことを見てきPropertyChangeましたが、例は常にオールインワンであり、処理とプログレスバーが同じクラス内にあり、クラス内にクラスがあります。それを私の状況に翻訳することはできません。

何か助けはありますか?.. (あまり明白ではない) アドバイスはありますか?

編集: btantlingerのおかげで、次のように機能しました:

public class SomeClass {
    private SomeClass () {
        myXMLParser reader = new myXMLParser();
        new Thread(new Runnable() {
            @Override
            public void run() {
                CoolStuff fromXml = reader.readTheXml();
            }
        }).start();
    }
}

public class LoadingDialog extends JDialog {
    private JProgressBar progressBar;
    /* ... */
    public void progress() {
        progressBar.setValue(progressBar.getValue() + 1);
    }
}

public class myXMLParser {
    private LoadingDialog loadingDialog = new LoadingDialog();

    public CoolStuff readTheXml() {
        CoolStuff fromXml = new CoolStuff();
        while(manyIterations) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    loadingDialog.progress();
                }
            });
            fromXml.add(some() + xml() + reading());
        }
        return fromXml;
    }
}
4

2 に答える 2

10

Swing イベント ディスパッチ スレッドの JProgress バーを更新する必要があります。他のスレッドで Swing コンポーネントを変更することはできません。

他の唯一の選択肢は、進行状況バーが前後に移動するスレッドを開始する前に、JProgress バーを「不確定」に設定することです。

例えば

progBar.setIndeterminate(true);

SwingWorker javadoc を参照してください: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

SwingWorker を使用したくない場合、別のオプションはSwingUtilities.invokeLaterメソッドです。

//inside your long running thread when you want to update a Swing component
SwingUtilities.invokeLater(new Runnable() {
    public void run() {

        //This will be called on the EDT
        progressBar.setValue(progressBar.getValue() + 1);


    }
});
于 2012-03-06T06:10:51.317 に答える