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

时间:2012-12-12 08:53:50

标签: java swing events event-handling

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

JFrame方法
@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解决方案(或任何其他解决方案)?

EDIT1: *解决了窗口停用时模糊的术语“焦点” *强调非纯Java解决方案是可以接受的

4 个答案:

答案 0 :(得分:1)

您是否可以将窗口设置为始终可聚焦(Window.setFocusableWindowState),因为JFrame确实从Window继承了该方法。像window.setFocusableWindowsState(true)这样简单的东西。在一个关键事件监听器里面调用: (此代码已修改,但最初来自Unresponsive KeyListener for JFrame

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

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

答案 1 :(得分:1)

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

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

要阻止某个键,只需返回1而不是调用CallNextHookEx - cf. MSDN documenttaion

2。)JNativeHook允许您挂钩全局事件处理,但是现在没有办法阻止事件被传递 - 例如Windows键仍将激活开始菜单。但是它仍然值得一看,因为它带来的开销要少得多,你可以修改它(从CallNextHookEx here开始)以你想要的方式运行。但它是GPL下的许可证。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

你可以使用WindowListener.Hope这有助于捕获事件。还有windowfocuslistener,windowstatelistener。

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