Ignore input method input in AWT Component on Mac - java

On Mac, the US International PC keyboard layout has dead keys for several keys such as ", ' and backtick. When typing ", the Mac starts input method composition - the " shown in compose mode (usually underlined) and waits for further input. If I use a, then the input method will complete and I'll get the character ä. There are several such dead keys, and e.g. the British keyboard layout treats Alt+n as a dead key to give something like ñ.
In a Java AWT application, is there any way I can disable this behaviour so that I get simply the raw keys typed? E.g. in the US International PC keyboard layout, if I type "+a, I want to receive events for " and a, and not one event for ä. In the British keyboard layout, I want to type Alt+n+n and receive events for Alt+n and n and not ñ.
If I call Component.enableInputMethods(false), then my event queue will receive the Alt+n event, but if I then follow with n, I receive ñ.
Similarly, if I use a Chinese keyboard layout, the popup input method is still active, even after calling Component.enableInputMethods(false).
Is there any way to completely disable input method processing, and receive just the keys, as typed?
For context, I'm trying to implement Vim like behaviour - normal mode editing requires ASCII input, while insert mode will of course handle input methods as expected. While it would be ideal to swap to an ASCII keyboard layout in normal mode, but even the Mac's "ABC" keyboard layout has dead keys for Alt+n, Alt+u, Alt+I and Alt+e and Alt+Backtick. Telling users to create a custom keyboard layout with something like Ukulele is not a viable option.

Related

glfwGetKeyName() returns null

I'm currently working on the input system of a game engine in java, and I use GLFW for the window. I set up a callback system to catch when a key is pressed:
GLFW.glfwSetKeyCallback(window, (windowId, key, scancode, action, mods) -> {
if (action == GLFW.GLFW_PRESS) {
System.out.println(GLFW.glfwGetKeyName(key, scancode));
}
});
And the problem is when I press space or enter or shift plus a different key it prints out null. My question is: how to use the mods attribute to capitalize the next key when I press shift or print out a new line when I press enter etc.
I don't know the solution for the first question, but the second one is easy.
Try using char callback. This one is different from key callback, as it only works with unicode characters being typed by user (letters are capitalized with Shift, CapsLock button also works). Also, if you want to detect modifier buttons being pressed while user types, try using charMods callback. Seems like the latter is marked for removal, so you can test whether the modifier button is pressed with glfwGetKey().
EDIT: Seems like I didn't understood you on the first one. glfwGetKeyName() is not designed to be used as text input method. Also note that it can display names for a limited range of buttons. What is more, when you press multiple keys, press event for each one is called in separate key callback event. You can't handle multiple key presses at once. (Modifier keys are put in mods argument of callback, but I can't tell by now whether they also trigger a key press event or not - check it yourself)

Is it possible to open the numeric keyboard before the text keyboard?

I have an editText that needs to be of the "text" type, but I want that when it gets focus my Android keyboard opens showing the numbers first, instead of the letters that are the default.
I've been researching for a while now, but I can't find an answer. Could anyone tell me if it is possible to do this?
PS: setting my editText to "number" doesn't get me the result I need.
EDIT
I need my keyboard to have this behavior when opening: https://streamable.com/2ohsaz ; that is, the user can type whatever he wants, but the numeric keypad option must appear first
No, there isn't. THe keyboard is a separate app, and it gets to decide what to show. There's an API to provide hints to the keyboard, such as NUMBER to tell it that it should show numbers. But there's no API to tell it to show certain information at certain times. You can try to hack it by setting the input type, but it will be more likely that a keyboard will ignore or be confused by changing input types, because they aren't actually supposed to change until a new field is focused.
Because the keyboard is a separate app that isn't part of the OS and is frequently replaced by OEMs and users, you can't require special advanced behavior like that- the API between the app and the keyboard just isn't set up to allow that, and is mostly guided by conventions and expectation. So any advanced trickery you use will work on some devices, and may totally break others. As such its recommended that other than setting an initial input type, you let the keyboard do what it wants.

Swing - Can Enter be used for focus traversal and action performed?

I understand that this is a ridiculous (and somewhat embarrassing) scenario and one which I am beginning to believe is not actually possible to overcome...
I have developed a basic swing application for my client which consists of a frame containing text fields and combo boxes which validates / processes the data captured when they lose focus - standard issue stuff.
My client is hell-bent on living in the "DOS days" by being able to traverse from field to field using the ENTER key instead of the default TAB key.
I achieved this simply and neatly by implementing KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(...). (See below for full code)
At certain points during data being captured I need to show an error or warning message and I achieve this by the obvious JOptionPane.showMessageDialog(parentComponent, message, "Warning", JOptionPane.WARNING_MESSAGE) routine.
The problem - when faced with the dialog message box, my client expects that he can then press ENTER to close it which no longer works because I have obviously overridden the actionPerformed event of ENTER and instead have assigned it as a focus traversal key.
I am aware that SPACE works perfectly instead to fire off the actionPerformed event on the Ok button which in turn merrily closes the dialog box. The issue is my client wants to be able to press ENTER...
I am trying to avoid creating a custom dialog message box but even if I attempted this I don't think I will be able to achieve the result I want because of my next point...
I have tried using JOptionPane.showOptionDialog(parentComponent, message, "Error", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE, null, buttons, null) instead where buttons is an array of pre-created buttons that I can add action / key / focus listeners onto to try re-create the default behaviour of the ENTER key. The problem is that ENTER no longer registers at all in any of these event listeners as long as I am assigning it as a focus traversal key.
This is how I am setting ENTER (and ESC, TAB and SHIFT+TAB) as focus traversal keys:
// Enable Enter & Tab as forward traversal keys and Esc & Shift-Tab as backward traversal keys
KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke shiftTab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK);
Set<KeyStroke> forwardKeys = new HashSet<KeyStroke>();
forwardKeys.add(enter);
forwardKeys.add(tab);
Set<KeyStroke> backwardKeys = new HashSet<KeyStroke>();
backwardKeys.add(esc);
backwardKeys.add(shiftTab);
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
Any idea if this is possible or should I just tell my client to deal with it and get used to pressing SPACE?
Thanks in advance,
Xandel
try this on the okButton and enter will start working but after this tab shift+tab also won't work on button.
okButton.setFocusTraversalKeysEnabled(false);

