tinkerbeast
tinkerbeast

Reputation: 2077

Capture all events in JFrame without deactivating the window

I'm trying to develop something like a remote desktop / VNC client. It's necessary for me to capture all events in the client window. The method I'm using is to override the processEvent method of the JFrame:

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

However on events like the Windows key or Alt+Tab the window is getting deactivated:

...    
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 
...

How do I keep the window active on such events?

I would prefer a pure Java solution to this. If there is no pure java solution, can someone point me towards a JNA solution (or any other solution for that fact)?

EDIT1: * Resolved ambiguous term 'focus' to window deactivation * Emphasized that non pure Java solutions are acceptible

Upvotes: 9

Views: 1447

Answers (4)

Tilo
Tilo

Reputation: 3325

1.) JNA comes with an example that does almost what you want:

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

In order to block a key, just return 1 instead of calling CallNextHookEx - cf. the MSDN documenttaion.

2.) JNativeHook allows you to hook into global event processing, but right now there is no way of stopping events from being deliverd - e.g. the Windows key will still activate the start menu. However it is still worth looking at since it comes with much less overhead, and you can modify it (starting with CallNextHookEx here) to behave the way you want. It is licensend under the GPL though.

3.) Another clean way of doing this, would be to switch to SWT and use the SWT Win32 Extensions to intercept keyboard events.

Upvotes: 1

abishkar bhattarai
abishkar bhattarai

Reputation: 7651

You can use WindowListener.Hope this will help to capture the event .There are windowfocuslistener,windowstatelistener too.

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

Upvotes: 0

acostache
acostache

Reputation: 2275

Can you not set the window to be focusable all the time (Window.setFocusableWindowState), because JFrame does inherit that method from Window. Something simple like: window.setFocusableWindowsState(true). And inside a key event listener call this: (this code is modified, but originally from 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);
    }
}

I did not get to test this code, but i hope at least the idea is getting you in right direction.

Upvotes: 1

R.Moeller
R.Moeller

Reputation: 3446

You can set a custom FocusManager and override the dispatchEvent method or use Toolkit.getDefaultToolkit().addAWTEventListener(..). However this won't catch OS-catched keyEvents, but you will still get events like repaint if you register at the toolkit.

Upvotes: 0

Related Questions