Java Swing InputEvent modifiers for various hardware - java

I am looking for a list of (hardware) modifier keys and their mapping to masks in the Java Swing interface InputEvent. As Java 7, there are five masks I know about:
SHIFT_DOWN_MASK
CTRL_DOWN_MASK
META_DOWN_MASK
See wiki.
ALT_DOWN_MASK
ALT_GRAPH_DOWN_MASK
See: wiki.
Please kindly draw my attention if I am missing any.
From this Eclipse bug report about SWT, I learned:
Apple machines tend to have four keys: command, option, shift and control.
PC-style machines tend to have five keys (nowadays): control, alt, shift, win,
and menu.
For this discussion, I do not consider the menu key a modifier. (Again: Correct me if wrong.)
However, win key can be used in combination, e.g., Win+E to open a new window for Windows Explorer.
I realize the line between "PC" and "Apple" has blurred in the past few years. It may be possible to have keyboards with a plethora of modifiers.
My questions:
How does the Apple command and option keys map to InputEvent masks?
How does the PC win key map to InputEvent masks?

"Shortcut" or "Accelerator" keys are easily handled in a cross- platform way
in Swing.
The Toolkit gives the key ID for the native OS shortcut key:
int shortcut = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask();
With this you can make a KeyStroke
int key = KeyEvent.VK_Q; // or whatever
KeyStroke ks = KeyStroke.getKeyStroke( key, shortcut );
The method getMenuShortcutKeyMask is the correct, cross-platform, Sun- supported way of obtaining the appropriate modifier mask for menu accelerators (AKA shortcuts) for the current platform. It returns a modifier mask using the appropriate java.awt.event.InputEvent constants for the current platform -- on OS X this is InputEvent.META_MASK, on Windows it is InputEvent.CTRL_MASK. Using these literals instead of calling getMenuShortcutKeyMask is bad form, although it works.
One additional thing to note is that you can use combinations of modifiers in accelerator keystrokes:
KeyStroke ks = KeyStroke.getKeyStroke( KeyEvent.VK_P, shortcut | InputEvent.SHIFT_MASK );
to create a Command+Shift+P keystroke (on OS X, Control+Shift+P on Windows). This allows you to create accelerator keystrokes using mnemonic keys that are used by standard menu items (e.g. Print, which uses Command+P) without conflicting with the standard keystrokes.
In the case of Windows key:
// Invoked when a key has been pressed.
public void keyPressed(KeyEvent e) {
// Returns the integer code for the key on the keyboard and if
// keyCode is equal to VK_WINDOWS)...
if (e.getKeyCode() == KeyEvent.VK_WINDOWS) {
// ...call the doIT method.
doIT();
}
}

Related

Capturing specific keystrokes in Java Swing

