简体   繁体   中英

Moving Shapes With KeyListener In Java

I'm trying to write a program that allows a user to move a shape with arrow keys and change its color with the enter key. I wasn't taught anything about GUIs or event-based programming, so this is my first experience with any of that. I think I understand the basics of it, but I'm having trouble just finishing the syntax to make everything run. The tutorials I find online use timers, which I'm not using. Here's my current code:

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

public class Lab15Panel extends JPanel
{
    Color[] colors = new Color[]{Color.blue, Color.green, Color.red, Color.orange, Color.yellow};
    int initialX = 90;
    int initialY = 80;

public void paintComponent(Graphics g)
{
    super.paintComponent(g);

    g.setColor(colors[0]);


    g.fillRect(initialX, initialY, 100, 100);


    Lab15Key listen = new Lab15Key();

}

private class Lab15Key implements KeyListener
{
    @Override
    public void keyTyped(KeyEvent event)
    {
        if (event.getKeyChar() == KeyEvent.VK_LEFT)
        {
            initialX++;
        }
    }

    @Override
    public void keyReleased(KeyEvent event)
    {}

    @Override
    public void keyPressed(KeyEvent event)
    {}
}

}

I make my frame in a different class. Right now I'm unsure of two things: 1. How do I use addKeyListener with the filled shape? Is there a way to refer to the filled shape? 2. Is my idea of "moving" the shape correct? That is, creating variables outside of the methods for the position of the shape and then using my KeyEvents to change those numbers? Or will the shape not be moved in this case? (Note I've only written the code for the up key event.)

Any help you can give me would be appreciated. I'm definitely a Java novice, and I'm just trying to understand these basic concepts but the resources I have aren't helping.

You need to add your KeyListener to your panel to actually make it listen for key presses. This is known as registering the listener. I would put it in the constructor:

public Lab15Panel()
{
    Lab15Key listen = new Lab15Key();
    this.addKeyListener(listen);
}

Without this step, you are creating the listener, but it has nobody to tell when it hears something.

If you just want your panel to get repainted each time the key gets pressed, then you could do something like this in your KeyListener:

@Override
public void keyTyped(KeyEvent event)
{
    if (event.getKeyChar() == KeyEvent.VK_LEFT)
    {
        initialX++;
    }
    Lab15Panel.this.repaint(); // Calls repaint on the instance of the enclosing class
}

There are a number of issues working against you...

  1. You've not registered the KeyListener with the component, so it will never receive key events
  2. You don't repaint the panel when you change the state of the rectangle, remember, Swing uses a passive painting algorithm, so it only paints the UI when it thinks it needs to. You need to give Swing a nudge by calling repaint
  3. Your component isn't focusable, meaning that even if you did the other two things, you'd probably still not get it it work.

KeyListener is a pain, it will only be triggered of the component it is attached to IS focusable AND HAS focus, generally, you are better off use Key Bindings

See How to use key bindings for more details

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM