Testing if # key is pressed in Java - java

for a program that I am writing I want to test if a few keys are pressed and then determine what to do out the combination of keys. so I got some problems trying to get the # key to be registered (Shift + 2) I tried this If statement
if (ke.getKeyCode() == KeyEvent.VK_2 && ke.getKeyCode() == KeyEvent.VK_SHIFT) {
Why does it not work? I am testing for the 2 and Shift key to be activated at the same time, o does it not work like that?

Use KeyEvent.VK_AT instead of looking for SHIFT + 2. The # symbol isn't in the same place on all keyboards.
So your code becomes:
if (ke.getKeyCode() == KeyEvent.VK_AT) {
}
If you really want to check if the shift key is being pressed have a look at InputEvent.getModifiers() or InputEvent.isShiftDown()
Based on updates spec in the comments, what you want to do is:
if (ke.getKeyChar() == '#') {
}

Related

Processing 3.3.7 - "key" variable does not always represent last key pressed

I am trying to create a sketch that will use the WASD keys to move a character around the screen in the Processing 3.3.7 IDE.
I am having an issue when one key is released and another is pressed at the same time, the key variable will not change to the new input for about a second. I cut down the offending code to this:
void draw(){
println(key);
}
With this code you can see, when you release one key and begin holding another in as close succession as possible (possibly only on the same frame) the printed value will not change for about a second (might differ depending on what your key repeat time). This is really annoying and I don't know how to get around it.
Thanks for reading!
The println() function is notoriously bad at timing, so I wouldn't trust it for micro-benchmarks like this.
Also, the key variable holds the last key that was interacted with, which could be the key you released instead of the key you pressed. For example, think about this sequence of events:
I press the a key. The key variable becomes a.
I press the s key. the key variable becomes s.
Now I release the a key. the key variable switches back to a.
I'm still holding the s key, so after a second, my keyboard triggers another s key event, switching the key variable to s.
If you want more fine-grained control over the keyboard events, I suggest using the event functions like keyPressed() and keyReleased(). You probably want to keep track of which keys are pressed using a set of variables that you set in the event functions. Here's an example:
boolean aPressed = false;
boolean sPressed = false;
void draw(){
if(aPressed){
// a is pressed
}
if(sPressed){
// s is pressed
}
}
void keyPressed(){
if(key == 'a'){
aPressed = true;
}
else if(key == 's'){
sPressed = true;
}
}
void keyReleased(){
if(key == 'a'){
aPressed = false;
}
else if(key == 's'){
sPressed = false;
}
}
Shameless self-promotion: here is a tutorial on handling input events. See the handling multiple key presses section to read more about this approach.

If statement seems to run some code but not all in java

I'm making a 2d platformer in libgdx with box2d. The below is the update method for one of my enemies. It's an extension of the 'Enemy' class, which is what 'super.update' refers to. I want the enemy to run when the player is behind it or far away and to stop and shoot when the player is close to it and in front of it.
I try to achieve this by setting the speed (velocity.x) initially [depending on the enemy's direction], then setting whether or not it's shooting afterwards.
The problem I have at the moment is that the enemy doesn't run when the player is behind it. As you can see, I printed out a lot of strings to console to see when the velocity.x gets changed back to 0. According to the console, it happens in the last if/else pair of statements which are supposed to check how far away the player is and which direction the enemy is running. However, the console strings within those statements, the ones that say 'Shoot Left' or 'Shoot Right', don't get printed out. Despite this, the line that changes velocity.x must get run because the it's value changes according to the string output in the next line. The if statements at the top which check direction must get run as well because the console outputs within those statements get printed, and the output that says the velocity says the correct velocity (either 2 or -2).
What is going on? It seems like the IDE is running only one of the lines in the if statement. That's impossible so what am I missing here?
Thanks for any help.
public void update (float dt, Player player){
super.update(dt, player);
if (b2body.isActive()){
System.out.println(b2body.getPosition().x - player.b2body.getPosition().x);
System.out.println("After Enemy code: " + velocity.x);
if (getRunningRight()) {
System.out.println("Right");
velocity.x = 2;
}
else if (!getRunningRight()) {
System.out.println("Left");
velocity.x = -2;
}
System.out.println("After checking direction: " + velocity.x);
if ((b2body.getPosition().x - player.b2body.getPosition().x <= 2 &&
b2body.getPosition().x - player.b2body.getPosition().x >= 0) && !getRunningRight()){
velocity.x = 0;
System.out.println("Shoot left");
}
else if ((b2body.getPosition().x - player.b2body.getPosition().x >= -2 &&
b2body.getPosition().x - player.b2body.getPosition().x < 0) && getRunningRight()){
System.out.println("Shoot right");
velocity.x = 0;
}
System.out.println("After shooting: " + velocity.x);
}
}
In your first set of ifs, you evaluate getRunningRight() after you have already determined that it will be false (by the initial if failing), so there is no need to evaluate it again.
If you think you are doing the same thing in the second block, you are not; the expression in the inner if is not the opposite of the first one. That is, (A && B) && C is not the opposite of (!A && !B) && !C. Thus, it is possible for both expressions to be false.

Inconsistency calling TextField text in setOnKeyTyped

I am making a typing test in Java with JavaFX. I want to compare the text that is being typed in a TextField to the defined random words. However, the TextField only updates with the letter just typed sometimes and not all the times. The following code is where this problem is occurring.
field.setOnKeyTyped(e -> {
String typingWord = field.getText();
if( typingWord.isEmpty() &&
e.getCharacter().charAt(0) == '\b' &&
!(typedWords.size() == 0) &&
typingWord.equals(previousWord)){
field.setText(typedWords.get(typedWords.size() - 1));
typedWords.remove(typedWords.size() - 1);
field.positionCaret(typingWord.length());
index--;
}
//compare random words to typed words
if (Character.isWhitespace(e.getCharacter().charAt(0))) {
typedWords.set(index, typingWord);
field.clear();
e.consume();
index++;
}
previousWord = field.getText();
});
Is this purely due to the speed of my computer or is it just a bug in JavaFX?
Sir i do not know what you want to do but i want to help, so in your onKeyPressed() or onKeyReleased(), it gives a KeyEvent that is e in your case, you can use that in place of Character.isWhitespace() & e.getCharacter().charAt(0) and also /b
To get your KeyCode
field.setOnKeyTyped(e -> {
KeyCode kc = e.getCode(); // your keycode here is the character you just pressed
now with the KeyCode you can check for a whole lot of goodies,without falling to character
equality checks
if(kc == KeyCode.BACK_SPACE) //checking for your backspace
if(kc.isWhitespaceKey()) // your enter, tabs, space etc
also you can make use of these methods
TextField.deletePreviousChar();,TextField.deleteNextChar(); that might save you all the selection before clearing. if you want to clear like 10 of them then loop it 10 times
lastly why do you check for emptiness & later check if its not empty

How to add a KeyListener to a JPanel [duplicate]

How can I let my custom KeyListener listen for combinations of ALT (or CTRL for that matter) + more than one other key?
Assume I have 11 different actions I want the application to do, depending on a combination of keys pressed. ALT + 0 - ALT + 9 obviously don't pose any problems, whereas for ALT + 1 + 0 (or "ALT+10" as it could be described in a Help file or similar) I cannot find a good solution anywhere on the web (or in my head). I'm not convinced that this solution with a timer is the only possible way.
Thanks a million in advance for any suggestions!
Edit: Actions 0-9 + action 10 = 11 actions. Thanks #X-Zero.
You should not use KeyListener for this type of interaction. Instead use key bindings, which you can read about in the Java Tutorial. Then you can use the InputEvent mask to represent when the various modifier keys are depresed. For example:
// Component that you want listening to your key
JComponent component = ...;
component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
java.awt.event.InputEvent.CTRL_DOWN_MASK),
"actionMapKey");
component.getActionMap().put("actionMapKey",
someAction);
See the javadoc for KeyStroke for the different codes you can use while getting the KeyStroke. These modifiers can be OR'ed together to represent various combinations of keys. Such as
KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
java.awt.event.InputEvent.CTRL_DOWN_MASK
| java.awt.event.InputEvent.SHIFT_DOWN_MASK)
To represent when the Ctrl + Shift keys were depressed.
Edit: As has been pointed out, this does not answer you question but instead should just be taken as some good advice.
You can use KeyListener for this purpose by combining certain things. Look at the following example, which should be placed in an overridden keyPressed(KeyEvent e) method.
if (e.isControlDown() && e.getKeyChar() != 'a' && e.getKeyCode() == 65) {
System.out.println("Select All");
}
The string Select All will be displayed when Ctrl + a is pressed. The method e.isControlDown() checks whether the Ctrl key is pressed or not.
Similarly, the Alt key combinations can be done with the same method by using e.isAltDown() method.
The logic behind this is, e.getKeyChar() returns the character of the key presses & e.getKeyCode() returns its ASCII code. When Ctrl is pressed and hold, the e.getKeyChar() won't return a and e.getKeyCode() will be the same 65. Hope you understand this. Feel free to ask more.
ALT + 1 + 0 (or "ALT+10" as it could be described in a Help file or similar)
seems to clash with (from one of your comments):
So for example if the user wants to change data in column 11 (which would be called "10"), s/he'd press ALT + 1 + [lets go of both ALT and 1] 0.
Assuming that ALT+10 means 'Pressing ALT, pressing and releasing 1, pressing and releasing 0, releasing ALT' I propose trying this:
In keyPressed, listening for the ALT key, activate a boolean flag, isAltPressed, and create a buffer to hold key presses that occur (a string, say).
In keyTyped, if isAltPressed is active, append key codes to the buffer.
In keyReleased, listening for ALT again, open a conditional querying the buffer and executing actions.
public void keyPressed (KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ALT){
buffer = ""; //declared globally
isAltPressed = true; } //declared globally
}
public void keyTyped (KeyEvent e){
if (isAltPressed)
buffer.append (e.getKeyChar());
}
public void keyReleased (KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ALT){
isAltPressed = false;
if (buffer.equals (4948)) //for pressing "1" and then "0"
doAction();
else if (buffer.equals(...))
doOtherAction();
...
}//if alt
}
import java.awt.*;
import java.awt.event.*;
class KDemo
{
public static void main(String args[])
{
Frame f = new Frame();
f.setSize(500,500);
f.setVisible(true);
f.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
AWTKeyStroke ak = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
if(ak.equals(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_F4,InputEvent.ALT_MASK)))
{
System.exit(0);
}
}
});
}
}
I would suggest that instead of using key combinations, consider some input field when the window isVisible() and is focused. The field can be hidden, like Windows' File explorer hidden filename search (enter a directory, type the filename and the correspondence is focused), or is visible, like in Ubuntu.
Key combinations are not designed for including more than one key other than modifiers, although you may be able to achieve this.
I think there's a simpler way which I am using. If the KeyEvent is ev then if you investigate:
(int)ev.getKeyChar()
you find that ctrl-a is 1, ctrl-b is 2 and so on. I wanted to use ctrl-s for save. So I just use:
(((int)ev.getKeyChar())==19)
to detect it. No idea why, but it works fine whereas:
ev.isControlDown() && ev.getKeyChar()=='s'
does not.

