遗留问题:
win7 java.awt.TrayIcon的displayMessage方法没有生效,通知消息不能正常弹出。
许多桌面环境都有一个区域用于放置在后台运行的程序的图标,这些程序偶尔会将某些事件通知给用户。
在Windos中,这个区域称为系统托盘,而这些图标称托盘图标。
java.awt.SystemTray类是跨平台的通向系统托盘的渠道,与前面讨论过的Desktop类似,首先要调用静态的SystemTray.isSupported方法来检查Java平台是否支持系统托盘。如果支持则通过调用静态的getSystemTray方法来获取SystemTray的单例。
SystemTray类是取重要的方法是add,它使得可以添加一个TrayIcon实例,托盘图标有三个主要的属性:
(1)图标的图像
(2)当鼠标滑过图标时显示的工具提示
(3)当用户用鼠标右键点击图标时显示右键菜单
package swing.systemtray; import java.awt.AWTException; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import javax.swing.Timer; /*2015-7-8*/ public class SystemTrayTest { public static void main(String[] args) { if (!SystemTray.isSupported()) { System.err.println("System tray is no supported"); return; } SystemTray tray = SystemTray.getSystemTray(); Image image = Toolkit.getDefaultToolkit().getImage("logo.jpg"); PopupMenu popup = new PopupMenu(); MenuItem exitItem = new MenuItem("Exit"); exitItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); popup.add(exitItem); final TrayIcon trayIcon = new TrayIcon(image, "Your Fortune", popup); trayIcon.setImageAutoSize(true); trayIcon.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("click me"); trayIcon.displayMessage("How do I turn this off", "Right-click on the fortune cookie and select exit", TrayIcon.MessageType.INFO); } }); try { tray.add(trayIcon); } catch (AWTException e1) { System.err.println("TrayIcon could not be added."); return; } final List<String> fortunes = readFortunes(); Timer timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int index = (int) (fortunes.size() * Math.random()); System.out.println("is "+index); trayIcon.displayMessage("Your Fortune", fortunes.get(index), TrayIcon.MessageType.INFO); } }); timer.start(); } private static List<String> readFortunes() { List<String> fortunes = new ArrayList<String>(); String path = SystemTrayTest.class.getResource("/swing/systemtray/fortunes.txt").getPath(); try { Scanner in = new Scanner(new File(path)); StringBuilder fortune = new StringBuilder(); while (in.hasNextLine()) { String line = in.nextLine(); if (line.equals("%")) { fortunes.add(fortune.toString()); fortune.setLength(0); } else { fortune.append(line); fortune.append(" "); } } } catch (FileNotFoundException e) { e.printStackTrace(); } System.out.println(fortunes.size()); System.out.println(fortunes); return fortunes; } }
fortunes.txt
Y1000 Y1000,000 % Y1000,000 Y1000,000,000 % Y5000,000 Y5000,000,000 % Y1000,000,000 Y1000,000,000,000 %
TrayIcon增加鼠标双击事件的监听:
trayIcon.setImageAutoSize(true);//如果托盘图标空间不够,那么图标将会被裁切 trayIcon.addMouseListener(new java.awt.event.MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if(e.getClickCount()==2){ showInterface(); } } }
demo2:绘制图标:
package swing.systemtray; 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); } } }
http://stackoverflow.com/questions/12667526/adding-jpopupmenu-to-the-trayicon