我有一個系統,我需要能夠問一個簡單的「繼續?」風格的問題。有一個文本字段和一個按鈕。無論是單獨修改文本字段還是單獨按下按鈕,我都需要能夠讓用戶確認。所以,這給了我一個關於文本字段的焦點偵聽器和一個按鈕上的動作偵聽器。但是,如果我編輯該字段,並立即單擊該按鈕,將彈出兩個確認對話框 - 一個來自焦點偵聽器,另一個來自緊跟其後的動作偵聽器。現在,我顯然只需要確認一次,所以我試着同步拋出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()被認爲是阻擋功能。對話框不會按順序彈出(這很有意義),它們並行打開!如果您嘗試使用該代碼,您會看到按下任何按鈕之前彈出「驗證」消息兩次。 –