2010-08-26 3 views
3

J'ai un composant JList qui doit être vidé et repeuplé. Le code suivant (basé sur mon code d'origine) montre une fenêtre simple avec un JList et un JButton:Repopulation JList très lente

import java.awt.BorderLayout; 
import javax.swing.*; 

public class JListTest extends javax.swing.JFrame{ 
    JList jList; 
    JButton button; 
    DefaultListModel model; 

    public JListTest() { 
     jList = new JList(); 
     model = new DefaultListModel(); 
     jList.setModel(model); 
     button = new JButton(); 

     getContentPane().add(jList, java.awt.BorderLayout.CENTER); 

     button.setText("add 10000 items"); 
     button.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       model.clear(); 
       for(int i=0; i<10000; ++i) { 
        model.addElement("aaaa"); 
       } 
      } 
     }); 
     getContentPane().add(button, BorderLayout.PAGE_START);   
     pack();   
    } 

    public static void main(String args[]) { 
     JListTest jlt =new JListTest(); 
     jlt.setSize(300, 300); 
     jlt.setVisible(true); 
    } 
} 

Si j'appuie sur le bouton de l'insertion (10000 articles) est très rapide. Si je presse encore et encore, c'est toujours très rapide.

Si je sélectionne le troisième élément et appuyez sur le bouton, le résultat est le même, l'insertion est très rapide.

Si je sélectionne le premier élément et que j'appuie sur le bouton, le programme devient très lent (en fait je dois l'arrêter). Pourquoi la sélection du premier élément ralentit l'exécution?

Pourquoi la sélection du premier élément ralentit l'exécution? J'ai testé avec JDK 1.5 et 1.6.

+0

Quels "articles" ??? –

+0

elements ("aaaa") – asalamon74

Répondre

2

Je suggère d'écrire votre propre modèle qui permet d'ajouter un tas de valeurs à la fois. Je suppose que ce n'est pas l'ajout au modèle, mais les choses de l'interface graphique déclenchées par ce qui tue la performance.

+0

Merci pour le conseil. Ma propre classe de modèle était basée sur DefaultListModel, je l'ai modifiée pour utiliser AsbtractListModel et j'ai créé une méthode qui ajoute un tas de valeurs. Le ralentissement est éliminé. Encore ne comprends pas complètement ce comportement étrange de DefaultListModel. – asalamon74

1

Vous ne devriez pas ajouter beaucoup d'éléments dans le modèle dans une telle boucle d'événement. Il vaudrait beaucoup mieux que votre écouteur d'action apparaisse sur un thread pour ajouter les éléments, et que ce thread appelle un SwingUtilities.invokeLater() pour lancer l'événement change dans la liste. Notez que selon le commentaire ci-dessous, vous devez créer un AbstractListModel (ou une sous-classe de celui-ci) et en faire le modèle, et appeler fireContentsChanged dessus dans le invokeLater.

+0

Vous ne pouvez pas ajouter d'éléments à un 'DefaultListModel' connecté hors EDT (et attendez-vous à ce qu'il fonctionne). –

1

Je ne suis pas sûr pourquoi la sélection d'un élément provoque le problème de performance. Mais à chaque fois que vous ajoutez un élément, un événement est déclenché qui indique à la liste de repeindre itslef. Alors peut-être le fait qu'un élément est sélectionné entraîne une repeinte supplémentaire.

Quoi qu'il en soit une meilleure façon de le faire serait de créer un nouveau modèle, puis il suffit d'ajouter à la liste:

button.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      DefaultListModel dlm = new DefaultListModel(); 
      for(int i=0; i<10000; ++i) { 
       dlm.addElement("aaaa"); 
      } 
      jList.setModel(dlm); 
     } 
    }); 

Cette façon d'événements ne sont pas déclenchés comme chaque nouvel élément est ajouté.

Questions connexes