Я не могу определить семантику для этой функциональности JRadioButton

Я думал, что лучший способ продемонстрировать это на скомпилированном примере. Я хочу иметь группу переключателей, которые ведут себя как таковые (можно выбрать только одну); однако, когда текущий выбранный переключатель снова "выбран", выбор очищается (например, флажок, я полагаю).

Моя реализация проверяет состояние переключателя и, если выбрано, очищает выбор (эмулируя "отмена выбора", как флажок). Проблема в том, что состояние выбора переключателя изменяется до ActionEvent пожары, следовательно isSelected() возвращает true независимо от того, был ли он уже выбран. Одним из решений было бы, по сути, регистрировать выбранную кнопку ButtonGroup непосредственно перед любым срабатыванием ActionEvent, хотя моя программа не такая экстрасенсорная:(Я подозреваю, что мог бы легко реализовать это, используя MouseListener, хотя это ограничивает функциональность использованием мыши, и я мог бы использовать клавиатуру и т. д.:) Спасибо за любые указатели!

Демо-версия:

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);
    }

}

2 ответа

Решение

Вам нужно объединить прослушиватель элементов и прослушиватель действий, чтобы добиться этого, путем тщательного анализа последовательности событий, если "событие действия" происходит после "события элемента", то есть время, чтобы очистить выбор группы кнопок.

Следующий код работает для меня.

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;
    }

}

}
Другие вопросы по тегам