简体   繁体   English

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

[英]How do I guarantee that a Java Swing JDialog will maintain focus and register all key presses in game?

I am making a game. 我在做游戏。 It uses a jDialog because one Stack Overflow question said I had to use a modal jDialog to always be in focus. 它使用jDialog,因为一个堆栈溢出问题说我必须使用模式jDialog才能始终保持焦点。 My jDialog has an outgoing chat field and a game window. 我的jDialog有一个外向聊天字段和一个游戏窗口。 The game window is a jPanel, the field a jTextField. 游戏窗口是jPanel,字段是jTextField。 When I press the arrow keys, I want that to go to the jPanel. 当我按箭头键时,我希望它转到jPanel。 When I type on the keyboard, I want that to go to the jTextField. 当我在键盘上键入内容时,我希望它转到jTextField。 When I press enter, I want the jTextField to clear. 当我按Enter键时,我希望清除jTextField。 I do not want to click on the jTextField to make it in focus to type stuff in it and then click on the game screen to to move again. 我不想单击jTextField使其成为焦点以在其中键入内容,然后在游戏屏幕上单击以再次移动。

My code looks like this: 我的代码如下所示:

/* 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);
            }
        });
    }
});

Constructor: 构造函数:

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.");
    }
}

One of the other StackOverflow questions told me that if I use a jDialog and make it modal, then it will maintain focus, but when I do: 其他StackOverflow问题之一告诉我,如果我使用jDialog并将其设置为模态,则它将保持焦点,但是当我这样做时:

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

It crashes and prints "JDialog must always be in focus." 它崩溃并打印“ JDialog必须始终在焦点上。”

Even when I don't crash the program, none of the key presses will register in my jDialog's key listener. 即使当我不崩溃程序时,也不会在我的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);
}

... ...

Mouse presses register, and button presses register, but the key presses won't register. 鼠标按下注册,按钮按下注册,但是按键不会注册。 I even have a I want the focus to be on the frame and the frame to modify its components based on what keys are pressed rather than having one of the components hog all the key input from the other components. 我什至希望将焦点放在框架上,并且框架可以根据按下的键来修改其组件,而不是让其中一个组件占用其他组件的所有键输入。 How do I fix this? 我该如何解决?

There is also a formWindowFocused listener that goes off when I run the program, but my jDialog's formFocusGained listener does not. 当我运行程序时,还有一个formWindowFocused侦听器会关闭,但jDialog的formFocusGained侦听器不会关闭。

KeyEvents are dispatched to the component that has focus, so using a KeyListener is not a good solution. KeyEvent被调度到具有焦点的组件,因此使用KeyListener不是一个好的解决方案。

For more flexibility in handling KeyStrokes you need to use Key Bindings . 为了更灵活地处理KeyStroke,您需要使用Key Bindings You can map a KeyStroke to an Action even when a component doesn't have focus. 即使组件没有焦点,也可以将KeyStroke映射到Action

Read the section from the Swing tutorial on How to Use Key Bindings for more information and examples. 阅读Swing教程中有关如何使用键绑定的部分, 获取更多信息和示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM