提问者:小点点

我如何保证JavaSwing JDialog将保持焦点并注册游戏中的所有按键?


我正在制作一个游戏。它使用jDialog,因为一个Stack Overflow问题说我必须使用模态jDialog才能始终保持焦点。我的jDialog有一个传出的聊天字段和一个游戏窗口。游戏窗口是一个jPanel,字段是一个jTextField。当我按下箭头键时,我希望它进入jPanel。当我在键盘上键入时,我希望它进入jTextField。当我按回车键时,我希望jTextField清除。我不想点击jTextField以使其成为焦点,在其中键入内容,然后单击游戏屏幕以再次移动。

我的代码如下所示:

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        jDialog_GUI.singleton_ = new jDialog_GUI(new javax.swing.JFrame(), true);
        singleton_.requestFocusInWindow();
        singleton_.setVisible(true);
        singleton_.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent e) {
                System.exit(0);
            }
        });
    }
});

构造函数:

public jDialog_GUI(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents(); // initializes all the components using Swing GUI builder code
    this.setModalityType(jDialog_GUI.ModalityType.APPLICATION_MODAL);
    if (this.getModalityType() != jDialog_GUI.ModalityType.APPLICATION_MODAL) {
        RunGame.printStackTraceAndCrashTheProgramBecause("Not modal.");
    }
}

另一个StackOverflow问题告诉我,如果我使用jDialog并使其模态化,那么它将保持焦点,但当我这样做时:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        if(! jDialog_GUI.get_GUI().isFocusOwner() ) {
            RunGame.printStackTraceAndCrashTheProgramBecause("JDialog must always be in focus.");
        }
    }
});

它崩溃并打印“JDialog必须始终处于焦点”。

即使我没有使程序崩溃,也没有任何按键会在我的jDialog的按键侦听器中注册。

addKeyListener(new java.awt.event.KeyAdapter() {
    public void keyPressed(java.awt.event.KeyEvent evt) {
        formKeyPressed(evt);
    }
    public void keyTyped(java.awt.event.KeyEvent evt) {
        formKeyTyped(evt);
    }
});

...

private void formKeyPressed(java.awt.event.KeyEvent evt) {     
    int keyCode = evt.getKeyCode();
    System.out.println(keyCode + " " + KeyEvent.getKeyText(keyCode));
}      
private void formKeyTyped(java.awt.event.KeyEvent evt) {
    char c = evt.getKeyChar();
    System.out.println(c);
}

...

鼠标按下注册,按钮按下注册,但按键按下不会注册。我甚至有一个我希望焦点在框架上,框架根据按下的键来修改其组件,而不是让其中一个组件占用其他组件的所有键输入。我该如何解决这个问题?

当我运行程序时,还有一个formWindowFORECOED侦听器会关闭,但我的jDialog的formFocus usG的侦听器不会关闭。


共1个答案

匿名用户

KeyEvents被分派到具有焦点的组件,因此使用KeyListener不是一个好的解决方案。

为了更灵活地处理KeyStroke,您需要使用Key Bindings。即使组件没有焦点,您也可以将KeyStroke映射到Action

有关详细信息和示例,请阅读Swing教程中有关如何使用键绑定的部分。