Java 在双监视器配置的特定屏幕中显示JFrame

Java 在双监视器配置的特定屏幕中显示JFrame,java,swing,jframe,multiple-monitors,Java,Swing,Jframe,Multiple Monitors,我有一个双监视器配置,如果找到,我想在一个特定的监视器中运行我的GUI。我试图通过屏幕设备的graphicsconfiguration对象创建我的JFrame窗口,但它不起作用,frame仍然显示在主屏幕上 如何设置必须显示帧的屏幕?我的经验是将桌面扩展到多个监视器,而不是将监视器配置为单独的(X11)显示器。如果这不是你想做的,这就不适用了 我的解决方案有点像黑客:我调用了Toolkit.getScreenSize(),确定我是否处于多监视器状态(通过比较高度和宽度,并假设宽度>两倍高度表示多

我有一个双监视器配置,如果找到,我想在一个特定的监视器中运行我的GUI。我试图通过屏幕设备的
graphicsconfiguration
对象创建我的
JFrame
窗口,但它不起作用,frame仍然显示在主屏幕上


如何设置必须显示帧的屏幕?

我的经验是将桌面扩展到多个监视器,而不是将监视器配置为单独的(X11)显示器。如果这不是你想做的,这就不适用了

我的解决方案有点像黑客:我调用了
Toolkit.getScreenSize()
,确定我是否处于多监视器状态(通过比较高度和宽度,并假设宽度>两倍高度表示多监视器),然后设置帧的初始X和Y位置。

请参考API,这里有一个很好的例子。

公共静态无效显示屏幕(int-screen,JFrame)
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" );
    }
}
{ GraphicsEnvironment ge=GraphicsEnvironment .getLocalGraphicsEnvironment(); GraphicsDevice[]gs=ge.getScreenDevices(); 如果(屏幕>-1&&screen0) { gs[0].setFullScreenWindow(框架); } 其他的 { 抛出新的RuntimeException(“未找到屏幕”); } }
我修改了@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" );
    }
}
publicstaticvoidshowonscreen(intscreen,JFrame){
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[]gd=ge.getScreenDevices();
如果(屏幕>-1&&screen0){
frame.setLocation(gd[0].getDefaultConfiguration().getBounds().x,frame.getY());
}否则{
抛出新的RuntimeException(“未找到屏幕”);
}
}
在这段代码中,我假设
getDefaultConfiguration()
永远不会返回null。如果不是这样的话,请有人纠正我。但是,此代码可以将您的
JFrame
移动到所需屏幕。

对我来说也很有效(假设左侧显示器的大小为1920x1200):

A) 将左监视器设置在某个精确位置:

newFrame.setBounds(200100400200)

B) 将右监视器设置在某个精确位置:

newFrame.setBounds(2000100200100)

C) 在左侧监视器上设置最大化:

newFrame.setBounds(200100400200)
newFrame.setExtendedState(JFrame.MAXIMIZED\u两者)

D) 设置为右监视器最大化

newFrame.setBounds(2000100200100)

newFrame.setExtendedState(JFrame.MAXIMIZED_两者)

阅读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);
}
public void moveToScreen(){
setVisible(假);
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[]screens=ge.getScreenDevices();
int n=屏幕长度;
对于(int i=0;i

此功能可用于在屏幕之间切换应用程序窗口

此处的许多解决方案适用于扩展显示。如果使用单独的显示,只需将所需图形设备的图形配置对象传递给jframe或jdialog的构造函数

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

如果要将其设置为左屏幕的中心:

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

我已经修改了@Joseph gordon和@ryvantage answer,以便在不强制全屏固定屏幕配置位置的情况下实现这一点,并将其置于选择屏幕的中心:

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" );
    }
}
public void show屏幕(int屏幕,JFrame){
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[]gd=ge.getScreenDevices();
整数宽度=0,高度=0;
如果(屏幕>-1&&screen
由于每个人都加入了自己的口味,基于其他口味,我添加了我的,因为其他人在选定屏幕上锁定了窗口的位置

这是最好的。它还允许您在另一个屏幕上设置位置

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_值调用。**

基于@ryvantage answer,我对其进行了改进,使其显示在屏幕中央:

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);
}
private static void show屏幕(内部屏幕、窗框){
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[]gd=ge.getScreenDevices();
图形设备图形设备;