如何将 KeyListener 与 JFrame 一起使用?

2022-09-03 06:29:04

所以,我试图用()使矩形移动,每当我尝试按键时,矩形都不会移动。KeyEventKeyListener

矩形被绘制,但每当我按和键时,没有任何反应。我有两个类,一个是我的主类,带有keyEvents和frame,另一个,绘制矩形并持有移动矩形的函数。leftright

这是我的代码:

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

import javax.swing.JFrame;


public class mainFrame extends JFrame implements KeyListener{

mainDraw Draw = new mainDraw();

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if(key == KeyEvent.VK_D){

        Draw.moveRight();
    }
}

public void keyReleased(KeyEvent e) {


}
public void keyTyped(KeyEvent e) {}

public mainFrame()
{
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
}

public static void main(String[] args) {

    mainFrame M1 = new mainFrame();

    mainDraw Draw = new mainDraw();

    JFrame frame = new JFrame("Square Move Practice");


    //frame
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setSize(600, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(Draw);

}
}

现在是第二类:

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JComponent;

public class mainDraw extends JComponent{

public int x = 50;
public int y = 50;

public void paint(Graphics g){

    g.drawRect(x, y, 50, 50);
    g.fillRect(x, y, 50, 50);
    g.setColor(Color.BLACK);
}

public void moveRight()
{
    x = x + 5;
    y = y + 0;
    repaint();
}

}

请告诉我如何移动矩形。提前致谢!


答案 1

矩形未移动,因为您未正确使用。您必须分配 到 而不是忽略实例化的对象。JFrameframenew mainFrame()mainFrame

正如@MadProgrammer所指出的,还有其他几个问题。

以下是修复某些问题的代码:

大型机.java

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;


public class mainFrame extends JFrame implements KeyListener{
    private mainDraw draw;

    public void keyPressed(KeyEvent e) {
        System.out.println("keyPressed");
    }

    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode()== KeyEvent.VK_RIGHT)
            draw.moveRight();
        else if(e.getKeyCode()== KeyEvent.VK_LEFT)
            draw.moveLeft();
        else if(e.getKeyCode()== KeyEvent.VK_DOWN)
            draw.moveDown();
        else if(e.getKeyCode()== KeyEvent.VK_UP)
            draw.moveUp();

    }
    public void keyTyped(KeyEvent e) {
        System.out.println("keyTyped");
    }

    public mainFrame(){
        this.draw=new mainDraw();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                mainFrame frame = new mainFrame();
                frame.setTitle("Square Move Practice");
                frame.setResizable(false);
                frame.setSize(600, 600);
                frame.setMinimumSize(new Dimension(600, 600));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().add(frame.draw);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

主抽奖.java

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

public class mainDraw extends JComponent {

    public int x = 50;
    public int y = 50;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawRect(x, y, 50, 50);
        g.fillRect(x, y, 50, 50);
        g.setColor(Color.BLACK);
    }

    public void moveRight() {
        x = x + 5;
        repaint();
    }

    public void moveLeft() {
        x = x - 5;
        repaint();
    }

    public void moveDown() {
        y = y + 5;
        repaint();
    }

    public void moveUp() {
        y = y - 5;
        repaint();
    }
}

顺便说一句,用于放置 gui 更新代码,因为 swing 对象不是线程安全的。SwingUtilities


答案 2

至少有三个问题...

首先。。。

来自 的类,但在您的方法中,通过创建自己的 .mainFrameextendsJFramemainJFrame

已注册到 的实例,这意味着,它已被忽略。KeyListenermainFrame

你应该摆脱,因为它只是混淆了这个问题extends JFrame

其次。。。

KeyListener仅当注册到的组件是可聚焦的并且具有直接焦点时,才会响应关键事件,这使得它不可靠。

相反,您应该在面板中使用键绑定API,这将允许您克服焦点问题。Draw

第三。。。

您已经打破了油漆链,这意味着当矩形移动时,以前绘制的内容仍将保留。

您应避免覆盖,而应使用 .造成这种情况的原因有很多,但通常,它在后台绘制,被称为子组件的更新。paintpaintComponent

最后,确保在做其他任何事情之前打电话,以确保上下文为绘画做好准备super.paintComponentGraphics

查看执行自定义绘画了解更多详情


推荐