Список в рисовании JScrollPane за пределами области просмотра

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

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


person Paul Tomblin    schedule 28.08.2008    source источник


Ответы (1)


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

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

eg:

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);
     }
}
person rcreswick    schedule 28.08.2008