Я не могу определить семантику для этой функциональности 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;
}
}
}
это общая проблема с JRadioButton и JCheckBox, и иногда для других JComponents JButtons эти события должны быть заключены в invokeLater()
для JRadioButton и JCheckBox лучше использовать только ItemListener, потому что сработали точные события
SELECTED
а такжеDESELECTED