2012-03-05 6 views
3

J'essaye d'écrire ma propre implémentation de ListSelectionModel et actuellement je suis bloqué en essayant d'implémenter insertIndexInterval. Je ne comprends pas le résultat de cette méthode dans l'implémentation DefautListSelectionModel de Sun/Oracle. Voici un exemple:Que fait exactement ListSelectionModel.insertIndexInterval()?

ListSelectionModel model = new DefaultListSelectionModel(); 
model.setSelectionInterval(3, 5); 
model.addListSelectionListener(new ListSelectionListener() 
{ 
    public void valueChanged(ListSelectionEvent e) 
    { 
     System.out.println("Changed range reported by event: " + 
      e.getFirstIndex() + "-" + e.getLastIndex()); 
    } 
}); 

System.out.print("Selected indices before insert: "); 
for (int i = model.getMinSelectionIndex(); i <= model.getMaxSelectionIndex(); i++) 
    if (model.isSelectedIndex(i)) System.out.print(i + " "); 
System.out.println(); 

model.insertIndexInterval(3, 3, true); 

System.out.print("Selected indices after insert: "); 
for (int i = model.getMinSelectionIndex(); i <= model.getMaxSelectionIndex(); i++) 
    if (model.isSelectedIndex(i)) System.out.print(i + " "); 
System.out.println(); 

Lorsque vous exécutez ce code, vous obtiendrez cette sortie:

Selected indices before insert: 3 4 5 
Changed range reported by event: 3-8 
Selected indices after insert: 3 4 5 6 7 8 

Ainsi, la sélection initiale était 3-5 et il a été étendu à 3-8 lors de l'insertion de nouveaux indices . Mais 3-5 ont déjà été sélectionnés alors le vrai changement n'est que 6-8 alors pourquoi l'événement me dit-il que la gamme 3-8 a été changée? Il est encore plus confuse lorsque vous modifiez le insertIndexInterval appel à ceci:

model.insertIndexInterval(3, 3, false); 

Maintenant la sortie est la suivante:

Selected indices before insert: 3 4 5 
Changed range reported by event: 5-8 
Selected indices after insert: 3 4 5 6 7 8 

Je ne sais pas pourquoi le changement est rapporté 5-8.

La documentation API de cette méthode est beaucoup trop courte pour comprendre ce qui s'y passe. En particulier ce paramètre before est un mystère pour moi car il n'a jamais d'effet sur la sélection mais il semble avoir un effet sur l'événement et sur les indices de plomb et d'ancrage.

Je ne peux même pas écrire un test unitaire pour ma mise en œuvre car je ne connais tout simplement pas les résultats attendus.

Donc, quelqu'un peut-il expliquer en détail ce que cette méthode (et en particulier le before drapeau) fait et quels effets secondaires il a sur le modèle de sélection et le ListSelectionEvent?

Répondre

4

Il est utilisé lorsque de nouvelles données sont ajoutées au modèle de données (de sorte que les indices de sélection doivent être déplacés). Si 2 signifie « nouvellement ajoutés et sélectionnés » que votre sortie serait:

[0,0,0,1,1,1,0,0,0,0] == [3A,4,5L] 
-> add after [0,0,0,1,2,2,2,1,1,0] == [3A,4,5,6,7,8L] 
-> add before [0,0,0,2,2,2,1,1,1,0] == [3,4,5,6A,7,8L] 

Ce que vous voyez ici est une caractéristique * de DefaultListSelectionModel - l'ajout d'indices dans une sélection en cours, étend automatiquement la sélection.

Commencez par exemple avec l'index 1 sélectionné, puis insérez trois lignes à l'index: trois

[1,0,0,0,0,0,0,0,0,0] 
-> add after [1,0,0,0,0,0,0,0,0,0] 

Notez que votre représentation de sélection est trompeuse, les zéros ne sont pas vraiment là.Une meilleure façon d'imprimer l'état de sélection serait:

private static void printSelection(ListSelectionModel model) { 
    System.out.print("["); 
    for (int i = model.getMinSelectionIndex(); i <= model.getMaxSelectionIndex(); i++) { 
     if(i > model.getMinSelectionIndex()) { 
      System.out.print(","); 
     } 
     if(model.isSelectedIndex(i)) { 
      System.out.print(i); 
      if(i == model.getAnchorSelectionIndex()) { 
       System.out.print("A"); 
      } 
      if(i == model.getLeadSelectionIndex()) { 
       System.out.print("L"); 
      } 
     } 
    } 
    System.out.println("]"); 
} 

*) La documentation de DefaultListSelectionModel # insertIndexInterval diffère de l'interface, vous pouvez aussi consulter http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4700643 et http://java.net/jira/browse/SWINGX-272

+0

Oui, je sais que les zéros ne sont pas vraiment là. Il est simplement plus facile de comparer de cette façon. Mais je ne comprends toujours pas. L'événement est lié au modèle de sélection et non au modèle de données. Les index 3-5 ont déjà été sélectionnés avant d'insérer de nouvelles données, de sorte que le seul véritable changement (au modèle de sélection, pas au modèle de données) est la plage de sélection supplémentaire de 6-8. Mais le changement rapporté est 3-8 (Quand avant = vrai) et 5-8 (Quand avant = faux). Surtout que 5-8 n'a pas de sens jusqu'à présent. – kayahr

+1

Oui, alors il explique le 3-8 (Parce que le 1s a été déplacé et le 2s a été ajouté) mais comment expliquez-vous la plage 5-8 signalée lors de l'utilisation de before = false? Lors de la visualisation à trois états, il doit être 6-8 parce que les trois 1 ne bouge pas et les trois 2 sont insérés à l'index 6, pas 5. – kayahr

+1

BTW: Lors de l'insertion après l'index 3 alors il devrait être 0001222110 et pas 0001112220, ou pas? La documentation dit "Insérer les indices de longueur commençant avant/après l'index". – kayahr

-2

EDIT J'espère que nous parler JList, pas JTable, puis le repos est dans l'avis

pouvez-vous s'il vous plaît utiliser ce SSCCE et modifier votre question avec le code domostrating clairement vos problèmes avec ListSelectionModel, ListeSelectionMode et le code connexe de solution de contournement, ce noticeListener ont obtenu un seul dimension ou directional,

import java.awt.Component; 
import java.awt.event.InputEvent; 
import java.awt.event.MouseEvent; 
import javax.swing.*; 

public class Ctrl_Down_JList { 

    private static void createAndShowUI() { 
     String[] items = {"Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"}; 
     JList myJList = new JList(items) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void processMouseEvent(MouseEvent e) { 
       int modifiers = e.getModifiers() | InputEvent.CTRL_MASK; 
       // change the modifiers to believe that control key is down 
       int modifiersEx = e.getModifiersEx() | InputEvent.CTRL_MASK; 
       // can I use this anywhere? I don't see how to change the modifiersEx of the MouseEvent 
       MouseEvent myME = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), modifiers, e.getX(), 
         e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton()); 
       super.processMouseEvent(myME); 
      } 
     }; 
     JFrame frame = new JFrame("Ctrl_Down_JList"); 
     frame.getContentPane().add(new JScrollPane(myJList)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
+1

Votre code affiché n'a rien à voir avec le question. –

+0

@Walter Laan vous avez raison, mais pourquoi s'embêter avec sans connaître SelectionMode, alors les choses pourraient être plus simples que vous décrivez dans votre réponse +1 pour déranger, EDIT et reste vous verrez dans le commentaire dans votre réponse :-) – mKorbel

+0

I ' J'ai ajouté un exemple de code complet. J'espère que cela démontre mon problème assez bien. – kayahr