2011-01-07 14 views
36

Tengo una configuración de monitor doble y quiero ejecutar mi GUI en un monitor específico si se encuentra. Traté de crear mi ventana JFrame pasando un objeto GraphicConfiguration de mi dispositivo de pantalla, pero no funciona, el cuadro sigue apareciendo en la pantalla principal.Mostrar JFrame en una pantalla específica en la configuración de monitor doble

¿Cómo puedo configurar la pantalla donde se debe mostrar mi marco?

Respuesta

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

¿Pero por qué esto se relaciona con "pantalla completa"? ¿Qué pasa si no necesito usar el modo de pantalla completa? – Dims

+1

@Dims, di una nueva respuesta que no obliga a pantalla completa. – ryvantage

1

Mi experiencia es con la extensión de escritorios a través de múltiples monitores, en comparación con la configuración de los monitores como pantallas separadas (X11). Si eso no es lo que quieres hacer, esto no se aplicará.

Y mi solución fue un poco hack: llamé a Toolkit.getScreenSize(), determinado si estaba en una situación de múltiples monitores (comparando la altura con el ancho y asumiendo que el ancho> dos veces la altura indicaba un multi-monitor), estableciendo la posición inicial X e Y del marco.

+0

Gracias por adivice. Lo resolví usando jframe.setBounds (graphicConfiguration.getBounds()) – blow

28

he modificado @ respuesta de Joseph Gordon-para permitir que una manera de lograr esto sin obligar a pantalla completa:

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

En este código estoy asumiendo getDefaultConfiguration() no volverá nula. Si ese no es el caso, entonces alguien por favor corrígeme. Sin embargo, este código funciona para mover su JFrame a la pantalla deseada.

+4

Esta solución solo funciona si los dispositivos no están alineados verticalmente. Reemplace 'frame.getY()' con 'gd [0] .getDefaultConfiguration(). GetBounds(). Y + frame.getY()' para solucionar este problema. – Ercksen

0

Para mí ha funcionado bien también (suponiendo monitor de la izquierda tiene 1920x1200 tamaño):

A) establecido en el monitor izquierdo en alguna posición exacta:

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

B) fijado en el monitor de la derecha en algunos posición exacta:

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

C) establecido en el monitor izquierdo maximizada:

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

D) establecer en el monitor derecho maximiza

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

2

Una solución mucho más limpio después de leer los docs para JFrame.setLocationRelativeTo mostrarlo en la pantalla 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); 
} 

Esta función se puede utilizar para cambiar la ventana de la aplicación entre pantallas

+2

¿Qué es exactamente la configuración? – Machado

0

Muchas de las soluciones aquí funcionan para pantallas extendidas. Si está utilizando pantallas separadas, simplemente pase el objeto de configuración de gráficos del dispositivo de gráficos deseado al constructor de jframe o jdialog.

0

Vickys answer contiene el puntero derecho. Es el nuevo JFrame (GraphicsConfiguration gc) que lo hace.

Puede hacerlo así:

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

Si quieres que ponerlo en el centro de la pantalla de la izquierda:

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

Si quieres que ponerlo en el centro de la pantalla de la derecha:

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

He modificado @ Joseph-gordon y @ryvantage respondo para permitir una forma de lograr esto sin forzar full-sc reen, la posición de configuración de pantalla fija y centrarlo en la pantalla de selección:

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

La referencia a 'mostrar' en la línea 5 no está definida. ¿A qué se refiere esto? –

0

Con todo el mundo astillado con sus propios sabores, sobre la base de otros sabores, que añadir la mía porque los otros se encerraron en lo que respecta a posicionamiento de la ventana en la pantalla seleccionada.

Es simplemente el mejor. Le permite establecer la ubicación en la otra pantalla también.

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

Ejemplo:

setLocation(2, 200, 200); 

Incluso le permite pasar de un porcentaje de la posición de la pantalla!

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

pantalla debe ser mayor que 0, lo que estoy seguro es un requisito difícil.

para colocar en el pasado, sólo tiene que llamar con Integer.MAX_VALUE. **

Cuestiones relacionadas