1

I thought the best way to demonstrate this is with a compilable example. I want to have a group of radio buttons which behave as such (only one can be selected at a time); however, when the currently selected radio button is 'selected' again, the selection is cleared (like a checkbox I guess).

My implementation checks the status of the radio button and, if selected, clears the selection (emulating the 'un-selecting' like a checkbox). The problem is, the radio button's select state changes before the ActionEvent fires, hence isSelected() returns true regardless of whether it was already selected. One solution would be to essentially log the ButtonGroup's selected button right before any ActionEvent fires, although my program isn't psychic like that :( I suspect I could easily implement this using a MouseListener, although that restricts functionality to mouse-usage, and I could use the keyboard, etc :) Thanks for any pointers!

Demo:

package sandbox;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JRadioButton;

public class Sandbox {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        final ButtonGroup btns = new ButtonGroup();
        final JRadioButton btn1 = new JRadioButton("Button 1");
        final JRadioButton btn2 = new JRadioButton("Button 2");
        btns.add(btn1);
        btns.add(btn2);
        ActionListener al = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() instanceof JRadioButton) {
                    btns.clearSelection();
                }
            }

        };
        btn1.addActionListener(al);
        btn2.addActionListener(al);
        f.setLayout(new FlowLayout());
        f.add(btn1);
        f.add(btn2);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

}
c24w
  • 7,421
  • 7
  • 39
  • 47
  • http://docs.oracle.com/javase/tutorial/uiswing/components/button.html#radiobutton – assylias Mar 28 '12 at 19:49
  • It's not psychic if you store what you just did and check it the next time the method gets called. – Thomas Mar 28 '12 at 19:53
  • What would be the use-case for this ? When you now select a radio button you will clear the selection again, which will frustrate the user. Are you certain radio-buttons are the way to go ? Why not opt for a ButtonGroup with `JCheckbox` instances ? – Robin Mar 28 '12 at 19:56
  • *"I thought the best way to demonstrate this is with a compilable example."* That is not compilable. For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Mar 28 '12 at 20:07
  • @Robin: the use-case is: two `JRadioButton`s appear next to a value entered in a `JTextField`. These are mutually exclusive, hence use of radio buttons. Selecting a `JRadioButton` provides further information to accompany the text, although this selection is optional, so must be 'undoable'. I thought this would be an unobtrusive and fairly intuitive solution. – c24w Mar 28 '12 at 20:22
  • @AndrewThompson: apologies, I have now included the entire class. – c24w Mar 28 '12 at 20:23

2 Answers2

2

you need combine item listener and action listener to achieve this, by oberseving the event sequence, if the "action event" occur after the "item event", that is the time to clear selection of button group.

Following code works for me.

public class JRadioButtonTest {

public static void main(String[] args) {
    JFrame f = new JFrame();
    final ButtonGroup btns = new ButtonGroup();
    final JRadioButton btn1 = new JRadioButton("Button 1");
    final JRadioButton btn2 = new JRadioButton("Button 2");
    btns.add(btn1);
    btns.add(btn2);
    EventAdapter ea = new EventAdapter(btns);
    btn1.addActionListener(ea);
    btn2.addActionListener(ea);
    btn1.addItemListener(ea);
    btn2.addItemListener(ea);

    f.setLayout(new FlowLayout());
    f.add(btn1);
    f.add(btn2);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
}

public static class EventAdapter implements ActionListener, ItemListener
{
    private ButtonGroup bg;

    boolean itemStateChanged = false;

    public EventAdapter(ButtonGroup bg)
    {

        this.bg = bg;
    }


    @Override
    public void itemStateChanged(ItemEvent itemEvent) {
        itemStateChanged = true;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
            if (!itemStateChanged)
            {
                System.out.println("UnSelected");
                bg.clearSelection();
            }
        itemStateChanged = false;
    }

}

}
chenyi1976
  • 1,104
  • 9
  • 17
  • I have been trying to combine them to such an effect, without success. Thanks for putting this together for me :) – c24w Mar 28 '12 at 21:48
1
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319