I have a piece of code that allows me to capture keystroke and print them with a System.out.println. My problem is that when I try to use it with ctrl (e.g. ctrl + m) it removes the KeyChar attribute of the m key. Does anyone know why this happen and how I can solve it?
public TestForm() {
initComponents();
KeyEventDispatcher keyEventDispatcher = new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(final KeyEvent e)
{
if (e.getID() == KeyEvent.KEY_PRESSED && e.isAltDown())
{
System.out.println("ALT + "+e.getKeyChar());
}
else if (e.getID() == KeyEvent.KEY_PRESSED && e.isShiftDown())
{
System.out.println("SHIFT + "+e.getKeyChar());
}
else if (e.getID() == KeyEvent.KEY_PRESSED && e.isControlDown())
{
System.out.println("CTRL + "+e.getKeyChar()/*+"\n"+e*/);
}
else
{
System.out.println(e);
}
return true;
}
};
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyEventDispatcher)
;
}
I'm quite new to java so it might be something simple im missing. Thanks in advance
There is an important difference between key code and key char. A key code represents a key on a keyboard. A key char represents a letter in some alphabet. There is a ctrl key on your keyboard but there is no letter in any alphabet (e.g. no unicode character) for ctrl. So when the ctrl key is pressed you get a KEY_PRESSED event with a key code but no key char.
Not all hope is lost though. It looks like you are trying to detect when CTRL and some character is pressed (e.g. if I type ctrl+A instead of just A). The problem is that you are looking at KEY_PRESSED events. In Java there is an important distinction between the KEY_PRESSED event and the KEY_TYPED event.
For exmaple, if I were to press Ctrl+A on my keyboard I would first press down the Ctrl key, then press down the A key, then release them more or less at the same time. In my mind I think of this as one action, but it's not. What happens in Java is you get:
KEY_PRESSED (keyCode = VK_CTRL, keyChar = CHAR_UNDEFINED) //I press down Ctrl key
KEY_PRESSED (keyCode = VK_A, keyChar = CHAR_UNDEFINED) //I press down the a key
KEY_TYPED (keyCode = VK_UNDEFINED, keyChar = 'A') //The 'typing' of the letter 'A'
//some key released events that are not relevant to this discussion
As you can see, a KEY_PRESSED event has a key code but no key char (this is fired when a key on the keyboard is pressed down). A KEY_TYPED event has a key char but not key code (this represents the completion of a key sequence resulting in a letter).
All of this is documented in detail on the javadocs for the KeyEvent page.
Related
I started playing with java a little bit, after few years of coding in C#. What I am trying to achieve is to handle a key press event for jTextField.
In C# i would code:
e.Handled = true;
I did a little research and read that I can use consume() in java. So i wrote the following code:
if (evt.getKeyChar() == '.' || DataController.getInstance().isDot_pressed())
{
jTextFieldQuery.setText(DataController.getInstance().generateText(jTextFieldQuery.getText()));
if(evt.getKeyChar()!='.')
{
DataController.getInstance().setOdgovor(DataController.getInstance().getOdgovor()+evt.getKeyChar());
}
else
{
DataController.getInstance().setDot_pressed(!DataController.getInstance().isDot_pressed());
}
evt.consume();
}
}
This code should handle key pres for "." and every key press until another "." is pressed in the mean time it loads predefined text in text field.
This solution doesn't work, it consumes(handles) for example delete button but it doesn't handle normal letters.
Any suggestions? Thanks.
I want to collect keyboard input and append it together in a java StringBuilder, but using LWJGL's Keyboard event, i end up fetching more than I wish, like Shift, CapsLock, Escape, F1 to F12, Enter, even punctuation etc.. These keys also have key ID's, but by appending them, they are printed as a square (unrecognized character i believe).
My goal is to ignore these non-printable keys without having to create a giant array with all these unwanted keys. Is there any way to do so?
P.S. Mind that i wish the common symbols like \,.-< etc. to still be considered into the string, like any text editor would.
Here's an example of what you could use. This example is then used as an inner class and you use it in stead of a regular ActionListener on a component. This example catches the keycode of the event (using KeyEvent). I placed some examples you asked in your questions, I'm sure you'll find more if needed.
You should append a custom string to your existing string in every case of the switch statement.
public class CustomListener extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
try {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_SHIFT:
//Append a string to your existing string
break;
case KeyEvent.VK_F1:
//Append a string to your existing string
break;
case KeyEvent.VK_CAPS_LOCK:
//Append a string to your existing string
break;
case KeyEvent.VK_ENTER:
//Append a string to your existing string
break;
}
}
} catch (NullPointerException e1) {
e1.printStackTrace();
}
}
}
Thanks to Mark W I just found out that the ASCII range from 32 to 126 and 128 to 255 covers, i believe, every single character that is commonly printed in the everyday text-editors. Thanks a bunch :)
Here is a minimal code chunk that might be useful for someone using lwjgl
private StringBuilder text;
private void updateInput()
{
while (Keyboard.next())
{
if (Keyboard.getEventKeyState())
{
// get key info
int key = Keyboard.getEventKey();
char ch = Keyboard.getEventCharacter();
int ascii = (int) ch;
// delete case
if(key == Keyboard.KEY_BACK)
text.setLength(Math.max(0, text.length() - 1));
// append if common char
if((ascii >= 32 && ascii <= 126) || (ascii >= 128 && ascii <= 255))
text.append(ch);
}
}
}
I created a simple JavaFX application that receives input from the user in a TextField. I attached the KeyTyped event from SceneBuilder to the controller. My function looks like this:
#FXML private void keyTyped(KeyEvent event) {
System.out.println(event.getCode().equals(KeyCode.ENTER));
}
This function always prints out UNDEFINED when I type the enter key. Any ideas on how to fix this? Other letters I type seem to have the same problem as well.
KeyTyped is a special event. It doesn't have KeyCode but has character set instead.
See example for letter 'a':
KeyEvent [source = TextField[id=null, styleClass=text-input text-field],
target = TextField[id=null, styleClass=text-input text-field], eventType = KEY_TYPED, consumed = false,
character = a, text = , code = UNDEFINED]
and javadoc: http://docs.oracle.com/javafx/2/api/javafx/scene/input/KeyEvent.html#getCode()
The key code associated with the key in this key pressed or key
released event. For key typed events, code is always
KeyCode.UNDEFINED.
I'm trying to use the Robot class in Java and type some text. Unfortunately I'm having problems finding the key codes of the square brackets, this symbol | and this symbol `. I can't find them in the KeyEvent constants. I want to use them, because the text i'm typing is in cyrillic and these symbols represent characters in the alphabet. Thanks in advance.
It's in the JavaDoc for KeyEvent
KeyEvent.VK_OPEN_BRACKET
and
KeyEvent.VK_CLOSE_BRACKET
Edit
From the KeyEvent JavaDoc
This low-level event is generated by a component object (such as a
text field) when a key is pressed, released, or typed.
So on a US 101-key keyboard, the ` and ~ will produce the same keycode, although ~ will have a SHIFT modifier. Also notice that KeyEvent.VK_BACK_SLASH traps the | (pipe) keystroke too.
Try adding the following sample KeyAdapter to your project to see this in action.
new KeyAdapter()
{
public void keyPressed(final KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_BACK_QUOTE)
{
e.toString();
}
if (e.getKeyCode() == KeyEvent.VK_BACK_SLASH)
{
e.toString();
}
if (e.getKeyCode() == KeyEvent.VK_OPEN_BRACKET)
{
e.toString();
}
}
}
The general solution is to call KeyEvent.getExtendedKeyCodeForChar(int c). If the unicode codepoint c has a VK_ constant that will be returned. Otherwise a "unique integer" is returned.
I think that '`' is KeyEvent.VK_BACK_QUOTE ...
I have a problem with typing in Robot Class. I want the robot to type something the
user has entered. The robot for some reason can't type some of the characters. Here is my type code:
public void type(String s,Robot robot) {
byte[] stringBytes = s.getBytes();
for (byte b : stringBytes) {
int code = b;
if (code > 96 && code < 123)
code = code - 32;
robot.keyPress(code);
robot.keyRelease(code);
}
}
how can i fix this problem?
If you want to "type back what the user entered", then surely you should be capturing a set of KeyEvent objects, and not a String. There is not a key for every String character, far from it! (for instance you need to press 'shift' to input a colon, so that's two key presses and not one)
Robot expects key codes defined in KeyEvent.