Список в рисовании JScrollPane вне области просмотра - PullRequest
3 голосов
/ 28 августа 2008

У меня есть список, каждый элемент которого содержит несколько вещей, в том числе 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. Принудительное событие экспозиции перекрасит эти вещи, но это раздражает.

Есть ли еще что-то, на что мне нужно обратить внимание, чтобы эти картины не появлялись за пределами их области отсечения?

1 Ответ

3 голосов
/ 28 августа 2008

Вы пытались явно включить двойную буферизацию в JList и / или компонентах, которые он рисует? (С: setDoubleBuffered(boolean aFlag))

Другая мысль состоит в том, что вам может необходимо выйти из функции сразу после делегирования в EDT. То, как написан ваш код, похоже, что обновление произойдет в обоих потоках, если ContentChanged вызывается из потока, не являющегося EDT. Вход в первый if (или установка точки останова в if - но not в runnable - должен помочь определить, является ли это вашей проблемой.

например:

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);
     }
}
...