2

我创建了一个支持系统托盘通知的程序。我为我的系统托盘设置了一个带有工具提示和气球消息的图标。当我启动程序时,图标出现在 Windows 的通知区域图标中,旁边的默认名称是 Java(TM) Platform SE Binary。我可以将此默认名称更改为自定义名称,例如我的程序名称吗?

4

2 回答 2

5

请也用这段代码引起

import java.awt.AWTException;
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 java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

public class ActiveTray {

    private SystemTray tray;
    private TrayIcon trayIcon;
    private Icon icon, icon1;
    private Image image, image1;
    private Timer timer;

    public ActiveTray() {
        if (SystemTray.isSupported() == false) {
            System.err.println("No system tray available");
            return;
        }
        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 = new BevelArrowIcon(BevelArrowIcon.UP, false, false);
        image = iconToImage(icon);
        icon1 = new BevelArrowIcon(BevelArrowIcon.DOWN, false, false);
        image1 = iconToImage(icon1);
        PopupMenu popup = new PopupMenu();
        MenuItem item = new MenuItem("Hello, World");
        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);
        try {
            tray.add(trayIcon);
            start();
        } catch (AWTException ex) {
            Logger.getLogger(ActiveTray.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void start() {
        timer = new javax.swing.Timer(125, updateCol());
        timer.start();
        trayIcon.displayMessage(null, "  Aplication Loaded  ", TrayIcon.MessageType.NONE);
    }

    private Action updateCol() {
        return new AbstractAction("Icon load action") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                Runnable doRun = new Runnable() {

                    @Override
                    public void run() {
                        Image img = trayIcon.getImage();
                        if (img == image) {
                            trayIcon.setImage(image1);
                        } else {
                            trayIcon.setImage(image);
                        }
                    }
                };
                SwingUtilities.invokeLater(doRun);
            }
        };
    }

    public static void main(String args[]) {
        ActiveTray activeTray = new ActiveTray();
    }

    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);
        }
    }
}
于 2013-04-05T12:35:23.533 回答
3

我今天遇到了同样的问题。正如 Petesh 在评论中提到的,我使用自定义启动器来解决这个问题。

启动4j

Launch4j 是一个跨平台工具,用于将作为 jar 包分发的 Java 应用程序打包到轻量级 Windows 本机可执行文件中。

以下是我创建它的步骤:

  1. 基本的
    1. 设置输出文件名
    2. 选择“不包装罐子,仅启动”
    3. 输入 .jar 文件的相对路径
      (我建议使用相同的文件夹以及 .exe 和 .jar 文件)
  2. 类路径
    这是必要的,因为我们不会通过 javaw.exe 或 java.exe 启动,
    只需导航到“主类”下的 .jar 文件就足够了,
    您应该看到主类出现并且列表应该为空
  3. Header
    Header Type: JNI GUI (beta),来自文档:

    当使用 JNI 标头时,JVM 由 launch4j 包装器可执行文件直接创建,而不是运行 java/javaw 启动器。进程名称将与包装器相同。

  4. JRE
    1. 输入适当的最低 JRE 版本
    2. 选择 32-bit only , JNI headers 当前与 64-Bit JRE 不兼容
  5. 版本信息
    1. 检查添加版本信息
    2. 填写所有必填字段文件描述
      条目 显示在 Windows 通知中

现在剩下要做的就是保存配置并构建。你会看到这样的警告:

警告:JNI 标头中未实现某些功能,请参阅文档。

这些限制可以在 <headerType> 下找到。

您当然可以使用完全不同的选项,例如捆绑 JRE 或将 .jar 捆绑到 .exe 文件中。

于 2017-06-14T04:25:45.290 回答