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

如何根据方向键调整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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:47:25