我目前有一个非常简单的游戏,您可以使用箭头键从一侧移动到另一侧。我的问题是,无论何时按下alt键(主要是偶然),游戏窗口都会失去焦点,并且不再回复箭头键。如果我再次按下alt,重新获得焦点,但如果矩形已经运动,它将继续不停。 我正在使用这些渲染和更新方法btw。
有没有办法阻止alt键完成其工作 - 专注于用户界面的菜单?
答案 0 :(得分:1)
有没有办法阻止alt键完成其工作 - 专注于用户界面的菜单?
严格来说,没有 - 或更重要的是,这是错误的做法。
你应该做的是使用Key Bindings API,这将克服KeyListener
的焦点相关问题,这样,你就不会有"照顾
这是一个非常简单的测试,它将动作绑定到 ALT 和其他键并且似乎对我有用,但是立刻,我在MacOS上测试。我还发现你只能绑定"发布的密钥"元键的事件
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
JMenuBar mb= new JMenuBar();
JMenu menu = new JMenu("Menu");
menu.add("This is test item");
mb.add(menu);
frame.setJMenuBar(mb);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
public TestPane() {
setLayout(new GridBagLayout());
label = new JLabel("...");
add(label);
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "A");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "W");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "S");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "D");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), "ALT");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true), "CTRL");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_META, 0, true), "META");
ActionMap actionMap = getActionMap();
actionMap.put("A", new TextAction("A"));
actionMap.put("W", new TextAction("W"));
actionMap.put("S", new TextAction("S"));
actionMap.put("D", new TextAction("D"));
actionMap.put("ALT", new TextAction("ALT"));
actionMap.put("CTRL", new TextAction("CTRL"));
actionMap.put("META", new TextAction("META"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected class TextAction extends AbstractAction {
private String text;
public TextAction(String text) {
this.text = text;
}
@Override
public void actionPerformed(ActionEvent e) {
label.setText(text);
}
}
}
}
作为替代方案,您还可以查看KeyboardFocusManager.addKeyEventDispatcher
和/或Toolkit.addAWTEventListener
,看看是否可以确定何时按下 ALT 键并强制重点关注组件OR,更好的是暂停游戏 - 因为用户可能有合理的理由想要访问系统菜单。
为此,FocusListener
可能是一个更简单的解决方案,因为您可以简单地确定焦点丢失或获得的时间,并适当地暂停/恢复游戏