Title: [jbehave] [666] trunk/extensions/swing/src/java/org/jbehave/threaded/swing: [EK] Restored Swing so that it works for Windows, but think it still pends for Linux.
Revision
666
Author
sirenian
Date
2007-01-09 04:46:50 -0600 (Tue, 09 Jan 2007)

Log Message

[EK] Restored Swing so that it works for Windows, but think it still pends for Linux. Switching to Ubuntu to try and fix that.
Also delegated character typing as window wrapper was getting large.

Modified Paths

Added Paths

Diff

Modified: trunk/extensions/swing/src/behaviour/org/jbehave/threaded/swing/DefaultWindowWrapperBehaviour.java (665 => 666)

--- trunk/extensions/swing/src/behaviour/org/jbehave/threaded/swing/DefaultWindowWrapperBehaviour.java	2007-01-08 15:16:52 UTC (rev 665)
+++ trunk/extensions/swing/src/behaviour/org/jbehave/threaded/swing/DefaultWindowWrapperBehaviour.java	2007-01-09 10:46:50 UTC (rev 666)
@@ -176,7 +176,6 @@
             wrapper.closeWindow();
         }
     }
-    
 
     private void checkForHeadless() {
         new HeadlessChecker().check();

Added: trunk/extensions/swing/src/java/org/jbehave/threaded/swing/CharacterTyper.java (0 => 666)

--- trunk/extensions/swing/src/java/org/jbehave/threaded/swing/CharacterTyper.java	                        (rev 0)
+++ trunk/extensions/swing/src/java/org/jbehave/threaded/swing/CharacterTyper.java	2007-01-09 10:46:50 UTC (rev 666)
@@ -0,0 +1,172 @@
+package org.jbehave.threaded.swing;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.KeyStroke;
+
+import org.jbehave.core.exception.PendingException;
+import org.jbehave.threaded.time.TimeoutException;
+
+/**
+ * Used for pressing or typing all keys which have valid characters associated with them.
+ */
+class CharacterTyper {
+
+    private static final String TEXT_TYPING_UNSUPPORTED = "Text typing not supported for your Swing library.";
+    private static Boolean typingCharWorks;
+    private static Boolean pressingCharWorks;
+    
+    private EventQueue sysQueue;
+    private Idler idler;
+
+
+    CharacterTyper() {
+        sysQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+        idler = new Idler();
+    }
+    
+    public void typeIntoComponent(Component component, String text) {
+        VerifyingKeyAdapter verifier = new VerifyingKeyAdapter();
+        component.addKeyListener(verifier);
+        
+        try {
+            for (int i = 0; i < text.length(); i++) {
+                postKeyEvent(component, text.charAt(i));
+                if (!verifier.keyTyped) {
+                    throw new PendingException(TEXT_TYPING_UNSUPPORTED);
+                }
+            }
+        } finally {
+            component.removeKeyListener(verifier);
+            idler.waitForIdle();
+        }
+    }
+    
+    /**
+     * Use this for any key which has a valid character associated with it, when it is being pressed
+     * (eg: as a game control key) rather than being typed into a text component.
+     */
+    public void pressKeychar(Window window, char key) throws TimeoutException {
+        if (pressingCharWorks == null) {
+            postTypedEventWithInputVerifier(window, key);
+        } else if (!pressingCharWorks.booleanValue()) {
+            throw new PendingException(TEXT_TYPING_UNSUPPORTED);
+        } else {
+            postKeyEvent(window, key);
+        }
+    }
+
+    private void postTypedEventWithInputVerifier(Window window, char key) throws TimeoutException {
+        boolean result = verifyKeyCharEventPostedToNewFrame(key);
+        
+        if (result) {
+            postTypedEvent(window, key); 
+            pressingCharWorks = Boolean.TRUE;
+        } else {
+            pressingCharWorks = Boolean.FALSE;
+            throw new PendingException(TEXT_TYPING_UNSUPPORTED);
+        }
+    }
+
+    private boolean verifyKeyCharEventPostedToNewFrame(char key) throws TimeoutException {
+        JFrame jFrame = new JFrame();
+        jFrame.setName("CharacterTyper.frame");
+        JPanel panel = new JPanel();
+        jFrame.setContentPane(panel);
+
+        
+        KeyStroke keyStroke = KeyStroke.getKeyStroke(key);
+        String actionId = "CharacterTyper.actionFor " + key;
+        VerifyingAction verifier = new VerifyingAction();
+        
+        panel.getInputMap().put(keyStroke, actionId);
+        panel.getActionMap().put(actionId, verifier);
+        
+        jFrame.pack();
+        jFrame.setVisible(true);
+        
+        new DefaultWindowWrapper("CharacterTyper.frame").getOpenWindow();
+        
+        postKeyEvent(jFrame, key);
+        
+        panel.getInputMap().remove(keyStroke);
+        panel.getActionMap().remove(actionId);
+        
+        boolean result = verifier.actionPerformed;
+        jFrame.dispose();
+        
+        idler.waitForIdle();
+        
+        return result;
+    }
+
+    private void postTypedEvent(Window window, char key) throws TimeoutException {
+        if (typingCharWorks == null) {
+            postTypedEventWithVerifier(window, key);
+        } else if (!typingCharWorks.booleanValue()) {
+            throw new PendingException(TEXT_TYPING_UNSUPPORTED);
+        } else {
+            postKeyEvent(window, key);
+        }
+    }
+
+    private void postTypedEventWithVerifier(Window window, char key) {
+        VerifyingKeyAdapter verifier = new VerifyingKeyAdapter();
+        window.addKeyListener(verifier);
+        
+        try {
+            postKeyEvent(window, key);
+            if (verifier.keyTyped) {
+                typingCharWorks = Boolean.TRUE;
+            } else {
+                typingCharWorks = Boolean.FALSE;
+                throw new PendingException(TEXT_TYPING_UNSUPPORTED);
+            }
+        }
+        finally {
+            window.removeKeyListener(verifier);
+        }
+    }
+
+    private void postKeyEvent(Component component, char key) {
+        sysQueue.postEvent(createKeyPressEvent(component, key, KeyEvent.KEY_PRESSED));
+        sysQueue.postEvent(createKeyPressEvent(component, key, KeyEvent.KEY_RELEASED));
+        sysQueue.postEvent(createKeyPressEvent(component, key, KeyEvent.KEY_TYPED));
+        idler.waitForIdle();
+    }
+    
+    private AWTEvent createKeyPressEvent(Component component, char c, int id) {
+        return new KeyEvent(component, 
+                id, 
+                System.currentTimeMillis(),
+                0,
+                KeyEvent.VK_UNDEFINED,
+                c);
+    }
+        
+    private class VerifyingKeyAdapter extends KeyAdapter {
+        private boolean keyTyped;
+        
+        public void keyTyped(KeyEvent e) {
+            keyTyped = true;
+        }
+    }
+    
+    private class VerifyingAction extends AbstractAction {
+        private boolean actionPerformed;
+        public void actionPerformed(ActionEvent e) {
+            actionPerformed = true;
+        }
+    }
+
+}

Modified: trunk/extensions/swing/src/java/org/jbehave/threaded/swing/DefaultWindowWrapper.java (665 => 666)

--- trunk/extensions/swing/src/java/org/jbehave/threaded/swing/DefaultWindowWrapper.java	2007-01-08 15:16:52 UTC (rev 665)
+++ trunk/extensions/swing/src/java/org/jbehave/threaded/swing/DefaultWindowWrapper.java	2007-01-09 10:46:50 UTC (rev 666)
@@ -1,22 +1,16 @@
 package org.jbehave.threaded.swing;
 
 import java.awt.AWTEvent;
-import java.awt.AWTException;
 import java.awt.Component;
 import java.awt.EventQueue;
-import java.awt.Robot;
 import java.awt.TextComponent;
 import java.awt.Toolkit;
 import java.awt.Window;
-import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.ArrayList;
 
 import javax.swing.AbstractButton;
 import javax.swing.text.JTextComponent;
 
-import org.jbehave.core.exception.PendingException;
 import org.jbehave.threaded.WindowGrabber;
 import org.jbehave.threaded.time.TimeoutException;
 
@@ -25,6 +19,8 @@
 
 	// Use of the DefaultWindowWrapper starts it grabbing windows ASAP.
 	private static final WindowGrabber grabber = new WindowGrabber();
+    
+	private final CharacterTyper typer;
 	
 	private final String windowName;
 	private final ComponentFinder finder;
@@ -43,100 +39,60 @@
 		this.finder = finder;
 		sysQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
 		idler = new Idler();
+        typer = new CharacterTyper();
 	}
 
 	public void closeWindow() throws TimeoutException {
-		getWindow().dispose();
+		getOpenWindow().dispose();
 		idler.waitForIdle();
 	}
 	
 	public void clickButton(String componentName) throws ComponentFinderException, TimeoutException {
 		AbstractButton button = (AbstractButton) finder.findExactComponent(
-				getWindow(), new NamedComponentFilter(componentName));
+				getOpenWindow(), new NamedComponentFilter(componentName));
         button.doClick(200);
