Show JFrame in a specific screen in dual monitor configuration

JavaSwingJframeMultiple Monitors

Java Problem Overview


I have a dual monitor config and I want to run my GUI in a specific monitor if it is found. I tried to create my JFrame window passing a GraphicConfiguration object of my screen device, but it doesn't work, frame still display on the main screen.

How can I set the screen where my frame must be displayed?

Java Solutions


Solution 1 - Java

public static void showOnScreen( int screen, JFrame frame )
{
    GraphicsEnvironment ge = GraphicsEnvironment
        .getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    if( screen > -1 && screen < gs.length )
    {
        gs[screen].setFullScreenWindow( frame );
    }
    else if( gs.length > 0 )
    {
        gs[0].setFullScreenWindow( frame );
    }
    else
    {
        throw new RuntimeException( "No Screens Found" );
    }
}

Solution 2 - Java

I have modified @Joseph-gordon's answer to allow for a way to achieve this without forcing full-screen:

public static void showOnScreen( int screen, JFrame frame ) {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gd = ge.getScreenDevices();
    if( screen > -1 && screen < gd.length ) {
        frame.setLocation(gd[screen].getDefaultConfiguration().getBounds().x, frame.getY());
    } else if( gd.length > 0 ) {
        frame.setLocation(gd[0].getDefaultConfiguration().getBounds().x, frame.getY());
    } else {
        throw new RuntimeException( "No Screens Found" );
    }
}

In this code I am assuming getDefaultConfiguration() will never return null. If that is not the case then someone please correct me. But, this code works to move your JFrame to the desired screen.

Solution 3 - Java

I have modified @Joseph-gordon and @ryvantage answer to allow for a way to achieve this without forcing full-screen, fixed screen configuration position and center it on select screen:

public void showOnScreen(int screen, JFrame frame ) {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gd = ge.getScreenDevices();
    int width = 0, height = 0;
    if( screen > -1 && screen < gd.length ) {
        width = gd[screen].getDefaultConfiguration().getBounds().width;
        height = gd[screen].getDefaultConfiguration().getBounds().height;
        frame.setLocation(
            ((width / 2) - (frame.getSize().width / 2)) + gd[screen].getDefaultConfiguration().getBounds().x, 
            ((height / 2) - (frame.getSize().height / 2)) + gd[screen].getDefaultConfiguration().getBounds().y
        );
        frame.setVisible(true);
    } else {
        throw new RuntimeException( "No Screens Found" );
    }
}

Solution 4 - Java

A much cleaner solution after reading the docs for JFrame.setLocationRelativeTo Display on screen 2

public void moveToScreen() {
    setVisible(false);
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] screens = ge.getScreenDevices();
    int n = screens.length;
    for (int i = 0; i < n; i++) {
        if (screens[i].getIDstring().contentEquals(settings.getScreen())) {
            JFrame dummy = new JFrame(screens[i].getDefaultConfiguration());
            setLocationRelativeTo(dummy);
            dummy.dispose();
        }
    }
    setVisible(true);
}

This function can be used to switch application window between screens

Solution 5 - Java

Please Refer to GraphicsDevice API, you have a good example there.

Solution 6 - Java

With everyone chipping in with their own flavors, based on other flavors, I add mine because the others locked you in with regards to positioning of the window on the selected screen.

It is simply the best. It allows you to set the location on the other screen as well.

public void setLocation( int screen, double x, double y ) {
        GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[]    d = g.getScreenDevices();

        if ( screen >= d.length ) {
                screen = d.length - 1;
        }

        Rectangle bounds = d[screen].getDefaultConfiguration().getBounds();
        
        // Is double?
        if ( x == Math.floor(x) && !Double.isInfinite(x) ) {
                x *= bounds.x;  // Decimal -> percentage
        }
        if ( y == Math.floor(y) && !Double.isInfinite(y) ) {
                y *= bounds.y;  // Decimal -> percentage
        }

        x = bounds.x      + x;
        y = jframe.getY() + y;

        if ( x > bounds.x) x = bounds.x;
        if ( y > bounds.y) y = bounds.y;

        // If double we do want to floor the value either way 
        jframe.setLocation((int)x, (int)y);
}

Example:

setLocation(2, 200, 200);

Even allows you to pass in a percentage for the screen position!

setLocation(2, 0.5, 0);     // Place on right edge from the top down if combined with setSize(50%, 100%);

