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)
Related
I'm trying to set the value of a variable to that of a keypress. It doesn't matter if the variable is set to the actual letter or the value of the letter. Just a way for the console to know which letter was pressed. AKA, I want to use WASD for Up, Down, Left, and Right. In order to do this, I need the console to accept my "WASD" inputs without being forced to hit enter each time I press a key. I'm using Replit as my IDE if that makes anything easier. (JAVA)
I'm writing a program using JavaFX and I currently have three TextFields. When you press enter while any of the text fields are focused, there is an EventHandler which calls the appropriate method for each field. There is no submit button because I want it to submit each input separately (that's just how I made the rest of the program) to be validated and return a String containing any errors in the input. If the users input is invalid, it resets it to the last valid value it had.
However, when testing I found that sometimes I just click somewhere else (such as the next field) rather than pressing enter, so I wanted to implement the same function as pressing enter but when the user clicks outside the field. There is a MouseClicked event on the root that I have attempted to make it submit the input for all of the fields at once which works, but if any field has not been filled in, then it will be unsuccessful and return an error message (which might confuse a user).
Additionally, if the user clicks inside the TextField again, say to delete something from the middle of the word, the event will be triggered and the field will be reset to the last valid value if the current input was invalid.
I've considered using a MouseExited event on each field, but I think that might be triggered by the cursor leaving the field, rather than a click outside of the field.
What would be a good way of doing this, while minimising the number of event methods in my program?
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);
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.
I've got a KeyboardFocusManager with overridden dispatchKeyEvent() method to handle navigation for arrow key and enter. I need to handle key events for as long as the key is pressed. Unfortunately, holding down enter results in KEY_TYPED events which do not contain the key location. Is there a way to find out which enter is currently being pressed? Or can I suppress KEY_TYPED events for enter in favour of KEY_PRESSED events?
edit:
I can't tell you the reason why it's done with a KeyboardFocusManager instead of KeyListeners but I'm sure there were reasons it was done this way. As of now, it is not possible anymore to change this. The problem is, that for our system(an old terminal emulator), the left enter key is a navigational key. Pressing enter moves the focus to the next textfield after the current line. The right enter key is a command key that sends the user input to the server.
Using the KeyEventDemo found in How to Write a Key Listener, I am unable to reproduce the effect you describe for either KEY_PRESSED or KEY_RELEASED. Of course, "KEY_TYPED events do not have a keyLocation."
It's not clear why you are using a Focus Listener, as many components already bind certain keys to a defined Action. The example binds the arrow keys, which respond to auto-repeat events regulated by the host's preferences.