JFrame 接近背景并听键

2022-01-24 00:00:00 java swing jframe

使用 jframe 处理新的个人项目.我的目标是将 ActionListener 中的框架关闭到背景,当按下特定键时 (Ctrl+Shft+L),我想要打开框架备份.

我不确定如何才能保持较低的 CPU 使用率.我知道我可以将框架可见性设置为 false 然后可能使用通用 ActionListener 作为键但是我有一些问题(和疑问).

  1. 这是最好的方法吗?我正在尝试尽可能降低 CPU 使用率.

  2. 即使框架不可见,ActionListener 也能工作吗?

  3. 如何监听多个按键?我有一个想法,但听起来行不通.

解决方案

  1. 这是最好的方法吗?我正在尝试尽可能降低 CPU 使用率.

如前所述,使用 JNativeHook.它是唯一的跨平台解决方案,与像 while (1) { GetAsyncKeyState(...);睡眠(5);} JNativeHook 最大的性能瓶颈是操作系统,而不是库.

<块引用>

  1. 即使框架不可见,ActionListener 也能工作吗?

除非框架具有焦点,否则它将无法工作,但本机库将提供其他在焦点外触发的事件,因此您可以通过从 NativeInputEvent 侦听器中制作自己的 ActionEvent 来使其工作.只需确保将库设置为使用 Swing 事件调度程序,因为它默认不使用!

<块引用>

  1. 如何聆听多次按键?我有一个想法,但听起来行不通.

多次按键"是什么意思?如果您的意思是在按住某个键时自动重复,则通过在以自动重复率的间隔超过自动重复延迟后发送多个 Key Pressed 事件来处理.如果该事件产生一个可打印的字符,那么许多人还会收到多个 Key Typed 事件.释放键时,将调度单个键释放事件.如果您同时指的是一系列键或多个键,则需要在本机输入侦听器中进行自己的跟踪或检查,但这应该是可能的.

基本修饰符示例:请注意,JNativeHook 库具有用于修饰键的左右掩码.我假设您想使用左侧或右侧的组合,这会使这有点复杂.

public void nativeKeyPressed(NativeKeyEvent e) {//如果键码是 Lif (e.getKeyCode() == NativeKeyEvent.VK_L) {//我们有一个 shift 掩码和一个左键或右键的控制掩码.if (e.getModifiers() & NativeInputEvent.SHIFT_MASK && e.getModifiers() & NativeInputEvent.CTRL_MASK) {//确保你没有像元键这样的额外修饰符.if (e.getModifiers() & ~(NativeInputEvent.SHIFT_MASK | NativeInputEvent.CTRL_MASK) == 0x00) {……}}}}

Working on a new personal project with jframe. My goal is to close the frame in an ActionListener to the background, and when specific keys are pressed (Ctrl+Shft+L), I want to open the frame back up.

I'm not sure how I can do this keeping CPU usage low. I know I can set the frames visibility to false and then probably use a generic ActionListener for the keys however I have a few problems (and questions).

  1. Is this the best way to do it? I'm trying to keep the CPU usage as low as possible.

  2. Will the ActionListener even work while the frame's not visible?

  3. How do I listen to multiple key presses? I have an idea but it doesn't sound like it will work.

解决方案

  1. Is this the best way to do it? I'm trying to keep the CPU usage as low as possible.

As previously mentioned, use JNativeHook. It is the only cross-platform solution and it will be much faster and less intensive than a polling approach like while (1) { GetAsyncKeyState(...); Sleep(5); } The biggest performance bottleneck with JNativeHook is the OS, not the library.

  1. Will the ActionListener even work while the frame's not visible?

It will not work unless the frame has focus, but the native library will provide other events that do fire out of focus, so you could make it work by fabricating your own ActionEvent's from the NativeInputEvent listeners. Just make sure you set the library to use the Swing event dispatcher as it does not by default!

  1. How do I listen to multiple key presses? I have an idea but it doesn't sound like it will work.

What do you mean by "multiple key presses?" If you mean auto-repeat when a key is held down, that is handled by sending multiple Key Pressed events after the auto repeat delay is exceeded at an interval of the auto repeat rate. You many also receive multiple Key Typed events if that event produces a printable character. When the key is released, a single key release event will be dispatched. If you mean a sequence of keys or multiple keys at the same time, you will need to do your own tracking or checks in the native input listener, but it should be possible.

Basic Modifier Example: Note that JNativeHook library has both a left and right mask for the modifier keys. I assume you want to use a combination of either the left or the right which makes this a tad more complicated.

public void nativeKeyPressed(NativeKeyEvent e) {
    // If the keycode is L
    if (e.getKeyCode() == NativeKeyEvent.VK_L) {
        // We have a shift mask and a control mask for either the left or right key.
        if (e.getModifiers() & NativeInputEvent.SHIFT_MASK && e.getModifiers() & NativeInputEvent.CTRL_MASK) {
            // Make sure you don't have extra modifiers like the meta key.
            if (e.getModifiers() & ~(NativeInputEvent.SHIFT_MASK | NativeInputEvent.CTRL_MASK) == 0x00) {
                ....
            }
        }
    }
}

相关文章