我想创建一组两个按钮(A 和 B),其中始终允许从 B 切换到 A,但从 A 切换到 B 取决于条件。只能在后一种情况下(A 到 B)检查条件,并且每次切换尝试只能进行一次检查。如果阻止切换,则必须没有ItemEvent.SELECTED
为任一按钮生成事件。
看起来很简单,所以我很困惑为什么我不能以一种简单而简洁的方式做到这一点。我认为扩展 ButtonGroup 是这样做的方法,但现在我不确定了。
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public class ToggleGroup extends JFrame {
private ButtonGroup group = new MyButtonGroup();
private JToggleButton buttonA = new JToggleButton("A");
private JToggleButton buttonB = new JToggleButton("B");
public ToggleGroup() {
setLayout(new FlowLayout());
add(buttonA);
add(buttonB);
group.add(buttonA);
group.add(buttonB);
group.setSelected(buttonA.getModel(), true);
pack();
setLocationRelativeTo(null);
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
System.out.println("-> " + (e.getSource() == buttonA ? "A" : "B") + " selected");
}
}
};
buttonA.addItemListener(itemListener);
buttonB.addItemListener(itemListener);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ToggleGroup test = new ToggleGroup();
test.setVisible(true);
}
});
}
private class MyButtonGroup extends ButtonGroup {
private boolean check() {
int result = JOptionPane.showConfirmDialog(
ToggleGroup.this, "May I switch to B?",
"Important question", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
return result == JOptionPane.YES_OPTION;
}
@Override
public void setSelected(ButtonModel m, boolean b) {
if (!b) {
return;
}
if (m == buttonA.getModel() || m == buttonB.getModel() && check()) {
super.setSelected(m, b);
}
}
}
}
我的代码的问题很明显。条件被多次检查,因此该对话框也被多次显示。
那么,当条件失败时,我如何“消耗”切换尝试呢?
编辑:
我使用这些按钮的上下文是在应用程序的不同模式之间切换的实现。其中一种模式允许更改数据并稍后提交。如果存在未提交的更改,则切换模式可能意味着数据丢失。我想确保开关是故意的。在满足条件之前禁用任何一个按钮不是一种选择。