1

SwingWorker に問題があるようです。基本的に、JFrame の propertyChange() メソッドから UI を更新する Java サンプル コードを実装しました。

doInBackground の 1 秒部分までのスリープもコピーしました。これにより、Worker 内の setProgress の更新率が良好になります。

ただし、propertyChange イベントは約 10 秒ごとに 1 回だけ発生します。すべての setProgress がイベントを発生させるわけではないことを API から知っていますが、それで問題ありませんが、これは少し遅く、失われるイベントが多すぎるようです。

デバッガーでステップスルーすると、setProgress の 3 回の呼び出しごとに 1 回の割合でより良いレートが得られます

なぜそれがとても遅いのですか?

私のコードの一部は次のとおりです。

public Void doInBackground() {
    Random random = new Random();
    setProgress(0);
    float getSize=0,gotSize=0;
    while (Sync.syncing) {
        //Sleep for up to one second.
        try {
             Thread.sleep(random.nextInt(1000));
        } catch (InterruptedException ignore) {
            ignore.printStackTrace();
        }
        try{
            getSize=Main.getSyncGet();
            gotSize=Main.getSyncGot();
            System.out.println("setProgress: "+(gotSize/getSize));
            setProgress((int)((gotSize/(getSize))*100));
        }catch(Exception e){
            Main.LOGGER.log(Level.WARNING,"Error setting progress",e);
        }
    }
    return null;
}

public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" == evt.getPropertyName()) {
            jpb.setValue((Integer) evt.getNewValue());
        }
}

敬具

イェンス

4

3 に答える 3

4

あなたの問題はおそらくここにあります:

System.out.println("setProgress: "+(gotSize/getSize));
setProgress((int)((gotSize/(getSize))*100));

進行状況が実際に変更されていることをテストしましたか? より良い println は次のようになります。

int value = (int)((gotSize/(getSize))*100);
System.out.println("setProgress: "+ value);
setProgress(value);

値が実際に変化しているかどうかを確認します。

おっと、これは間違いなく間違っています:

public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" == evt.getPropertyName()) {
            jpb.setValue((Integer) evt.getNewValue());
        }
}

を使用して文字列を比較しないでください==。代わりにequals(...)またはメソッドを使用してください。equalsIgnoreCase(...)== は、2 つのオブジェクトが同じであるかどうかをチェックしますが、それはあなたが興味を持っているものではないことを理解してください。一方、メソッドは、2 つの文字列が同じ文字を同じ順序で持っているかどうかをチェックします。それがここで重要なことです。だから代わりに

if (fu == "bar") {
  // do something
}

行う、

if ("bar".equals(fu)) {
  // do something
}

また、

if ("bar".equalsIgnoreCase(fu)) {
  // do something
}
于 2012-08-30T18:26:56.037 に答える
2
  1. SwingWorkerを読んでください。コード例を含む、考えられるシナリオが説明されています

  2. setProgress(0);EDTで setProgress((int)((gotSize/(getSize))*100));呼び出す必要があります

  3. folows メソッドからの出力は、 doInBackground() 中に EDT で実行できます。

    • process()

    • publish()

    • setProgress()

  4. @trashgod による PropertyChangeListener に関する最も複雑なコード例

  5. より良いヘルプのために、SSCCEをすぐに投稿してください

于 2012-08-30T18:28:56.963 に答える
0

プロパティの変更を手動で開始することができます:

setProgress(1);
firePropertyChange("progress", 0, 1);
于 2015-11-18T08:05:00.973 に答える