There are a lot of topics on how to capture keystrokes in Java Swing, but I'd like to ask about the best practice. For example, I have a window in which I wish to listen to a keystroke of either F1 or Command-P on a Mac (or CTRL-P on a PC).
Reading The official Javadoc for KeyEvent, it seems that it is a better practice to use Key Typed events rather than Key Pressed or Key Released events, because they are higher-level. This makes sense to me, and I've even found that in order to make sure the program is platform-agnostic, I have to specify a keystroke object thusly:
private KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
This should allow for capturing of either the Command accelerator key on a Mac, and the CTRL accelerator key on a PC. (I hope I'm using those terms correctly.) So now that I have a KeyStroke object, how do I go about checking it against a KeyEvent object in my KeyListener? And throwing a check for an F1 key event as well only complicates the matter further, though hopefully not too much.
Suggestions?
So now that I have a KeyStroke object, how do I go about checking it against a KeyEvent object in my KeyListener?
You don't use a KeyListener. Swing was designed to be used with Key Bindings.
Check out Key Bindings which contains a program to list the default bindings of each Swing component. It also give some example of how you might create your own ey Bindings. It also contains a link to the Swing tutorial on Key Bindings which explains the whole process in more detail

Java - How can i select all rows in JTable using Command+A shortcut in Mac?

I have many tables in my Java application. When i click "Ctrl + A" in Mac OS X, it selects all rows inside the current table. I wonder if i can change the default shortcut to use "Command + A" instead to select all the rows in the table ?
I am trying to do this inside the EventQueue class to be applied automatically on all the tables in my application.
Swing uses Key Bindings to map KeyStrokes to Actions. So you can add another binding to map "Command A" to the existing "Control A" binding.
See Key Bindings for more information on how to do this as well as a link to the Swing tutorial on How to Use Key Bindings.
Also, check out How do you refer to the mac command key in the String version of Java's KeyStroke.getKeystroke? for information on how to specify the "command" key in a KeyStroke.
Edit:
... I wanted to do that in the EventQueue class to be applied automatically to all tables i create in my application
Yes, usually Key Bindings are applied to individual components. If you want to change bindings for all components then you need to use the UIManager to access the default InputMap. For a JTable you should be able to use:
InputMap im = (InputMap) UIManager.get("Table.ancestorInputMap");
See UIManager Defaults for more information showing the default InputMap used for each Swing component.
By default, the "selectAll" action for JTable on Mac OS X is bound to ⌘-A. Instead of using the control key explicitly, use getMenuShortcutKeyMask(), which returns the corresponding Event.META_MASK on Mac OS X and Event.CTRL_MASK on Windows. Some examples are cited here, but here's the basic idea:
int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
KeyStroke.getKeyStroke(KeyEvent.VK_A, MASK)
That is the final solution i have used(Thanks to camickr) :
InputMap im = myTable.getInputMap( JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
final int CMD_BTN = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
im.put( KeyStroke.getKeyStroke( KeyEvent.VK_A, CMD_BTN ), "selectAll" );

How to add three Shortcut keys ( Ctrl + Shift + C) in Java Swing Menubar?

I want to add shortcut keys in Java Swing Menubar. Below is what I have tried.
jMenuItem1.setText("Create");
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.CTRL_MASK));
Here I want three KeyEvent.VK_C, KeyEvent.CTRL_MASK, and KeyEvent.SHIFT_MASK.
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK+ALT_MASK)
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,java.awt.Event.CTRL_MASK | java.awt.Event.SHIFT_MASK));
KeyStroke.getKeyStroke(KeyEvent.VK_C, 21);
http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/KeyStroke.html#getKeyStroke(int, int)
Read about the modifiers and you'll know what the 21 (or 2 and the 1) is for...
From the Java Menu Tutorial:
To specify an accelerator you must use a KeyStroke object, which combines a key (specified by a KeyEvent constant) and a modifier-key mask (specified by an ActionEvent constant).
The referenced "modifier-key mask" is created from multiple ActionEvents via bitwise operations, so the bitwise OR specifying multiple events in the setAccelerator() method does the same thing.
On Windows Only:
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
java.awt.Event.CTRL_MASK | java.awt.Event.SHIFT_MASK));
Cross-platform:
To enable this cross-platform (i.e. to use the Command button on a Mac instead of Control), simply replace the java.awt.Event.CTRL_MASK with:
#SuppressWarnings("deprecation")
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); // Java 9 or older
or
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx(); // Java 10 or newer
for a final setAccelerator that looks like
jMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() |
java.awt.Event.SHIFT_MASK));
On a Mac you'll also notice that the Accelerator text in the menu itself shows the CMD symbol, too, while on Windows it'll still show CTRL (e.g. CMD+S vs. CTRL+S).

Java KeyEvents on Mac

I am trying to write a program that uses key events to activate a method. The code works on Windows machines but when transered to Mac it does no respond to my "Spacebar" being pressed. I presume this is to do with the different key codes used.
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
System.out.println("SPACEBAR");
grid.stepGame();
}
}
Any ideas how i can get this working on Mac?
Edit - The problem has been solved using the answer below - For note though it seems that on Mac the Frame never automatically regains focus, hence why the keylistener doesn't work is another JComponent is activated.
I'm uncertain as to your particular issue but it's a good bet that if you switch to using key bindings instead of key listeners your issue would disapear.
From the Java Tutorials site:
Note:
To define special reactions to particular keys, use key bindings instead of a key listener.
As an example
// Component that you want listening to your key
JComponent component = ...;
component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
"actionMapKey");
component.getActionMap().put("actionMapKey",
someAction);

What are `VK_META` and `META_MASK` in the Java Robot class?

What are VK_META and META_MASK in the Java Robot class? Any example that explains what they are or what they do would be very helpful.
Also, VK_META gives me an invalid keycode error on my Windows 7 PC.
VK_META and META_MASK are defined in KeyEvent and InputEvent classes. They both define the META key as a standalone key pressed and as a modifier used pressing another key respectively.
The META key is a key used in old keyboards and now can be emulated using the Windows Key.
Robot class allows to simulate key strokes (pressed, released, typed) and mouse movement, "acting" as a user using the keyboard and mouse. When you use the robot class, you define the sequence of "actions" to simulate, mouse movements and keyboard usage. If you want to simulate the META key pressed or used as a modifier, need to pass the keyCode and these two constants define the keyCode for META typed and modifier.
You can have problems using this key depending some factors, such your keyboard layout, keyboard configuration, operating system...
If you have problem, try avoid using this key except you need to simulate the Windows (PC) or Command (Mac) key.

Categories

Resources