7

プログレス バーとラベルの両方を使用して、目立たない数の操作の進行状況を表示しようとしています。両方を更新するたびに、ラベルはすぐに更新されますが、プログレス バーは変更されるまでにかなりの遅延があります

ボタンを押すと、ラベルと進行状況バーの両方を更新して 1 の増加を反映するテスト ダイアログがあります。これは、ループやスレッドが呼び出されることなく、コード内ですぐに発生します(原因です)-値の単純な変更。これが発生すると、ラベルはすぐに更新されますが、プログレス バーは約 0.5 秒待ってから視覚的に更新されます。これにより、たとえば、バーの 3 分の 1 が満たされていることを短時間ではあるが顕著に示している場合に、「3 のうち 2」と表示される場合が生じます。

ここに画像の説明を入力

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public class ProgressBarTest extends Shell {

    private ProgressBar progressBar;
    private Label lblXOfX;
    private Button btnGo;

    public static void main(String args[]) {
        try {
            Display display = Display.getDefault();
            ProgressBarTest shell = new ProgressBarTest(display);
            shell.open();
            shell.layout();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public ProgressBarTest(Display display) {
        super(display, SWT.SHELL_TRIM);
        createContents();
    }

    protected void createContents() {
        setText("SWT Application");
        setSize(450, 300);
        setLayout(new GridLayout());

        progressBar = new ProgressBar(this, SWT.NONE);
        progressBar.setMaximum(3);
        progressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        lblXOfX = new Label(this, SWT.NONE);
        lblXOfX.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        lblXOfX.setText("x of x");

        btnGo = new Button(this, SWT.NONE);
        btnGo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent arg0) {
                go();
            }
        });
        btnGo.setText("Go");
    }

    @Override
    protected void checkSubclass() {
        // Disable the check that prevents subclassing of SWT components
    }

    protected void go() {

        int iCur = progressBar.getSelection();
        iCur++;
        if (iCur > progressBar.getMaximum())
            iCur = 0;

        progressBar.setSelection(iCur);
        lblXOfX.setText(String.format("%s of %s", iCur, progressBar.getMaximum()));
    }

}

これは、プログレス バーの内部変数を使用して値を追跡し、その値を使用してラベルを更新しているにもかかわらず発生します。

特に、進行状況バーの「状態」プロパティを「エラー」または「一時停止」に変更すると、問題が解消されます。

これはアニメーションのバグですか? これは、使用している Windows 7 など、特定のバージョンの Windows だけの問題ですか? それとも別のものですか?

4

4 に答える 4

4

ProgressBarコードは Linux と Mac OS X で動作するため、これは の Windows バージョンのバグのようです。

の Windows バージョンにProgressBar.setSelectionは、このような問題に対処しようとしているというコードがありますが、状態が正常でない場合にのみ実行されます。これが、エラーおよび一時停止状態で動作する理由である可能性があります。彼らの修正は選択をやり直すだけなので、setSelection2回呼び出すとうまくいくかもしれません!

于 2013-09-26T15:14:57.437 に答える
1

Windows 7 SP 1 および Windows XP SP3 で最新バージョンの SWT (4.3 最終リリース - 2013 年 6 月 5 日) を使用して、提供されたコードをテストしました。どちらの場合も、進行状況バーは遅滞なく更新されました。おそらく、SWT ライブラリの更新が役立つでしょう。

于 2013-10-01T15:14:35.720 に答える
1

数週間前、棒グラフを使用して、連続して完了した約 500 の操作の進行状況を示すときに、この問題に遭遇しました。棒グラフが半分になる前に、プロセスが終了したことがわかりました。回避策として以下のコードを使用しました。

bargraph.value = (Target + 1)
bargraph.value = (Target)

bargraph はオブジェクトの名前で、 target は移動先です。

棒グラフにはマーキー効果というグラフィカルな側面があるため、追いつくのに時間がかかります。グラフ側では 50 の値が表示されていても、実際の bargraph.value は 60 になる可能性があります。値をレベルに設定してから1つ減らすと、棒グラフは即座に(っぽい)グラフィック側を更新します。

編集

以下のコメントが示すように、値を最大に設定しようとすると、上記の回答が機能しない場合があります。

今、私はこれを試していませんが、以下の行に沿って何かがうまくいくと思います:

if (bargraph.value <> Target) then
   if (Target = bargraph.maximumvalue) then
      bargraph.maximumvalue = Target + 1
      bargraph.value = (Target + 1)
      bargraph.value = (Target)
      bargraph.maximumvalue = Target
   else
      bargraph.value = (Target + 1)
      bargraph.value = (Target)
   end if
else
end if

私が言ったように、テストされていませんが、原則は機能するはずです。

于 2013-10-02T15:49:59.420 に答える