メソッドで synchronized キーワードを使用すると、一度に 1 つのスレッドしかそのメソッドを実行できませんが、EDT はそのメソッドで同時に実行される複数の「イベント」を処理できます。デモンストレーションについては、以下のサンプル コードを参照してください。テスト ボタンをクリックすると、出力は次のようになります。
0 before dialog, EDT=true
1 before dialog, EDT=true
(click OK button for 1 here)
1 after dialog, EDT=true
(click OK button for 0 here)
0 after dialog, EDT=true
私が探しているのは、test() メソッドで一度に 1 つの EDT イベントのみをアクティブにして、出力が次のようになる方法です。
0 before dialog, EDT=true
(click OK button for 0 here)
0 after dialog, EDT=true
1 before dialog, EDT=true
(click OK button for 1 here)
1 after dialog, EDT=true
誰かが以前にこの問題を解決したに違いないようです。メソッドの開始時に使用する何らかのロック オブジェクトを記述したり、メソッドをラップしたりすることは可能だと思いますが、怠け者なので、車輪を再発明したくはありません。
私のテストケース:
package test1;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class EDTSyncTest extends javax.swing.JFrame {
private static final Object locker = new Object();
private int counter;
public EDTSyncTest() {
initComponents();
}
private synchronized void test() {
int l_id = counter++;
logit("" + l_id + " before dialog, EDT=" + SwingUtilities.isEventDispatchThread());
JOptionPane l_pane = new JOptionPane("test id " + l_id);
JDialog l_diag = l_pane.createDialog(this, "test");
l_diag.setModal(true);
l_diag.setVisible(true);
logit("" + l_id + " after dialog, EDT=" + SwingUtilities.isEventDispatchThread());
}
private void startTest() {
new Delayer().execute();
test();
}
private static void logit(String a_msg) {
System.out.println(a_msg);
}
private class Delayer extends SwingWorker<Object, Object> {
@Override
protected Object doInBackground() throws Exception {
Thread.sleep(2000);
return null;
}
@Override
protected void done() {
test();
}
}
private void initComponents() {
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.FlowLayout());
jButton1.setText("Test");
jButton1.setName("jButton1"); // NOI18N
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
getContentPane().add(jButton1);
pack();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
startTest();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new EDTSyncTest().setVisible(true);
}
});
}
protected javax.swing.JButton jButton1;
}