2008-08-28 5 views
3

J'ai une liste, chaque élément a plusieurs choses, y compris un JProgressBar qui peut être mise à jour beaucoup. Chaque fois que l'un des éléments met à jour son JProgressBar, la ListDataListener sur la liste essaie de faire défiler la plage visible à l'aideListe dans JScrollPane peinture à l'extérieur de la fenêtre

/* 
* 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 vous assurer que le défilement se fait dans le fil d'expédition, puisque je pensait que le problème était peut-être qu'il défilait pendant qu'il repeignait. Et pourtant, j'ai toujours un problème où, si les choses sont vraiment actives, certains éléments de la liste peignent en dehors de la fenêtre d'affichage, écrasant ce qui est en dehors du JScrollPane. Forcer un événement d'exposition va repeindre ces choses, mais c'est agaçant.

Y a-t-il quelque chose d'autre dont j'ai besoin pour empêcher ces choses de peindre en dehors de leur zone de découpage?

Répondre

3

Avez-vous essayé d'activer explicitement le double-buffering sur le JList et/ou les composants qu'il dessine? (avec: setDoubleBuffered(boolean aFlag))

Une autre idée est que vous devez devoir quitter la fonction immédiatement après avoir délégué à l'EDT. La façon dont votre code est écrit, il semble que la mise à jour se produira dans les deux threads si ContentChanged est appelée à partir d'un thread non-EDT. Connexion à la première if (ou définir un point d'arrêt dans le cas - mais pas dans le runnable - devrait aider à déterminer si tel 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); 
    } 
} 
.
Questions connexes