What's wrong with my KeyListener?

I’m trying to get a simple rectangle moving around on my JPanel.

everything is set up except for the fact the rectangle doesn’t respond to the keys.

package game;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.*;

@SuppressWarnings("serial")
public class Main extends JPanel implements KeyListener, ActionListener {
	
	private final int frameHeight = 400;
	private final int frameWidth = 400;
	private int objectDimension = 15;
	
	JMenuBar menuBar;
	JMenu file;
	JMenuItem newGame;
	JMenuItem checkScore;
	JMenuItem endGame;
	
	int objectX = 150;
	int objectY = 150;
	
	int velX = 0; // speed object moves X axis
	int velY = 0; // speed object moves Y axis
	
	// CONSTRUCTOR
	public Main() {
		
		//JMenuBar
		menuBar = new JMenuBar();
		file = new JMenu("File");
		newGame = new JMenuItem("New Game");
		checkScore = new JMenuItem("Check Score");
		endGame = new JMenuItem("End Game");
		
		menuBar.add(file);
		file.add(newGame);
		file.add(checkScore);
		file.addSeparator();
		file.add(endGame);
		
		
		addKeyListener(this);
		setFocusable(true);
		setFocusTraversalKeysEnabled(false);
	}
		
	public JMenuBar setJMenuBar(){
		return menuBar;
	}
	
	// SETS SIZE FOR FRAME
	   @Override
	   public Dimension getPreferredSize() {
	      return new Dimension(frameWidth, frameHeight);
	   }
	
	//PAINTCOMPONENT	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.fillRect(objectX, objectY, objectDimension, objectDimension);
		
		
	}
	
	public void actionPerformed(ActionEvent e){
		objectX = objectX + velX;
		objectY = objectY + velY;
		
		repaint();
	}
	
	public void keyPressed(KeyEvent e){
		int key = e.getKeyCode();
		
		if(key == KeyEvent.VK_LEFT){
			velX = -1;
			velY = 0;
		}
		if(key == KeyEvent.VK_UP){
			velY = -1;
			velX = 0;
		}
		if(key == KeyEvent.VK_RIGHT){
			velX = +1;
			velY = 0;
		}
		if(key == KeyEvent.VK_DOWN){
			velY = +1;
			velX = 0;
		}
	}
	
	public void keyReleased(KeyEvent e){}
	public void keyTyped(KeyEvent e){}
			
	
	
	public static void createAndShowGui() {
		Main main = new Main();
		
		JFrame frame = new JFrame("My New Game!");
		frame.getContentPane().add(main);
		frame.setJMenuBar(main.setJMenuBar());
		frame.pack();
		frame.setVisible(true);
		
	}
	
	// MAIN METHOD
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				createAndShowGui();
			}
		});	
	}
	
}

any suggestions of where I’m going wrong?

 menuBar = new JMenuBar();
      file = new JMenu("File");
      newGame = new JMenuItem("New Game");
      checkScore = new JMenuItem("Check Score");
      endGame = new JMenuItem("End Game");
      
      menuBar.add(file);
      file.add(newGame);
      file.add(checkScore);
      file.addSeparator();
      file.add(endGame);
      
      this.add(menuBar); // Try this?
      
      addKeyListener(this);
      setFocusable(true);
      setFocusTraversalKeysEnabled(false);
   }

I don’t think it’s a problem with your key listener, the action listener is the problem - it will never get invoked as far as I can tell since none of the components are generating events that will update the position and repaint the component.

Either move the update/repaint code into your key handler or add some component that will generate an ActionEvent, i.e. a button or your menu.

hi StrideColossus,
you were right about it being the ActionListener.
I added the repaint to the keyhandler with still nothing happening.

but I added commands for my JMenuBar and the rectangle responds when I click something in the JMenuBar.

I’m confused about what I can use in the actionPerformed that will update everything I press one of the assigned keys…

Any suggestion?

I’m afraid you’re pushing the limits of my meagre AWT/SWING knowledge - I’m surprised what you tried didn’t work, anybody else shed any light?

  1. your actionlistener hasn’t been added to anything (timer, button, etc.)
  2. how do you want motion to work? it it’s current state, your square will keep going whichever direction was last pressed.

put

 Timer t = new Timer(100, this);
      t.start();

at the end of your constructor

Deepthought, that worked perfectly.
Could I get a quick explanation on exactly what its doing?

I will add the keyReleased commands to set everything back to 0

your main class implemented an Actionlistener, which would have worked. However, you did not add it to anything that can call actionperformed.

the timer class takes a constructor Timer(delay,actionlistener);
start() starts the timer.
you can use different values in delay for different framerates.

I would recommend a different approach besides swing/java2d for games, but if you’ve just started learning, it’s as good a place to start as any.

Thanks for the help.
I’m just starting, but if there’s a better way to go about it, I’d prefer to start off that way?