我正在制作一个游戏。它使用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的侦听器不会关闭。
KeyEvents被分派到具有焦点的组件,因此使用KeyListener不是一个好的解决方案。
为了更灵活地处理KeyStroke,您需要使用Key Bindings
。即使组件没有焦点,您也可以将KeyStroke
映射到Action
。
有关详细信息和示例,请阅读Swing教程中有关如何使用键绑定的部分。