1 /*
2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
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
21  * questions.
22  */
23 
24 /*
25   @test
26   @bug 6252005 8242174
27   @key headful
28   @summary Tests that realSync feature works
29   @author denis.mikhalkin: area=awt.toolkit
30   @modules java.desktop/sun.awt
31   @run main/timeout=6000 Test
32 */
33 
34 import java.awt.Frame;
35 import java.awt.Point;
36 import java.awt.Robot;
37 import java.awt.*;
38 import java.awt.event.*;
39 import java.lang.reflect.Method;
40 import java.lang.reflect.Modifier;
41 import java.util.Collections;
42 import java.util.LinkedList;
43 
44 import javax.swing.*;
45 
46 /**
47  * Tests various problematic areas and how they are fixed using real-sync API:
48  * - requesting focus
49  * - showing and robot mouse pressing
50  * - showing and getting location on screen
51  * - showing and typing
52  */
53 
54 public class Test {
55     private static boolean doRealSync = true;
56     private static boolean someFailed = false;
57     private static Robot robot;
main(String[] args)58     public static void main(String[] args) {
59         installListeners();
60 
61         try {
62             robot = new Robot();
63         } catch (Exception e) {
64             e.printStackTrace();
65             return;
66         }
67 
68 
69         int count = 100;
70         String method = null;
71         if (args.length != 0) {
72             try {
73                 count = Integer.parseInt(args[0]);
74             } catch (NumberFormatException nfe) {
75                 method = args[0];
76                 count = 1;
77             }
78         }
79         while (count > 0 && !someFailed) {
80             run(method);
81             gc();
82             count--;
83         }
84 
85         System.err.println("Total results: " + (someFailed? ("some tests failed (" + count + ")"): "ALL TESTS PASSED!!!"));
86     }
87 
gc()88     private static void gc() {
89         System.gc();
90         sleep(50);
91         System.gc();
92         Thread.yield();
93         System.gc();
94     }
95 
sleep(int time)96     private static void sleep(int time) {
97         try {
98             Thread.sleep(time);
99         } catch (InterruptedException ie) {
100         }
101     }
102 
103     private static java.util.List<Object> events = Collections.synchronizedList(new LinkedList<Object>());
104 
105     private static class TestFailureException extends RuntimeException {
106     }
107 
run(String method)108     public static void run(String method) {
109         Class cl = Test.class;
110         for (Method m : cl.getMethods()) {
111             if (Modifier.isStatic(m.getModifiers()) && m.getName().startsWith("test") && method == null ||
112                 (method != null && method.equals(m.getName()))) {
113                 realSync(null);
114                 events.clear();
115                 try {
116                     m.invoke(null);
117                 } catch (TestFailureException e) {
118                     // Do nothing
119                 } catch (Exception e) {
120                     fail(e);
121                 }
122                 reportErrors(m);
123             }
124         }
125     }
126 
127     private static java.util.List<Object> errors = Collections.synchronizedList(new LinkedList<Object>());
reportErrors(Method m)128     public static void reportErrors(Method m) {
129         realSync(null);
130         if (errors.size() == 0) {
131 //             System.err.println("Test passed: " + m.getName());
132 //             System.err.println("------------------------------------------------------\nEvents for " + m.getName());
133 //             for (Object e : events) {
134 //                 System.err.println(e);
135 //             }
136             return;
137         }
138 
139         someFailed = true;
140         System.err.println("Test failed: " + m.getName());
141         for (Object error : errors) {
142             if (error instanceof Throwable) {
143                 ((Throwable)error).printStackTrace();
144             } else {
145                 System.err.println("Cause: " + error);
146             }
147         }
148         System.err.println("Events:");
149         synchronized(events) {
150             for (Object e : events) {
151                 System.err.println(e);
152             }
153         }
154         errors.clear();
155         throw new Error();
156     }
157 
asser(boolean value)158     public static void asser(boolean value) {
159         if (!value) {
160             fail("Test failed");
161         }
162     }
asser(boolean value, String msg)163     public static void asser(boolean value, String msg) {
164         if (!value) {
165             fail(msg);
166         }
167     }
168     static int screenNum = 0;
fail(Object cause)169     public static void fail(Object cause) {
170         synchronized (events) {
171             events.add("FAILURE MOMENT");
172         }
173         errors.add(cause);
174         errors.add("- Focus owner: " + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());
175         errors.add("- Focused window: " + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow());
176 //         try {
177 //             Robot r = new Robot();
178 //             BufferedImage image = r.createScreenCapture(new Rectangle(0, 0, 1024, 768));
179 //             ImageIO.write(image, "GIF", new File("/tmp/screen" + screenNum + ".gif"));
180 //             screenNum++;
181 //             image.flush();
182 //         } catch (Exception e) {
183 //         }
184     }
185 
_test1()186     public static void _test1() {
187         Frame f = new Frame();
188         f.setLocation(100, 100);
189 
190         f.setVisible(true);
191 
192         Point loc = new Point(100, 100);
193         robot.mouseMove(loc.x+30, loc.y+40);
194 
195         robot.mousePress(InputEvent.BUTTON1_MASK);
196         robot.mouseRelease(InputEvent.BUTTON1_MASK);
197 
198         try {
199             Thread.sleep(3000);
200         } catch (InterruptedException ie) {
201         }
202     }
203 
testType()204     public static void testType() {
205         Frame f = new Frame("testType");
206         f.setLayout(new BorderLayout());
207         TextField b = new TextField();
208         f.add(b, BorderLayout.CENTER);
209         f.setBounds(100, 100, 200, 200);
210 
211         f.setVisible(true);
212         realSync(f);
213 
214         f.toFront();
215         realSync(f);
216         b.requestFocus();
217         realSync(f);
218         asser(b.isFocusOwner(), "Couldn't focus text field");
219 
220         robot.keyPress(KeyEvent.VK_A);
221         robot.keyRelease(KeyEvent.VK_A);
222         realSync(f);
223         asser("a".equals(b.getText()), "Expected 'a' got " + "'" +
224             b.getText() + "'.");
225         f.dispose();
226     }
227 
testTypeSwing()228     public static void testTypeSwing() {
229         JFrame f = new JFrame("testTypeSwing");
230         f.setLayout(new BorderLayout());
231         JTextField b = new JTextField();
232         f.add(b, BorderLayout.CENTER);
233         f.setBounds(100, 100, 200, 200);
234 
235         f.setVisible(true);
236         realSync(f);
237 
238         f.toFront();
239         realSync(f);
240         b.requestFocus();
241         realSync(f);
242         asser(b.isFocusOwner(), "Couldn't focus text field");
243 
244         robot.keyPress(KeyEvent.VK_A);
245         robot.keyRelease(KeyEvent.VK_A);
246         realSync(f);
247         asser("a".equals(b.getText()), "Expected 'a' got " + "'" +
248             b.getText() + "'.");
249         f.dispose();
250     }
251 
252     private static boolean pressed;
testPress()253     public static void testPress() {
254         Frame f = new Frame("testPress");
255         f.setLayout(new FlowLayout());
256         Button b = new Button("b");
257         b.addActionListener(new ActionListener() {
258                 public void actionPerformed(ActionEvent e) {
259                     pressed = true;
260                 }
261             });
262         f.add(b);
263         f.setBounds(100, 100, 200, 200);
264 
265         f.setVisible(true);
266         realSync(f);
267 
268         Point loc = b.getLocationOnScreen();
269         events.add("Pressing at " + loc);
270         robot.mouseMove(loc.x+3, loc.y+3);
271         pressed = false;
272         robot.mousePress(InputEvent.BUTTON1_MASK);
273         robot.mouseRelease(InputEvent.BUTTON1_MASK);
274         realSync(f);
275         asser(pressed, "Not pressed");
276         f.dispose();
277     }
278 
testPressSwing()279     public static void testPressSwing() {
280         JFrame f = new JFrame("testPressSwing");
281         f.setLayout(new FlowLayout());
282         JButton b = new JButton("b");
283         b.addActionListener(new ActionListener() {
284                 public void actionPerformed(ActionEvent e) {
285                     pressed = true;
286                 }
287             });
288         f.add(b);
289         f.setBounds(100, 100, 200, 200);
290 
291         f.setVisible(true);
292         realSync(f);
293 
294         Point loc = b.getLocationOnScreen();
295         events.add("Pressing at " + loc);
296         robot.mouseMove(loc.x+3, loc.y+3);
297         pressed = false;
298         robot.mousePress(InputEvent.BUTTON1_MASK);
299         robot.mouseRelease(InputEvent.BUTTON1_MASK);
300         realSync(f);
301         asser(pressed, "Not pressed");
302         f.dispose();
303     }
304 
testFocus0()305     public static void testFocus0() {
306         Frame f = new Frame("testFocus0");
307         f.setLayout(new FlowLayout());
308         Button b1 = new Button("b1");
309         Button b2 = new Button("b2");
310         f.add(b1);
311         f.add(b2);
312         f.setBounds(100, 100, 200, 200);
313         f.setVisible(true);
314         realSync(f);
315         f.toFront();
316         realSync(f);
317         asser(b1.isFocusOwner(), "B1 didn't get focus");
318         b2.requestFocus();
319         realSync(f);
320         asser(b2.isFocusOwner(), "Couldn't focus b2");
321         f.dispose();
322     }
323 
testFocus1()324     public static void testFocus1() {
325         Frame f = new Frame("testFocus1");
326         f.setLayout(new FlowLayout());
327         Button b1 = new Button("b1");
328         f.add(b1);
329         f.setBounds(100, 100, 200, 200);
330         f.setVisible(true);
331         realSync(f);
332         f.toFront();
333         realSync(f);
334         asser(b1.isFocusOwner(), "B1 didn't get focus");
335         f.dispose();
336     }
337 
testFocus2()338     public static void testFocus2() {
339         Frame f = new Frame("testFocus2");
340         f.setLayout(new FlowLayout());
341         Button b1 = new Button("b1");
342         Button b2 = new Button("b2");
343         f.add(b1);
344         f.add(b2);
345         f.setBounds(100, 100, 200, 200);
346         f.setVisible(true);
347         realSync(f);
348         f.toFront();
349         realSync(f);
350         b2.requestFocus();
351         realSync(f);
352         if (!b2.isFocusOwner()) {
353             fail("1: " + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());
354         } else {
355             // Half passed
356             b1.requestFocus();
357             realSync(f);
358             asser(b1.isFocusOwner(), "B1 couldn't get focus");
359         }
360         f.dispose();
361     }
362 
testFocus2Swing()363     public static void testFocus2Swing() {
364         JFrame f = new JFrame("testFocus2Swing");
365         f.setLayout(new FlowLayout());
366         JButton b1 = new JButton("b1");
367         JButton b2 = new JButton("b2");
368         f.add(b1);
369         f.add(b2);
370         f.setBounds(100, 100, 200, 200);
371         f.setVisible(true);
372         realSync(f);
373         f.toFront();
374         realSync(f);
375         b2.requestFocus();
376         realSync(f);
377         if (!b2.isFocusOwner()) {
378             fail("1: " + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());
379         } else {
380             // Half passed
381             b1.requestFocus();
382             realSync(f);
383             asser(b1.isFocusOwner(), "B1 couldn't get focus");
384         }
385         f.dispose();
386     }
387 
realSync(Window w)388     public static void realSync(Window w) {
389         if (doRealSync) {
390             ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync();
391         }
392     }
393 
installListeners()394     public static void installListeners() {
395         Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
396                 public void eventDispatched(AWTEvent e) {
397                     synchronized(events) {
398                         events.add(e);
399                     }
400                 }
401             }, 0xffff & ~AWTEvent.HIERARCHY_EVENT_MASK);
402 //         ((XToolkit)Toolkit.getDefaultToolkit()).addXEventListener(new XToolkit.XEventListener() {
403 //                 public void eventProcessed(IXAnyEvent e) {
404 //                     synchronized(events) {
405 //                         events.add(e);
406 //                     }
407 //                 }
408 //             });
409     }
410 }
411