【问题标题】:Run only in system tray with no dock/taskbar icon in Java仅在系统托盘中运行,Java 中没有停靠/任务栏图标
【发布时间】:2017-04-27 23:57:43
【问题描述】:

Java 应用程序,确切地说是.jar,是否有可能只在SystemTray 中运行,而用户在他的任务栏/dock 上没有看到任何东西,但有像JWindow 这样的可见组件?
一个例子是 Dropbox 的 MacOS 应用程序,它在SystemTray 中出现以下窗口,但在停靠栏上仍然没有可见的图标。

如果是这样,那该怎么做呢?

【问题讨论】:

  • 您要的是 Windows 还是其他操作系统? AWT?其他框架?
  • 有没有搜到这样的情况?
  • 当然。在系统托盘中放置一个图标。不要显示窗口。
  • kichik 任何操作系统都可以,我只是好奇。 可怕的袋熊不,我只是好奇这样的事情是否可能。

标签: java


【解决方案1】:

把这一行:

System.setProperty("apple.awt.UIElement", "true");

作为你的主要声明:

public static void main(String[] args) {
    System.setProperty("apple.awt.UIElement", "true");
    // Your stuff...
}

我已成功尝试使用 @DevilsHnd 的“TrayIconDemo2”示例,您可以在此页面中找到另一个答案。


顺便说一句,我会添加更多的东西给@Muhammad Usman 的this answer。 我已将我检查过的所有答案粘贴在下面:

根据 JavaFX,您无法在 JavaFX 应用程序中隐藏停靠图标。 请查看此link

有两种方法可以隐藏停靠图标。

  • Apple 标准方式,只需修改 *.app/Contents/Info.plist 并添加<key>LSUIElement</key> <string>1</string>
  • 以 AWT 应用程序启动您的应用程序并使用系统属性隐藏停靠图标。设置系统属性后调用 JavaFX main 方法和 JavaFX 应用程序现在将接管,没有停靠图标。 请参阅下面的示例代码 sn-p。

/**
 - This class is intended to start application as AWT application before initializing
 - JavaFX application. JavaFX does not support dock-icon-less application so we are 
 - creating JavaFX application from AWT application so that we can achieve the desired
 - functionality.
 - */

public class AWTMain {

  public static void main(String[] args) {

      // This is awt property which enables dock-icon-less
      // applications 
      System.setProperty("apple.awt.UIElement", "true");
      java.awt.Toolkit.getDefaultToolkit();

      // This is a call to JavaFX application main method.
      // From now on we are transferring control to FX application. 
      FXMain.main(args);
  }
}

这里的 FXMain 被称为具有 main 方法的前一个类。

如果您使用 maven 和 其他地方你也提到了应用程序的主类。

