Question

The code below is a testable class that should print out some text when control+A has been pushed on the keyboard, and will also display an image in the system tray. This is all dependent on the system tray being supported by your operating system.

My issue is that the text is not being printed out when I push control+A, it is only printed when I press the item in the system tray.

/**
 *
 * @author Tyluur
 * @since Aug 23, 2013
 */
public class Testable {

public static void main(String... args) {
    registerTrayItems();
}

private static void registerTrayItems() {
    if (SystemTray.isSupported()) {
        SystemTray tray = SystemTray.getSystemTray();
        TrayIcon icon = null;
        MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A);
        MenuItem menuItem = new MenuItem("Toggle", shortcut);
        menuItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.err.println("The action has been called!");
            }
        });
        PopupMenu popup = new PopupMenu();
        popup.add(menuItem);
        try {
            icon = new TrayIcon(new ImageIcon(new URL("http://i.imgur.com/xQoz2TN.png")).getImage(), "Typer", popup);
            tray.add(icon);
        } catch (MalformedURLException | AWTException e) {
            e.printStackTrace();
        }
    }       
}

}
Was it helpful?

Solution

The reason your code is not working is because Java is not 'globally' listening for your key event, but only when the menu has your focus and is shown.

This is also the reason why there is no possibility to write a pure Java keylogger. Java only allows you to capture window-directed messages.

A workaround would be to implement one of these options:

  • Use JNI/JNA/whatever native wrapper to access global key hooking
  • Use an invisible window, always being on top and not shown in the system tray that captures the events. I would not suggest using this one as it may either not work like a charm or annoys your user.

The top approach is not a hard one but will require you to use native access and therefor your application becomes platform-specific.

Good luck!

OTHER TIPS

From the API, it looks like you should try this constructor for the MenuItem()

MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A, false);

as the default is to require that the Shift key be pressed too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top