7

How do I define a keyboard shortcut for top level special keys like german umlaut key Ä? I found a way to map unicode letters that are used for default american layout keys, see here. But the key event for the german umlaut key Ä is:

java.awt.event.KeyEvent[KEY_PRESSED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar='ä',keyLocation=KEY_LOCATION_STANDARD,rawCode=222,primaryLevelUnicode=228,scancode=40] on frame0 

The idea is to register a keyboard action:

import java.awt.Dimension;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;


public class KeyStrokeForGermanUmlaut {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.setPreferredSize(new Dimension(600, 400));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel panel = new JPanel();
                final JLabel label = new JLabel("Text shall change with shortcut");
                panel.add(label);
                panel.registerKeyboardAction(new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent event) {
                        label.setText("It is working!!!");
                    }
                }, KeyStroke.getKeyStroke("control typed Ä"), JComponent.WHEN_IN_FOCUSED_WINDOW);

                frame.getContentPane().add(panel);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Community
  • 1
  • 1
jan
  • 2,741
  • 4
  • 35
  • 56
  • JLabel isn't focusable for KeyEvent, use only focusable (container in the case - use JPanel) JComponents – mKorbel Apr 03 '14 at 09:10
  • @mKorbel corrected that. Didn't realize because this is only demo code... – jan Apr 03 '14 at 09:18
  • I see your previous question asked yestrerday, was maked by me +1 too, interesting is fact that there wasn't any answer, comment e.i. , you have to decide for why reason and how will be used, effects from, note focus is very important (can be concurency between two of more JComponents with the same KeyStroke), note there sin't possible to use more that two KeyPressed in the same time, otherwise you have to use AWTEventListener – mKorbel Apr 03 '14 at 09:23
  • Updated my question yesterday. The two events shall only demonstrate that one is working, but the other not. Of course I only want to use one... – jan Apr 03 '14 at 09:36

3 Answers3

4
  • you can to conjuring with JLabel, nothing happends for KeyEvents

  • should be start point with moving the focus to JFrames ContentPane (can be used as JPanel, but has BorderLayout in compare with plain JPanel - FlowLayout)

-

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class KeyStrokeForGermanUmlaut {

    private JFrame frame = new JFrame();
    private JLabel label = new JLabel("Text shall change with shortcut");

    public KeyStrokeForGermanUmlaut() {
        frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK), "CTRL + A");
        frame.getRootPane().getActionMap().put("CTRL + A", updateCol());
        frame.setPreferredSize(new Dimension(600, 100));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(label);
        frame.pack();
        frame.setLocation(150, 150);
        frame.setVisible(true);
    }

    private Action updateCol() {
        return new AbstractAction("Hello World") {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText(label.getText() + " presses");
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new KeyStrokeForGermanUmlaut();
            }
        });
    }
}

.

.


EDIT see description in API getKeyStroke/ v.s. getKeyStrokeForEvent

then result is could be (little bit lost when and how to use modifiers SHIFT with uppercase form (ä and ú) for those two chars, maybe someone will help us with those pieces of KeyEvents)

enter image description here

