2010-11-07 7 views
2

Cela doit être un malentendu de mon côté, mais j'ai ce qui suit:
J'ai ajouté un ItemListener à un Jcombobox.
Dans l'écouteur d'élément, je vérifie l'événement s'il est de type ItemSelected.
Si c'est le cas, je mets à jour une valeur dans un JTextPane. Le problème est que cela fonctionne comme suit:
Je clique sur une nouvelle valeur dans le jcombobox et rien n'est changé dans le jtextfield. Je dois effectivement cliquer sur un autre composant, par exemple le jtextfield puis le jtextfield est mis à jour.
Il semble que le focus doit être supprimé de jcombobox afin que la modification d'événement soit envoyée au code de l'élément.
Est-ce que c'est comme ça que ça fonctionne, ou est-ce que je fais quelque chose de mal? Est-il possible de gérer l'événement sans avoir besoin de supprimer le focus?itemlistener obtient l'événement après que le focus est enlevé de jcombobox

MISE À JOUR: Ce mon code et la méthode updateJTextPane est appelée après avoir cliqué sur un autre composant un pas lorsque je sélectionne une nouvelle valeur de la liste déroulante. C'est à dire. combo a la valeur "1", je clique sur la liste déroulante et clique sur "2". L'élément actuellement sélectionné est maintenant "2". Ma méthode n'est pas appelée à ce stade. Je clique sur une deuxième zone de liste déroulante, le second combo a le focus et ensuite ma méthode updateJTextPane() est appelée. Pourquoi?
MISE À JOUR 2:

//Code from Netbeans generator 
JComboBox myCbx = new javax.swing.JComboBox();  
myCbx.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); 
myCbx.setName("myCbx"); // NOI18N 
//My ItemListener 
class myItemListener implements ItemListener{ 
public void itemStateChanged(ItemEvent ie) { 
      if (ie.getStateChange() == ItemEvent.SELECTED) { // Item was just selected 
       updateJTextPane(); 
      }  
     } 
    } 
//add item listener to combo 
myCbx.addItemListener(new myItemListener()); 

MISE À JOUR 3: myItemListener classe interne est ajouté à 5 plus comboboxes dans le même JDialog si cette question est importante d'une manière que je ne sais pas Merci

+0

Code reformaté; s'il vous plaît revenir si incorrect. – trashgod

+0

@ user384706: Pouvez-vous essayer les deux tests mentionnés dans ma réponse? – Grodriguez

+0

@Grrriguez: Merci pour votre aide.Les tests ont également échoué, mais quand j'ai redémarré mon PC, il n'y avait pas de problème, avec mon code et avec vos tests. Je ne sais pas comment ça s'est passé. Je vais fermer cette question – Cratylus

Répondre

1

Cette Ce n'est pas comme ça que ça doit fonctionner. Les événements d'élément doivent être générés immédiatement chaque fois que l'élément sélectionné change.

Je suggère de commencer avec un exemple simple tel que this one et de voir si les événements sont réellement générés. Si cela fonctionne, il vous suffit de rechercher les différences entre ceci et votre propre code.

Mise à jour:

Votre méthode itemStateChanged semble bien, le problème doit être ailleurs. Peut-être qu'il y a quelque chose qui ne va pas avec updateJTextPane. Que se passe-t-il si vous remplacez l'appel par updateJTextPane par un System.out.println? En outre, pouvez-vous imprimer la source de l'événement (ie.getSource()) et vérifier que l'événement provient réellement de la première zone de liste déroulante?

Si vous postez un exemple autonome qui peut être compilé et exécuté, il devrait être beaucoup plus facile de localiser le problème.

+0

