web-dev-qa-db-fra.com

Afficher JFrame dans un écran spécifique en configuration double moniteur

J'ai une configuration double moniteur et je veux exécuter mon interface graphique dans un moniteur spécifique s'il est trouvé. J'ai essayé de créer ma fenêtre JFrame en passant un objet GraphicConfiguration de mon périphérique d'écran, mais cela ne fonctionne pas, le cadre s'affiche toujours sur l'écran principal.

Comment puis-je définir l'écran où mon cadre doit être affiché?

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

J'ai modifié la réponse de @ Joseph-gordon pour permettre un moyen d'y parvenir sans forcer le plein écran:

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

Dans ce code, je suppose que getDefaultConfiguration() ne retournera jamais null. Si ce n'est pas le cas, alors corrigez-moi. Mais, ce code fonctionne pour déplacer votre JFrame vers l'écran souhaité.

33
ryvantage

Une solution beaucoup plus propre après avoir lu la documentation de JFrame.setLocationRelativeTo Display sur l'écran 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);
}

Cette fonction peut être utilisée pour basculer la fenêtre d'application entre les écrans

3
Vicky Ronnen

Veuillez vous référer à GraphicsDevice API, vous en avez un bon exemple.

2
ring bearer

Avec tout le monde avec leurs propres saveurs, basé sur d'autres saveurs, j'ajoute le mien parce que les autres vous ont enfermé en ce qui concerne le positionnement de la fenêtre sur l'écran sélectionné.

C'est tout simplement le meilleur. Il vous permet également de définir l'emplacement sur l'autre écran.

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

Exemple:

setLocation(2, 200, 200);

Vous permet même de passer un pourcentage pour la position de l'écran!

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

l'écran doit être supérieur à 0, ce qui, j'en suis sûr, est une exigence difficile!

Pour placer le dernier, appelez simplement avec Integer.MAX_VALUE. **

1
momomo

Mon expérience consiste à étendre les bureaux sur plusieurs moniteurs, au lieu de configurer les moniteurs en tant qu'écrans séparés (X11). Si ce n'est pas ce que vous voulez faire, cela ne s'appliquera pas.

Et ma solution était un peu un hack: j'ai appelé Toolkit.getScreenSize(), déterminé si j'étais dans une situation multi-moniteur (en comparant la hauteur à la largeur et en supposant que largeur> deux fois la hauteur indiquée multi-moniteur) , puis définissez la position initiale X et Y du cadre.

1
Anon

basé sur la réponse @ryvantage, je l'ai amélioré pour qu'il s'affiche au centre de l'écran:

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

Si vous voulez le placer au centre de l'écran gauche:

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

Si vous voulez le placer au centre de l'écran droit:

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

J'ai modifié @ Joseph-gordon et @ryvantage answer pour permettre un moyen d'y parvenir sans forcer la position de configuration d'écran fixe en plein écran et le centrer sur l'écran sélectionné:

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

De nombreuses solutions fonctionnent ici pour les écrans étendus. Si vous utilisez des affichages séparés, passez simplement l'objet de configuration graphique du périphérique graphique souhaité au constructeur de jframe ou jdialog.

0
Sado

La réponse Vickys contient le bon pointeur. C'est le nouveau JFrame (GraphicsConfiguration gc) qui le fait.

Vous pouvez le faire comme ça:

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

Pour moi, cela a bien fonctionné également (en supposant que le moniteur gauche ait une taille de 1920 x 1200):

A) placé sur le moniteur gauche sur une position exacte:

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

B) mis sur le moniteur droit sur une position exacte:

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

C) réglé sur le moniteur gauche maximisé:

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

D) réglé sur le moniteur droit maximisé

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

0
user2641449