ビューポート外の JScrollPane ペイント内のリスト
-
09-06-2019 - |
質問
私はリストを持っており、その各項目にはいくつかの内容が含まれています。 JProgressBar
たくさん更新できます。いずれかの項目が更新されるたびに、 JProgressBar
, 、 ListDataListener
リスト上で、次を使用して表示範囲までスクロールしようとします。
/*
* 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
. 。露出イベントを強制するとそれらが再描画されますが、面倒です。
これらがクリッピング領域の外にペイントされるのを防ぐために、他に注意する必要があることはありますか?
解決
JList やそれが描画しているコンポーネントでダブルバッファリングを明示的に有効にしてみましたか?(と:setDoubleBuffered(boolean aFlag)
)
もう一つの考えは、あなたは かもしれない EDT に委任した後、すぐに関数を終了する必要があります。コードの書き方からすると、次の場合には両方のスレッドで更新が行われるように見えます。 ContentChanged
非 EDT スレッドから呼び出されます。最初にログインする if
(または if -- but にブレークポイントを設定します ない 実行可能ファイル内 -- それが問題であるかどうかを判断するのに役立つはずです。
例えば:
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);
}
}
所属していません StackOverflow