from

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class KeyStrokeForGermanUmlaut {

    private JFrame frame = new JFrame();
    private JLabel label = new JLabel("Text shall change with shortcut");

    public KeyStrokeForGermanUmlaut() {
        frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("typed ä"), "typed ä");
        frame.getRootPane().getActionMap().put("typed ä", updateCol());
        frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("typed ú"), "typed ú");
        frame.getRootPane().getActionMap().put("typed ú", updateCol1());
        frame.setPreferredSize(new Dimension(600, 100));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(label);
        frame.pack();
        frame.setLocation(150, 150);
        frame.setVisible(true);
    }

    private Action updateCol() {
        return new AbstractAction("Hello World") {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText(label.getText() + " presses - ä");
            }
        };
    }

    private Action updateCol1() {
        return new AbstractAction("Hello World") {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText(label.getText() + " presses - ú");
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new KeyStrokeForGermanUmlaut();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I don't get it. My question is related to the german umlaut `Ä`. There is no `KeyEvent.VK_Ä`. So how shall your answer work for `Ä`? – jan Apr 03 '14 at 09:23
  • yes is true because can be lovercase and uppercase, have to check, I'm have the same issue with, doesn't matter only for standard (us) ASCII chars – mKorbel Apr 03 '14 at 09:25
  • You can easily add other keyboards in your system and activate screen keyboard or use the keys right of `L`, in american that are `;` and `'` which are the german umlauts `ö` and `ä`. What do you think how I test with arabic keys? :) – jan Apr 03 '14 at 09:34
  • (`; - ö` and `' - ä`) very good point, only to change mapping in native OS, for german keys we have to waiting for reply by kleopatra, everything here will be, could be only speculations – mKorbel Apr 03 '14 at 09:43
  • @jan [read getKeyStroke](http://docs.oracle.com/javase/7/docs/api/javax/swing/KeyStroke.html#getKeyStrokeForEvent%28java.awt.event.KeyEvent%29), rest you can see in my edit – mKorbel Apr 03 '14 at 10:29
  • I know the definition notation and would assume it works with `KeyStroke.getKeyStroke(new Character('ä'), KeyEvent.CTRL_MASK)`, but it doesn't. See my other question yesterday http://stackoverflow.com/questions/22807892/how-to-allow-configurable-shortcuts-for-all-languages-i-e-how-to-map-unicode-k?lq=1. Look at my exact question text, where I ask to get it working for CTRL... – jan Apr 03 '14 at 11:17
  • @jan [see an issue with modifiers](http://stackoverflow.com/questions/22741215/how-to-use-key-bindings-instead-of-key-listeners), is rellated, there is/was bug with (multi)modifiers and key and/or modifiers and mouse events in Java7 – mKorbel Apr 03 '14 at 11:33
2

I am afraid there is something fishy in the handling of modifiers for CTRL. That is: when inspecting the received key modifier=InputEvent.CTRL_MASK, extended modifier=InputEvent.CTRL_DOWN_MASK. And the API's javadoc is a bit suspicious.

Apart from that, Ä is not a special case, when "control" is left out.

To make it work, I had to add a dirty hack: register a key listener, that calls the action itself. I must be overseeing something.

For the rest I used an InputMap/ActionMap as intended. The input map does not seem to work, but to my understanding it does not work if added to a JTextField, or in the other answer (for Ä). The following works - in a horrible way.

final JLabel label = new JLabel("Text shall change with shortcut");
final KeyStroke key = KeyStroke.getKeyStroke((Character)'k',
        InputEvent.CTRL_DOWN_MASK, false);
final Object actionKey = "auml";
final Action action = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent event) {
        System.out.println("aha");
        label.setText("It is working!!!");
    }
};
label.addKeyListener(new KeyAdapter() {

    @Override
    public void keyPressed(java.awt.event.KeyEvent e) {
        if (e.isControlDown() && e.getKeyChar() == 'ä') {
            System.out.println("Ctrl-ä");
            label.getActionMap().get(actionKey).actionPerformed(null);
            // return;
        }
        super.keyPressed(e);
    }
});
label.getInputMap().put(key, actionKey);
label.getActionMap().put(actionKey, action);
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • That is ugly low level, but working. See my question http://stackoverflow.com/questions/22814845/how-to-define-readable-shortcuts-for-international-keyboards yesterday for having nearly that already. But why is this? Were the Java developer only lazy or is there a technical reason we don't obviously see? If no better answer comes, I will accept this... – jan Apr 03 '14 at 11:31
  • [not fishy, nice bug](http://stackoverflow.com/questions/22741215/how-to-use-key-bindings-instead-of-key-listeners) binarry difference between api and returns from print_out – mKorbel Apr 03 '14 at 12:09
-2
Ä, \xC4, Ä, Ä, %C4, %C3%84

There are the code for Ä. Please try with this, maybe one them will work for you.

user2075328
  • 423
  • 2
  • 7
  • 16
  • What kind of code do you mean? Where shall I replace what exactly? Why do you repeat `Ä` three times? More questions after that answer. ;) – jan Apr 03 '14 at 09:27
  • these are the HexCode so replace \xC4 in place of Ä – user2075328 Apr 03 '14 at 11:43
  • Have you tried that successfully? I don't get it working with that. I'm still not 100% sure what you mean. Can you provide code? Have you realized this is a Java question, not JavaScript? – jan Apr 03 '14 at 11:53