如果用户将焦点放在当前窗口上并按一个键,我将打印相关信息。但是,它适用于某些键,例如“ 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"); } }); } } }
我该怎么做才能达到目标?提前致谢。
引自《如何使用Focus子系统》(Java™教程>使用JFC / Swing创建GUI>使用其他Swing功能)(由@ alex2410建议(链接到@camickr帖子)和@mKorbel建议):
在大多数外观模型中,使用Tab和Shift-Tab键浏览组件。这些键是默认的焦点遍历键,可以通过编程更改。 … 选项卡将焦点向前移动。Shift- Tab键可将焦点向后移动。Tab键将焦点通过按钮移动到文本区域。附加的制表符会将光标移动到文本区域内,但不能移出文本区域,因为在文本区域内,Tab不是焦点遍历键。但是,Control- Tab键可将焦点移出文本区域并移至第一个文本字段。同样,Control-Shift-Tab键可将焦点移出文本区域并移至上一个组件。 … 按惯例,Control键用于将焦点移出以特殊方式处理Tab的任何组件,例如JTable。 您刚刚收到了有关焦点体系结构的简短介绍。如果您需要更多详细信息,请参阅Focus Subsystem的规范。
因此,如果要使Tab键绑定动作在面板中起作用,则需要从面板中删除Tab键焦点导航。
import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; //http://stackoverflow.com/q/24800417/714968 public class KeyBindingTest3 { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame("KeyBinding Test"); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new MainPanel()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } } class MainPanel extends JPanel { public MainPanel() { super(); //@see JTable constructor Set<KeyStroke> forwardKeys = new HashSet<KeyStroke>(1); forwardKeys.add(KeyStroke.getKeyStroke( KeyEvent.VK_TAB, InputEvent.CTRL_MASK)); setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); Set<KeyStroke> backwardKeys = new HashSet<KeyStroke>(1); backwardKeys.add(KeyStroke.getKeyStroke( KeyEvent.VK_TAB, InputEvent.SHIFT_MASK | InputEvent.CTRL_MASK)); setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); setPreferredSize(new Dimension(200, 200)); String aString = "aStr"; getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), aString); getActionMap().put(aString, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("a is typed"); } }); String tabString = "TAB"; getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), tabString); getActionMap().put(tabString, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("tab is typed"); } }); } }