You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问题:Java中KeyListener控制矩形移动功能失效

问题原因及修复方案

核心问题分析

  1. 未清除旧绘制痕迹:paintComponent方法里没调用super.paintComponent(gr),Swing无法自动清除上一次的绘制内容,新矩形会叠加在旧矩形上,视觉上看起来没移动。
  2. 无限重绘循环:在paintComponent内调用repaint()会触发持续的重绘请求,既浪费资源,还会干扰正常绘制逻辑。
  3. 焦点隐患:JPanel默认可能没获得键盘焦点,虽然当前控制台能输出move值,但显式设置焦点能避免后续事件接收异常。

修复后的代码

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

public class SHOWHITBOX extends JPanel implements KeyListener{

    int move = 0;

    public SHOWHITBOX(){
        setFocusable(true); // 确保组件能接收键盘事件
        addKeyListener(this);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key1 = e.getKeyCode();
        if(key1 == KeyEvent.VK_RIGHT){ // 用常量替代魔法数字,提升可读性
            move += 10;
            System.out.println(move);
        }
        
        if(key1 == KeyEvent.VK_LEFT){
            move -= 10;
            System.out.println(move);
        }
        repaint(); // 修改位置后主动触发重绘
    }

    @Override
    public void keyReleased(KeyEvent arg0) {}

    @Override
    public void keyTyped(KeyEvent arg0) {}

    @Override
    public void paintComponent(Graphics gr) {
        super.paintComponent(gr); // 调用父类方法清除旧绘制内容
        gr.drawRect(move, 400, 1000, 100);
        gr.drawRect(move, 400, 100, 100);
    }
}

关键修改说明

  • 加入super.paintComponent(gr):每次重绘前清空面板旧图形,确保新矩形位置变化能正常显示。
  • 把repaint()移到keyPressed方法中:仅在位置修改后触发重绘,避免无效循环。
  • 构造方法内添加setFocusable(true)和addKeyListener(this):保证组件能获取焦点并接收键盘事件。
  • 替换数字为KeyEvent常量:避免魔法数字,让代码逻辑更清晰。

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:30:06