Liste dans JScrollPane la peinture à l'extérieur de la fenêtre d'affichage
-
09-06-2019 - |
Question
J'ai une liste, chaque élément de ce qui a plusieurs choses, y compris un JProgressBar
qui peut être mis à jour beaucoup.Chaque fois que l'un des éléments les mises à jour de ses JProgressBar
, le ListDataListener
sur la liste essaie de la faire défiler à la plage visible à l'aide de
/*
* 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);
}
}
Notez que je suis en train de assurez-vous que le défilement se fait dans le thread d'expédition, car je pensais peut-être que le problème était-il être défile alors qu'il a été repeint.Et pourtant, j'ai encore un problème où, si les choses sont vraiment actif, certains des éléments de la liste de peindre à l'extérieur de la fenêtre d'affichage, en écrasant ce qui est en dehors de la JScrollPane
.Forcer une exposition événement repeindre ces choses, mais c'est ennuyeux.
Est-il autre chose que je besoin pour regarder dehors pour arrêter ces choses la peinture à l'extérieur de leur zone de fenêtrage?
La solution
Avez-vous essayé de l'activer explicitement double-tampon sur la JList et/ou les composants que c'est le dessin plus?(avec:setDoubleBuffered(boolean aFlag)
)
Une autre pensée, c'est que vous peut besoin de sortir de la fonction immédiatement après la délégation de l'EDT.La façon dont votre code est écrit, il semble que la mise à jour va se passer dans les deux threads s' ContentChanged
est appelé à partir d'un non-HAE fil.L'exploitation forestière dans la première if
(ou de définir un point d'arrêt dans le si-mais pas dans l'exécutable -- devraient aider à déterminer si c'est votre problème.
par exemple:
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);
}
}