簡體   English   中英

僅在Java中沒有停靠/任務欄圖標的系統托盤中運行

[英]Run only in system tray with no dock/taskbar icon in Java

是否有可能Java應用程序(精確的.jar只能在SystemTray運行,而用戶不會在任務欄/ Dock上看到任何內容,而是擁有像JWindow這樣的可見組件?
一個例子是Dropbox的MacOS應用程序,它在SystemTray顯示以下窗口,同時碼頭上仍然沒有可見圖標。

如果是這樣,那怎么辦呢?

是的,可以做到。 下面是一些示例代碼,它將菜單添加到托盤圖標,並將監聽器添加到該菜單中的菜單項,該菜單項創建了一個用戶單擊該項目的對話框。 當我使用此代碼創建一個可運行的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();
        }
    }
}

當然可以做到(對於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.");
        }
    }
}

您可以從系統托盤圖標中顯示任何您喜歡的內容,但您應該通過彈出菜單進行顯示。

把這一行:

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

作為主要內容的第一個陳述:

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

我已成功通過@DevilsHnd的“TrayIconDemo2”示例嘗試了它,您可以在此頁面中找到另一個答案。


順便說一句,我會添加更多東西給@Muhammad Usman的答案 我已經粘貼了我在下面檢查過的所有答案:

根據JavaFX,您無法在JavaFX應用程序中隱藏停靠圖標。 請查看此鏈接

隱藏停靠圖標有兩種方法。

  • Apple標准方式,只需修改* .app / Contents / Info.plist並添加<key>LSUIElement</key> <string>1</string>
  • 以AWT應用程序啟動應用程序並使用系統屬性隱藏停靠圖標。 設置系統屬性調用后,JavaFX主方法和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被稱為主類方法的前一類。

如果你正在使用maven和其他地方,你也需要修改.pom文件,你提到應用程序的主類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM