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