1 /*
   2  * Copyright (c) 2016 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  * @summary Test of mouse move messages to lightweight components
  27  * @library ../../regtesthelpers
  28  * @build Util
  29  * @compile LightweightEventTest.java
  30  * @run main LightweightEventTest
  31  */
  32 import java.awt.BorderLayout;
  33 import java.awt.Button;
  34 import java.awt.Color;
  35 import java.awt.Component;
  36 import java.awt.Container;
  37 import java.awt.Dimension;
  38 import java.awt.FontMetrics;
  39 import java.awt.Frame;
  40 import java.awt.Graphics;
  41 import java.awt.Insets;
  42 import java.awt.Point;
  43 import java.awt.Rectangle;
  44 import java.awt.Robot;
  45 import java.awt.AWTException;
  46 import java.awt.event.MouseAdapter;
  47 import java.awt.event.MouseEvent;
  48 import javax.swing.SwingUtilities;
  49 import test.java.awt.regtesthelpers.Util;
  50 
  51 
  52 /*
  53 There are 3 steps to this test :
  54 1. Two frames are created one with heavy weight component and
  55    another with light weight component. Each frame has a centrally placed
  56    button
  57 2. Mouse is dragged along diagonals of each window using Robot object
  58 3. Events are noted for mouse in and out of frames & buttons and asserted
  59 */
  60 
  61 public class LightweightEventTest {
  62 
  63     private static EventBug HeavyComponent;
  64     private static EventBug LightComponent;
  65     private static Robot testRobot;
  66 
  67     public static void main(String[] args) throws Throwable {
  68 
  69         SwingUtilities.invokeAndWait(new Runnable() {
  70             @Override
  71             public void run() {
  72                 constructTestUI();
  73             }
  74         });
  75 
  76         try {
  77             testRobot = new Robot();
  78         } catch (AWTException ex) {
  79             throw new RuntimeException("Could not initiate a drag operation");
  80         }
  81 
  82         testRobot.waitForIdle();
  83 
  84         // Method performing auto test operation
  85         boolean result = test();
  86 
  87         disposeTestUI();
  88 
  89         if (result == false) {
  90             throw new RuntimeException("Test FAILED!");
  91         }
  92     }
  93 
  94     private static boolean test() {
  95         // Test events for HeavyComponent
  96         Point loc = HeavyComponent.getLocationOnScreen();
  97         Dimension size = HeavyComponent.getSize();
  98 
  99         Util.mouseMove(testRobot,
 100                 new Point((int) loc.x + 4, (int) loc.y + 4),
 101                 new Point((int) loc.x + size.width, (int) loc.y + size.height));
 102 
 103         testRobot.waitForIdle();
 104 
 105         boolean HeavyComponentAssert = HeavyComponent.assertEvents(2, 1);
 106 
 107         // Test events for LightComponent
 108         loc = LightComponent.getLocationOnScreen();
 109         size = LightComponent.getSize();
 110 
 111         Util.mouseMove(testRobot,
 112                 new Point((int) loc.x + 4, (int) loc.y + 4),
 113                 new Point((int) loc.x + size.width, (int) loc.y + size.height));
 114 
 115         testRobot.waitForIdle();
 116 
 117         boolean LightComponentAssert = LightComponent.assertEvents(2, 1);
 118 
 119         return (HeavyComponentAssert && LightComponentAssert);
 120     }
 121 
 122     private static void constructTestUI() {
 123         // here, create the items that will be tested for correct behavior
 124         HeavyComponent = new EventBug();
 125         Button b = (Button) HeavyComponent.add("Center", new Button("Heavy"));
 126 
 127         LightComponent = new EventBug();
 128         BorderedLabel b1 = (BorderedLabel) LightComponent.add("Center",
 129                 new BorderedLabel("Lite"));
 130 
 131         HeavyComponent.addListeners(b);
 132         LightComponent.addListeners(b1);
 133 
 134         LightComponent.setLocation(200, 0);
 135         HeavyComponent.setVisible(true);
 136         LightComponent.setVisible(true);
 137     }
 138 
 139     private static void disposeTestUI() {
 140         HeavyComponent.setVisible(false);
 141         LightComponent.setVisible(false);
 142 
 143         HeavyComponent.dispose();
 144         LightComponent.dispose();
 145     }
 146 }
 147 
 148 /*
 149  * Lightweight component
 150  */
 151 class BorderedLabel extends Component {
 152 
 153     boolean superIsButton = false;
 154     String labelString;
 155 
 156     BorderedLabel(String labelString) {
 157         this.labelString = labelString;
 158 
 159         Component thisComponent = this;
 160         superIsButton = (thisComponent instanceof Button);
 161         if (superIsButton) {
 162             ((Button) thisComponent).setLabel(labelString);
 163         }
 164     }
 165 
 166     @Override
 167     public Dimension getMinimumSize() {
 168         Dimension minSize = new Dimension();
 169 
 170         if (superIsButton) {
 171             minSize = super.getMinimumSize();
 172         } else {
 173 
 174             Graphics g = getGraphics();
 175             FontMetrics metrics = g.getFontMetrics();
 176 
 177             minSize.width = metrics.stringWidth(labelString) + 14;
 178             minSize.height = metrics.getMaxAscent()
 179                     + metrics.getMaxDescent() + 9;
 180 
 181             g.dispose();
 182             g = null;
 183         }
 184         return minSize;
 185     }
 186 
 187     @Override
 188     public Dimension getPreferredSize() {
 189         Dimension prefSize;
 190         if (superIsButton) {
 191             prefSize = super.getPreferredSize();
 192         } else {
 193             prefSize = getMinimumSize();
 194         }
 195         return prefSize;
 196     }
 197 
 198     @Override
 199     public void paint(Graphics g) {
 200 
 201         super.paint(g);
 202         Rectangle bounds = getBounds();
 203         if (superIsButton) {
 204             return;
 205         }
 206         Dimension size = getSize();
 207         Color oldColor = g.getColor();
 208 
 209         // draw border
 210         g.setColor(getBackground());
 211         g.fill3DRect(0, 0, size.width, size.height, false);
 212         g.fill3DRect(3, 3, size.width - 6, size.height - 6, true);
 213 
 214         // draw text
 215         FontMetrics metrics = g.getFontMetrics();
 216         int centerX = size.width / 2;
 217         int centerY = size.height / 2;
 218         int textX = centerX - (metrics.stringWidth(labelString) / 2);
 219         int textY = centerY
 220                 + ((metrics.getMaxAscent() + metrics.getMaxDescent()) / 2);
 221         g.setColor(getForeground());
 222         g.drawString(labelString, textX, textY);
 223 
 224         g.setColor(oldColor);
 225     }
 226 } // class BorderedLabel
 227 
 228 class EventBug extends Container {
 229 
 230     Frame testFrame;
 231     int frameEnters = 0;
 232     int frameExits = 0;
 233     int buttonEnters = 0;
 234     int buttonExits = 0;
 235 
 236     public EventBug() {
 237         super();
 238         testFrame = new Frame();
 239         testFrame.setLayout(new BorderLayout());
 240         this.setLayout(new BorderLayout());
 241         testFrame.add("Center", this);
 242         testFrame.pack();
 243         testFrame.setVisible(true);
 244     }
 245 
 246     @Override
 247     public Dimension getPreferredSize() {
 248         return new Dimension(100, 100);
 249     }
 250 
 251     @Override
 252     public Insets getInsets() {
 253         return new Insets(20, 20, 20, 20);
 254     }
 255 
 256     public boolean assertEvents(int expectedFrameEnterEvents,
 257             int expectedButtonEnterEvents) {
 258         return (frameEnters == expectedFrameEnterEvents)
 259                 && (buttonEnters == expectedButtonEnterEvents);
 260     }
 261 
 262     // Forward to the Window
 263     @Override
 264     public void setLocation(int x, int y) {
 265         testFrame.setLocation(x, y);
 266     }
 267 
 268     @Override
 269     public void setVisible(boolean b) {
 270         testFrame.setVisible(b);
 271     }
 272 
 273     public void dispose() {
 274         testFrame.dispose();
 275     }
 276 
 277     // Add listeners to Frame and button
 278     public void addListeners(Component b) {
 279         b.setName("Button");
 280         b.addMouseListener(new MouseAdapter() {
 281             @Override
 282             public void mouseEntered(MouseEvent e) {
 283                 buttonEnters++;
 284             }
 285 
 286             @Override
 287             public void mouseExited(MouseEvent e) {
 288                 buttonExits++;
 289             }
 290 
 291         });
 292         testFrame.addMouseListener(new MouseAdapter() {
 293             @Override
 294             public void mouseEntered(MouseEvent e) {
 295                 frameEnters++;
 296             }
 297 
 298             @Override
 299             public void mouseExited(MouseEvent e) {
 300                 frameExits++;
 301             }
 302         });
 303     }
 304 } // class EventBug