@Godriguez: La différence est que dans mon listenerener je vérifie: if (ie.getStateChange() == ItemEvent.SELECTED) {// appelle ma fonction}. Vous dites que je devrais supprimer ce chèque? Mais alors, comment saurais-je que l'objet sélectionné a été changé? – Cratylus

+1

Non, ce que j'ai dit, c'est que vous devriez essayer d'abord avec un exemple simple, puis ajouter des fonctionnalités de façon incrémentielle pour voir où est le problème. Est-ce que l'exemple que j'ai lié fonctionne pour vous? – Grodriguez

+0

@ user384706, ce processus est connu comme la création d'un SSCCE (http://sscce.org). Chaque question devrait avoir un SSCCE inclus. Personne ne peut dire ce que vous faites de mal en fonction des 4 lignes de code que vous avez publiées. – camickr

1

Est-il possible de gérer l'événement sans avoir à supprimer le focus? Bien sûr que oui! :)

Voici un échantillon de la façon dont cela pourrait fonctionner, en supposant ma compréhension de vos besoins est correcte:

class ComboListener implements ItemListener { 
    @Override 
    public void itemStateChanged(ItemEvent e) { 
     if (e.getStateChange() == ItemEvent.SELECTED) { 
      System.out.println("Selected Item: \"" 
       + ((JComboBox)e.getSource()).getSelectedItem() + "\""); 
     } 
    } 
} 

Si vous n'ajoutez pas si le chèque, vous allez effectuer l'action pour le premier élément étant non sélectionné et le second étant sélectionné.

+0

Je ne suis pas sûr de suivre. J'ai la condition if dans la méthode itemStateChanged, et je reçois l'événement seulement après que le focus est retiré du jcombobox. – Cratylus

+0

Code reformaté; s'il vous plaît revenir si incorrect. – trashgod

+0

@Cratylus l'auditeur sera appelé une fois pour la sélection de l'élément sur lequel vous cliquez et une fois pour la désélection de l'élément précédemment sélectionné. La vérification if permet d'atteindre uniquement l'événement pour l'élément sélectionné, pas pour la désélection. – javatarz

1

Il devrait fonctionner comme vous l'avez décrit, les pistes suivantes: très bien

class Frame extends JFrame { 
    JComboBox box; 
    JTextField field; 
    String[] entries = { "one", "two", "three" }; 

    Frame() { 
     setLayout(new FlowLayout()); 

     box = new JComboBox(entries); 
     box.addItemListener(new ItemListener() { 
      @Override 
      public void itemStateChanged(ItemEvent e) { 
       if (e.getStateChange() == ItemEvent.SELECTED) { 
        field.setText((String) box.getSelectedItem()); 
       } 
      } 
     }); 
     add(box); 

     field = new JTextField(); 
     field.setColumns(10); 
     add(field); 

     setSize(400, 300); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 
    } 
} 

public class Test { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       Frame frame = new Frame(); 
      } 
     }); 

    } 
} 
+0

@fcocq: étrange. Cela pourrait-il être quelque chose à faire avec netbeans? J'utilise IDE pour mon code – Cratylus

+0

Pourrait être, ne sais pas comment Netbeans génère le code GUI. Si votre ItemListener est implémenté par la classe englobante, par ex. "class Frame extends JFrame implémente ItemListener" et ajouté à d'autres composants, vous devez également vérifier le composant que vous manipulez, par ex. if ((ie.getSource() == yourComboBox) && (ie.getStateChange() == ItemEvent.SELECTED)) {... – deorst

+0

@ fbcocq: L'écouteur d'élément est ajouté à 5 autres comboboxes. Cela a-t-il une importance? – Cratylus

1

que j'ai rencontré la même situation sur le choix. Pour moi, il aime plus un bug en Java. Mon cas est que j'ai deux choix A et B. B dépend de la sélection de A. Par exemple, A = {a1, a2, a3}. Si A = a1 B est une liste de choix de {1, 2, 3}. Si A = a2, B est une liste de {4,5,6}. Si A = a3, B est une liste de {7,8,9}. Le flux est sélectionné a1, puis sélectionnez 2 sur B. Sélectionnez a2 et B est dans l'index par défaut 0 (4) et sélectionnez 5 sur B, la fonction itemStateChanged() ne sera pas appelée. Il semble que le contrôle de la vue ne soit pas synchronisé avec le jeu de données. La raison pour laquelle itemStateChanged() n'est pas appelé puisque le 5 a le même index que la sélection précédente.

Questions connexes