Как отменить выбор уже выбранного JRadioButton, щелкнув по нему

Допустим, у нас есть несколько JRadioButton, которые принадлежат одному и тому же ButtonGroup, когда пользователь нажимает на JRadioButton, он выбирается. Я хочу добавить функцию, при которой, когда пользователь нажимает на уже выбранный JRadioButton, он отменяется, то есть весь ButtonGroup не будет выбран JRadioButton. Я уже искал, что привело меня к подсказке использовать метод ButtonGroup, clearSelection. но проблема в том, что когда пользователь нажимает на уже выбранный JRadioButton, он не генерирует никаких ItemStateChangeEvent, которые генерируются при нажатии на другие невыбранные JRadioButton.


person Sukhbir    schedule 02.06.2016    source источник
comment
Угадайте: вы не «должны» отменить выбор радиокнопки, для этой цели используйте флажок   -  person Kennet    schedule 02.06.2016
comment
Возможный дубликат Отмена выбора RadioButtons в Java Swing. Поскольку щелчок недоступен, отредактируйте свой вопрос, указав, какие другие жесты пользователя вы рассмотрели.   -  person trashgod    schedule 02.06.2016
comment
Позвольте мне прояснить это для вас, если buttonGroup имеет, предположим, 4 JRadioButton, из которых 3-й JRadioButton уже выбран. Затем снова нажмите на 3-й JRadioButton. Это должно очистить выбор 3-го JRadioButton.   -  person Sukhbir    schedule 02.06.2016


Ответы (2)


Или, как альтернативный подход, переопределите 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);
    });
  }
}
person aterai    schedule 03.06.2016
comment
Мастерски! Протестировано с помощью com.apple.laf.AquaLookAndFeel и привязки клавиш и прослушивателя мыши, предложенного здесь. - person trashgod; 05.06.2016

Я бы использовал подход, процитированный. Поскольку JRadioButton — это JToggleButton, жесты мыши возможны, но проблематичны. Я бы использовал MouseListener на закрывающей панели и привязки клавиш на кнопках, как показано ниже. Нажмите на панель вокруг кнопок или нажмите клавишу escape, чтобы снять выделение со всех кнопок в ButtonGroup.

изображение

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://stackoverflow.com/a/37599961/230513
 */
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);
    }
}
person trashgod    schedule 02.06.2016