【讨论】:

    【解决方案2】:

    是的,它可以做到。下面是一些示例代码,它将菜单添加到托盘图标,并将侦听器添加到该菜单中的菜单项,该菜单项会在用户单击该项目时创建一个对话框。当我使用此代码创建可运行 jar 时,它不会在任务栏上显示图标,而只会在系统托盘中显示图标。

    import java.awt.AWTException;
    import java.awt.Image;
    import java.awt.SystemTray;
    import java.awt.TrayIcon;
    import java.awt.Menu;
    import java.awt.MenuItem;
    import java.awt.PopupMenu;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.net.URL;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    
    public class SystemTrayExample {
        private static final SystemTray tray = SystemTray.getSystemTray();
        private static final PopupMenu popup = new PopupMenu();
        private static TrayIcon trayIcon;
    
        public static void main(String[] args) {
    
            if (!SystemTray.isSupported()) {
                // SystemTray is not supported
            }
    
            trayIcon = new TrayIcon(createImage("icon.jpg", "tray icon"));
            trayIcon.setImageAutoSize(true);
    
            ActionListener listener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    MenuItem item = (MenuItem) e.getSource();
    
                    String s = (String) JOptionPane.showInputDialog(null, "Report "
                            + item.getLabel(), "Create Report",
                            JOptionPane.PLAIN_MESSAGE, null, null, "");
    
                    // Do something with the string...
                }
            };
            MenuItem exitItem = new MenuItem("Exit");
            exitItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    tray.remove(trayIcon);
                    System.exit(0);
                }
            });
    
    
            Menu reportMenu = new Menu("Report");
            MenuItem menuItem = new MenuItem("Item");
            reportMenu.add(menuItem);
            menuItem.addActionListener(listener);
            popup.add(reportMenu);
            popup.add(exitItem);
            trayIcon.setPopupMenu(popup);
    
            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                // TrayIcon could not be added
            }
    
        }
    
        // Obtain the image URL
        protected static Image createImage(String path, String description) {
            URL imageURL = SystemTrayExample.class.getResource(path);
    
            if (imageURL == null) {
                System.err.println("Resource not found: " + path);
                return null;
            } else {
                return (new ImageIcon(imageURL, description)).getImage();
            }
        }
    }
    

    【讨论】:

    • 这确实改善了这种情况,因为它向我的 SystemTray 添加了一个图标,从而使用户可以访问它。现在剩下的就是让图标从任务栏/停靠栏中消失。
    【解决方案3】:

    当然可以(无论如何对于 Windows)。这是一个带有弹出菜单的可运行示例。托盘中显示的图标是从 URL 中检索的(使用您想要的任何图标:

    import java.awt.AWTException;
    import java.awt.CheckboxMenuItem;
    import java.awt.Image;
    import java.awt.Menu;
    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.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;
    
    
    public class TrayIconDemo2 {
    
        public TrayIconDemo2() throws Exception {
            initComponents();
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        new TrayIconDemo2();
                    } catch (Exception ex) { System.out.println("Error - " + ex.getMessage()); }
                }
            });
        }
    
        private void initComponents() throws Exception {
            createAndShowTray();
        }
    
        private void createAndShowTray() throws Exception {
            //Check the SystemTray is supported
            if (!SystemTray.isSupported()) {
                System.out.println("SystemTray is not supported");
                return;
            }
    
            PopupMenu popup = new PopupMenu();
            //retrieve icon form url and scale it to 32 x 32
            final TrayIcon trayIcon = new TrayIcon(ImageIO.read(
                    new URL("http://www.optical-illusions.com/thumb/ec665b8dfcc248da272224972e9eaf92.jpg"))
                    .getScaledInstance(32, 32, Image.SCALE_SMOOTH), null);
    
            //get the system tray
            final SystemTray tray = SystemTray.getSystemTray();
    
            // Create a pop-up menu components
            MenuItem aboutItem = new MenuItem("About");
            aboutItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    JOptionPane.showMessageDialog(null, "About");
                }
            });
    
            final  CheckboxMenuItem cb1 = new CheckboxMenuItem("Show Tooltip");
            cb1.addItemListener(new ItemListener() {
                @Override
                public void itemStateChanged(ItemEvent ie) {
                    if(cb1.getState()==true) {
                    trayIcon.setToolTip("Hello, world");
                    }else {
                    trayIcon.setToolTip("");
                    }
                }
            });
    
            Menu displayMenu = new Menu("Display");
    
            MenuItem infoItem = new MenuItem("Info");
            //add actionlistner to Info menu item
            infoItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    JOptionPane.showMessageDialog(null, "Display Info of some sort :D");
                }
            });
    
            MenuItem exitItem = new MenuItem("Exit");
            //add actionlistner to Exit menu item
            exitItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    System.exit(0);
                }
            });
    
            //Add components to pop-up menu
            popup.add(aboutItem);
            popup.addSeparator();
            popup.add(cb1);
            popup.addSeparator();
            popup.add(displayMenu);
            displayMenu.add(infoItem);
            popup.add(exitItem);
    
            trayIcon.setPopupMenu(popup);
    
            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                System.out.println("TrayIcon could not be added.");
            }
        }
    }
    

    您可以通过系统托盘图标显示您喜欢的任何内容,但您应该通过弹出菜单来进行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多