我有一个系统,我需要能够问一个简单的“继续?”风格的问题。有一个文本字段和一个按钮。无论是单独修改文本字段还是单独按下按钮,我都需要能够让用户确认。所以,这给了我一个关于文本字段的焦点侦听器和一个按钮上的动作侦听器。但是,如果我编辑该字段,并立即单击该按钮,将弹出两个确认对话框 - 一个来自焦点侦听器,另一个来自紧跟其后的动作侦听器。现在,我显然只需要确认一次,所以我试着同步抛出JOptionPane的函数,所以它不会输入两次,但这似乎没有效果。JOptionPane如何不尊重同步?
一些代码演示此:
public class Main extends JFrame {
static public void main(String [] args) {
SwingUtilities.invokeLater(() -> {
Main m = new Main();
m.setVisible(true);
});
}
private JTextField field;
private JButton button;
private boolean isValid;
public Main() {
isValid = false;
setLayout(new BorderLayout());
field = new JTextField(15);
field.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent arg0) {}
@Override
public void focusLost(FocusEvent e) {
doValidate();
}
});
add(field, BorderLayout.CENTER);
button = new JButton("Push Me");
button.addActionListener((ActionEvent e) -> {
doValidate();
doAction();
});
add(button, BorderLayout.SOUTH);
pack();
}
private synchronized void doValidate() {
System.out.println("Validating");
if(!isValid) {
int answer = JOptionPane.showConfirmDialog(this, "Really do it?");
if(answer == JOptionPane.YES_OPTION)
isValid = true;
}
}
private void doAction() {
System.out.println("Action done!");
}
}
首先,这多少有些令人吃惊的行为。如果有人对Swing/JOptionPane如何能够绕行同步关键字有所解释,我很乐意。
至于如何处理,我的想法是,我需要实现一个线程,等待确认对话框的答案。然后,我需要检查线程是否处于活动状态(如果对话框已经启动,那就是),如果它已经启动,我需要添加一个监听器来给出答案。我已经提前完成了这个任务,但感觉就像是过度设计解决问题的方案,特别是因为我对这个问题首先发生的原因缺乏了解。此外,我已经可以想象至少有几个不同的情况下,我最终会陷入困境,使其可能更容易出错。
===编辑===
需要明确的是,这些消息框弹出的同时,没有先后顺序。例如:
那么,什么是令人困惑的是,JOptionPane.showConfirmDialog()被认为是阻挡功能。对话框不会按顺序弹出(这很有意义),它们并行打开!如果您尝试使用该代码,您会看到按下任何按钮之前弹出“验证”消息两次。 –