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