Reputation: 21329
I want to add JPopupMenu
to the task bar as a TrayIcon
(i.e systemTray.add(trayIcon)
) but I haven't found a way to do so.From the docs the constructor of TrayIcon looks like :
public TrayIcon(Image image,
String tooltip,
PopupMenu popup)
Is there any way I can do this ?
Upvotes: 16
Views: 6181
Reputation: 1
So excited, I found a solution.The idea is as follows:
TrayIcon trayIcon = new TrayIcon(image, "Tip Text"); // The popup parameter is no longer needed.
trayIcon.addMouseListener(new CustomTrayIconMouseListener());
Class CustomTrayIconMouseListener extends MouseAdapter, and int the TrayIconMouseListener class you need to accomplish two things:
3.1 Define member variables of type JPopupMenu and do what you want to do, such as adding some JMenuItem and so on.
3.2 Override mouseClicked method, then pop up the JPopupMenu(setVisible method) by judging the right mouse click event. You need to set its position before popping up JPopupMenu(setLocation method).
Because I also encountered the problem today, I thought of this idea just a moment ago, and I am working hard to solve it now, and I am writing code now. Maybe I will encounterd other problems.
Upvotes: 0
Reputation:
For the current TrayIcon
implementation, it is not possible to directly add a JPopupMenu
or JMenu
to TrayIcon
. However, some people did manage to work around it by implementing a custom MouseListener
which listens to right click only at the Trayicon
. When the mouse is right-clicked, set location of the Popupmenu at event.getXOnScreen()
and event.getYOnScreen()
and setvisible it.
Upvotes: 2
Reputation: 1648
This is a known problem. There is a bug report, which contains the outline of a workaround. I've adapted that below:
// Build your popup menu
final JPopupMenu trayPopup = new JPopupMenu();
// I'm using actions, there are other ways of doing this.
trayPopup.add(someFantaticAction);
// Get your tray icon
trayIcon = new TrayIcon(icon, "My awesome application");
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
@Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
trayPopup.setLocation(e.getX(), e.getY());
trayPopup.setInvoker(trayPopup);
trayPopup.setVisible(true);
}
}
});
Upvotes: 7
Reputation: 109813
I can't see any issues with constructor public TrayIcon(Image image, String tooltip, PopupMenu popup), nor is Java7 on WinXp / Win7 (Win2003/2008)
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.UIManager;
public class ActiveTray {
public static void main(String args[]) throws Exception {
if (SystemTray.isSupported() == false) {
System.err.println("No system tray available");
return;
}
final SystemTray tray = SystemTray.getSystemTray();
PropertyChangeListener propListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
TrayIcon oldTray[] = (TrayIcon[]) evt.getOldValue();
TrayIcon newTray[] = (TrayIcon[]) evt.getNewValue();
System.out.println(oldTray.length + " / " + newTray.length);
}
};
tray.addPropertyChangeListener("trayIcons", propListener);
Icon icon = new BevelArrowIcon(BevelArrowIcon.UP, false, false);
Image image = iconToImage(icon);
PopupMenu popup = new PopupMenu();
MenuItem item = new MenuItem("Hello, World");
final TrayIcon trayIcon = new TrayIcon(image, "Tip Text", popup);
ActionListener menuActionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
trayIcon.displayMessage("Good-bye", "Cruel World",
TrayIcon.MessageType.WARNING);
}
};
item.addActionListener(menuActionListener);
popup.add(item);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
tray.remove(trayIcon);
}
};
trayIcon.addActionListener(actionListener);
tray.add(trayIcon);
}
static Image iconToImage(Icon icon) {
if (icon instanceof ImageIcon) {
return ((ImageIcon) icon).getImage();
} else {
int w = icon.getIconWidth();
int h = icon.getIconHeight();
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
Graphics2D g = image.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return image;
}
}
static class BevelArrowIcon implements Icon {
public static final int UP = 0; // direction
public static final int DOWN = 1;
private static final int DEFAULT_SIZE = 16;
private Color edge1;
private Color edge2;
private Color fill;
private int size;
private int direction;
public BevelArrowIcon(int direction, boolean isRaisedView,
boolean isPressedView) {
if (isRaisedView) {
if (isPressedView) {
init(UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
} else {
init(UIManager.getColor("controlHighlight"),
UIManager.getColor("controlShadow"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
} else {
if (isPressedView) {
init(UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
} else {
init(UIManager.getColor("controlShadow"),
UIManager.getColor("controlHighlight"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
}
}
public BevelArrowIcon(Color edge1, Color edge2, Color fill,
int size, int direction) {
init(edge1, edge2, fill, size, direction);
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
switch (direction) {
case DOWN:
drawDownArrow(g, x, y);
break;
case UP:
drawUpArrow(g, x, y);
break;
}
}
@Override
public int getIconWidth() {
return size;
}
@Override
public int getIconHeight() {
return size;
}
private void init(Color edge1, Color edge2, Color fill,
int size, int direction) {
edge1 = Color.red;
edge2 = Color.blue;
this.edge1 = edge1;
this.edge2 = edge2;
this.fill = fill;
this.size = size;
this.direction = direction;
}
private void drawDownArrow(Graphics g, int xo, int yo) {
g.setColor(edge1);
g.drawLine(xo, yo, xo + size - 1, yo);
g.drawLine(xo, yo + 1, xo + size - 3, yo + 1);
g.setColor(edge2);
g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1);
int x = xo + 1;
int y = yo + 2;
int dx = size - 6;
while (y + 1 < yo + size) {
g.setColor(edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x += 1;
y += 2;
dx -= 2;
}
g.setColor(edge1);
g.drawLine(xo + (size / 2), yo + size - 1, xo
+ (size / 2), yo + size - 1);
}
private void drawUpArrow(Graphics g, int xo, int yo) {
g.setColor(edge1);
int x = xo + (size / 2);
g.drawLine(x, yo, x, yo);
x--;
int y = yo + 1;
int dx = 0;
while (y + 3 < yo + size) {
g.setColor(edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x -= 1;
y += 2;
dx += 2;
}
g.setColor(edge1);
g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3);
g.setColor(edge2);
g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2);
g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1);
}
}
}
Upvotes: -3
Reputation: 665
You can look into Oracle's tutorial and example how to use the system tray
Upvotes: -2