How to know if a JFrame is on screen in a multi sc

2019-07-18 03:43发布

My application is used in multi-screen environments. The application stores it's location on close and starts on the last position.
I obtain the position by calling frame.getLocation() This gives me a positive value if the frame is on the main screen or it is on the right of the main screen. Frames located on a screen left to the main screen get negative values for X.
The problem comes up, when the screen configuration changes (for example multiple users share one Citrix-Account and have different screen resolutions).

My problem now is to determine if the stored position is visible on the screen. According to some other posts, I should use GraphicsEnvironment to get the size of the available screens, but I can't get the position of the different screens.

Example: getLocation() gives Point(-250,10)
GraphicsEnvironment gives
Device1-Width: 1920
Device2-Width: 1280

Now, depending on the ordering of the screens (wether the secondary monitor is placed on the left or on the right of the primary one), the frame might be visible, or not.

Can you tell me how to fix this problem?

Thanks a lot

2条回答
地球回转人心会变
2楼-- · 2019-07-18 04:19

This is a little redumentry, but, if all you want to know is if the frame would be visible on the screen, you could calculate the "virtual" bounds of desktop and test to see if the frame is contained within in.

public class ScreenCheck {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setBounds(-200, -200, 200, 200);
        Rectangle virtualBounds = getVirtualBounds();

        System.out.println(virtualBounds.contains(frame.getBounds()));

    }

    public static Rectangle getVirtualBounds() {
        Rectangle bounds = new Rectangle(0, 0, 0, 0);
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice lstGDs[] = ge.getScreenDevices();
        for (GraphicsDevice gd : lstGDs) {
            bounds.add(gd.getDefaultConfiguration().getBounds());
        }
        return bounds;
    }
}

Now, this uses the Rectangle of the frame, but you could use it's location instead.

Equally, you could use each GraphicsDevice individually and check each one in turn...

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-07-18 04:22

This might be helpful to others out there looking for a similar solution.

I wanted to know if any part of my swing application location was off the screen. This method calculates the application's area and determines if all of it is visible, even if it's split across multiple screens. Helps when you save your applications location and then restart it and your display configuration is different.

public static boolean isClipped(Rectangle rec) {

    boolean isClipped = false;
    int recArea = rec.width * rec.height;
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice sd[] = ge.getScreenDevices();
    Rectangle bounds;
    int boundsArea = 0;

    for (GraphicsDevice gd : sd) {
        bounds = gd.getDefaultConfiguration().getBounds();
        if (bounds.intersects(rec)) {
            bounds = bounds.intersection(rec);
            boundsArea = boundsArea + (bounds.width * bounds.height);
        }
    }
    if (boundsArea != recArea) {
        isClipped = true;
    }
    return isClipped;
}
查看更多
登录 后发表回答