我能用Java创建一个系统托盘应用程序,但我在定位方面遇到了麻烦。该程序只需要处理一些输入/输出,因此我希望它易于访问。
我的问题是,当我点击应用程序的系统托盘图标时,如何在系统托盘上方优雅地设置它?无论显示设置(分辨率,多显示器等)和任务栏位置如何,都要求它执行此操作。有没有办法告诉它在托盘附近打开,而不是完全定位?
我希望它能完全按照Windows中的“网络”设置按钮执行操作。类似于以下内容:
这在Java中是否可行?
答案 0 :(得分:8)
正如Vulcan指出的那样,是的,这是可能的。
此外,我们可以考虑将弹出窗口放在哪里(与任务图标的位置相关)
public class TestTrayIcon {
protected static final PopupFrame POPUP_FRAME = new PopupFrame();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
TrayIcon trayIcon = new TrayIcon(ImageIO.read(new File("D:/DevWork/common/icons/iconex_v_bundle_png/iconexperience/v_collections_png/basic_foundation/16x16/plain/about.png")));
trayIcon.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Point pos = e.getLocationOnScreen();
Rectangle screen = getScreenBoundsAt(pos);
if (pos.x + POPUP_FRAME.getWidth() > screen.x + screen.width) {
pos.x = screen.x + screen.width - POPUP_FRAME.getWidth();
}
if (pos.x < screen.x) {
pos.x = screen.x;
}
if (pos.y + POPUP_FRAME.getHeight() > screen.y + screen.height) {
pos.y = screen.y + screen.height - POPUP_FRAME.getHeight();
}
if (pos.y < screen.y) {
pos.y = screen.y;
}
POPUP_FRAME.setLocation(pos);
POPUP_FRAME.setVisible(true);
}
});
SystemTray.getSystemTray().add(trayIcon);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
public static class PopupFrame extends JFrame {
public PopupFrame() throws HeadlessException {
setLayout(new BorderLayout());
add(new JLabel("Hello world"));
pack();
}
}
public static Rectangle getScreenBoundsAt(Point pos) {
GraphicsDevice gd = getGraphicsDeviceAt(pos);
Rectangle bounds = null;
if (gd != null) {
bounds = gd.getDefaultConfiguration().getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= (insets.left + insets.right);
bounds.height -= (insets.top + insets.bottom);
}
return bounds;
}
public static GraphicsDevice getGraphicsDeviceAt(Point pos) {
GraphicsDevice device = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);
for (GraphicsDevice gd : lstGDs) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
Rectangle screenBounds = gc.getBounds();
if (screenBounds.contains(pos)) {
lstDevices.add(gd);
}
}
if (lstDevices.size() == 1) {
device = lstDevices.get(0);
}
return device;
}
}
答案 1 :(得分:4)
是的,这是可能的。
要设置窗口相对于屏幕右下角的位置,您可以获得图形环境的最大窗口边界,然后执行简单的数学运算。
Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getMaximumWindowBounds();
String os = System.getProperty("os.name");
if (os.contains("Windows")) {
setLocation(screen.width - windowSize.width - 6, screen.height - windowSize.height - 6);
} else if (os.contains("Mac")) {
setLocation(screen.width - windowSize.width + 6, 6);
}
宽度和高度上的- 6
是窗口和任务栏之间的小差距,并且可以轻松自定义。
但是,使用此方法时,请注意位于顶部或左侧的Windows任务栏在窗口的右侧/底部仍将具有任务栏大小的间隙。我不相信可以单独从Java API中找到任务栏方向。