Search code examples
javaswinggraphicsjframe

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


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


Solution

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