【问题标题】:What keys are pressed (modifiers) in other events than action events?在动作事件之外的其他事件中按下了哪些键(修饰符)?
【发布时间】:2014-06-27 16:40:03
【问题描述】:

我想知道是否有任何方法可以找出是否在不使用 InputEvent 的情况下按下了任何键或鼠标按钮。

例如:我的应用程序没有焦点,但是当它获得焦点时,我想知道是否按下了 Ctrl 键。这在大多数情况下都有效,但如果通过单击标题栏获得焦点(这正是我正在寻找的),则无效。

或者:我开始拖动一个窗口,我想知道在此拖动过程中是否按下或释放了 Ctrl 键。

我曾尝试监听 Keystrokes 并使用 AWTEventListener 但这无济于事,因为没有关于按下的键的信息。

有没有办法从 Swing 中获取按下的键? 据我搜索,我不认为这是因为修饰符是直接从操作系统生成的事件(例如 XWindow 中的 getModifiers() )收集在工具包中的,但也许我错了。

有这种方式:GlobalKeyListener,但它非常复杂并且还依赖于操作系统。

【问题讨论】:

  • 你可以试试这个,InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(KeyStroke.getKeyStroke("ctrl"), "aSwingAction"); component.getActionMap().put("Swing 的 AbstractAction", action);在这里,您可以将诸如 ctrl 或 alt 之类的按键绑定到 Swing Action,您必须编写一个 Swing 动作,当您按下此按键时会调用它
  • 使用未修饰的框架,则 KeyStrokes 将由 Java 处理。当然你需要实现自己的“标题栏”并支持自己拖动。
  • @rahulpasricha - 我希望它在窗口没有聚焦时也能工作。
  • @camickr - 不能更改标题栏。我想创建一个非侵入式库。

标签: java swing listener keystroke


【解决方案1】:

标题栏不是 Swing 组件,因此在使用 Swing 侦听器时无法接收事件。

如果你想监听事件,那么你需要使用带有 Swing 装饰的 JFrame:

JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
frame.getRootPane().addMouseListener(...);

【讨论】:

  • 问题的想法是我是否可以知道是否可以通过使用 ActionEvent 以外的任何其他方式按下键。在第二种情况下,您的方式将无济于事,我想知道在拖动事件期间是否按下了某个键,而且我不想更改窗口中的任何内容。我希望一切都是外部的。
  • Swing 不处理来自单击标题栏的事件。不管你试图监听什么样的事件,它都行不通。正如您在最初的问题中所说:有这种方式:GlobalKeyListener,但它非常复杂并且还依赖于操作系统。 - 它复杂的原因是因为 Swing 不支持它。我给了你一个建议,展示了如何构建一个完全由 Swing 组件组成的框架,以便你可以监听事件。它要么是那个解决方案,要么是非 Java 解决方案。
  • 暂时忽略标题栏部分。问题是“在动作事件之外的其他事件中按下了哪些键(修饰符)?”。我想也许工具包中有一个方法,您可以随时调用(有或没有监听器)来找出按下了哪些键,但我错过了。
  • '我想也许工具包中有一个方法可以随时调用' - 我不知道。您可以在生成 KeyEvents 时收听它们,MouseEvent 还将指示是否按下了 Ctrl、Alt、Shift。但我再次强调标题栏不是 Swing 组件,所以你不能监听这些事件!
【解决方案2】:

监听键和设置一些布尔变量怎么样。然后,当您的应用程序获得焦点时,您只需检查布尔值是否已设置。

例如

private boolean isCtrlDown;
public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_CONTROL) {
        isCtrlDown = true;
    }
}
public void keyReleased(KeyEvent e) {
   if(e.getKeycode() == KeyEvent.VK_CONTROL) {
       isCtrlDown = false;
   }
}


public void focusGained(FocusEvent e) {
     if(isCtrlDown) {
         // Do what you wanted to do
     }
}

【讨论】:

  • 不幸的是,这不适用于焦点在另一个应用程序中并且我单击应用程序中的标题栏的第一种情况。
【解决方案3】:

我发现的唯一实际可能性是使用https://code.google.com/p/jnativehook/

这会添加一个使用 JNI 的本机侦听器。

【讨论】:

    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    相关资源
    最近更新 更多