简体   繁体   English

如何使用KeyListener在JFrame中移动矩形?

[英]How to move a rectangle in a JFrame using KeyListener?

I'm trying to move a rectangle I've created (actually, I'm changing X and Y variables I've created) in a JFrame using a KeyListener. 我正在尝试使用KeyListener在JFrame中移动创建的矩形(实际上,我正在更改创建的X和Y变量)。 I'd like to state that I do not wish to use keybindings. 我想声明我希望使用键绑定。 I would like to use a KeyListener. 我想使用KeyListener。 That being said, I can't seem to find anything wrong with my logic here. 话虽如此,我似乎在这里找不到我的逻辑有什么问题。

Frame (Main) class: 框架(主)类:

import java.awt.Color;
import javax.swing.JFrame;

@SuppressWarnings ("serial")
public class GameFrame extends JFrame
{
    public static void main (String[] args)
    {
        JFrame frame = new JFrame ("Java Game");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setSize (1000, 600);
        frame.getContentPane().setBackground (Color.WHITE);
        frame.getContentPane().add (new GamePaint());
        frame.addKeyListener (new GameController());
        frame.setVisible (true);
    }
}

Paint class: 油漆类:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;

@SuppressWarnings ("serial")
public class GamePaint extends JComponent
{
    public int x;
    public int y;

    public void paintComponent (Graphics graphics)
    {
        super.paintComponent (graphics);
        graphics.setColor (Color.BLACK);
        graphics.fillRect (x, y, 100, 100);
    }
}

Controller class: 控制器类:

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GameController implements KeyListener
{
    GamePaint paint = new GamePaint();

    public void keyPressed (KeyEvent event)
    {
        if (event.getKeyCode() == KeyEvent.VK_LEFT)
        {
            paint.x--;
            paint.repaint();
        }
        else if (event.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            paint.x++;
            paint.repaint();
        }
    }

    public void keyReleased (KeyEvent event) {}
    public void keyTyped (KeyEvent event) {}
}

You're creating multiple instances of GamePaint ... 您正在创建GamePaint多个实例...

frame.getContentPane().add (new GamePaint());

And

public class GameController implements KeyListener
{
    GamePaint paint = new GamePaint();

So when you GameController controller tries to change the x / y positions of the rectangle, it's not interacting with the instance of GamePaint which is actually on the screen... 因此,当您的GameController控制器尝试更改矩形的x / y位置时,它不会与实际上在屏幕上的GamePaint实例进行交互...

Instead, create a single instance of GamePaint , add this to the frame and pass a reference to the GameController 而是创建一个GamePaint实例,将其添加到框架中,并将引用传递给GameController

GamePaint gp = new GamePaint();
frame.getContentPane().add (gp);
frame.addKeyListener (new GameController(gp));

And update the GameController ... 并更新GameController ...

public class GameController implements KeyListener
{
    private GamePaint paint;
    public GameController(GamePaint paint) {
        this.paint = paint;

But this approach is bunch of weirdness...isn't GamePaint suppose to be receiving keyboard input and not the frame?? 但是这种方法GamePaint怪异... GamePaint是否应该接收键盘输入而不是框架输入?

Instead, consider using the key bindings API, it solves so many other issues associated with KeyListener . 相反,可以考虑使用键绑定API,它可以解决与KeyListener相关的许多其他问题。 See How to Use Key Bindings for more details 有关更多详细信息,请参见如何使用键绑定

Instead of the controller modifying the x / y properties directly, it should be calling a method on the GamePaint class (something like, moveLeft , moveRight etc...), this way GamePaint can make the decisions about what that means... 代替控制器直接修改x / y属性,它应该在GamePaint类上调用一个方法(诸如moveLeftmoveRight等...),这样GamePaint可以做出关于这意味着什么的决定...

But, personally, I'd inject a model in there, which controlled the location of entities and which the GamePaint simply painted and the controller controlled...but that's me... 但是,就我个人而言,我将在其中注入一个模型,该模型控制实体的位置,并简单地绘制GamePaint控制器控制...但这就是我...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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