Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中从系统托盘中弹出JFrame_Java_Windows_Swing_Jframe_System Tray - Fatal编程技术网

如何在Java中从系统托盘中弹出JFrame

如何在Java中从系统托盘中弹出JFrame,java,windows,swing,jframe,system-tray,Java,Windows,Swing,Jframe,System Tray,我能够用Java创建一个系统托盘应用程序,但在定位方面遇到了问题。该程序只需要处理一些输入/输出,因此我希望它易于访问 我的问题是,当我为我的应用程序单击系统托盘图标时,如何将其优雅地设置在系统托盘上方?其要求是,无论显示设置(分辨率、多显示器等)和任务栏位置如何,它都会执行此操作。有没有办法告诉它在托盘附近打开,而不是将其定位 我想让它完全像Windows中的“网络”设置按钮那样。与以下内容类似: 这在Java中可能吗?是的,可能 要设置窗口相对于屏幕右下角的位置,可以获得图形环境的最大窗口

我能够用Java创建一个系统托盘应用程序,但在定位方面遇到了问题。该程序只需要处理一些输入/输出,因此我希望它易于访问

我的问题是,当我为我的应用程序单击系统托盘图标时,如何将其优雅地设置在系统托盘上方?其要求是,无论显示设置(分辨率、多显示器等)和任务栏位置如何,它都会执行此操作。有没有办法告诉它在托盘附近打开,而不是将其定位

我想让它完全像Windows中的“网络”设置按钮那样。与以下内容类似:

这在Java中可能吗?

是的,可能

要设置窗口相对于屏幕右下角的位置,可以获得图形环境的最大窗口边界,然后执行简单的数学运算

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任务栏在窗口的右侧/底部仍有任务栏大小的间隙。我不相信仅仅从JavaAPI就可以找到任务栏方向。

正如Vulcan所指出的,是的,这是可能的

此外,还可以考虑将弹出窗口放置在何处(与任务图标所在的位置相关)

公共类TestTrayIcon{
受保护的静态最终PopupFrame POPUP_FRAME=新PopupFrame();
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
TrayIcon TrayIcon=new TrayIcon(ImageIO.read(新文件(“D:/DevWork/common/icons/iconex\u v\u bundle\u png/iconexperience/v\u collections\u png/basic\u foundation/16x16/plain/about.png”);
trayIcon.addMouseListener(新的MouseAdapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
点位置=e.getLocationOnScreen();
矩形屏幕=getScreenBoundsAt(位置);
if(pos.x+POPUP_FRAME.getWidth()>screen.x+screen.width){
pos.x=screen.x+screen.width-POPUP_FRAME.getWidth();
}
如果(位置x<屏幕x){
位置x=屏幕x;
}
if(pos.y+POPUP_FRAME.getHeight()>screen.y+screen.height){
pos.y=screen.y+screen.height-POPUP_FRAME.getHeight();
}
如果(位置y<屏幕y){
位置y=屏幕y;
}
弹出框设置位置(pos);
弹出框设置可见(真);
}
});
SystemTray.getSystemTray().add(trayIcon);
}捕获(例外情况除外){
例如printStackTrace();
}
}
});
}
公共静态类PopupFrame扩展了JFrame{
public PopupFrame()引发HeadlessException{
setLayout(新的BorderLayout());
添加(新JLabel(“Hello world”);
包装();
}
}
公共静态矩形getScreenBoundsAt(点位置){
GraphicsDevice gd=GetGraphicsDevice(位置);
矩形边界=空;
如果(gd!=null){
bounds=gd.getDefaultConfiguration().getBounds();
Insets Insets=Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
bounds.x+=左插图;
bounds.y+=insets.top;
bounds.width-=(插图左+插图右);
bounds.height-=(insets.top+insets.bottom);
}
返回边界;
}
公共静态图形设备获取图形设备(点位置){
GraphicsDevice设备=空;
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[]=ge.getScreenDevices();
ArrayList lstDevices=新的ArrayList(lstGDs.length);
用于(图形设备gd:lstGDs){
GraphicsConfiguration gc=gd.getDefaultConfiguration();
矩形screenBounds=gc.getBounds();
如果(屏幕边界包含(位置)){
添加(gd);
}
}
如果(lstDevices.size()==1){
device=lstDevices.get(0);
}
返回装置;
}
}

如果任务栏不在屏幕底部怎么办?@MadProgrammer很少有人将Windows任务栏放置在底部以外的位置;我不确定Java API中是否有办法检测它在哪一边。在Windows 7中,任务栏位于顶部时,窗口仍将显示在右下角,窗口下方有任务栏高度间隙。猜猜这一小部分中有谁;)-还有,你在给Mac打折扣;)谢谢你的快速回复。这是否适用于水平双监视器,或者MaximumWindowBounds()是否等于两个监视器的长度?@DustinFain
MaximumWindowBounds
应该适用于水平监视器。这是一种非常巧妙的方法;比我的更全面。早上这么早就这么做真是太好了+1不幸的是,我也同意我的回答:P我的应用程序不会在点击时弹出窗口,而是在按下组合键时弹出窗口(这是一个剪贴板上载应用程序,窗口显示上载进度),但考虑到您指出的情况,我稍后将重新编写该应用程序
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;
    }
}