To better understand how EDT synchronization works along
- Java Event-Dispatching Thread explanation
- A simple scenario using wait() and notify() in java and
- http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
I have created a simple JUnit3 Testcase - see below. The goal is to wait for two events:
- the GUI / JFrame to be created
- a modification of a Textfield
First I tried a wait() call on the corresponding Boolean lock objects but that didn't work as expected. Then I tried a loop waiting for the boolean lock content. Both approaches do not work as I would expect.
How needs the code below to be modified to get the expected waiting behaviour?
JUnit Testcase
package com.bitplan.test.common;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import junit.framework.TestCase;
/**
 * test the event dispatching thread handling
 * 
 * @author wf
 *
 */
public class TestEDT extends TestCase {
  private JTextField field;
  private  Boolean modified=new Boolean(false);
  private  Boolean created=new Boolean(false);
  /**
   * test UI handling
   * 
   * @throws InterruptedException
   */
  public void testUI() throws InterruptedException {
    // see
    // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
    synchronized(created) {
      created.wait();
      /**
      while(!created.isTrue()) {
        Thread.sleep(10);
      } */
    }
    field.getDocument().addDocumentListener(new DocumentListener() {
      public void flagModification() {
        synchronized(modified) {
          modified=true;
          modified.notify();
        }      
      }
      public void insertUpdate(DocumentEvent e) {
        flagModification();
      }
      @Override
      public void removeUpdate(DocumentEvent e) {     
        flagModification();
      }
      @Override
      public void changedUpdate(DocumentEvent e) {
        flagModification();        
      }
    });
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        updateField("fieldcontent");
      }
    });
    synchronized(modified) {
      // https://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java?noredirect=1&lq=1
      modified.wait();
      /**
      while(!modified) {
        Thread.sleep(10);
      } */
    }
  }
  /**
   * update the field with the new content;
   * 
   * @param newContent
   */
  protected void updateField(String newContent) {
    field.setText(newContent);
  }
  /**
   * create and show the given gui
   */
  protected void createAndShowGUI() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("Example GUI");
    JPanel panel = new JPanel();
    field = new JTextField(30);
    panel.add(field);
    frame.setContentPane(panel);
    frame.pack();
    frame.setVisible(true);
    synchronized(created) {
      created=true;
      created.notify();
    }
  }
}
 
    