如何在所有组件中侦听按键(在JavaSwing中)?

如何在所有组件中侦听按键(在JavaSwing中)?,java,swing,keylistener,Java,Swing,Keylistener,我希望在不向Swing应用程序中的每个组件添加键侦听器的情况下,侦听诸如Control+S之类的组合键。我如何才能做到这一点?我认为没有办法像您希望的那样添加“全局”键侦听器。这个问题和一个类似的问题支持我。您只需要将它们添加到每个组件中。不过这只需要做一次,所以我想你可以结束它,继续前进。这是可能的 KeyboardFocusManager.getCurrentKeyboardFocusManager() .addKeyEventDispatcher(new KeyEventDispatc

我希望在不向Swing应用程序中的每个组件添加键侦听器的情况下,侦听诸如Control+S之类的组合键。我如何才能做到这一点?

我认为没有办法像您希望的那样添加“全局”键侦听器。这个问题和一个类似的问题支持我。您只需要将它们添加到每个组件中。不过这只需要做一次,所以我想你可以结束它,继续前进。

这是可能的

KeyboardFocusManager.getCurrentKeyboardFocusManager()
  .addKeyEventDispatcher(new KeyEventDispatcher() {
      @Override
      public boolean dispatchKeyEvent(KeyEvent e) {
        System.out.println("Got key event!");
        return false;
      }
});
这将抓住所有关键事件。返回false允许键盘焦点管理器恢复到各个组件的正常按键事件调度

如果你想捕捉组合键,你可以保留一组“按下的键”。每当按下一个键时,将其添加到集合中,并检查集合中已有哪些键。释放钥匙后,将其从集合中移除。

非常简单,我的朋友: 你所要做的就是创建一个 类KeyEventDispatcher并注册到KeyboardFocusManager C.1

然后解析并提取状态和密钥信息,参见:C.2 但奇怪的是,您必须通过ThatEvent.getID()获取密钥状态

对我来说似乎是个误称

///////////////////////////////////////////////////////////////////////////////////////////   C.1)
         KeyDispatcher        ThisKeyDispatcher  = new KeyDispatcher();

         KeyboardFocusManager ThisKbFocusMngr = KeyboardFocusManager 
                                              . getCurrentKeyboardFocusManager();

         ThisKbFocusMngr                      . addKeyEventDispatcher(ThisKeyDispatcher);
         return ThisKeyDispatcher;

///////////////////////////////////////////////////////////////////////////////////////////   
C.2
public static class KeyDispatcher implements KeyEventDispatcher {

  public boolean dispatchKeyEvent(final KeyEvent ThatEvent) {

     KeyboardFocusManager ThisKbFocusMngr    = null;
     Component            ThisComponent      = null;
     Container            ThisRoot           = null;
     Window               ThisWindow         = null;
     int                  ThisKeyStateEvent  = 0;

     try {
        ThisKbFocusMngr       = KeyboardFocusManager  . getCurrentKeyboardFocusManager();
        ThisComponent         = ThisKbFocusMngr       . getFocusOwner();
        ThisRoot              = ThisKbFocusMngr       . getCurrentFocusCycleRoot();
        ThisWindow            = ThisKbFocusMngr       . getActiveWindow();
        ThisKeyStateEvent     = ThatEvent.getID();   // i.e.  KeyEvent.KEY_RELEASED

        if(false                           == ThatEvent.isConsumed()) {
           boolean       RetBool          = false;
           if((KeyEvent.VK_BACK           == ThatEvent.getKeyCode())) {
              RetBool                      = true;
           } else {
              RetBool                      = m_CallSomeoneEvent(ThatEvent);
           }
           if(RetBool) {
              ThatEvent.consume();
              return true;
           }
        }
     }
     catch( Throwable e ) {
        LogThis(". ", e);
     }
     return false;
  }
}

我不认为有一种方法可以像你想做的那样添加一个“全局”键侦听器。这是错误的
Toolkit.addAWTEventListener
,你可以侦听任何内容,除此之外,还提到你可以向addKeyEventDispatcher添加事件,还可以添加加速键等等on@bestsss我想你误解了。我不是说正在侦听的事件类型,而是侦听器工作的组件。在获取全局事件后,获取聚焦组件?我认为freshwire仍然必须在每个组件中放置侦听器。然后,当
KeyEventDispatcher
发出事件时,组件可以侦听某些事件并执行特定于组件的操作。这听起来像是额外的工作。@Treebranch他只是想抓住一个全球ctr+s。。。好的,我同意。我假设freshwire会将事件推送到组件级别,但我认为情况并非如此。KeyboardFocusManager实际上会捕获所有关键事件,而AWTEventListener不会对所有事件做出反应。若你们需要听一听像F11这样的关键事件来切换到全屏,KeyboardFocusManager肯定更好。AWTEventListener似乎只侦听组件事件。但当没有组件具有焦点时,AWTEventListener不会收到按键事件的通知。此代码返回每次按键的所有事件,即一次按键、一次按键、一次按键释放和一次按键类型事件。为了进一步过滤以给出一个事件,可以添加代码if(KeyEvent.KEY_PRESSED==e.getID()){…}来过滤例如KEY_PRESSED事件。感谢您的回答,但我已经在一年多前接受了答案。你的答案与公认的答案有何不同?它有很多额外的代码,在我的问题中似乎没有任何意义。