Alt键中断GUI

时间:2018-03-10 23:39:37

标签: java

我目前有一个非常简单的游戏,您可以使用箭头键从一侧移动到另一侧。我的问题是,无论何时按下alt键(主要是偶然),游戏窗口都会失去焦点,并且不再回复箭头键。如果我再次按下alt,重新获得焦点,但如果矩形已经运动,它将继续不停。 我正在使用这些渲染和更新方法btw。

有没有办法阻止alt键完成其工作 - 专注于用户界面的菜单?

1 个答案:

答案 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可能是一个更简单的解决方案,因为您可以简单地确定焦点丢失或获得的时间,并适当地暂停/恢复游戏