How to deselect already selected JRadioButton by clicking on it
Asked Answered
C

2

1

Let's say we are having some JRadioButtons which belongs to same ButtonGroup, when user clicks on a JRadioButton it got selected. I want to add a feature that when user click on already selected JRadioButton, it gets deselected, that is whole ButtonGroup will have no JRadioButton selected. I already searched which leads me hint to use, ButtonGroup method, clearSelection. but problem is that when user clicks on already selected JRadioButton, it is not generating any ItemStateChangeEvent, which is generating by clicking on other unselected JRadioButtons.

Chrysa answered 2/6, 2016 at 17:13 Comment(3)
Guess: your not 'supposed' to deselect a radiobutton, for that purpose use a checkboxVisualize
Possible duplicate of Unselecting RadioButtons in Java Swing. As clicking is unavailable, please edit your question to indicate what other user gesture(s) you have considered.Soggy
Let me clear this for you, if a buttonGroup has suppose 4 JRadioButtons, out of which 3rd JRadioButton is already selected one. Then again clicking on 3rd JRadioButton. It should clear selection of 3rd JRadioButton.Chrysa
D
3

Or, as an alternate approach, override ButtonGroup#setSelected(...):

import java.awt.*;
import java.util.Arrays;
import javax.swing.*;

public class Test2 {
  public JComponent makeUI() {
    JPanel p = new JPanel(new GridLayout(2, 1));
      p.add(makePanel("Default ButtonGroup", new ButtonGroup()));
      p.add(makePanel("Custom ButtonGroup", new ButtonGroup() {
          private ButtonModel prevModel;
          private boolean isAdjusting = false;
          @Override public void setSelected(ButtonModel m, boolean b) {
              if (isAdjusting) {
                  return;
              }
              if (m.equals(prevModel)) {
                  isAdjusting = true;
                  clearSelection();
                  isAdjusting = false;
              } else {
                  super.setSelected(m, b);
              }
              prevModel = getSelection();
          }
      }));
    return p;
  }
  private JComponent makePanel(String title, ButtonGroup g) {
    JPanel p = new JPanel();
    p.setBorder(BorderFactory.createTitledBorder(title));
    for (String s: Arrays.asList("aaa", "bbb", "ccc")) {
      AbstractButton r = new JRadioButton(s);
      //AbstractButton r = new JToggleButton(s);
      p.add(r);
      g.add(r);
    }
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new Test2().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}
Degree answered 3/6, 2016 at 6:40 Comment(1)
Masterful! Tested with com.apple.laf.AquaLookAndFeel and the key binding & mouse listener suggested here.Soggy
S
2

I'd use the approach cited. Because a JRadioButton is a JToggleButton, a mouse gesture is possible but problematic. I'd use a MouseListener on the enclosing panel and Key Bindings on the buttons as shown below. Click in the panel surrounding the buttons or press the escape key to clear the selection of all buttons in the ButtonGroup.

image

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.KeyStroke;

/**
 * @see https://mcmap.net/q/408184/-how-to-deselect-already-selected-jradiobutton-by-clicking-on-it
 */
public class Test {

    private static final String UNSELECT = "UNSELECT";

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new JPanel(new GridLayout(1, 0, 5, 5));
        p.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
        ButtonGroup group = new ButtonGroup();
        JRadioButton r1 = create("One", group);
        JRadioButton r2 = create("Two", group);
        p.add(r1);
        p.add(r2);
        p.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                group.clearSelection();
            }
        });
        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JRadioButton create(String name, ButtonGroup group) {
        JRadioButton b = new JRadioButton(name);
        group.add(b);
        b.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), UNSELECT);
        b.getActionMap().put(UNSELECT, new AbstractAction(UNSELECT) {
            @Override
            public void actionPerformed(ActionEvent e) {
                group.clearSelection();
            }
        });
        return b;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Test()::display);
    }
}
Soggy answered 2/6, 2016 at 18:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.