一个Java应用程序({1}}可以准确地运行,是否有可能只在.jar
中运行,而用户在任务栏/ Dock上看不到任何内容但是有{{{}}之类的可见组件1}}?
一个例子是Dropbox的MacOS应用程序,其中SystemTray
显示以下窗口,但在停靠栏中仍然没有可见图标。
如果是,那该怎么办呢?
答案 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文件。 您还提到了其他主要类别的应用程序。