How to Override Key Repeat - KeyListener - java

I have a Graphics project that contains KeyListener, where the arrow keys and space bar controls the movement of a spaceship. However, when a key is held down, it registers the next key presses after a delay after the first. I would like for a held down key to register continuously.
I suspect that this is due to my computer's setting for key repeat delay, so is there any way to temporarily override this in my program, or a workaround for it?
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 38) { //Up Arrow
currentLevel.moveSpiffUp();
} else if (e.getKeyCode() == 40) { //Down Arrow
currentLevel.moveSpiffDown();
} else if (e.getKeyCode() == 32 && !currentLevel.getFrapRayActive()) {
currentLevel.shoot();
}
repaint();
}

I would suggest using key press and key released
public class MyKeyListener implements KeyListener {
//class gets the input from the player
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Left")) {
//left arrow key
} else if (KeyEvent.getKeyText(e.getKeyCode()).equals("Right")) {
//right arrow key
}
}
public void keyReleased(KeyEvent e) {
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Left"){
//left key released
}
if(KeyEvent.getKeyText(e.getKeyCode()).equals("Right")) {
//right key released
}
}
}
I then used this bit of code in my main constructor
main() {
KeyListener listener = new MyKeyListener();
addKeyListener(listener);
setFocusable(true);
}
This way you wont have your delay when hitting keys.

Related

The compiler is not recognizing my input for .getPoint

We areto create a plane and have its speed increase 5mph every time the user inputs the up arrow key and decrease 9mph when hitting the down key. It is supposed it report this back to the user in output box whenever whichever action is completed. How do I set it up so that the keylistener will tell the user that they have pressed the up key? Im still working on this so sorry if it is messy.
private class PolygonPanel implements MouseListener, MouseMotionListener, KeyListener
{
public void mousePressed(MouseEvent event){} //unused event
public void mouseDragged(MouseEvent event){} //unused event
public void keyReleased(KeyEvent event){}
public void keyTyped(KeyEvent event){}
//public void keyPressed(KeyEvent event){}
public void keyPressed(KeyEvent event) {
Integer planespeed=event.getKeyCode();
if (event.getKeyCode() == KeyEvent.VK_RIGHT)
{
//Not gonna use this.
}
if (event.getKeyCode() == 39)//KeyEvent.VK_LEFT
{
System.out.print("This key is up");
}
if (event.getKeyCode() == KeyEvent.VK_UP)
{
System.out.print("This key has been pressed");
//speed=planespeed+5;
}
if (event.getKeyCode() == KeyEvent.VK_DOWN)
{
//speed=planespeed-9;
}
repaint();
}
A frame doesn't detect keybaord input if it is not focused on. Therefore, in order to retrieve keyboard input of any kind, you would have to set your frame to be focusable, using a line such as setFocusable(true); in your constructor. You might also have to add a line such as addKeyListener(new PolygonPanel()); so the listener is registered at all.

How do I respond to two different KeyEvents Simultaneously?

So I am basically creating a platformer game in java. Here is a simple question. Can I respond to two different KeyEvents simultaneously? For example, I am pressing the right arrow key and my player is moving right. Now, I want my player to jump but keep moving right. For this I would need to respond to two different KeyEvents simultaneously. How do I achieve this? I have not tried any code yet because I don't know where to start with. Thank you for the answer in advance.
You can use seperate "KeyDown" and "KeyUp"-events and set state values for your player.
You need a State-Machine for your player.
public class KeyboardListener extends JFrame implements KeyListener {
public KeyboardListener() {
addKeyListener(this);
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key pressed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key pressed");
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key Released");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key Released");
}
}
public static void main(String[] args) {
new KeyboardListener();
}
}
Use the keyPressed and keyReleased-EventHandlers from the KeyListener Interface and save your current player states like walking, jumping, walk_left, walk_right etc as booleans for example.
In your mainloop you can check what state your player is in and change its coordinates. Like:
if(player.left) { player.x += speed } //etc.
You might want to use Threads and then add pressed keys to a list the player physics class.
public class KeysListener implements KeyListener
...
//FIRST THREAD
new Thread(new Runnable() {
#Override
public void run() {
public void keyEvent(KeyEvent e) {
int key = e.getKeyCode();
//TODO ADD KEY TO A LIST IN THE CLASS THAT HANDLES YOUR PHYSYICS
}
}
}).start();
//SECOND THREAD
new Thread(new Runnable() {
#Override
public void run() {
public void keyEvent(KeyEvent e) {
int key = e.getKeyCode();
//TODO ADD KEY TO A LIST IN THE CLASS THAT HANDLES YOUR PHYSICS
}
}
}).start();
...
}
Add as many threads as the number of simultaneous keys you require.

How to use KeyListener

