19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 import java.awt.AWTException; |
25 test |
25 import java.awt.FlowLayout; |
26 @bug 5028014 |
26 import java.awt.KeyboardFocusManager; |
27 @summary Focus request & mouse click performed nearly synchronously shouldn't lead to a focus race. |
27 import java.awt.Point; |
28 @author anton.tarasov@sun.com: area=awt-focus |
28 import java.awt.Robot; |
29 @run applet MouseClickRequestFocusRaceTest.html |
29 import java.awt.event.InputEvent; |
30 */ |
30 import java.awt.event.KeyEvent; |
|
31 import java.awt.event.MouseAdapter; |
|
32 import java.awt.event.MouseEvent; |
31 |
33 |
32 import java.awt.*; |
34 import javax.swing.JButton; |
33 import javax.swing.*; |
35 import javax.swing.JComponent; |
34 import java.awt.event.*; |
36 import javax.swing.JFrame; |
35 import java.applet.Applet; |
37 import javax.swing.JMenuItem; |
|
38 import javax.swing.JPopupMenu; |
|
39 import javax.swing.WindowConstants; |
36 |
40 |
37 public class MouseClickRequestFocusRaceTest extends Applet { |
41 import jdk.testlibrary.OSInfo; |
38 Robot robot; |
42 |
39 JFrame frame1 = new JFrame("Frame-1") { |
43 /** |
|
44 * @test |
|
45 * @bug 5028014 |
|
46 * @summary Focus request & mouse click being performed nearly synchronously |
|
47 * shouldn't break the focus subsystem |
|
48 * @author anton.tarasov@sun.com: area=awt-focus |
|
49 * @library ../../../../lib/testlibrary |
|
50 * @build jdk.testlibrary.OSInfo |
|
51 * @run main MouseClickRequestFocusRaceTest |
|
52 */ |
|
53 public class MouseClickRequestFocusRaceTest { |
|
54 static Robot robot; |
|
55 static JFrame frame1 = new JFrame("Frame-1") { |
40 public String toString() { return "Frame-1";} |
56 public String toString() { return "Frame-1";} |
41 }; |
57 }; |
42 JFrame frame2 = new JFrame("Frame-2") { |
58 static JFrame frame2 = new JFrame("Frame-2") { |
43 public String toString() { return "Frame-2";} |
59 public String toString() { return "Frame-2";} |
44 }; |
60 }; |
45 JButton button1 = new JButton("button-1") { |
61 static JButton button1 = new JButton("button-1") { |
46 public String toString() { return "button-1";} |
62 public String toString() { return "button-1";} |
47 }; |
63 }; |
48 JButton button2 = new JButton("button-2") { |
64 static JButton button2 = new JButton("button-2") { |
49 public String toString() { return "button-2";} |
65 public String toString() { return "button-2";} |
50 }; |
66 }; |
51 JPopupMenu popup = new JPopupMenu(); |
67 static JPopupMenu popup = new JPopupMenu(); |
52 |
68 |
53 public static void main(String[] args) { |
69 public static void main(String[] args) { |
54 MouseClickRequestFocusRaceTest app = new MouseClickRequestFocusRaceTest(); |
|
55 app.init(); |
|
56 app.start(); |
|
57 } |
|
58 |
|
59 public void init() { |
|
60 try { |
70 try { |
61 robot = new Robot(); |
71 robot = new Robot(); |
|
72 robot.setAutoWaitForIdle(true); |
|
73 robot.setAutoDelay(100); |
62 } catch (AWTException e) { |
74 } catch (AWTException e) { |
63 throw new RuntimeException("Error: unable to create robot", e); |
75 throw new RuntimeException("Error: unable to create robot", e); |
64 } |
76 } |
65 // Create instructions for the user here, as well as set up |
|
66 // the environment -- set the layout manager, add buttons, |
|
67 // etc. |
|
68 this.setLayout (new BorderLayout ()); |
|
69 Sysout.createDialogWithInstructions(new String[] |
|
70 {"Automatic test. Simply wait until it is done." |
|
71 }); |
|
72 } |
|
73 |
|
74 public void start() { |
|
75 frame1.add(button1); |
77 frame1.add(button1); |
76 frame2.add(button2); |
78 frame2.add(button2); |
77 frame1.setBounds(0, 0, 200, 300); |
79 frame1.setBounds(0, 0, 200, 300); |
78 frame2.setBounds(300, 0, 200, 300); |
80 frame2.setBounds(300, 0, 200, 300); |
79 frame1.setLayout(new FlowLayout()); |
81 frame1.setLayout(new FlowLayout()); |
108 |
110 |
109 frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
111 frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
110 |
112 |
111 frame1.setVisible(true); |
113 frame1.setVisible(true); |
112 frame2.setVisible(true); |
114 frame2.setVisible(true); |
113 // ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); |
115 |
114 robot.delay(1000); |
116 robot.delay(1000); |
115 |
117 try { |
116 test(); |
118 test(); |
|
119 } finally { |
|
120 frame1.dispose(); |
|
121 frame2.dispose(); |
|
122 } |
117 } |
123 } |
118 |
124 |
119 public void test() { |
125 public static void test() { |
120 // Right click Frame-1 |
126 // Right click Frame-1 |
121 robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200); |
127 robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200); |
122 robot.mousePress(InputEvent.BUTTON3_MASK); |
128 robot.mousePress(InputEvent.BUTTON3_MASK); |
123 robot.delay(100); |
|
124 robot.mouseRelease(InputEvent.BUTTON3_MASK); |
129 robot.mouseRelease(InputEvent.BUTTON3_MASK); |
125 |
130 |
126 // ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); |
|
127 robot.delay(1000); |
131 robot.delay(1000); |
128 |
132 |
129 // Left click Frame-2 |
133 // Left click Frame-2 |
130 robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200); |
134 robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200); |
131 robot.mousePress(InputEvent.BUTTON1_MASK); |
135 robot.mousePress(InputEvent.BUTTON1_MASK); |
132 robot.delay(100); |
|
133 robot.mouseRelease(InputEvent.BUTTON1_MASK); |
136 robot.mouseRelease(InputEvent.BUTTON1_MASK); |
134 |
137 |
135 // ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); |
|
136 robot.delay(1000); |
138 robot.delay(1000); |
137 |
139 |
138 JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); |
140 JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); |
139 JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); |
141 JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); |
140 |
142 |
141 Sysout.println("focus owner: " + focusOwner); |
143 System.out.println("focus owner: " + focusOwner); |
142 Sysout.println("focused window: " + focusedWindow); |
144 System.out.println("focused window: " + focusedWindow); |
143 |
145 |
144 // Verify that the focused window is the ancestor of the focus owner |
146 // Verify that the focused window is the ancestor of the focus owner |
145 if (!focusedWindow.isAncestorOf(focusOwner)) { |
147 if (!focusedWindow.isAncestorOf(focusOwner)) { |
146 throw new TestFailedException("The focus owner is not in the focused window!"); |
148 throw new RuntimeException("The focus owner is not in the focused window!"); |
147 } |
149 } |
148 |
150 |
149 // Try to close native focused window |
151 if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) { |
150 robot.keyPress(KeyEvent.VK_ALT); |
152 // Try to close native focused window |
151 robot.keyPress(KeyEvent.VK_F4); |
153 robot.keyPress(KeyEvent.VK_ALT); |
152 robot.keyRelease(KeyEvent.VK_F4); |
154 robot.keyPress(KeyEvent.VK_F4); |
153 robot.keyRelease(KeyEvent.VK_ALT); |
155 robot.keyRelease(KeyEvent.VK_F4); |
154 |
156 robot.keyRelease(KeyEvent.VK_ALT); |
155 // ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); |
157 robot.delay(1000); |
156 robot.delay(1000); |
158 // Verify that the Java focused window really mapped the native focused window. |
157 |
159 if (focusedWindow.isVisible()) { |
158 // Verify that the Java focused window really mapped the native focused window. |
160 throw new RuntimeException("The focused window is different on Java and on the native level."); |
159 if (focusedWindow.isVisible()) { |
161 } |
160 throw new TestFailedException("The focused window is different on Java and on the native level."); |
162 } else { |
161 } |
163 // Try to move native focus to previous window |
162 } |
164 robot.keyPress(KeyEvent.VK_CONTROL); |
163 |
165 robot.keyPress(KeyEvent.VK_F4); |
164 class TestFailedException extends RuntimeException { |
166 robot.keyRelease(KeyEvent.VK_F4); |
165 public TestFailedException(String cause) { |
167 robot.keyRelease(KeyEvent.VK_CONTROL); |
166 super("Test failed."); |
168 robot.delay(1000); |
167 Sysout.println(cause); |
169 // Verify that the Java focused window really mapped the native focused window. |
|
170 if (focusedWindow.isFocused()) { |
|
171 throw new RuntimeException("The focused window is different on Java and on the native level."); |
|
172 } |
168 } |
173 } |
169 } |
174 } |
170 } |
175 } |
171 |
|
172 /**************************************************** |
|
173 Standard Test Machinery |
|
174 DO NOT modify anything below -- it's a standard |
|
175 chunk of code whose purpose is to make user |
|
176 interaction uniform, and thereby make it simpler |
|
177 to read and understand someone else's test. |
|
178 ****************************************************/ |
|
179 |
|
180 /** |
|
181 This is part of the standard test machinery. |
|
182 It creates a dialog (with the instructions), and is the interface |
|
183 for sending text messages to the user. |
|
184 To print the instructions, send an array of strings to Sysout.createDialog |
|
185 WithInstructions method. Put one line of instructions per array entry. |
|
186 To display a message for the tester to see, simply call Sysout.println |
|
187 with the string to be displayed. |
|
188 This mimics System.out.println but works within the test harness as well |
|
189 as standalone. |
|
190 */ |
|
191 |
|
192 class Sysout |
|
193 { |
|
194 static TestDialog dialog; |
|
195 |
|
196 public static void createDialogWithInstructions( String[] instructions ) |
|
197 { |
|
198 dialog = new TestDialog( new Frame(), "Instructions" ); |
|
199 dialog.printInstructions( instructions ); |
|
200 // dialog.setVisible(true); |
|
201 println( "Any messages for the tester will display here." ); |
|
202 } |
|
203 |
|
204 public static void createDialog( ) |
|
205 { |
|
206 dialog = new TestDialog( new Frame(), "Instructions" ); |
|
207 String[] defInstr = { "Instructions will appear here. ", "" } ; |
|
208 dialog.printInstructions( defInstr ); |
|
209 // dialog.setVisible(true); |
|
210 println( "Any messages for the tester will display here." ); |
|
211 } |
|
212 |
|
213 |
|
214 public static void printInstructions( String[] instructions ) |
|
215 { |
|
216 dialog.printInstructions( instructions ); |
|
217 } |
|
218 |
|
219 |
|
220 public static void println( String messageIn ) |
|
221 { |
|
222 dialog.displayMessage( messageIn ); |
|
223 } |
|
224 |
|
225 }// Sysout class |
|
226 |
|
227 /** |
|
228 This is part of the standard test machinery. It provides a place for the |
|
229 test instructions to be displayed, and a place for interactive messages |
|
230 to the user to be displayed. |
|
231 To have the test instructions displayed, see Sysout. |
|
232 To have a message to the user be displayed, see Sysout. |
|
233 Do not call anything in this dialog directly. |
|
234 */ |
|
235 class TestDialog extends Dialog |
|
236 { |
|
237 |
|
238 TextArea instructionsText; |
|
239 TextArea messageText; |
|
240 int maxStringLength = 80; |
|
241 |
|
242 //DO NOT call this directly, go through Sysout |
|
243 public TestDialog( Frame frame, String name ) |
|
244 { |
|
245 super( frame, name ); |
|
246 int scrollBoth = TextArea.SCROLLBARS_BOTH; |
|
247 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); |
|
248 add( "North", instructionsText ); |
|
249 |
|
250 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); |
|
251 add("Center", messageText); |
|
252 |
|
253 pack(); |
|
254 |
|
255 // setVisible(true); |
|
256 }// TestDialog() |
|
257 |
|
258 //DO NOT call this directly, go through Sysout |
|
259 public void printInstructions( String[] instructions ) |
|
260 { |
|
261 //Clear out any current instructions |
|
262 instructionsText.setText( "" ); |
|
263 |
|
264 //Go down array of instruction strings |
|
265 |
|
266 String printStr, remainingStr; |
|
267 for( int i=0; i < instructions.length; i++ ) |
|
268 { |
|
269 //chop up each into pieces maxSringLength long |
|
270 remainingStr = instructions[ i ]; |
|
271 while( remainingStr.length() > 0 ) |
|
272 { |
|
273 //if longer than max then chop off first max chars to print |
|
274 if( remainingStr.length() >= maxStringLength ) |
|
275 { |
|
276 //Try to chop on a word boundary |
|
277 int posOfSpace = remainingStr. |
|
278 lastIndexOf( ' ', maxStringLength - 1 ); |
|
279 |
|
280 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; |
|
281 |
|
282 printStr = remainingStr.substring( 0, posOfSpace + 1 ); |
|
283 remainingStr = remainingStr.substring( posOfSpace + 1 ); |
|
284 } |
|
285 //else just print |
|
286 else |
|
287 { |
|
288 printStr = remainingStr; |
|
289 remainingStr = ""; |
|
290 } |
|
291 |
|
292 instructionsText.append( printStr + "\n" ); |
|
293 |
|
294 }// while |
|
295 |
|
296 }// for |
|
297 |
|
298 }//printInstructions() |
|
299 |
|
300 //DO NOT call this directly, go through Sysout |
|
301 public void displayMessage( String messageIn ) |
|
302 { |
|
303 messageText.append( messageIn + "\n" ); |
|
304 System.out.println(messageIn); |
|
305 } |
|
306 |
|
307 }// TestDialog class |
|