3

私はリストを持っており、その各アイテムにはいくつかのものが含まれておりJProgressBar、多くの更新が可能です。項目の 1 つがその を更新するたびにJProgressBarListDataListenerリスト上の は、

/*
 * This makes the updating content item automatically scroll
 * into view if it is off the viewport.
 */
public void contentsChanged(final ListDataEvent evt) {
    if (!EventQueue.isDispatchThread()) {
        /**
          * Make sure the scrolling happens in the graphics "dispatch" thread.
          */
        EventQueue.invokeLater(new Runnable() {
            public void run()  {
               contentsChanged(evt);
            }
        });
    }
    if (playbackInProgress) {
        int index = evt.getIndex0();
        currentContentList.ensureIndexIsVisible(index);
    }
}

ディスパッチスレッドでスクロールが行われるようにしようとしていることに注意してください。おそらく、再描画中にスクロールされていることが問題だと思ったからです。それでも、物事が本当にアクティブな場合、リスト項目の一部がビューポートの外側に描画され、JScrollPane. 露出イベントを強制すると、それらが再描画されますが、面倒です。

これらがクリッピング領域の外に描画されるのを防ぐために、他に注意する必要があることはありますか?

4

1 に答える 1

3

JList および/またはそれが描画しているコンポーネントでダブルバッファリングを明示的に有効にしようとしましたか? (と: setDoubleBuffered(boolean aFlag))

もう 1 つの考えは、EDT に委任した直後に関数を終了する必要があるかもしれないということです。ContentChangedあなたのコードが書かれている方法は、EDT 以外のスレッドから呼び出された場合、両方のスレッドで更新が行われるように見えます。最初にログインする(または実行可能ファイルではなくifif にブレークポイントを設定する) と、それが問題かどうかを判断するのに役立ちます。

例えば:

public void contentsChanged(final ListDataEvent evt)
{
    if (!EventQueue.isDispatchThread())
    {
        log.debug("Delegating contentsChanged(...) to EDT");

        EventQueue.invokeLater(new Runnable() 
        {
            public void run() 
            {
                contentsChanged(evt);
            }
        });
        // don't run ensureIndexIsVisible twice:
        return;
     }

     if (playbackInProgress)
     {
         int index = evt.getIndex0();
         currentContentList.ensureIndexIsVisible(index);
     }
}
于 2008-08-28T16:17:19.207 に答える