Показывать JFrame на определенном экране в конфигурации с двумя мониторами - PullRequest
44 голосов
/ 07 января 2011

У меня есть конфигурация с двумя мониторами, и я хочу запустить свой графический интерфейс на определенном мониторе, если он найден.Я пытался создать свое JFrame окно, пропуская объект GraphicConfiguration моего экранного устройства, но оно не работает, кадр все равно отображается на главном экране.

Как установить экран там, где находится мой кадрдолжен отображаться?

Ответы [ 12 ]

36 голосов
/ 07 января 2011
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" );
    }
}
32 голосов
/ 01 августа 2013

Я изменил ответ @ Джозефа-Гордона, чтобы дать способ достичь этого без принудительного полноэкранного режима:

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" );
    }
}

В этом коде я предполагаю, что getDefaultConfiguration() никогда не вернет ноль. Если это не так, тогда, пожалуйста, поправьте меня. Но этот код работает для перемещения вашего JFrame на нужный экран.

3 голосов
/ 22 июля 2014

Гораздо более чистое решение после прочтения документации для JFrame.setLocationRelativeTo Показать на экране 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);
}

Эта функция может использоваться для переключения окна приложения между экранами

2 голосов
/ 07 января 2011

Пожалуйста, обратитесь к GraphicsDevice API, у вас есть хороший пример там.

1 голос
/ 18 августа 2017

С каждым участником со своими собственными ароматами , основанными на других ароматах, Я добавляю свои , потому что другие заблокировали вас в отношении расположения окна на выбранном экране.

Это просто лучшее. Позволяет вам также указать местоположение на другом экране.

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);
}

Пример:

setLocation(2, 200, 200);

Даже позволяет передавать в процентах за позицию экрана!

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

экран должен быть больше 0, что, я уверен, является жестким требованием!

Чтобы поставить на последнюю, просто позвоните с Integer.MAX_VALUE. **

1 голос
/ 07 января 2011

Мой опыт заключается в расширении рабочих столов на нескольких мониторах по сравнению с настройкой мониторов как отдельных дисплеев (X11).Если это не то, что вы хотите сделать, это не будет применяться.

И мое решение было немного хакерским: я позвонил Toolkit.getScreenSize(), определил, был ли я в ситуации с несколькими мониторами (сравниваявысота до ширины и предполагая, что ширина> удвоенная высота указывает на несколько мониторов), затем устанавливаются начальные положения X и Y кадра.

0 голосов
/ 06 мая 2019

на основе ответа @ryvantage, я улучшил его, чтобы оно отображалось в центре экрана:

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);
}
0 голосов
/ 01 октября 2016

Я изменил ответы @ Joseph-gordon и @ryvantage, чтобы обеспечить способ достижения этого без принудительного использования полноэкранного, фиксированного положения конфигурации экрана и центрирования его на экране выбора:

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" );
    }
}
0 голосов
/ 10 марта 2016

Если вы хотите установить его в центр левого экрана:

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

Если вы хотите установить его в центре правого экрана:

int halfScreen = (int)(screenSize.width/2);
                frame.setLocation((halfScreen - frame.getSize().width)/2 + halfScreen, (screenSize.height - frame.getSize().height)/2);
0 голосов
/ 12 июня 2015

Ответ Вики содержит правильный указатель. Это новый JFrame (GraphicsConfiguration gc), который делает это.

Вы можете сделать это так:

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