gpt4 book ai didi

java - JPanel 不想聚焦所以 KeyAdapter 不起作用

转载 作者:行者123 更新时间:2023-11-29 05:23:14 25 4
gpt4 key购买 nike

背景

我有一个简单的游戏。我有一个 JPanel 类,里面什么都有(菜单、游戏、游戏结束)。

然后我决定,我应该让我的游戏更好,我制作了两个面板(一个用于菜单,第二个用于游戏等级)。

一切都很好,但是我的 KeyAdapter 类在我的 JPanel 上不起作用。我不知道为什么它不想聚焦。

这就是我所拥有的:

  • 扩展 JFrame 的主类,在这里我添加了我的面板(和 KeyListener 到第一个面板)

    public class JavaGame2 extends JFrame {

    public JavaGame2(){
    gamePanel = new GamePanel();
    menuPanel = new MenuPanel();
    setContentPane(menuPanel);

    menuPanel.addKeyListener(new KeyListener() {

    @Override
    public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP) {
    menuPanel.changeCursor();
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    menuPanel.changeCursor();
    }
    if (menuPanel.getCursorPos()==1){
    if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {

    setContentPane(gamePanel);
    //add(gamePanel);
    }
    }
    else{
    if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
    System.exit(0);
    }
    }
    }

    });
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(800, 600);
    setLocationRelativeTo(null);
    setTitle("JavaGame2");
    setResizable(false);
    }
    public static void main(String[] args) {
    JFrame jgame = new JavaGame2();
    jgame.setVisible(true);
    }
    }
  • MenuPanel 类扩展 JPanel

    public class MenuPanel extends JPanel implements ActionListener{

    public MenuPanel(){
    setFocusable(true);
    setBackground(Color.BLACK);
    setDoubleBuffered(true);
    setSize(800,600);
    }
    public void actionPerformed(ActionEvent e) {
    }
    }
  • 这里是 GamePanel

    public class GamePanel extends JPanel implements ActionListener{

    public GamePanel (){
    addKeyListener(new GameAdapter());
    setFocusable(true);
    requestFocus();
    setBackground(Color.BLACK);
    setDoubleBuffered(true);
    setSize(800,600);
    }

    private class GameAdapter extends KeyAdapter{

    public void keyReleased(KeyEvent e) {
    ship.keyReleased(e);
    }

    public void keyPressed(KeyEvent e) {
    ship.keyPressed(e);
    }
    }
    }

这是行不通的。 GamePanel 不想集中注意力,我试图做我阅读的每一件事。我想你会说 JPanel 不是可聚焦的组件。但是当有一个面板时,它以某种方式工作。

如何解决这个焦点问题?也许您会说您不喜欢使用 KeyAdapter,但我认为它在我的代码中看起来相当不错。

setFocusable()?或者 requestFocus()requestFocusInWindow()?我应该如何使用它们?也许我之前有错误,这不是我的第一个问题?

提前致谢。

感谢编辑。

最佳答案

简答,使用key bindings API , 它允许您控制组件在触发关键事件之前所需的关注级别。

更长的答案, Activity 面板需要有键盘焦点。您可以使用 requestFocusInWindow,但不能保证组件会真正获得焦点。何时调用它是一件棘手的事情。您可以尝试覆盖面板的 addNotify 并调用到那里,只要确保您先调用 super.addNotify ,当您不这样做时会发生奇怪的事情

你还需要考虑如果组件失去焦点会发生什么

作为旁注:

  • setDoubleBuffered(true); 是无关紧要的,因为默认情况下 Swing 组件是双缓冲的。如果您想打印组件,通常可以禁用此功能。不过这样称呼也无妨
  • 在您的组件上调用setSize 是无关紧要的,因为您的组件将处于布局管理器的控制之下,这将决定组件本身的大小。您最好覆盖 getPreferredSize 并为布局管理器返回适当的大小
  • JFrame 上调用setSize 也是一个坏主意。框架有边框,这意味着您的可视区域将是 框架大小 - 框架边框插入,这将小于您指定的 800x600。最好利用前面的注释并在 JFrame 上调用 pack,这将围绕内容打包框架,使其满足内容要求...
  • 就个人而言,我也会将 KeyListener 本地化到实际组件本身,这允许组件充当它自己的 Controller ,使其更便携...恕我直言

更新了 Controller 的想法...

一个“真正”简化的概念是拥有某种“ Controller ”,菜单和游戏面板可以通过它进行通信,例如......

public interface GameController {
public void showMenu();
public void showGame();
}

然后您可以将此接口(interface)的引用传递给 MenuPanel...

public class MenuPanel extends JPanel implements ActionListener{

public MenuPanel(GameController controller){
//...
}

public Dimension getPreferredSize() {
return new Dimension(800, 600);
}

还有游戏面板...

public class GamePanel extends JPanel implements ActionListener{

public GamePanel (GameController controller){
//...
}

public Dimension getPreferredSize() {
return new Dimension(800, 600);
}

显然,您需要构建 Controller 的实现...

public class CardLayoutGameController implements GameController {
public static final String GAME_PANEL = "GamePanel";
public static final String MENU_PANEL = "MenuPanel";

private Container container;
private CardLayout cardLayout;

public CardLayoutGameController(Container parent, CardLayout layout) {
container = parent;
cardLayout = layout;
}

public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}

public void showGame() {
cardLayout.show(container, GAME_PANEL);
}
}

然后您将围绕这个 Controller 构建您的 UI,例如...

public class JavaGame2 extends JFrame {

public JavaGame2(){
CardLayout layout = new CardLayout();
setLayout(layout);
GameController controller = new CardLayoutGameController(getContentPane(), layout);

gamePanel = new GamePanel(controller);
menuPanel = new MenuPanel(controller);

add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(menuPanel, CardLayoutGameController.MENU_PANEL);

controller.showMenu();

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setTitle("JavaGame2");
setResizable(false);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame jgame = new JavaGame2();
jgame.setVisible(true);
}
});
}
}

这只是一个帮助激发想法的“例子”吗,还没有测试过,只是在这里破解,所以它可能会爆炸:P

关于java - JPanel 不想聚焦所以 KeyAdapter 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23820556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com