This discussion is archived
1 Reply Latest reply: Mar 22, 2012 8:03 AM by 925770 RSS

JNA: key listener + JFrame

925770 Newbie
Currently Being Moderated
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!
  • 1. Re: JNA: key listener + JFrame
    925770 Newbie
    Currently Being Moderated
    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);
    }
    });

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points