动态更改 TrayIcon 菜单项的启用状态
Changing the enabled state of a TrayIcon menu item dynamically
我有成功使用 SystemTray
、TrayIcon
、PopupMenu
、MenuItem
的代码。我试图根据其他几个线程中发生的事情的状态使 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);
}
}
我有成功使用 SystemTray
、TrayIcon
、PopupMenu
、MenuItem
的代码。我试图根据其他几个线程中发生的事情的状态使 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);
}
}