JPanel keylistener

我正在尝试添加一个包含JTabbedPane的密钥监听器。
它应该在收到ctrl + tab时切换标签。
但是keypressed事件从未发送过我尝试将其添加到面板和选项卡式对象 – 但没有成功。

这是我的代码

 SwitchTabsListener ctrlTabListener = new SwitchTabsListener(genericTabbedPanel); jMainFrame.addKeyListener(ctrlTabListener); genericTabbedPanel.addKeyListener(ctrlTabListener); 

在典型的方式中,您的键事件不会被正确的Swing组件拦截。 您必须了解光标下方的第一个组件将接收键盘事件。 如果你用键盘选择一个按钮,那将是这个JButton会收到关键事件。

为了确保获得所有这些事件,您不必在组件上注册,而是使用KeyboardFocusManager ,它将在任何地方接收关键事件。

然后,您的代码需要以下元素

 KeyEventDispatcher myKeyEventDispatcher = new DefaultFocusManager(); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(myKeyEventDispatcher); 

无论何时按下某个键, myKeyEventDispatcher都将接收对dispatchKeyEvent调用,无论它在UI中的myKeyEventDispatcher位置。 这样,您可以确保正确调用您的代码。

注册键侦听器的另一种方法是要求您使用HierarchyListener以便添加键侦听器:删除到每个swing组件,这些组件似乎是作为根组件的子组件添加/删除的。 这不仅编写起来很麻烦,而且很难调试和理解。

这就是为什么我更喜欢蛮力,但是将应用程序全局键监听器添加到特定键盘焦点管理器的方式却相当优雅。

Ctrl+TabCtrl+Shift+Tab允许您在Windows LookAndFeel中默认循环切换选项卡:

 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 

这应该工作。 这可能不适合你,因为

  1. 您没有选择正确的窗口。
  2. 其他组件捕获此事件。

这是我为你写的代码。

 public class Test { public static void main(String[] args) throws InterruptedException { JFrame f = new JFrame("aaaa"); f.setSize(100, 100); f.setLocation(100, 100); JPanel p = new JPanel(); f.add(p); f.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { System.out.println("pressed"); } }); p.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { System.out.println("pressed"); } }); f.setVisible(true); } 

它工作正常。 尝试使用它,并了解你和我的代码之间的区别。 如果您失败,请向我们发送更大的代码片段。

根据Riduidel的回答,这是一个完整的例子。 我不知道如何确定该事件是来自按键还是按键发布。

 import java.awt.KeyboardFocusManager; import java.awt.KeyEventDispatcher; import java.awt.event.KeyEvent; import javax.swing.JFrame; public class Exit { public static void main(String[] args) { KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new ExitKeyEventDispatcher()); JFrame frame = new JFrame(); frame.setBounds(50, 50, 200, 200); frame.setVisible(true); } } class ExitKeyEventDispatcher implements KeyEventDispatcher { public boolean dispatchKeyEvent(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { System.exit(0); e.consume(); } return false; } }