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