Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 648
tinkerbeast Avatar asked Dec 12 '12 08:12

tinkerbeast


People also ask

Which of these help the JFrame to hide or close the window?

awt. Frame class. JFrame works like the main window where components like labels, buttons, textfields are added to create a GUI. Unlike Frame, JFrame has the option to hide or close the window with the help of setDefaultCloseOperation(int) method.

What is listener windows?

Window listeners are commonly used to implement custom window-closing behavior. For example, a window listener is used to save data before closing the window, or to exit the program when the last window closes.

How do I close a JFrame without the button?

You can't remove close Button from JFrames, but you can disable by calling setDefaultCloseOperation(WindowConstants. DO_NOTHING_ON_CLOSE) on that JFrame.

How do you close a frame in a swing?

Best way to close a Swing frame programmatically is to make it behave like it would when the "X" button is pressed. To do that you will need to implement WindowAdapter that suits your needs and set frame's default close operation to do nothing (DO_NOTHING_ON_CLOSE).


2 Answers

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.

like image 60
Tilo Avatar answered Oct 23 '22 11:10

Tilo


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.

like image 37
acostache Avatar answered Oct 23 '22 11:10

acostache