动态更改 TrayIcon 菜单项的启用状态

Changing the enabled state of a TrayIcon menu item dynamically

我有成功使用 SystemTrayTrayIconPopupMenuMenuItem 的代码。我试图根据其他几个线程中发生的事情的状态使 MenuItem 的启用状态准确。我有能力 运行 一个进程(我称之为 getUnknownConditionFromTheThreads()),它可以告诉我是否需要在特定时刻及时启用或禁用菜单项。

问题是当用户右击托盘图标时,菜单项显示在之前 setEnabled() 是运行。

也就是说,用户右击托盘图标,菜单显示当时enable/disable状态,然后mouseClicked()方法运行s和setEnabled() 运行s, 但是太迟了!

所以我可以尝试将状态泵入托盘图标,以便提前准备好,但这意味着很多复杂性,因为有很多独立的线程,但没有一个 "knows"菜单项的 enable/disable 状态应该是什么。

我的问题:是否有"trick"根据用户在托盘图标中生成的事件获取弹出菜单项enabled/disabled?

下面的代码通常是我正在做的。这里什么都没有"fancy",只是为了说明当用户点击右键时,enabling/disabling菜单项没有反应。

代码现在是这样工作的:假设菜单项的默认设置已启用,下一次调用 getUnknownConditionFromTheThreads() 将 return 为假。用户将在第一次右键单击时看到该项目已启用。下一次右键单击,它将被禁用。

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);

代替mouseClicked,使用mousePressed:

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

您也可以试试:

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);
    }
}