web-dev-qa-db-ja.com

デュアルモニター構成で特定の画面にJFrameを表示する

デュアルモニター構成があり、GUIが見つかった場合は特定のモニターでGUIを実行したい。スクリーンデバイスのJFrameオブジェクトを渡すGraphicConfigurationウィンドウを作成しようとしましたが、動作しません。メイン画面にフレームが表示されたままです。

フレームを表示する必要がある画面を設定するにはどうすればよいですか?

44
blow
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" );
    }
}
37
Joseph Gordon

フルスクリーンを強制せずにこれを達成する方法を可能にするために、@ Joseph-gordonの答えを修正しました。

_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()は決してnullを返さないと想定しています。そうでない場合は、誰かが私を修正してください。ただし、このコードは、JFrameを目的の画面に移動するために機能します。

33
ryvantage

画面2のJFrame.setLocationRelativeTo Displayのドキュメントを読んだ後のはるかにクリーンなソリューション

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

この関数を使用して、画面間でアプリケーションウィンドウを切り替えることができます。

3
Vicky Ronnen

GraphicsDevice APIを参照してください。良い例があります。

2
ring bearer

他のフレーバーに基づいて、みんながown flavorsでチッピングしているので、I add mine選択した画面上のウィンドウの位置に関して他のユーザーがあなたをロックしたためです。

これは単に最高です。他の画面でも同様に場所を設定できます。

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
momomo

私の経験では、デスクトップを複数のモニターに拡張し、モニターを個別の(X11)ディスプレイとして構成しています。それがあなたがしたいことではない場合、これは適用されません。

そして私の解決策はちょっとしたハックでした:Toolkit.getScreenSize()を呼び出し、マルチモニターの状況にあるかどうかを判断しました(高さと幅を比較し、幅が高さの2倍がマルチモニターを示していると仮定して) 、次にフレームの最初のXおよびY位置を設定します。

1
Anon

@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
lqbweb

左画面の中央に設定する場合:

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
Lalithesh

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

ここでのソリューションの多くは、拡張ディスプレイで機能します。個別のディスプレイを使用している場合は、目的のグラフィックデバイスのグラフィック構成オブジェクトをjframeまたはjdialogのコンストラクターに渡すだけです。

0
Sado

Vickysの回答には正しいポインターが含まれています。それを行うのは新しい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;
}
0
user2081279

私にとってもうまくいきました(左のモニターのサイズが1920x1200だと仮定して):

A)いくつかの正確な位置で左モニターに設定:

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

B)正確な位置で右モニターに設定します:

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

C)左モニターを最大に設定:

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

D)右モニターを最大に設定

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

0
user2641449