-//		sysQueue.postEvent(createMouseEvent(button, MouseEvent.MOUSE_PRESSED));
-//		sysQueue.postEvent(createMouseEvent(button, MouseEvent.MOUSE_RELEASED));
-//		sysQueue.postEvent(createMouseEvent(button, MouseEvent.MOUSE_CLICKED));
 		idler.waitForIdle();
 	}
 
 	public void enterText(String componentName, String text) throws ComponentFinderException, TimeoutException {
 		Component component = findComponent(componentName);
-		
 		component.requestFocus();
-		if (component instanceof TextComponent) {
-			typeIntoTextComponent((TextComponent)component, text);
-		} else if (component instanceof JTextComponent) {
-			typeIntoJTextComponent((JTextComponent)component, text);
-		}		
+		typer.typeIntoComponent(component, text);
 	}
 		
 
-	public void typeIntoTextComponent(TextComponent textComponent, String text) {
-		for (int i = 0; i < text.length(); i++) {
-			sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_PRESSED));
-			sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_RELEASED));
-			sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_TYPED));
-		}
-		idler.waitForIdle();
+	public void typeIntoTextComponent(TextComponent component, String text) {
+		typer.typeIntoComponent(component, text);
 	}
     
-    public void typeIntoJTextComponent(JTextComponent textComponent, String text) {
-    	VerifyingKeyAdapter verifier = new VerifyingKeyAdapter();
-    	
-		textComponent.addKeyListener(verifier);
-    	
-		try {
-	        for (int i = 0; i < text.length(); i++) {
-	            sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_PRESSED));
-	            sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_RELEASED));
-	            sysQueue.postEvent(createKeyPressEvent(textComponent, text.charAt(i), KeyEvent.KEY_TYPED));
-	            if (!verifier.events.contains(new KeycodeEventsReceived(text.charAt(i), KeyEvent.KEY_TYPED))) {
-	            	throw new PendingException("Text typing not supported for your Swing library.");
-	            }
-	        }
-		} finally {
-			textComponent.removeKeyListener(verifier);
-		}
-        
-        idler.waitForIdle();
+    public void typeIntoJTextComponent(JTextComponent component, String text) {
+    	typer.typeIntoComponent(component, text);
     }   
 	
     /**
-     * Use this for any key which doesn't have a corresponding character.
+     * Use this for any key which doesn't have a corresponding character (eg: directional keys).
+     * If the key has a character, listeners will not always detect this mimicry.
      */
 	public void pressKeycode(int keycode) throws TimeoutException {
-	    sysQueue.postEvent(createKeyPressEvent(getWindow(), keycode, KeyEvent.KEY_PRESSED));
-	    sysQueue.postEvent(createKeyPressEvent(getWindow(), keycode, KeyEvent.KEY_RELEASED));
+	    sysQueue.postEvent(createKeyPressEvent(getOpenWindow(), keycode, KeyEvent.KEY_PRESSED));
+	    sysQueue.postEvent(createKeyPressEvent(getOpenWindow(), keycode, KeyEvent.KEY_RELEASED));
             
 		idler.waitForIdle();
 	}
