Show JFrame in a specific screen in dual monitor configuration
Asked Answered
B

12

52

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?

Bookplate answered 7/1, 2011 at 16:13 Comment(0)
D
46
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" );
    }
}
Devereux answered 7/1, 2011 at 16:31 Comment(3)
But why this relates with "full screen"? What if I need not use full screen mode?Plainsman
@Dims, I gave a new answer that doesn't force full-screen.Waylan
This didn't work for me on a vertical dual monitor setup. Although both are detected in GraphicsDevices, the frame is always shown on the main monitor.Turbinate
W
41

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.

Waylan answered 1/8, 2013 at 0:1 Comment(3)
This solution only works, if the devices are not aligned vertically. Replace frame.getY() with gd[0].getDefaultConfiguration().getBounds().y + frame.getY() to fix this issue.Guilty
This solution (also with @Guilty 's comment) works fine but the window is slightly off-centered. To fix that call frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH); at the end or after the showOnScreen(SCREEN_ID, frame) callSymonds
what is that int screen for? is that index of 0 and 1 code as if the 1st monitor & 2nd monitor ?Inductile
E
6

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" );
    }
}
Englut answered 30/9, 2016 at 22:48 Comment(2)
The reference to 'display' on line 5 is undefined. What does this refer to?Conglomeration
This works perfectly for me in a vertical setup.Turbinate
L
4

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

Leaper answered 22/7, 2014 at 15:21 Comment(3)
What exactly is settings?Apgar
It's probably the output of some settings parser which has a field of String called screen.Isabel
interface with a frame to be positionned?Ciracirca
S
2

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

Stratocracy answered 7/1, 2011 at 16:30 Comment(1)
? seems to create some frame on each screenCiracirca
H
2

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.

Haste answered 18/8, 2017 at 13:26 Comment(0)
J
1

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.

Jeannettejeannie answered 7/1, 2011 at 16:18 Comment(1)
Thank you for adivice. I solved using jframe.setBounds(graphicConfiguration.getBounds())Bookplate
E
1

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);
}
Engeddi answered 6/5, 2019 at 14:55 Comment(0)
A
0

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)

Aeriell answered 5/6, 2014 at 9:31 Comment(0)
S
0

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.

Sech answered 2/9, 2014 at 8:22 Comment(0)
U
0

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;
}
Unbrace answered 12/6, 2015 at 13:9 Comment(0)
A
0

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);
Ara answered 10/3, 2016 at 6:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.