2

問題:

ClassA
    static JProgressBar progressBar;
ClassB
    ClassA.progressBar.setValue(0);
    ...
    ClassA.progressBar.setValue(10);
    ...
    ClassA.progressBar.setValue(20);

プログレス バーは 0 を表示し、次に 0 の上に 10 を表示し、次に 10 の上に 20 を表示します。

コード:

public class ClassA
{
    static JProgressBar progressBar;
    public ClassA()
    {
        ...
        progressBar = new JProgressBar(0, 100);
        progressBar.setStringPainted(true);
        ...
    }
    public static void main(String[] args)
    {
        ClassA cA = new ClassA();
        cA.something();
    }
    public void something()
    {
        ...
        panel.add(progressBar, BorderLayout.CENTER);
        ...
    }
    ...
}
public class ClassB
{
    public void something()
    {
        ...
        ClassA.progressBar.setValue(0);
        ClassA.progressBar.update(ClassA.progressBar.getGraphics());
        ...
    }
    ...
}

また、進行状況バーをパネルに追加しています。上で述べたように、進行状況バーとパーセンテージが表示されますが、各値が別の値の上に表示されます。

編集: 問題はこれと非常によく似ています: Java Swing revalidate() vs repaint()。ただし、代わりに

古いコンテンツはまだ実際に表示されています (ただし、新しいコンテンツによって隠されています)

JPanelの問題であり、私のものはJProgressBarの問題です。試しClassA.progressBar.revalidate();てみましたが、上記のように、古い値の上に新しい値を表示するClassA.progressBar.repaint();以外は何も機能しません。ClassA.progressBar.update(ClassA.progressBar.getGraphics());

4

2 に答える 2

3

アーサー、あなたのコード スニペットは ClassB.something がどのように呼び出されるかを示していません。ほとんどの Swing はスレッド セーフではありません。javadoc に別段の明示的な記述がない限り、Swing UI コンポーネントはイベント ディスパッチ スレッドから変更する必要があります。通常、Swing コンポーネントがスレッドセーフである場合、javadoc でこれを明示的に呼び出します。JProgressBar javadocを調べたところ、免責事項はありませんでした。実際には、Swing がスレッドセーフではないという警告が表示されています。
Swing コンポーネントが他のスレッドからアクセスされると、アプリケーションが異常な動作をする可能性があります。不適切なスレッドが原因で、コンポーネントが奇妙に不完全にレンダリングされるのを見てきました。ClassA がコンストラクターでスイング コンポーネントを構築および変更する場合、コンストラクターはイベント ディスパッチ スレッドから実行される必要があります。

public class ClassA 
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new ClassA());
    }
}
于 2013-05-01T06:44:21.843 に答える