仅在系统托盘中运行,而在Java

时间:2017-04-27 23:57:44

标签: java

一个Java应用程序({1}}可以准确地运行,是否有可能只在.jar中运行,而用户在任务栏/ Dock上看不到任何内容但是有{{{}}之类的可见组件1}}?
一个例子是Dropbox的MacOS应用程序,其中SystemTray显示以下窗口,但在停靠栏中仍然没有可见图标。

如果是,那该怎么办呢?

3 个答案:

答案 0 :(得分:0)

是的,可以做到。下面是一些示例代码,它将菜单添加到托盘图标,并将监听器添加到该菜单中的菜单项,该菜单项创建了一个用户单击该项目的对话框。当我使用此代码创建一个可运行的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();
        }
    }
}

答案 1 :(得分:0)

当然可以做到(对于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.");
        }
    }
}

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

答案 2 :(得分:0)

放入此行:

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应用程序将立即接管而没有停靠图标。   请参阅下面的示例代码片段。
  •   
     

/**
 - 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,则还需要修改.pom文件。   您还提到了其他主要类别的应用程序。