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