-    
+
+    /**
+     * Use this for any key which has a valid character associated with it, when it is being pressed
+     * (eg: as a game control key) rather than being typed into a text component.
+     */
     public void pressKeychar(char key) throws TimeoutException {
-    	VerifyingKeyAdapter verifier = new VerifyingKeyAdapter();
-    	
-		getWindow().addKeyListener(verifier);
-    	
-		try {
-	        sysQueue.postEvent(createKeyPressEvent(getWindow(), key, KeyEvent.KEY_PRESSED));
-	        sysQueue.postEvent(createKeyPressEvent(getWindow(), key, KeyEvent.KEY_RELEASED));
-	        sysQueue.postEvent(createKeyPressEvent(getWindow(), key, KeyEvent.KEY_TYPED));
-	        if (!verifier.events.contains(new KeycodeEventsReceived(key, KeyEvent.KEY_TYPED))) {
-	        	throw new PendingException("Text typing not supported for your Swing library.");
-	        }
-		} finally {
-			getWindow().removeKeyListener(verifier);
-		}
-		
-		idler.waitForIdle();
-		
+        typer.pressKeychar(getOpenWindow(), key);
     }
     
 	public Component findComponent(String componentName) throws ComponentFinderException, TimeoutException {
-		return finder.findExactComponent(getWindow(), new NamedComponentFilter(componentName));
+		return finder.findExactComponent(getOpenWindow(), new NamedComponentFilter(componentName));
 	}
 	
-	private Window getWindow() throws TimeoutException {
+	public Window getOpenWindow() throws TimeoutException {
 		if (window == null) {
 			idler.waitForIdle();
 			window = grabber.getWindow(windowName);
@@ -144,15 +100,7 @@
 		return window;
 	}
 	
-	private AWTEvent createKeyPressEvent(Component component, char c, int id) {
-		return new KeyEvent(component, 
-				id, 
-				System.currentTimeMillis(),
-				0,
-				KeyEvent.VK_UNDEFINED,
-				c);
-	}
-    
+
     private AWTEvent createKeyPressEvent(Component component, int keycode, int id) {
         return new KeyEvent(component, 
                 id, 
@@ -163,25 +111,9 @@
     }
 
     public void requestWindowFocus() throws TimeoutException {
-        getWindow().requestFocus();
+        getOpenWindow().requestFocus();
         idler.waitForIdle();
     }
     
-    private class VerifyingKeyAdapter extends KeyAdapter {
-    	private ArrayList events = new ArrayList();
-    	
-		public void keyTyped(KeyEvent e) {
-			events.add(new KeycodeEventsReceived(e.getKeyChar(), KeyEvent.KEY_TYPED));
-		}
-    }
-    
-    private class KeycodeEventsReceived {
-    	private char keyChar;
-    	private int event;
-    	
-    	private KeycodeEventsReceived(char keyChar, int event) {
-			this.keyChar = keyChar;
-			this.event = event;
-		}
-    }
+
 }


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to