user3343497
user3343497

Reputation: 194

How to detect a key press in Java

My son (aged 11) who is learning Java is going to enter a question and some code. He tells me he has not been able to find the answer to this question on the site. You will be reading my edited version of his question. Many thanks.

How can I detect a keypress in java, My IDE is called eclipse and I have made some classes. I found the code inside keyconfigofplayer of the internet and changed it to extend player class. I want it so when I hold down a key a rectangle or oval will move across the screen, how could I do this? For some reason it wont type the code correctly which is why my imports dont have the asterisk and look wierd. sorry about that. please ignore it. I cant fix that:(. here is my code:

code for window:

import javax.swing.*;
import java.awt.*;

public class window {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setSize(600, 600);
        player p = new player();
        f.add(p);

        keyconfigofplayer key = new keyconfigofplayer();
        p.add(key);
        f.add(key);

    }
}

//this class is the player graphic

import javax.swing.*;
import java.awt.*;

    public class player extends JPanel {

    int x = 50;
    int y = 50;

    public void paint() {//This is where the graphic is painted to the screen
        repaint();
    }

    public void paintComponent(Graphics g) {
        //This is where the graphic is 'manufactured'
        super.paintComponent(g);
        g.setColor(Color.GREEN);
        int width = 20;
        int height = 20;
        g.fillRect(x, y, width, height);

        int width2 = 10;
        int height2 = 10;
        g.fillOval(x, y, width2, height2);

    }
}

//the keyconfigofplayer class(where i think the problems are):
//this class is the player graphic

import javax.swing.*;
import java.awt.*;

    public class player extends JPanel {

    int x = 50;
    int y = 50;

    public void paint() {//This is where the graphic is painted to the screen
        repaint();
    }

    public void paintComponent(Graphics g) {
        //This is where the graphic is 'manufactured'
        super.paintComponent(g);
        g.setColor(Color.GREEN);
        int width = 20;
        int height = 20;
        g.fillRect(x, y, width, height);

        int width2 = 10;
        int height2 = 10;
        g.fillOval(x, y, width2, height2);
    }
}

The classes I have tried to comment well so you know what it means. I got keyconfigofplayer's code from the youtube channel macheads101 how to program GUI in java episode 12 or 11 I think. I think my problem isn't about updating the image, but about detecting when the key is pressed and then released. So maybe I should make a while loop stating that: if this key is pressed down, + 10 to the x coordinates until its done and constantly update the position. I would also like to ask, when to use public, private and void? I dont understand those :( and if Ive done the extends player implements thing correctly. I tried to alter macheads101's code carefully, when I copied it exactly it didn't work too. So I really dont know what is wrong. I would be thankfull if you answered my question and helped me to alter my code. In the end its gonna be a shooter, like the arcade game 'space invaders' or 'dragon shooter'.

Upvotes: 15

Views: 114777

Answers (6)

InfinitePower563
InfinitePower563

Reputation: 29

Suppose you need to detect the key f, use this:

//packageStatement
import javax.swing.*;
import java.awt.event.*;
//more imports
public class window {
 //code
 f.addKeyListener(new KeyListener() {
    @Override
    public void KeyTyped(KeyEvent e) {
        if(e.getKeyChar == 'f'){
           //code
        }
    }
    //more code
 });
 //more code
}

Remember to use the string literal, because the getKeyChar() method returns a char.

Upvotes: -1

Rav
Rav

Reputation: 1470

There's a great library which works smoothly and it listens to global events. It's the only thing which worked without any issues for me: https://github.com/kwhat/jnativehook

It grabs every event in the system, pretty cool for any development.

You can use it like this:

package main;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

class MyKeyboard implements NativeKeyListener {

    public static void main(String[] args) {
        try {
            GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }

        GlobalScreen.addNativeKeyListener(new MyKeyboard());

        // Now press any keys and look at the output
    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent nke) {
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent nke) {
    }

}

Upvotes: 3

Paul Samsotha
Paul Samsotha

Reputation: 208994

So GUI are event driven. Everything that occurs is driven by an event. A key press is an event. A component needs to listen for events, and do something when the event is fired. You can read more about how to write different listeners here. Some of the basic listeners are fairly easy to recognize (by name) like KeyListener or MouseListener. ActionListener is also pretty common for button presses. You'll want to go through the tutorials and learn the different listeners.

Note though that with Swing there are focus issues with using a KeyListener so it is preferred to use key bindings. As stated in the KeyListener tutorial:

To define special reactions to particular keys, use key bindings instead of a key listener

A tutorial for key bindings can be found here and an example can been seen here. Here's the gif from the example, showing the movement of rectangle with a key press using key bindings

enter image description here


UPDATE just notice.

  1. Don't override the paint method of JPanel
  2. Never call repaint() from inside a paint/paintComponent method

    public void paint() {//This is where the graphic is painted to the screen
        repaint();
    }
    

Get completely rid of the above code.

Upvotes: 6

Shrey
Shrey

Reputation: 671

KeyListener

You should be putting his KeyListener Event within the class you need it not in the Main Method!

addKeyListener(new KeyListener() {
    public void keyPressed(KeyEvent e) {
        //This is where you want to implement your key!
        if(e.getKeyCode() == KeyEvent.VK_SPACE){
             //Fire Gun!
        }
        ....
    }

    public void keyReleased(KeyEvent e) { //I dont really use these!
    }

    public void keyTyped(KeyEvent e) { //I dont really use these!
    }
});

More on Keys here: KeyListeners


Public and Private:

Now for Public and Private, there is already an answer on StackOVerflow which I think does the job pretty well! Here


Functions/Methods and Void:

As for Void, It is used in functions where you wish to return nothing! I do not know how well you know about functions but let me give you an example:

int sum;
public int addReturn(int x, int y){
    sum = x +y;
    return sum;
}

What this does is it adds the two ints given as x and y and then returns the sum as an integer!

With void what you can do is:

int sum;
public void add(int x, int y){
    sum = x+ y;
}

Here you return nothing but it still stores x+y into sum!

So in your class:

int Summation, x = 10, y = 10;
summation = addReturn(x,y); //<-- This will place summation = 10+10 = 20

For the void function you do not need to make a variable since it doesnt return a value, rather it sets the value within the function. All you need to do is call it

add(x,y);

If you need more help just comment! :) Also I find it awesome that your son is so interested in Java at such a young age. Great Parenting :D

Upvotes: 1

user3329098
user3329098

Reputation:

Read about java.awt.event.KeyListener

A code should look like this:

    f.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }
    });

Upvotes: 19

Tim B
Tim B

Reputation: 41188

I don't see anything in your code which actually listens for key presses or which modifies the position of x and y. The circle will only move if you change x and y and then repaint the screen.

You have set up the panel, etc here but not actually added anything to respond to user action. You will probably need to add a KeyListener somewhere to respond to key presses. This is probably either in the tutorial you are doing or in a previous or later tutorial.

Upvotes: 1

Related Questions