KeyEvent#consume() method

Could any one explain what is consume() method and its purpose since I couldn't find much relevant information of it on the net? (example might be the best for a novice like me)
The consume method marks the event as processed. Typically this is executed from your program code when you've chosen to act upon the input, e.g. when you wish to prevent a text input from receiving the key stroke.
Or, to take the example given in the Javadocs:
[The consume method] allows listeners and component subclasses to "consume" the event so that the source will not process them in their default manner. For example, consuming mousePressed events on a Button component will prevent the Button from being activated.
Suppose you playing a Game FIFA for example your team is South Africa playing Russia .In normal circumstances if am marking a Russian player and l press key T in instance ,it will invoke a SlideTackle() ,sliding tackling function on the Russian player .
But what if l want to only make it possible that a sliding tackle can only occur whilst they is a opponent player near only that's when l will call consume() method so that the SlidingTackle() function doesn't respond to key press T when Russian opponent is not close .
That's how best l understood

How to simulate keyboard input (including cursor movement) by programmatically generating KeyEvents

I am trying to simulate keyboard input by programmatically generating KeyEvent objects and pumping them to the event queue. This works fine except that when characters are being entered into a JTextField, for example, the cursor (caret?) does not move to always be at the end of the entered value. For example, if we denote the caret as the pipe | then this is what I get:
An 'A' keypress is simulated by sending a KEY_PRESSED, KEY_TYPED, KEY_RELEASED event, and the JTextField value is:
|A
that is, the cursor/caret is back at the beginning of the field after the A is entered.
How do I get the cursor/caret to automatically move as it would when actual physical keys are pressed?
Have you tried using the Robot Class in the JDK?
http://docs.oracle.com/javase/6/docs/api/java/awt/Robot.html
After you issue each command, call a method that uses setCaretPosition() to the end of the text in the JTextField. This will be much easier if you use a J*Pane so you can call getDocument() and you will have much more control.

Categories