当我对 JPanel 使用按键绑定时,为什么无法获取 KeyEvent.VK_TAB

Eug*_*ene 3 java swing awt key-bindings

如果用户关注当前窗口并按下某个键,我将打印相关信息。但是,它适用于某些键,例如“a”,但不适用于“tab”。这是一个简单的演示:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;


public class KeyBindingTest {
    public static void main(String[] args) {
        KeyBindingTest test = new KeyBindingTest();
        test.createUI();
    }

    public void createUI(){
        JFrame frame = new JFrame("KeyBinding Test");
        MainPanel mainPanel = new MainPanel();
        frame.add(mainPanel,BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @SuppressWarnings("serial")
    class MainPanel extends JPanel{
        public MainPanel(){
            setPreferredSize(new Dimension(200, 200));
            //========================key binding============================
            requestFocusInWindow();
            String aString = "aStr";
            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), aString);
            getActionMap().put(aString, new AbstractAction() {          
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    System.out.println("a is typed");
                }
            });     

            String tabString = "tabStr";
            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), tabString);
            getActionMap().put(tabString, new AbstractAction() {            
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    System.out.println("tab is typed");
                }
            });     
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能达到这个目标?提前致谢。

ate*_*rai 5

引用如何使用焦点子系统(Java\xe2\x84\xa2 教程 > 使用 JFC/Swing 创建 GUI > 使用其他 Swing 功能)(由 @alex2410(链接到 @camickr 帖子)和 @mKorbel 建议):

\n\n
\n

在大多数外观模型中,使用 Tab 和 Shift-Tab 键来导航组件。这些键是默认的焦点遍历键,可以通过编程方式更改。
\n ...
\n Tab 将焦点向前移动。Shift-Tab 向后移动焦点。按 T​​ab 键将焦点通过按钮移动到文本区域。额外的 Tab 键将光标在文本区域内移动,但不会移出文本区域,因为在文本区域内,Tab 不是焦点遍历键。但是,Control-Tab 将焦点从文本区域移至第一个文本字段。同样,Control-Shift-Tab 将焦点从文本区域移至上一个组件。
\n ...
\n 按惯例,使用 Control 键将焦点移出任何以特殊方式处理 Tab 的组件(例如 JTable)。
\n 您刚刚收到了焦点架构的简要介绍。如果您需要更多详细信息,请参阅Focus 子系统的规范。

\n
\n\n

因此,如果您想让 Tab KeyBinding 操作在面板中起作用,您需要从面板中删除 Tab 键焦点导航。

\n\n
import java.awt.*;\nimport java.awt.event.*;\nimport java.util.*;\nimport javax.swing.*;\n\n//http://stackoverflow.com/q/24800417/714968\npublic class KeyBindingTest3 {\n  public static void main(String[] args) {\n    EventQueue.invokeLater(new Runnable() {\n      @Override public void run() {\n        createAndShowGUI();\n      }\n    });\n  }\n  public static void createAndShowGUI() {\n    JFrame f = new JFrame("KeyBinding Test");\n    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);\n    f.getContentPane().add(new MainPanel());\n    f.setSize(320, 240);\n    f.setLocationRelativeTo(null);\n    f.setVisible(true);\n  }\n}\n\nclass MainPanel extends JPanel {\n  public MainPanel() {\n    super();\n    //@see JTable constructor\n    Set<KeyStroke> forwardKeys = new HashSet<KeyStroke>(1);\n    forwardKeys.add(KeyStroke.getKeyStroke(\n        KeyEvent.VK_TAB, InputEvent.CTRL_MASK));\n    setFocusTraversalKeys(\n        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);\n\n    Set<KeyStroke> backwardKeys = new HashSet<KeyStroke>(1);\n    backwardKeys.add(KeyStroke.getKeyStroke(\n        KeyEvent.VK_TAB, InputEvent.SHIFT_MASK | InputEvent.CTRL_MASK));\n    setFocusTraversalKeys(\n        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);\n\n    setPreferredSize(new Dimension(200, 200));\n\n    String aString = "aStr";\n    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), aString);\n    getActionMap().put(aString, new AbstractAction() {\n      @Override public void actionPerformed(ActionEvent e) {\n        System.out.println("a is typed");\n      }\n    });\n    String tabString = "TAB";\n    getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(\n      KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), tabString);\n    getActionMap().put(tabString, new AbstractAction() {\n      @Override public void actionPerformed(ActionEvent e) {\n        System.out.println("tab is typed");\n      }\n    });\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n