私はシンプルな「続行」を聞くことができる必要があるシステムを持っています。スタイルの質問。テキストフィールドとボタンがあります。孤立してテキストフィールドを変更するか、ボタンを単独で押してください。ユーザーに確認を依頼する必要があります。これは、テキストフィールドのフォーカスリスナーと、ボタンのアクションリスナーを提供します。JOptionPaneはどのように同期されていませんか?
ただし、フィールドを編集してすぐにボタンをクリックすると、フォーカスリスナーからの確認ダイアログボックスと、直後のアクションリスナーからの確認ダイアログボックスが表示されます。今は確認が一度だけ必要なので、JOptionPaneをスローする関数を同期させてみましたので、2回入力しなくても効果はないようです。
これを証明するいくつかのコード:
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がsynchronizedキーワードをどのように巡回することができるかについて誰かが説明してくれれば幸いです。
対処方法については、私は確認ダイアログへの答えを待つスレッドを実装する必要があると考えています。次に、スレッドがアクティブかどうかを確認する必要があります(ダイアログがすでに起動している場合)。もしそれが起動している場合は、応答が与えられたときにリスナーを追加する必要があります。私はすでに先に行ってこれをやっていましたが、問題の解決策のオーバーエンジニアリングのように感じます。なぜこれが最初に起こったのかについての限られた理解があるからです。さらに、私はすでに少なくともいくつかの異なるケースを想像することができます。問題が発生すると、エラーが発生しやすくなります。
===編集===
を明確にするために、これらのメッセージボックスはない順序で、同時にポップアップします。たとえば:
だから何混乱していますがJOptionPane.showConfirmDialog()がブロッキング機能することになっているということです。ダイアログは順番にポップアップしません(それは理にかなっています)。それらは並行して開きます!コードを試してみると、いずれかのボタンを押す前に「検証中」というメッセージが2回ポップアップすることがわかります。 –