I am currently trying to implement a keylistener in my program so that it does an action when I pressed an arrow key, the object in my program either moves left or right.
Here is the moving method in my program
public void moveDirection(KeyEvent e)
{
int move = 0;
int r = K.getRow();
int c = K.getCol();
if (e.getKeyCode() == 39) move = 1; //KeyEvent.VK_RIGHT
if (e.getKeyCode() == 37) move = 2; //KeyEvent.VK_LEFT
//if (e.getKeyCode() == KeyEvent.VK_DOWN) move = 3;
switch (move)
{
case 1: if (inBound(r, c+1))
K.setLocation(r ,c+1);
if (inBound(r, c-1) && frame2[r][c-1] == K)
frame2[K.getRow()][K.getCol()-1] = null;
break; //move right 39
case 2: K.setLocation(K.getRow(), K.getCol()-1); break; //move left 37
//case 3: b.setLocation(b.getRow()+1, b.getCol()); break; //move down
default: return;
}
processBlockList();
}
I am wondering how the program is supposed to read in (KeyEvent) e. I cannot really type in an arrowkey....
Please help!
edit: I also need to know what I need to add to my code so that my program waits about 700 milliseconds for a keyinput before moving on to another method
http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
Check this tutorial
If it's a UI based application , then " I also need to know what I need to add to my code so that my program waits about 700 milliseconds for a keyinput before moving on to another method" you can use GlassPane or Timer class to fulfill the requirement.
For key Event:
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
check this game example http://zetcode.com/tutorials/javagamestutorial/movingsprites/
Here is an SSCCE,
package experiment;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class KeyListenerTester extends JFrame implements KeyListener {
JLabel label;
public KeyListenerTester(String s) {
super(s);
JPanel p = new JPanel();
label = new JLabel("Key Listener!");
p.add(label);
add(p);
addKeyListener(this);
setSize(200, 100);
setVisible(true);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key typed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key typed");
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key pressed");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key pressed");
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right key Released");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left key Released");
}
}
public static void main(String[] args) {
new KeyListenerTester("Key Listener Tester");
}
}
Additionally read upon these links : How to Write a Key Listener and How to Use Key Bindings
The class which implements KeyListener interface becomes our custom key event listener. This listener can not directly listen the key events. It can only listen the key events through intermediate objects such as JFrame. So
Make one Key listener class as
class MyListener implements KeyListener{
// override all the methods of KeyListener interface.
}
Now our class MyKeyListener is ready to listen the key events. But it can not directly do so.
Create any object like JFrame object through which MyListener can listen the key events. for that you need to add MyListener object to the JFrame object.
JFrame f=new JFrame();
f.addKeyListener(new MyKeyListener);
In addition to using KeyListener (as shown by others' answers), sometimes you have to ensure that the JComponent you are using is Focusable. This can be set by adding this to your component(if you are subclassing):
#Override
public void setFocusable(boolean b) {
super.setFocusable(b);
}
And by adding this to your constructor:
setFocusable(true);
Or, if you are calling the function from a parent class/container:
JComponent childComponent = new JComponent();
childComponent.setFocusable(true);
And then doing all the KeyListener stuff mentioned by others.

Remove key listener from panel

Is it possible to clear a listener that I put on my JPanel? When I call a method, I put a KeyListener on the panel but when I quit this method, I want to clear that listener.
Here is my method :
private void stopBall(final Graphics2D g2, int posBallY, String winner) {
move = false;
scorePanel.showPressSpace(true);
setFocusable(true);
requestFocus();
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_SPACE){
setPosX(getPlayPanelWidth()/2);
setPosY(0);
move = true;
scorePanel.showPressSpace(false);
initBall(g2);
}
}});
if (winner == "player1") {
scoreCountPlayer1++;
scorePanel.getLab_Player1().setText("" + scoreCountPlayer1);
} else if (winner == "comp") {
scoreCountComputer++;
scorePanel.getLab_Computer().setText("" + scoreCountComputer);
}
}
You have an unqualified call to addKeyListener(KeyListener), so I presume that you've extended JPanel. If so, then you can call removeKeyListener(KeyListener). In your current code, your key listener is anonymous. You'll need to change it just a bit to hold on to that reference, like so:
// Create a variable holding the listener
KeyAdapter keyAdapter = new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
setPosX(getPlayPanelWidth() / 2);
setPosY(0);
move = true;
scorePanel.showPressSpace(false);
initBall(g2);
}
}
};
// Register the listener with this JPanel
addKeyListener(keyAdapter);
// Time passes...
// Remove the listener from this JPanel
removeKeyListener(keyAdapter);
Or the way with the absolute minimal adjustments to your code
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_SPACE){
((JPanel)e.getSource()).removeKeyListener( this );
setPosX(getPlayPanelWidth()/2);
setPosY(0);
move = true;
scorePanel.showPressSpace(false);
initBall(g2);
}
}
});
But as already stated in the comments, you should opt for keybindings instead of keylisteners

Java Applet - Moving a ball over the screen

Ok, how to i move from keyboard a ball using an Applet?
I have so far this code, that don't do anything.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class KeyboardGame extends Applet implements KeyListener
{
private static final long serialVersionUID = 1L;
private static boolean keyboadrRightPressed = false;
public void init()
{
addKeyListener(this);
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT)
{
keyboadrRightPressed = true;
}
else
{
keyboadrRightPressed = false;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void paint(Graphics g)
{
g.fillOval(20,20,20,20);
g.drawString("String :"+keyboadrRightPressed,20,30);
}
}
And also i have to understand how it works. I don't get why my action listener won't work, do i need an
while(true)
or an Thread?
Your action listener might actually be working fine, but you need to repaint the applet when the key is pressed so that your string actually appears. Try changing the keyPressed to this:
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_RIGHT)
{
keyboadrRightPressed = true;
}
else
{
keyboadrRightPressed = false;
}
repaint();
}
Actually moving the ball will differ depending on how you want the ball to actually move. I'm guessing you want it to continue moving right while the key is held down, so what I would do is implement a timer or some other form of thread that every .25 seconds (or however long you want) checks the keyboardRightPressed and will move the ball right if it is true. Then in the keyReleased portion of your code you should also add logic to set keyboardRightPressed back to false when you let up on the key.

Categories