This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 31st, when you will be able to use this site as normal.

    Forum Stats

  • 3,890,899 Users
  • 2,269,649 Discussions
  • 7,916,821 Comments

Discussions

JNA: key listener + JFrame

925770
925770 Member Posts: 2
edited Mar 22, 2012 11:03AM in Java Native Interface (JNI)
Hello,
I'm trying to write a simple application where I have a keyboard listener in the background and JFrame. Practically, I use the following code to create the listener:

public class KeyHook {
private static volatile boolean quit;
private static HHOOK hhk;
private static LowLevelKeyboardProc keyboardHook;

public static void main(String[] args) {
final User32 lib = User32.INSTANCE;
HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
keyboardHook = new LowLevelKeyboardProc() {
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
if (nCode >= 0) {
switch(wParam.intValue()) {
case WinUser.WM_KEYUP:
case WinUser.WM_KEYDOWN:
case WinUser.WM_SYSKEYUP:
case WinUser.WM_SYSKEYDOWN:
System.err.println("in callback, key=" + info.vkCode);
if (info.vkCode == 81) {
quit = true;
}
}
}
return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
}
};
hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
new Thread() {
public void run() {
while (!quit) {
try { Thread.sleep(10); } catch(Exception e) { }
}
System.err.println("unhook and exit");
lib.UnhookWindowsHookEx(hhk);
System.exit(0);
}
}.start();

// This bit never returns from GetMessage
int result;
MSG msg = new MSG();
while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
if (result == -1) {
System.err.println("error in get message");
break;
}
else {
System.err.println("got message");
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
lib.UnhookWindowsHookEx(hhk);
}
}

My requirement is to create the listener as the first and after it JFrame. The problem is that I don't know how to create JFrame because of GetMessage. Now, GetMessage blocks the current thread so I can't create JFrame after it. On the other hand, I can't put it in a new Thread because then, the listener doesn't work. I hope you understand the issue :) Any ideas how to solve it?

Thanks in advance!
Tagged:

Answers

  • 925770
    925770 Member Posts: 2
    Ok, this is what should be done to solve the problem:

    We throw out this fragment:

    new Thread() {
    public void run() {
    while (!quit) {
    try { Thread.sleep(10); } catch(Exception e) { }
    }
    System.err.println("unhook and exit");
    lib.UnhookWindowsHookEx(hhk);
    System.exit(0);
    }
    }.start();

    and next, we enclose code from the main method in:

    new Thread(new Runnable() {
    ...
    }).start();

    Then, we are free to type in the main method e.g. :

    startListening(); // key listener

    JFrame frame = new JFrame();
    ...
    SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
    frame.setVisible(true);
    }
    });
This discussion has been closed.