screen must be larger than 0, which I am sure is a tough requirement!

To place on last, simply call with Integer.MAX_VALUE.

Solution 7 - Java

My experience is with extending desktops across multiple monitors, versus configuring the monitors as separate (X11) displays. If that's not what you want to do, this won't apply.

And my solution was a bit of a hack: I called Toolkit.getScreenSize(), determined if I was in a multi-monitor situation (by comparing the height to the width and assuming that width > twice height indicated multi-monitor), then setting the initial X and Y position of the frame.

Solution 8 - Java

based on @ryvantage answer, I improved it so it is displayed in the center of the screen:

private static void showOnScreen( int screen, Window frame ) {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gd = ge.getScreenDevices();
    GraphicsDevice graphicsDevice;
    if( screen > -1 && screen < gd.length ) {
        graphicsDevice = gd[screen];
    } else if( gd.length > 0 ) {
        graphicsDevice = gd[0];
    } else {
        throw new RuntimeException( "No Screens Found" );
    }
    Rectangle bounds = graphicsDevice.getDefaultConfiguration().getBounds();
    int screenWidth = graphicsDevice.getDisplayMode().getWidth();
    int screenHeight = graphicsDevice.getDisplayMode().getHeight();
    frame.setLocation(bounds.x + (screenWidth - frame.getPreferredSize().width) / 2,
            bounds.y + (screenHeight - frame.getPreferredSize().height) / 2);
    frame.setVisible(true);
}

Solution 9 - Java

For me worked well also (supposing left monitor has size 1920x1200):

A) set on left monitor on some exact position:

newFrame.setBounds(200,100,400,200)

B) set on right monitor on some exact position:

newFrame.setBounds(2000,100,200,100)

C) set on left monitor maximized:

newFrame.setBounds(200,100,400,200) newFrame.setExtendedState(JFrame.MAXIMIZED_BOTH)

D) set on right monitor maximized

newFrame.setBounds(2000,100,200,100) newFrame.setExtendedState(JFrame.MAXIMIZED_BOTH)

Solution 10 - Java

Many of the solutions here works for extended displays. If you are using separate displays just pass the graphics configuration object of the desired graphics device to the constructor of jframe or jdialog.

Solution 11 - Java

Vickys answer contains the right pointer. It is new JFrame(GraphicsConfiguration gc) that does it.

You can do it like that:

GraphicsDevice otherScreen = getOtherScreen(this);
JFrame frameOnOtherScreen = new JFrame(otherScreen.getDefaultConfiguration());

private GraphicsDevice getOtherScreen(Component component) {
	GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
	if (graphicsEnvironment.getScreenDevices().length == 1) {
		// if there is only one screen, return that one
		return graphicsEnvironment.getScreenDevices()[0];
	}

	GraphicsDevice theWrongOne = component.getGraphicsConfiguration().getDevice();
	for (GraphicsDevice dev : graphicsEnvironment.getScreenDevices()) {
		if (dev != theWrongOne) {
			return dev;
		}
	}

	return null;
}

Solution 12 - Java

If u want to set it to center of left screen:

int halfScreen = (int)(screenSize.width/2);
				frame.setLocation((halfScreen - frame.getSize().width)/2, (screenSize.height - frame.getSize().height)/2);

If u want to set it to center of right screen:

int halfScreen = (int)(screenSize.width/2);
				frame.setLocation((halfScreen - frame.getSize().width)/2 + halfScreen, (screenSize.height - frame.getSize().height)/2);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionblowView Question on Stackoverflow
Solution 1 - JavaJoseph GordonView Answer on Stackoverflow
Solution 2 - JavaryvantageView Answer on Stackoverflow
Solution 3 - JavaGerardo Cignarella GodoyView Answer on Stackoverflow
Solution 4 - JavaVicky RonnenView Answer on Stackoverflow
Solution 5 - Javaring bearerView Answer on Stackoverflow
Solution 6 - JavamjsView Answer on Stackoverflow
Solution 7 - JavaAnonView Answer on Stackoverflow
Solution 8 - JavalqbwebView Answer on Stackoverflow
Solution 9 - Javauser2641449View Answer on Stackoverflow
Solution 10 - JavaSadoView Answer on Stackoverflow
Solution 11 - Javauser2081279View Answer on Stackoverflow
Solution 12 - JavaLalitheshView Answer on Stackoverflow