Java Swing创建类对象时代码崩溃,如何跨类调用repaint移动矩形
核心问题
代码崩溃的根本原因是循环实例化导致栈溢出:test类实例化test2,test2类实例化test3,test3类中又再次实例化test2,三者形成无限循环创建对象的逻辑,最终内存耗尽程序崩溃。
修复步骤
1. 解除循环依赖
删除test3类中主动实例化test2的代码,改为通过构造方法传入已经创建的test2实例。
修改后的test3构造部分:
public class test3 { public boolean down = false; public boolean up = false; public int playerXpos = 45; public int playerYpos = 300; public int playerWidth = 15; public int playerHeight = 80; Rectangle player = new Rectangle(playerXpos, playerYpos, playerWidth, playerHeight); // 仅保留test2成员变量,不主动实例化 test2 theBoard; // 新增构造方法接收外部传入的test2实例 public test3(test2 board){ this.theBoard = board; } // 其余方法保留,需要修改keyPressed中的错误逻辑 }
2. 修改test2类的实例化逻辑
创建test3实例时把当前test2对象传入,同时绑定键盘监听器,否则键盘操作不会触发响应:
public class test2 extends JPanel { public int playerScore = 0; public int opponentScore = 0; // 传入当前test2实例this初始化test3 test3 player = new test3(this); // 新增构造方法绑定监听器 public test2(){ this.addKeyListener(player); // JPanel默认不获取焦点,必须设置才能响应键盘事件 this.setFocusable(true); } // 重写paintComponent而非paint,是Swing标准绘制方法 @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; board(g); g.setColor(Color.WHITE); // 同步更新矩形坐标,否则绘制不会变化 player.player.y = player.playerYpos; g2d.fill(player.player); } public void board(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, 900, 700); } }
3. 修复键盘事件的错误逻辑
原代码中keyPressed的for循环完全冗余,且向下移动的坐标逻辑写反,修改后代码如下:
public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { playerYpos -= 20; if (playerYpos < 50) { playerYpos = 50; } theBoard.repaint(); } if (e.getKeyCode() == KeyEvent.VK_DOWN) { playerYpos += 20; // 窗口高度仅705,限制最大坐标避免移出可视区域 if (playerYpos > 600) { playerYpos = 600; } theBoard.repaint(); } }
其他优化提示
- 现有实现按一次按键移动一次,如果需要按住按键连续移动,可结合
javax.swing.Timer实现平滑位移 - 空实现的
actionPerformed方法目前无实际作用,可在添加定时器后再补充对应逻辑
内容的提问来源于stack exchange,提问作者jon doe
相关产品推荐
相关产品推荐

