1 /*
   2  * Copyright (c) 2011, 2014, 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 /* @test
  25    @bug 7088744
  26    @summary SwingUtilities.isMiddleMouseButton does not work with ALT/Meta keys
  27    @author Pavel Porvatov
  28 */
  29 
  30 import java.awt.Component;
  31 import java.awt.Event;
  32 import java.awt.Point;
  33 import java.awt.Robot;
  34 import java.awt.event.InputEvent;
  35 import java.awt.event.MouseAdapter;
  36 import java.awt.event.MouseEvent;
  37 
  38 import javax.swing.JFrame;
  39 import javax.swing.JLabel;
  40 import javax.swing.SwingUtilities;
  41 
  42 public class bug7088744 {
  43 
  44     private static volatile JLabel label;
  45     private static volatile JFrame frame;
  46 
  47     private static volatile Point point = new Point();
  48 
  49     private static final int MOUSE_CLICKED = 1;
  50     private static final int MOUSE_PRESSED = 2;
  51     private static final int MOUSE_RELEASED = 3;
  52 
  53     // Pair with (EventType, Mouse Button)
  54     private static final int[][] BUTTON_EVENTS_SEQUENCE = {
  55             {MOUSE_PRESSED, 1},
  56             {MOUSE_PRESSED, 2},
  57             {MOUSE_PRESSED, 3},
  58             {MOUSE_RELEASED, 1},
  59             {MOUSE_CLICKED, 1},
  60             {MOUSE_RELEASED, 2},
  61             {MOUSE_CLICKED, 2},
  62             {MOUSE_RELEASED, 3},
  63             {MOUSE_CLICKED, 3}
  64     };
  65 
  66     private static int eventCount;
  67 
  68     public static void main(String[] args) throws Exception {
  69         SwingUtilities.invokeAndWait(new Runnable() {
  70             public void run() {
  71                 Component source = new JLabel();
  72 
  73                 MouseEvent mouseEventNoButtons = new MouseEvent(source, 0, System.currentTimeMillis(),
  74                         Event.ALT_MASK | Event.META_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK,
  75                         0, 0, 0, false, MouseEvent.NOBUTTON);
  76 
  77                 // isLeftMouseButton
  78                 if (SwingUtilities.isLeftMouseButton(mouseEventNoButtons)) {
  79                     throw new RuntimeException("SwingUtilities.isLeftMouseButton fails 1");
  80                 }
  81 
  82                 if (!SwingUtilities.isLeftMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
  83                         InputEvent.BUTTON1_MASK, 0, 0, 1, false, MouseEvent.BUTTON1))) {
  84                     throw new RuntimeException("SwingUtilities.isLeftMouseButton fails 2");
  85                 }
  86 
  87                 if (!SwingUtilities.isLeftMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
  88                         InputEvent.BUTTON1_DOWN_MASK, 0, 0, 1, false, MouseEvent.BUTTON1))) {
  89                     throw new RuntimeException("SwingUtilities.isLeftMouseButton fails 3");
  90                 }
  91 
  92                 // isMiddleMouseButton
  93                 if (SwingUtilities.isMiddleMouseButton(mouseEventNoButtons)) {
  94                     throw new RuntimeException("SwingUtilities.isMiddleMouseButton fails 1");
  95                 }
  96 
  97                 if (!SwingUtilities.isMiddleMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
  98                         InputEvent.BUTTON2_MASK, 0, 0, 1, false, MouseEvent.BUTTON2))) {
  99                     throw new RuntimeException("SwingUtilities.isMiddleMouseButton fails 2");
 100                 }
 101 
 102                 if (!SwingUtilities.isMiddleMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
 103                         InputEvent.BUTTON2_DOWN_MASK, 0, 0, 1, false, MouseEvent.BUTTON2))) {
 104                     throw new RuntimeException("SwingUtilities.isMiddleMouseButton fails 3");
 105                 }
 106 
 107                 // isRightMouseButton
 108                 if (SwingUtilities.isRightMouseButton(mouseEventNoButtons)) {
 109                     throw new RuntimeException("SwingUtilities.isRightMouseButton fails 1");
 110                 }
 111 
 112                 if (!SwingUtilities.isRightMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
 113                         InputEvent.BUTTON3_MASK, 0, 0, 1, false, MouseEvent.BUTTON3))) {
 114                     throw new RuntimeException("SwingUtilities.isRightMouseButton fails 2");
 115                 }
 116 
 117                 if (!SwingUtilities.isRightMouseButton(new MouseEvent(source, 0, System.currentTimeMillis(),
 118                         InputEvent.BUTTON3_DOWN_MASK, 0, 0, 1, false, MouseEvent.BUTTON3))) {
 119                     throw new RuntimeException("SwingUtilities.isRightMouseButton fails 3");
 120                 }
 121             }
 122         });
 123 
 124         SwingUtilities.invokeAndWait(new Runnable() {
 125             public void run() {
 126                 frame = new JFrame();
 127 
 128                 label = new JLabel("A label");
 129 
 130                 label.addMouseListener(new MouseAdapter() {
 131                     public void mouseClicked(MouseEvent e) {
 132                         processEvent(MOUSE_CLICKED, e);
 133                     }
 134 
 135                     public void mousePressed(MouseEvent e) {
 136                         processEvent(MOUSE_PRESSED, e);
 137                     }
 138 
 139                     public void mouseReleased(MouseEvent e) {
 140                         processEvent(MOUSE_RELEASED, e);
 141                     }
 142                 });
 143                 frame.add(label);
 144                 frame.setSize(200, 100);
 145                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 146                 frame.setLocationRelativeTo(null);
 147                 frame.setVisible(true);
 148             }
 149         });
 150 
 151         Robot robot = new Robot();
 152         robot.waitForIdle();
 153 
 154         SwingUtilities.invokeAndWait(new Runnable() {
 155             public void run() {
 156                 Point pt = label.getLocationOnScreen();
 157                 point.x = pt.x + label.getWidth() / 2;
 158                 point.y = pt.y + label.getHeight() / 2;
 159             }
 160         });
 161 
 162         robot.setAutoDelay(100);
 163         robot.setAutoWaitForIdle(true);
 164         robot.mouseMove(point.x, point.y);
 165         robot.mousePress(InputEvent.BUTTON1_MASK);
 166         robot.mousePress(InputEvent.BUTTON2_MASK);
 167         robot.mousePress(InputEvent.BUTTON3_MASK);
 168         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 169         robot.mouseRelease(InputEvent.BUTTON2_MASK);
 170         robot.mouseRelease(InputEvent.BUTTON3_MASK);
 171 
 172         SwingUtilities.invokeAndWait(new Runnable() {
 173             public void run() {
 174                 frame.dispose();
 175                 if (eventCount != BUTTON_EVENTS_SEQUENCE.length) {
 176                     throw new RuntimeException("Not all events received");
 177                 }
 178 
 179             }
 180         });
 181 
 182         System.out.println("Test passed");
 183     }
 184 
 185     private static void processEvent(int eventType, MouseEvent e) {
 186         if (eventCount >= BUTTON_EVENTS_SEQUENCE.length) {
 187             throw new RuntimeException("Unexpected event " + e);
 188         }
 189 
 190         int[] arr = BUTTON_EVENTS_SEQUENCE[eventCount];
 191 
 192         if (arr[0] != eventType) {
 193             throw new RuntimeException("Unexpected eventType " + eventType + "on step " + eventCount);
 194         }
 195 
 196         boolean result;
 197 
 198         switch (arr[1]) {
 199             case 1:
 200                 result = SwingUtilities.isLeftMouseButton(e);
 201 
 202                 break;
 203 
 204             case 2:
 205                 result = SwingUtilities.isMiddleMouseButton(e);
 206 
 207                 break;
 208 
 209             case 3:
 210                 result = SwingUtilities.isRightMouseButton(e);
 211 
 212                 break;
 213 
 214             default:
 215                 throw new RuntimeException("Incorrect arr[1] on step " + eventCount);
 216         }
 217 
 218         if (!result) {
 219             throw new RuntimeException("Test failed on step " + eventCount);
 220         }
 221 
 222         eventCount++;
 223     }
 224 }