2

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

klib009
  • 263
  • 5
  • 18

2 Answers2

6

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...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • This seems problematic since the screen area may not be rectangular. How can you tell if an app is sitting above your smaller screen, but still lower than the top of your larger one? Still it's going in the right direction! – Bill K Feb 05 '21 at 19:42
  • @BillK This would need you know the screens and their positions, once you have the rectangle bounds of each screen, you can start making decisions about "how" it's laid out – MadProgrammer Feb 05 '21 at 22:45
  • @BillK You could have a look at [something like this](https://stackoverflow.com/questions/21585121/java-getting-mouse-location-on-multiple-monitor-environment/21592711#21592711) which generates a "virtual" view of your screen layouts - once you have the rectangles, you can determine their positions relative to each and make decisions about what you want to do - the problem then comes down to basic geometry – MadProgrammer Feb 05 '21 at 22:54
5

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;
}
John
  • 61
  • 1
  • 3