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