У меня есть код, который успешно использует SystemTray
, TrayIcon
, PopupMenu
, MenuItem
. Я пытаюсь сделать так, чтобы включенное состояние MenuItem
было точным, основываясь на состоянии чего-то, что происходит в нескольких других потоках. У меня есть возможность запустить процесс (который я назвал getUnknownConditionFromTheThreads()
), который может сказать мне, нужно ли мне включить или отключить пункт меню в этот конкретный момент времени.
Проблема в том, что когда пользователь щелкает правой кнопкой мыши значок в трее, элементы меню отображаются до запуска setEnabled()
.
Другими словами, пользователь щелкает правой кнопкой мыши значок в области уведомлений, меню отображается с включенным/отключенным состоянием в данный момент, затем запускается метод mouseClicked()
и запускается setEnabled()
, но уже слишком поздно!
Так что я мог бы попытаться закачать состояние в иконку в трее, чтобы оно было готово заранее, но это означало бы большую сложность, потому что есть много независимых потоков, и никто из них не «знает», какое состояние включения/отключения у пункт меню должен быть.
Мой вопрос: есть ли «хитрость», чтобы включить / отключить элемент всплывающего меню на основе события, сгенерированного пользователем на значке в трее?
Код ниже, как правило, то, что я делаю. Здесь нет ничего «причудливого», просто чтобы показать, что когда пользователь щелкает правой кнопкой мыши, включение/отключение пункта меню не отражается.
Вот как теперь работает код: скажем, по умолчанию для пункта меню включено, и следующий вызов getUnknownConditionFromTheThreads()
вернет false. Пользователь увидит, что элемент включен при первом щелчке правой кнопкой мыши. Следующий щелчок правой кнопкой мыши отключит его.
PopupMenu popup = new PopupMenu();
final MenuItem itemToDisable = new MenuItem("Testing");
ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
.....
}
};
itemToDisable.addActionListener(listener);
popup.add(itemToDisable);
trayIcon = new TrayIcon(xImg, xMsg, popup);
trayIcon.addActionListener(listener);
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
boolean someCondition = getUnknownConditionFromTheThreads();
itemToDisable.setEnabled(someCondition); // Not reflected first time
}
});
SystemTray.getSystemTray().add(trayIcon);