Keyboard input isn't working

I have a very simple game which consists of nothing but a blue rectangle (the paddle) against a red background. The program is made up of three classes: Game, Paddle, and Input. The input allows for both mouse and keyboard functionality, but for some reason only the mouse input is working, not the keyboard. I’ve reviewed the code several times and can’t figure out what is causing the problem. Can anyone check my code and tell me what I’m doing wrong?


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Game extends JPanel implements Runnable {
	
	private static final long serialVersionUID = 1L;
	
	private Image dbImage;
	private Graphics dbG;
	
	static Thread thread;
	
	public static final int APPLICATION_WIDTH = 400;
	public static final int APPLICATION_HEIGHT = 300;
	
	private Input input;
	private Paddle player;
	
	public Game() {
		Dimension size = new Dimension(APPLICATION_WIDTH, APPLICATION_HEIGHT);
		setSize(size);
		setPreferredSize(size);
		setFocusable(true);
		
		input = new Input();
		addKeyListener(input);
		addMouseMotionListener(input);
		
		thread = new Thread(this);
		
		player = new Paddle(50, 250);
	}

	@Override
	public void run() {
		while(true) {
			player.update();
			repaint();
			try {
				Thread.sleep(17);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
	
	public void update (Graphics g) {
		dbImage = createImage(APPLICATION_WIDTH, APPLICATION_HEIGHT);
		dbG = dbImage.getGraphics();
		paint(dbG);
		dbG.drawImage(dbImage, 0, 0, this);
		
	}

	public void paintComponent (Graphics g) {
		super.paintComponent(g);	
		g.setColor(Color.red);
		g.fillRect(0, 0, APPLICATION_WIDTH, APPLICATION_HEIGHT);
		player.paintComponent(g);	
	}
	
	public static void main(String args[]) {
		Game g = new Game();
		thread.start();
		JFrame frame = new JFrame();
		frame.setResizable(false);
		frame.add(g);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
}


import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class Input extends KeyAdapter implements MouseMotionListener {
	
	private static boolean[] keys = new boolean[2 << 16];
	private static int mx;

	public void keyPressed(KeyEvent e) {
		keys[e.getKeyCode()] = true;
	}

	public void keyReleased(KeyEvent e) {
		keys[e.getKeyCode()] = false;
	}
	
	public void mouseDragged(MouseEvent e) {
		
	}

	public void mouseMoved(MouseEvent e) {
		mx = e.getX();
	}
	
	public static boolean isKeyPressed(int keycode) {
		return keys[keycode];
	}
	
	public static int getMX() {
		return mx;
	}
}


import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;

public class Paddle {
	
	private int x, y;
	private final int WIDTH = 100;
	private final int HEIGHT = 10;
	
	public Paddle(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void update() {
		x = Input.getMX();
		
		if (Input.isKeyPressed(KeyEvent.VK_LEFT))
			x -= 10;        
		if (Input.isKeyPressed(KeyEvent.VK_RIGHT))
			x += 10; 	
		
	}
	
	public void paintComponent(Graphics g) {
		g.setColor(Color.blue);
		g.fillRect(x, y, WIDTH, HEIGHT);
	}
}


Not sure what you exactly mean by not working, but i would think assigning the VK value to mx on keyPressed would cause a problem. Example: on a left arrow you are assigning VK_LEFT (0x25) to mx then on update you are assigning mx to x and then subtracting 60, you will always get the same result. Or am I missing something?

I guess what I want is to allow the user to control the paddle with either the mouse or the keyboard.

Try adding a setFocusable(true) after the addKeyListener(…) and addMouseMotionListener(…)

Didn’t work.

Your problem now is that you are resetting x to mx every update. Mx is the current mouse position, that’s why when you let go of the left or right arrow keys the paddle returns to it’s previous position(mx).

How can I resolve this?

You could create moveRight and moveLeft methods that the player update method could call. If you press the left arrow call moveLeft, or if the mouse current position is less than the previous position call moveLeft, for example.

Still have the same problem

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;

public class Paddle {
	
	private int x, y;
	private final int WIDTH = 100;
	private final int HEIGHT = 10;
	
	public Paddle(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void update() {
		
		x = Input.getMX();
		
		if (Input.isKeyPressed(KeyEvent.VK_LEFT)) 
			moveLeft();  
			
		if (Input.isKeyPressed(KeyEvent.VK_RIGHT))
			moveRight(); 		
		
	}

	public void moveLeft() {
		x -= 10;
	}
	
	public void moveRight() {
		x += 10;
	}
	
	public void paintComponent(Graphics g) {
		g.setColor(Color.blue);
		g.fillRect(x, y, WIDTH, HEIGHT);
	}
}

I’d rather you figure it out yourself so, figure out how to make the mouse trigger the move methods, and quit assigning mx to x. Use mx to figure out which way you need to move the paddle.

I’m with him on having you figure it out on your own. I know these things can be difficult when you’re starting out, but your issue is one of logic. You’re going about it the wrong way. Basically, you’re making the x of the paddle moot. Currently, the actual position of the paddle is entirely reliant on the mouse. Think in relative terms instead of the absolute position of the mouse. Draw it out on paper, write down your thought process. Use a piece of paper and move it your your hand. Whatever will help you get past this. Figuring out this simple issue is very important for your growth as a programmer.

You’ve made a mistake and that’s a good thing. Right now you have something that does not work. So now you’re going to either find the correct solution or make another mistake. Eventually with enough mistakes you WILL figure it out. Keep posting your progress even if it still doesn’t work. We’ll help guide you. When you solve it on your own, it’s something you won’t forget. And it’ll feel very good.

Thank you bitbytebytes and ryukujinishi. I’ll keep at it and let you guys know how it goes.

Did it! I simply set the value of mx in both the moveLeft and moveRight functions! What do you guys think?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;

public class Paddle {
	
	private int x, y;
	private final int WIDTH = 100;
	private final int HEIGHT = 10;
	
	public Paddle(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void update() {
		
		x = Input.getMX();
		
		
		if (Input.isKeyPressed(KeyEvent.VK_LEFT)) 
			moveLeft();  
			
		if (Input.isKeyPressed(KeyEvent.VK_RIGHT))
			moveRight(); 		
		
	}

	public void moveLeft() {
		x -= 10;
		Input.setMx(x);
	}
	
	public void moveRight() {
		x += 10;
		Input.setMx(x);
	}
	
	public void paintComponent(Graphics g) {
		g.setColor(Color.blue);
		g.fillRect(x, y, WIDTH, HEIGHT);
	}
}