MenuShortcut KeyEvent не работает
Приведенный ниже код является тестируемым классом, который должен распечатывать некоторый текст, когда на клавиатуре нажата клавиша Control+A, а также отображать изображение в системном трее. Все это зависит от того, поддерживается ли системный трей вашей операционной системой.
Моя проблема в том, что текст не печатается, когда я нажимаю Control+A, он печатается только тогда, когда я нажимаю на элемент в системном трее.
/**
*
* @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();
}
}
}
}
2 ответа
Причина, по которой ваш код не работает, состоит в том, что Java не "глобально" прослушивает ваше ключевое событие, а только тогда, когда меню имеет ваш фокус и отображается.
Это также причина, почему нет возможности написать чистый кейлоггер Java. Java только позволяет вам захватывать оконные сообщения.
Обходной путь должен был бы реализовать один из этих вариантов:
- Используйте JNI/JNA/ любую другую встроенную оболочку для доступа к перехвату глобальных ключей
- Используйте невидимое окно, всегда находящееся сверху и не отображаемое в системном трее, в котором фиксируются события. Я бы не советовал использовать этот, так как он может либо не работать как шарм, либо раздражать вашего пользователя.
Верхний подход не сложен, но потребует от вас использовать собственный доступ, и поэтому ваше приложение становится специфичным для платформы.
Удачи!
Похоже, что из API вы должны попробовать этот конструктор для MenuItem()
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A, false);
по умолчанию требуется также нажатие клавиши Shift.