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