How can a KeyListener detect key combinations (e.g., ALT + 1 + 1)

How can I let my custom KeyListener listen for combinations of ALT (or CTRL for that matter) + more than one other key?
Assume I have 11 different actions I want the application to do, depending on a combination of keys pressed. ALT + 0 - ALT + 9 obviously don't pose any problems, whereas for ALT + 1 + 0 (or "ALT+10" as it could be described in a Help file or similar) I cannot find a good solution anywhere on the web (or in my head). I'm not convinced that this solution with a timer is the only possible way.
Thanks a million in advance for any suggestions!
Edit: Actions 0-9 + action 10 = 11 actions. Thanks #X-Zero.
You should not use KeyListener for this type of interaction. Instead use key bindings, which you can read about in the Java Tutorial. Then you can use the InputEvent mask to represent when the various modifier keys are depresed. For example:
// Component that you want listening to your key
JComponent component = ...;
component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
java.awt.event.InputEvent.CTRL_DOWN_MASK),
"actionMapKey");
component.getActionMap().put("actionMapKey",
someAction);
See the javadoc for KeyStroke for the different codes you can use while getting the KeyStroke. These modifiers can be OR'ed together to represent various combinations of keys. Such as
KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
java.awt.event.InputEvent.CTRL_DOWN_MASK
| java.awt.event.InputEvent.SHIFT_DOWN_MASK)
To represent when the Ctrl + Shift keys were depressed.
Edit: As has been pointed out, this does not answer you question but instead should just be taken as some good advice.
You can use KeyListener for this purpose by combining certain things. Look at the following example, which should be placed in an overridden keyPressed(KeyEvent e) method.
if (e.isControlDown() && e.getKeyChar() != 'a' && e.getKeyCode() == 65) {
System.out.println("Select All");
}
The string Select All will be displayed when Ctrl + a is pressed. The method e.isControlDown() checks whether the Ctrl key is pressed or not.
Similarly, the Alt key combinations can be done with the same method by using e.isAltDown() method.
The logic behind this is, e.getKeyChar() returns the character of the key presses & e.getKeyCode() returns its ASCII code. When Ctrl is pressed and hold, the e.getKeyChar() won't return a and e.getKeyCode() will be the same 65. Hope you understand this. Feel free to ask more.
ALT + 1 + 0 (or "ALT+10" as it could be described in a Help file or similar)
seems to clash with (from one of your comments):
So for example if the user wants to change data in column 11 (which would be called "10"), s/he'd press ALT + 1 + [lets go of both ALT and 1] 0.
Assuming that ALT+10 means 'Pressing ALT, pressing and releasing 1, pressing and releasing 0, releasing ALT' I propose trying this:
In keyPressed, listening for the ALT key, activate a boolean flag, isAltPressed, and create a buffer to hold key presses that occur (a string, say).
In keyTyped, if isAltPressed is active, append key codes to the buffer.
In keyReleased, listening for ALT again, open a conditional querying the buffer and executing actions.
public void keyPressed (KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ALT){
buffer = ""; //declared globally
isAltPressed = true; } //declared globally
}
public void keyTyped (KeyEvent e){
if (isAltPressed)
buffer.append (e.getKeyChar());
}
public void keyReleased (KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ALT){
isAltPressed = false;
if (buffer.equals (4948)) //for pressing "1" and then "0"
doAction();
else if (buffer.equals(...))
doOtherAction();
...
}//if alt
}
import java.awt.*;
import java.awt.event.*;
class KDemo
{
public static void main(String args[])
{
Frame f = new Frame();
f.setSize(500,500);
f.setVisible(true);
f.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
AWTKeyStroke ak = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
if(ak.equals(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_F4,InputEvent.ALT_MASK)))
{
System.exit(0);
}
}
});
}
}
I would suggest that instead of using key combinations, consider some input field when the window isVisible() and is focused. The field can be hidden, like Windows' File explorer hidden filename search (enter a directory, type the filename and the correspondence is focused), or is visible, like in Ubuntu.
Key combinations are not designed for including more than one key other than modifiers, although you may be able to achieve this.
I think there's a simpler way which I am using. If the KeyEvent is ev then if you investigate:
(int)ev.getKeyChar()
you find that ctrl-a is 1, ctrl-b is 2 and so on. I wanted to use ctrl-s for save. So I just use:
(((int)ev.getKeyChar())==19)
to detect it. No idea why, but it works fine whereas:
ev.isControlDown() && ev.getKeyChar()=='s'
does not.

Categories