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