如何根据方向键调整charaposx/y101数值(步长60)及解决调用报错
问题描述
希望在JFrame运行时,通过方向键调整MainFrame类中charaposx101或charaposy101的数值(按方向键时±60),但调用自定义方法时一直报错。相关代码片段如下:
MainFrame类代码
class MainFrame extends JComponent { public int charaposx101=0; public int charaposy101=0; }
Main类代码
public class Main { public static void main(String[] args) { JFrame Frame = new JFrame("game"); Frame.setSize(675, 700); Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Frame.getContentPane().add(new MainFrame ()); Frame.setVisible(true); Frame.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_UP) { System.out.println("Up Arrrow-Key is pressed!"); } else if (keyCode == KeyEvent.VK_DOWN) { System.out.println("Down Arrrow-Key is pressed!"); } else if (keyCode == KeyEvent.VK_LEFT) { System.out.println("Left Arrrow-Key is pressed!"); } else if (keyCode == KeyEvent.VK_RIGHT) { System.out.println("Right Arrrow-Key is pressed!"); } } }); } }
尝试在MainFrame中添加changeCharPos方法,但调用时报错:
Frame.changeCharPos() //or MainFrame.changeCharPos() //or Main.changeCharPos()
解决方案
1. 方法调用报错的原因
你报错的核心问题是:
Frame是JFrame对象,本身没有changeCharPos方法,直接调用无效;MainFrame.changeCharPos()是试图调用静态方法,但你定义的是实例方法,必须通过MainFrame的对象调用;Main类中不存在该方法,因此Main.changeCharPos()也不成立。
正确做法是先保存MainFrame的实例引用,再在键盘监听器中调用该实例的方法或修改属性。
2. 完整实现代码
修改后的MainFrame类
可以封装位置调整方法(更符合面向对象规范),也可以后续直接修改属性:
class MainFrame extends JComponent { // 建议改为private,通过方法修改,符合封装原则 private int charaposx101 = 0; private int charaposy101 = 0; // 封装方向移动方法 public void moveUp() { charaposy101 -= 60; repaint(); // 修改位置后刷新画面 } public void moveDown() { charaposy101 += 60; repaint(); } public void moveLeft() { charaposx101 -= 60; repaint(); } public void moveRight() { charaposx101 += 60; repaint(); } // 提供获取位置的方法,用于验证 public int getCharaposx101() { return charaposx101; } public int getCharaposy101() { return charaposy101; } }
修改后的Main类
关键是保存MainFrame实例,并在键盘监听器中调用其方法:
import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JComponent; import javax.swing.JFrame; public class Main { public static void main(String[] args) { JFrame frame = new JFrame("game"); frame.setSize(675, 700); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 保存MainFrame实例,而非直接new后添加 MainFrame gamePanel = new MainFrame(); frame.getContentPane().add(gamePanel); frame.setVisible(true); // 确保JFrame获取焦点,否则键盘事件可能不响应 frame.setFocusable(true); frame.requestFocusInWindow(); frame.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_UP: System.out.println("Up Arrow-Key is pressed!"); gamePanel.moveUp(); break; case KeyEvent.VK_DOWN: System.out.println("Down Arrow-Key is pressed!"); gamePanel.moveDown(); break; case KeyEvent.VK_LEFT: System.out.println("Left Arrow-Key is pressed!"); gamePanel.moveLeft(); break; case KeyEvent.VK_RIGHT: System.out.println("Right Arrow-Key is pressed!"); gamePanel.moveRight(); break; } // 打印当前位置验证效果 System.out.println("当前位置:x=" + gamePanel.getCharaposx101() + ", y=" + gamePanel.getCharaposy101()); } }); } }
3. 额外注意事项
- 如果需要在界面上绘制角色,需在
MainFrame中重写paintComponent方法,使用charaposx101和charaposy101确定绘制位置; KeyListener依赖焦点,代码中已添加setFocusable(true)和requestFocusInWindow()确保JFrame能接收键盘事件;- 尽量避免使用
public成员变量,通过封装方法修改状态,降低代码耦合度。
内容的提问来源于stack exchange,提问作者Trish Huff
相关产品推荐
相关产品推荐

