在不停用窗口的情况下捕获 JFrame 中的所有事件



我正在尝试开发远程桌面/VNC客户端之类的东西。我有必要捕获客户端窗口中的所有事件。我正在使用的方法是覆盖JFrameprocessEvent方法:

@Override
protected void processEvent(AWTEvent e) {
    ...
}

但是,在Windows键或Alt+Tab等事件中,窗口被停用:

...    
00000191 KEY_PRESSED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c 
00000192 KEY_RELEASED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c 
000000ce WINDOW_DEACTIVATED,opposite=null,oldState=0,newState=0 
...

如何在此类事件上保持窗口处于活动状态?

更喜欢一个纯粹的Java解决方案。如果没有纯粹的Java解决方案,有人可以指出我使用JNA解决方案(或任何其他解决方案)吗?

编辑1:* 解决了窗口停用的歧义术语"焦点"* 强调非纯Java解决方案是可以接受

1.) JNA 附带了一个示例,几乎可以满足您的需求:

http://java.net/projects/jna/sources/svn/content/trunk/jnalib/contrib/w32keyhook/KeyHook.java

为了阻止密钥,只需返回 1 而不是调用 CallNextHookEx - 参见 MSDN 文档。

2.) JNativeHook 允许您挂接到全局事件处理,但现在无法阻止事件被传递 - 例如 Windows 键仍将激活开始菜单。但是,它仍然值得一看,因为它的开销要少得多,您可以对其进行修改(从此处的CallNextHookEx开始)以按照您想要的方式运行。不过,它是GPL下的许可证。

3.) 另一种干净的方法是切换到 SWT 并使用 SWT Win32 扩展来拦截键盘事件。

您能否不将窗口设置为始终可聚焦(Window.setFocusableWindowState),因为 JFrame 确实从 Windows 继承了该方法。像这样简单的东西:window.setFocusableWindowsState(true).在关键事件侦听器中调用以下内容:(此代码已修改,但最初来自 JFrame 的无响应 KeyListener

public class MyFrame extends JFrame { 
    private class MyDispatcher implements KeyEventDispatcher 
    {
        private JFrame frame;
        public MyDispatcher(JFrame jf)
        {
            this.frame = jf;
        }
        public boolean dispatchKeyEvent(KeyEvent e) 
        {
            frame.setFocusableWindowState(true);
            return false;
        }
    }
    public MyFrame() 
    {
        add(new JTextField());
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher(this));
    }
    public static void main(String[] args) 
    {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}

我没有测试这段代码,但我希望至少这个想法能让你朝着正确的方向前进。

您可以设置自定义 FocusManager 并覆盖 dispatchEvent 方法或使用 Toolkit.getDefaultToolkit().addAWTEventListener(..)。但是,这不会捕获操作系统捕获的 keyEvents,但如果您在工具包中注册,您仍然会收到重绘等事件。

您可以使用 WindowListener.希望这将有助于捕获事件。也有窗口焦点监听器,窗口状态监听器。

public class WindowListenerImpl implements WindowListener(){
     @Override
                        public void windowOpened(WindowEvent windowevent) {
                           //urs windowevent to get source.
                        }
                        @Override
                        public void windowIconified(WindowEvent windowevent) {
                           //urs windowevent to get source.
                        }
                        @Override
                        public void windowDeiconified(WindowEvent windowevent) {
                            //urs windowevent to get source.
                        }
                        @Override
                        public void windowDeactivated(WindowEvent windowevent) {
                             //urs windowevent to get source.
                        }
                        @Override
                        public void windowClosing(WindowEvent windowevent) {
                           //urs windowevent to get source.
                        }
                        @Override
                        public void windowClosed(WindowEvent windowevent) {
                             //urs windowevent to get source.
                        }
                        @Override
                        public void windowActivated(WindowEvent windowevent) {
                           //urs windowevent to get source.
                        }
    public WindowEvent{
    public static void main(String[] args){
    WindowListenerImpl  listenerImpl=new WindowListenerImpl ();
    new JFrame.addWindowListener(listenerImpl);
    }

相关内容

  • 没有找到相关文章

最新更新