Evento ItemStateChanged no invocado al anular la selección de un JToggleButton

Tengo algunos JToggleButton en un ButtonGroup usando el evento itemStateChanged de ItemListener para detectar cuándo un botón está seleccionado/no seleccionado. No funciona en el caso de que haga clic en un botón para seleccionarlo o deseleccionarlo. ¿Cómo soluciono este problema? Si uso ActionListener, cuando se invoca ActionEvent, el estado de selección del botón (isSelected()) siempre dice verdadero.

ButtonGroup buttonGroup = new ButtonGroup();
for(int i=0;i<toggleButtons.length;i++){
    buttonGroup.add(toggleButtons[i]);
}
for(int i=0;i<toggleButtons.length;i++){
    final int  j=i;
    toggleButtons[i].addItemListener(new ItemListener(){
    public void itemStateChanged(ItemEvent e) {
         JToggleButton item=(JToggleButton)e.getSource();
      if(e.getStateChange()==ItemEvent.SELECTED){
          System.err.println(j+" selected!!!! "+item.getText());
      } else if(e.getStateChange()==ItemEvent.DESELECTED){
          System.err.println(j+" unselected!!!! "+item.getText());
      }
    }
    });
}

preguntado el 02 de mayo de 12 a las 19:05

No agregue su JToggleButton al ButtonGroup, eso es todo, entonces puede tener el comportamiento que busca, aunque tiene que hacer el trabajo adicional manualmente, que previamente fue realizado por su ButtonGroup :-)-

2 Respuestas

No puede anular activamente la selección de un botón en un ButtonGroup, tiene que seleccionar otro botón, pero cuando se selecciona un botón nuevo, se deselecciona el anterior y se activan dos eventos, uno para el elemento seleccionado y otro para el elemento deseleccionado.

Por ejemplo:

public class FrameTest extends JFrame {

    public FrameTest init() {
        ItemListener listener = new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                ((JToggleButton)e.getSource()).setText("" + e.getStateChange());
            }
        };
        setLayout(new GridLayout(2,1));
        ButtonGroup bg = new ButtonGroup();
        // button 1
        JToggleButton jtb = new JToggleButton("Button");
        jtb.addItemListener(listener);
        bg.add(jtb);
        add(jtb);
        // button 2
        jtb = new JToggleButton("Button");
        jtb.addItemListener(listener);
        bg.add(jtb);
        add(jtb);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        pack();
        return this;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new FrameTest().init();
            }
        });
    }
}

produce:

no seleccionado ninguno todavía Botón superior seleccionado Botón inferior seleccionado

contestado el 02 de mayo de 12 a las 19:05

Sharetbut: si quiero anular activamente la selección de un botón sin seleccionar otros botones, ¿cuál es la mejor manera de hacerlo? - user121196

En el grupo de botones, solo puede tener un botón seleccionado a la vez, si desea anular la selección, es como anular la selección de todos, puede llamar al clearSelection método de ButtonGroup. - MByD

Si realmente quieres usar grupo de botones, entonces tienes que buscar ButtonGroup personalizado (izado) por Darryl Burke

contestado el 02 de mayo de 12 a las 21:05

¿Funcionaría el grupo de botones personalizado para anular la selección haciendo clic en el propio botón? No dice en la documentación. ¿Hay otros enfoques además de ButtonGroup? - user121196

@ user121196 correcto pero válido solo para JRadioButton o JCheckBox, pero luego es posible seleccionar solo un elemento de ButtonGroup: mKorbel

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.