Динамическое изменение включенного состояния пункта меню TrayIcon - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть код, который успешно использует 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);

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Вы также можете попробовать:

PopupMenu popup = new PopupMenu() {
    @Override
    public void show(Component origin, int x, int y) {
        boolean someCondition = getUnknownConditionFromTheThreads();
        itemToDisable.setEnabled(someCondition);  // Reflected first time
        super(origin, x, y);
    }
}
0 голосов
/ 26 ноября 2018

Вместо mouseClicked используйте mousePressed:

trayIcon.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        boolean someCondition = getUnknownConditionFromTheThreads();
        itemToDisable.setEnabled(someCondition);  // Reflected first time
    }
});
...