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

Alt_GR Key Reported Incorrectly

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      The alt_graph key is reported incorrectly. Results differ between java versions and input schemes, but are always incorrect.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Use the Keycode Listener example from here.
      https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
      https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/KeyEventDemoProject\KeyEventDemo.jar

      Press the alt_gr key. Combine it with other keys like arrow up.
      Compare java 8 with with java 11 or 13. Switch the keyboard layout between us/german

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Alt graph key is reported as alt_graph_key and or mask.
      ACTUAL -
      Depending on the combination of java version and keyboard layout the alt_gr key will be reported as either:

      Alt ( no graph) (java 8)
      Alt+ Alt_graph (us)
      Alt+Alt_graph + ctrl (german)

      ---------- BEGIN SOURCE ----------
      /*
       * 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.
       */

      package events;

      /*
      * KeyEventDemo
      */

      import java.awt.BorderLayout;
      import java.awt.Container;
      import java.awt.Dimension;
      import java.awt.event.*;
      import javax.swing.*;

      public class KeyEventDemo extends JFrame
              implements KeyListener,
              ActionListener
      {
          JTextArea displayArea;
          JTextField typingArea;
          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 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-dispatching thread.
           */
          private static void createAndShowGUI() {
              //Create and set up the window.
              KeyEventDemo frame = new KeyEventDemo("KeyEventDemo");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              
              //Set up the content pane.
              frame.addComponentsToPane();
              
              
              //Display the window.
              frame.pack();
              frame.setVisible(true);
          }
          
          private void addComponentsToPane() {
              
              JButton button = new JButton("Clear");
              button.addActionListener(this);
              
              typingArea = new JTextField(20);
              typingArea.addKeyListener(this);
              
              //Uncomment this if you wish to turn off focus
              //traversal. The focus subsystem consumes
              //focus traversal keys, such as Tab and Shift Tab.
              //If you uncomment the following line of code, this
              //disables focus traversal and the Tab events will
              //become available to the key event listener.
              //typingArea.setFocusTraversalKeysEnabled(false);
              
              displayArea = new JTextArea();
              displayArea.setEditable(false);
              JScrollPane scrollPane = new JScrollPane(displayArea);
              scrollPane.setPreferredSize(new Dimension(375, 125));
              
              getContentPane().add(typingArea, BorderLayout.PAGE_START);
              getContentPane().add(scrollPane, BorderLayout.CENTER);
              getContentPane().add(button, BorderLayout.PAGE_END);
          }
          
          public KeyEventDemo(String name) {
              super(name);
          }
          
          
          /** Handle the key typed event from the text field. */
          public void keyTyped(KeyEvent e) {
              displayInfo(e, "KEY TYPED: ");
          }
          
          /** Handle the key pressed event from the text field. */
          public void keyPressed(KeyEvent e) {
              displayInfo(e, "KEY PRESSED: ");
          }
          
          /** Handle the key released event from the text field. */
          public void keyReleased(KeyEvent e) {
              displayInfo(e, "KEY RELEASED: ");
          }
          
          /** Handle the button click. */
          public void actionPerformed(ActionEvent e) {
              //Clear the text components.
              displayArea.setText("");
              typingArea.setText("");
              
              //Return the focus to the typing area.
              typingArea.requestFocusInWindow();
          }
          
          /*
           * We have to jump through some hoops to avoid
           * trying to print non-printing characters
           * such as Shift. (Not only do they not print,
           * but if you put them in a String, the characters
           * afterward won't show up in the text area.)
           */
          private void displayInfo(KeyEvent e, String keyStatus){
              
              //You should only rely on the key char if the event
              //is a key typed event.
              int id = e.getID();
              String keyString;
              if (id == KeyEvent.KEY_TYPED) {
                  char c = e.getKeyChar();
                  keyString = "key character = '" + c + "'";
              } else {
                  int keyCode = e.getKeyCode();
                  keyString = "key code = " + keyCode
                          + " ("
                          + KeyEvent.getKeyText(keyCode)
                          + ")";
              }
              
              int modifiersEx = e.getModifiersEx();
              String modString = "extended modifiers = " + modifiersEx;
              String tmpString = KeyEvent.getModifiersExText(modifiersEx);
              if (tmpString.length() > 0) {
                  modString += " (" + tmpString + ")";
              } else {
                  modString += " (no extended modifiers)";
              }
              
              String actionString = "action key? ";
              if (e.isActionKey()) {
                  actionString += "YES";
              } else {
                  actionString += "NO";
              }
              
              String locationString = "key location: ";
              int location = e.getKeyLocation();
              if (location == KeyEvent.KEY_LOCATION_STANDARD) {
                  locationString += "standard";
              } else if (location == KeyEvent.KEY_LOCATION_LEFT) {
                  locationString += "left";
              } else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
                  locationString += "right";
              } else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
                  locationString += "numpad";
              } else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
                  locationString += "unknown";
              }
              
              displayArea.append(keyStatus + newline
                      + " " + keyString + newline
                      + " " + modString + newline
                      + " " + actionString + newline
                      + " " + locationString + newline);
              displayArea.setCaretPosition(displayArea.getDocument().getLength());
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Use InputEvent.CTRL_DOWN_MASK|InputEvent.ALT_DOWN_MASK |InputEvent.ALT_GRAPH_DOWN_MASK
      AND also InputEvent.ALT_DOWN_MASK |InputEvent.ALT_GRAPH_DOWN_MASK instead of InputEvent.ALT_GRAPH_DOWN_MASK .. at least for Java 11-13

      FREQUENCY : always


            tr Tejesh R
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: