Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8146275

Robot keyPress(KeyEvent.VK_SHIFT) does not work unless preceded by left click.

    Details

    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      linux_ubuntu

      Description

      FULL PRODUCT VERSION :
      $ java -version
      java version "1.7.0_79"
      OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
      OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      $ uname -a
      Linux <name> 3.13.0-65-generic #106-Ubuntu SMP Fri Oct 2 22:08:27 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      Getting Robot to execute a keyPress(KeyEvent.VK_SHIFT) fails unless Robot is used to press and release left mouse button first.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Run the code in MouseEventDemo.java (which requires BlankArea.java). This launches a window that will output any typing or mouses clicks that happen inside the yellow area.
      2. While MouseEventDemo.java is running, launch JavaRobotExample.java. Using Robot, this will move the mouse to MouseEventDemo's window (depending on monitor, it is possible that the integers passed to robot.mouseMove(172, 105) might have to be adjusted). Then using Robot is should press the shift key, click and release the left mouse button, and then release the shift key.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The expected output in the MouseEventDemo output window should be:

      Mouse entered detected on BlankArea.
      Key pressed ( ￿ 16 1) detected on javax.swing.JTextArea.
      Mouse pressed (# of clicks: 1 1 17 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.
      Key released ( ￿ 16 0) detected on javax.swing.JTextArea.
      Mouse pressed (# of clicks: 1 1 16 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.

      ACTUAL -
      The actual output in the MouseEventDemo output window is (note that the press(KeyEvent.VK_SHIFT) is not logged):

      Mouse entered detected on BlankArea.
      Mouse pressed (# of clicks: 1 1 17 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.
      Key released ( ￿ 16 0) detected on javax.swing.JTextArea.
      Mouse pressed (# of clicks: 1 1 16 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      JavaRobotExample.java:

      import java.awt.AWTException;
      import java.awt.Robot;
      import java.awt.event.InputEvent;
      import java.awt.event.KeyEvent;

      public class JavaRobotExample {
      Robot robot = new Robot();

      public static void main(String[] args) throws AWTException
      {
      new JavaRobotExample();
      }

      public JavaRobotExample() throws AWTException
      {
      robot.setAutoDelay(40);
      robot.setAutoWaitForIdle(true);

      robot.delay(4000);
      robot.mouseMove(172, 105);

      //leftClick();
      press(KeyEvent.VK_SHIFT);
      leftClick();
      release(KeyEvent.VK_SHIFT);
      robot.delay(500);
      leftClick();

      robot.delay(10000);
      System.exit(0);
      }

      private void leftClick()
      {
      robot.mousePress(InputEvent.BUTTON1_MASK);
      robot.delay(200);
      robot.mouseRelease(InputEvent.BUTTON1_MASK);
      robot.delay(200);
      }

      private void press(int i )
      {
      robot.delay(40);
      robot.keyPress(i);
      }

      private void release(int i )
      {
      robot.delay(40);
      robot.keyRelease(i);
      }

      private void type(int i)
      {
      robot.delay(40);
      robot.keyPress(i);
      robot.keyRelease(i);
      }

      private void type(String s)
      {
      byte[] bytes = s.getBytes();
      for (byte b : bytes)
      {
      int code = b;
      // keycode only handles [A-Z] (which is ASCII decimal [65-90])
      if (code > 96 && code < 123) code = code - 32;
      robot.delay(40);
      robot.keyPress(code);
      robot.keyRelease(code);
      }
      }

      }


      MouseEventDemo.java (a modified version of Oracle's file to include key presses):

      /*
       * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
       *
       * Redistribution and use in source and binary forms, with or without
       * modification, are permitted provided that the following conditions
       * are met:
       *
       * - Redistributions of source code must retain the above copyright
       * notice, this list of conditions and the following disclaimer.
       *
       * - Redistributions in binary form must reproduce the above copyright
       * notice, this list of conditions and the following disclaimer in the
       * documentation and/or other materials provided with the distribution.
       *
       * - Neither the name of Oracle or the names of its
       * contributors may be used to endorse or promote products derived
       * from this software without specific prior written permission.
       *
       * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       */
       
      /*
      * MouseEventDemo.java
      */
       
      import java.awt.GridLayout;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.event.MouseListener;
      import java.awt.event.MouseEvent;
      import java.awt.event.KeyListener;
      import java.awt.event.KeyEvent;

      import javax.swing.*;
       
      public class MouseEventDemo extends JPanel
      implements MouseListener, KeyListener
      {

      BlankArea blankArea;
      JTextArea textArea;
      static final String NEWLINE = System.getProperty("line.separator");

      public static void main(String[] args) {
      /* Use an appropriate Look and Feel */
      try {
      //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
      //UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
      UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
      } catch (UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      } catch (IllegalAccessException ex) {
      ex.printStackTrace();
      } catch (InstantiationException ex) {
      ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
      ex.printStackTrace();
      }
      /* Turn off metal's use of bold fonts */
      UIManager.put("swing.boldMetal", Boolean.FALSE);
      //Schedule a job for the event dispatch thread:
      //creating and showing this application's GUI.
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
      createAndShowGUI();
      }
      });
      }

      /**
      * Create the GUI and show it. For thread safety,
      * this method should be invoked from the
      * event dispatch thread.
      * @throws AWTException
      */
      private static void createAndShowGUI() {
      //Create and set up the window.
      JFrame frame = new JFrame("MouseEventDemo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      //Create and set up the content pane.
      JComponent newContentPane = new MouseEventDemo();
      newContentPane.setOpaque(true); //content panes must be opaque
      frame.setContentPane(newContentPane);

      //Display the window.
      frame.pack();
      frame.setVisible(true);
      }

      public MouseEventDemo() {
      super(new GridLayout(0,1));
      blankArea = new BlankArea(Color.YELLOW);
      add(blankArea);
      textArea = new JTextArea();
      textArea.setEditable(false);
      JScrollPane scrollPane = new JScrollPane(textArea);
      scrollPane.setVerticalScrollBarPolicy(
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
      scrollPane.setPreferredSize(new Dimension(200, 75));
      add(scrollPane);

      //Register for mouse events on blankArea and the panel.
      blankArea.addMouseListener(this);
      textArea.addKeyListener(this);
      addMouseListener(this);
      addKeyListener(this);
      setPreferredSize(new Dimension(450, 450));
      setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
      }

      void eventOutput(String eventDescription, MouseEvent e) {
      textArea.append(eventDescription + " detected on "
      + e.getComponent().getClass().getName()
      + "." + NEWLINE);
      textArea.setCaretPosition(textArea.getDocument().getLength());
      }

      void eventOutput(String eventDescription, KeyEvent e) {
      textArea.append(eventDescription + " detected on "
      + e.getComponent().getClass().getName()
      + "." + NEWLINE);
      textArea.setCaretPosition(textArea.getDocument().getLength());
      }

      public void mousePressed(MouseEvent e) {
      eventOutput("Mouse pressed (# of clicks: "
      + e.getClickCount() + " " + e.getButton()
      + " " + e.getModifiers() + " "
      + e.getX() + " " + e.getY() +")", e);
      }

      public void mouseReleased(MouseEvent e) {
      eventOutput("Mouse released (# of clicks: "
      + e.getClickCount() + ")", e);
      }

      public void keyPressed(KeyEvent e) {
      eventOutput("Key pressed ( "
      + e.getKeyChar() + " " + e.getKeyCode()
      + " " + e.getModifiers() + ")", e);
      }

      public void keyReleased(KeyEvent e) {
      eventOutput("Key released ( "
      + e.getKeyChar() + " " + e.getKeyCode()
      + " " + e.getModifiers() + ")", e);
      }

      public void keyTyped(KeyEvent e) {
      eventOutput("Key typed ", e);
      }

      public void mouseEntered(MouseEvent e) {
      eventOutput("Mouse entered", e);
      }

      public void mouseExited(MouseEvent e) {
      eventOutput("Mouse exited", e);
      }

      public void mouseClicked(MouseEvent e) {
      eventOutput("Mouse clicked (# of clicks: "
      + e.getClickCount() + ")", e);
      }
      }


      BlankArea.java (Oracle's example code):

      /*
       * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
       *
       * Redistribution and use in source and binary forms, with or without
       * modification, are permitted provided that the following conditions
       * are met:
       *
       * - Redistributions of source code must retain the above copyright
       * notice, this list of conditions and the following disclaimer.
       *
       * - Redistributions in binary form must reproduce the above copyright
       * notice, this list of conditions and the following disclaimer in the
       * documentation and/or other materials provided with the distribution.
       *
       * - Neither the name of Oracle or the names of its
       * contributors may be used to endorse or promote products derived
       * from this software without specific prior written permission.
       *
       * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       */
       
      /*
       * BlankArea.java is used by:
       * MouseEventDemo.java.
       * MouseMotionEventDemo.java
       */
       
      import javax.swing.*;
      import java.awt.Dimension;
      import java.awt.Color;
      import java.awt.Graphics;
      public class BlankArea extends JLabel {
          Dimension minSize = new Dimension(100, 50);
          
          public BlankArea(Color color) {
              setBackground(color);
              setOpaque(true);
              setBorder(BorderFactory.createLineBorder(Color.black));
          }
       
          public Dimension getMinimumSize() {
              return minSize;
          }
       
          public Dimension getPreferredSize() {
              return minSize;
          }
      }


      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      If I uncomment the '//leftClick()' line JavaRobotExample(), the output (see below) makes sense and the shift key press is registered. However, this only works if the application allows a preceding mouse click to happen. The current larger application for which I need this solution does not allow use of this workaround.

      Mouse entered detected on BlankArea.
      Mouse pressed (# of clicks: 1 1 16 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.
      Key pressed ( ￿ 16 1) detected on javax.swing.JTextArea.
      Mouse pressed (# of clicks: 1 1 17 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.
      Key released ( ￿ 16 0) detected on javax.swing.JTextArea.
      Mouse pressed (# of clicks: 1 1 16 77 23) detected on BlankArea.
      Mouse released (# of clicks: 1) detected on BlankArea.
      Mouse clicked (# of clicks: 1) detected on BlankArea.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: