Lista na pintura JScrollPane fora da janela de visualização
-
09-06-2019 - |
Pergunta
Eu tenho uma lista, cada item contém várias coisas, incluindo um JProgressBar
que pode ser muito atualizado.Cada vez que um dos itens atualiza seu JProgressBar
, o ListDataListener
na lista tenta rolar para o intervalo visível usando
/*
* 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);
}
}
Observe que estou tentando garantir que a rolagem seja feita no thread de despacho, pois pensei que talvez o problema fosse a rolagem durante a repintura.E ainda assim, ainda tenho um problema onde, se as coisas estiverem realmente ativas, alguns dos itens da lista são pintados fora da janela de visualização, substituindo o que está fora da janela de visualização. JScrollPane
.Forçar um evento de exposição irá redesenhar essas coisas, mas é irritante.
Há mais alguma coisa que preciso observar para impedir que essas coisas sejam pintadas fora da área de recorte?
Solução
Você tentou ativar explicitamente o buffer duplo no JList e/ou nos componentes sobre os quais ele está sendo desenhado?(com:setDoubleBuffered(boolean aFlag)
)
Outro pensamento é que você poder precisa sair da função imediatamente após delegar ao EDT.Da forma como seu código está escrito, parece que a atualização acontecerá em ambos os threads se ContentChanged
é invocado a partir de um thread não EDT.Fazendo login no primeiro if
(ou defina um ponto de interrupção no if -- but não no executável - deve ajudar a determinar se esse é o seu problema.
por exemplo:
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);
}
}