This is my first time trying to use KeyListener and I just need it to move an image over 20 px every time I press the right arrow key. After 400px, it should move down to the next line vertically 'playery.' For Some reason it prints out the console output twice. I also just want to make sure my layout for everything is common and acceptable

addKeyListener (
	         new KeyListener() {
	            public void keyPressed(KeyEvent e) {
	            	System.out.println("key pressed");
	            	if (e.getKeyCode() == KeyEvent.VK_RIGHT){
	            		playerx+=20;
	            		System.out.println("playerx: "+playerx);
	            		if (playerx>400){
	            			playery+=20;
	            			playerx=0;
	            		}
	            		repaint();
	            	}
	            }
				public void keyReleased(KeyEvent arg0) {
					System.out.println("key released");
				}
				public void keyTyped(KeyEvent arg0) {
					System.out.println("key typed");
				}
	         }
	);

This is my console output:

key pressed
playerx: 20
key pressed
playerx: 40
key released
key released
key released

For some reason, one key stroke replies with 2.

I have code for a basic game I'm building. I haven't used KeyListener before and I need a player image to move over 20 pixels when an arrow key is pressed.

addKeyListener (
    		new KeyListener() {
    			public void keyPressed(KeyEvent p) {
    				System.out.println("key pressed");
    				if ((p.getKeyCode() == KeyEvent.VK_RIGHT)&&(playerx<380)){
    					playerx+=20;
    					System.out.println("playerx: "+playerx);
    					repaint();
    				}
    				if ((p.getKeyCode() == KeyEvent.VK_LEFT)&&(playerx>0)){
    					playerx-=20;
    					System.out.println("playerx: "+playerx);
    					repaint();
    				}
    				if ((p.getKeyCode() == KeyEvent.VK_UP)&&(playery>0)){
    					playery-=20;
    					System.out.println("playerx: "+playerx);
    					repaint();
    				}
    				if ((p.getKeyCode() == KeyEvent.VK_DOWN)&&(playery<400)){
    					playery+=20;
    					System.out.println("playerx: "+playerx);
    					repaint();
    				}
    			}
    			public void keyReleased(KeyEvent r) {
    				System.out.println("key released");
    			}
    			public void keyTyped(KeyEvent t) {
    				System.out.println("key typed");
    			}
    		}
    );

What I get from this with right arrow key is used twice:

key pressed
playerx: 20
key pressed
playerx: 40
key released
key released
key released
key pressed
playerx: 60
key pressed
playerx: 80
key pressed
playerx: 100
key released
key released
key released
key released

What I want:

key pressed
playerx: 40
key released
key pressed
playerx: 60
key released

Are you sure you haven't added the listener more than once? Because that is kind of what your output looks like. I don't see anything wrong with your listener code itself.

Are you sure you haven't added the listener more than once? Because that is kind of what your output looks like. I don't see anything wrong with your listener code itself.

I'm positive. I'll post the entire program if that helps, but I've looked into almost everything. I just thought it might be something to do with KeyListener itself

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.border.TitledBorder;

class GridsCanvas extends Canvas {
   int width, height;
   int rows;
   int cols;
   int playerx=0, playery=0;
   BufferedImage mob1=null, bg=null;
   ImageObserver observe = null;

   GridsCanvas(int w, int h, int r, int c) {
      setSize(width=w, height=h);
      rows = r;
      cols = c;
   }

   public void paint(Graphics g) {
      int i;
      width = getSize().width;
      height = getSize().height;
      
      try {
		mob1 = ImageIO.read(new File("mob1.png"));
		bg = ImageIO.read(new File("grid.png"));
	} catch (IOException e) {
		e.printStackTrace();
	}
	
      //grid is 20x21
      boolean wall=false;
      int NumofTiles=420;
      int x=0, y=0;

    g.drawImage(bg, 0, 0, observe);
    g.drawImage(mob1, playerx, playery, observe);

    addKeyListener (
	         new KeyListener() {
	            public void keyPressed(KeyEvent p) {
	            	System.out.println("PLAYERX 1: "+playerx);
	            	System.out.println("key pressed");
	            	if ((p.getKeyCode() == KeyEvent.VK_RIGHT)&&(playerx<380)){
	            		playerx+=20;
	            		System.out.println("playerx: "+playerx);
	            	}
	            	else if ((p.getKeyCode() == KeyEvent.VK_LEFT)&&(playerx>0)){
	            		playerx-=20;
	            		System.out.println("playerx: "+playerx);
	            	}
	            	else if ((p.getKeyCode() == KeyEvent.VK_UP)&&(playery>0)){
	            		playery-=20;
	            		System.out.println("playery: "+playery);
	            	}
	            	else if ((p.getKeyCode() == KeyEvent.VK_DOWN)&&(playery<400)){
	            		playery+=20;
	            		System.out.println("playery: "+playery);
	            	}
	            	repaint();
	            	System.out.println("PLAYERX 2: "+playerx);
	            }
				public void keyReleased(KeyEvent r) {
					System.out.println("key released");
				}
				public void keyTyped(KeyEvent t) {
					System.out.println("key typed");
				}
	         }
	);  
   }
}

/** This is the demo class. */
public class Grids extends Frame {
   /* Construct a GfxDemo2 given its title, width and height.
    * Uses a GridBagLayout to make the Canvas resize properly.
    */
	
   Grids(String title, int w, int h, int rows, int cols) {
      setTitle(title);

      // Now create a Canvas and add it to the Frame.
      GridsCanvas xyz = new GridsCanvas(w, h, rows, cols);
      add(xyz);
      setResizable(true);

        addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            setVisible(false);
            dispose();
            System.exit(0);
         }
      });

      // Normal end ... pack it up!
      pack();
   }  

   public static void main(String[] a) {
      new Grids("Grid", 500, 500, 20, 20).setVisible(true);
   }
}

EDIT: Ok, so I just added a MouseListener and a counter for number of mouseclicks. It's doubling that as well but it doesn't exponentially increase. It's always two mouse clicks when I'm actually only clicking once.

You are adding the key listener in your paint() method. Every time it gets called, you add another.

You are adding the key listener in your paint() method. Every time it gets called, you add another.

Ahhh, thank you :D I cleaned up the code a bit now and trying to figure out how to repaint(); from inside the main class for the keylistener now...

Just move the addListener() code up into the constructor. You can still call repaint() the same way.

edit: You may want to consider using Swing JFrame and JPanel classes instead of Frame and Canvas unless there is a reason you need to stick to older awt classes.

Just move the addListener() code up into the constructor. You can still call repaint() the same way.

edit: You may want to consider using Swing JFrame and JPanel classes instead of Frame and Canvas unless there is a reason you need to stick to older awt classes.

Huzzah! It's working perfectly and all the code is completely cleaned up. Thanks for your help. Darwin fish ftw

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.