【问题标题】:JPanel keylistenerJPanel 按键监听器
【发布时间】:2011-06-14 10:24:09
【问题描述】:

我正在尝试添加一个包含JTabbedPane 的关键侦听器。
它应该在收到 ctrl + tab 时切换选项卡。
但是keypressed事件永远不会发送 我尝试将它添加到面板和选项卡式对象 - 但没有成功。

这是我的代码

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

【问题讨论】:

    标签: java swing jpanel


    【解决方案1】:

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

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

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

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

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

    注册键侦听器的替代方法需要您使用HierarchyListener 以便添加您的键侦听器:已删除到似乎作为根组件的子级添加/删除的每个摆动组件.这不仅写起来麻烦,而且很难调试和理解。

    这就是为什么我更喜欢使用更暴力但非常优雅的方式将应用程序全局键侦听器添加到特定键盘焦点管理器的原因。

    【讨论】:

    • KeyboarFocusManager.getCurrentKeyboardFocusManager() - 你写了 KeyboarFocus...,但没有任何“D”(有效:键盘)
    • "你要明白光标下的第一个组件会收到键盘事件"不成立,当前有键盘焦点的组件会收到按键事件(在焦点窗口)。现在,键绑定 API 可能是更好的解决方案
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这应该可行。这可能对您不起作用,因为

      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);
      
          }
      

      它工作正常。尝试使用它并了解您的代码和我的代码之间的区别。如果您失败了,请将您的代码的更大的 sn-p 发送给我们。

      【讨论】:

      • 核心是他要抓ctrl + tab
      • 我不确定,伙计。但可能你是对的。无论如何,e.getKeyCode() 和 e.getModifiers() 可以提供帮助
      【解决方案4】:

      根据 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;
          }
      }
      

      【讨论】:

      • 要确定事件是来自按键还是释放,请执行e.getID() == KeyEvent.KEY_RELEASED
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多