2012-08-28 12 views
7

Tengo una aplicación realmente grande que tiene varios cuadros de diálogo. Mi tarea es asegurarme de que un cuadro de diálogo, que no está completamente visible (porque el usuario lo sacó del área de la pantalla visible) se mueve de vuelta al centro de la pantalla.Cómo saber en qué pantalla se muestra un JDialog

No hay problema cuando trato con una sola pantalla. Funciona bien ... sin embargo, la mayoría de los usuarios de esta aplicación tienen dos pantallas en su escritorio ...

Cuando trato de averiguar en qué pantalla se muestra el cuadro de diálogo y centrarlo en esa pantalla específica,. .. bueno, realmente se CENTRA, pero en la pantalla principal (que puede no ser la pantalla en la que se muestra el cuadro de diálogo).

de mostrar lo que eran mis pensamientos hasta ahora, aquí está el código ...

/** 
* Get the number of the screen the dialog is shown on ... 
*/ 
private static int getActiveScreen(JDialog jd) { 
    int screenId = 1; 
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice[] gd = ge.getScreenDevices(); 
    for (int i = 0; i < gd.length; i++) { 
     GraphicsConfiguration gc = gd[i].getDefaultConfiguration(); 
     Rectangle r = gc.getBounds(); 
     if (r.contains(jd.getLocation())) { 
      screenId = i + 1; 
     } 
    } 
    return screenId; 
} 

/** 
* Get the Dimension of the screen with the given id ... 
*/ 
private static Dimension getScreenDimension(int screenId) { 
    Dimension d = new Dimension(0, 0); 
    if (screenId > 0) { 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     DisplayMode mode = ge.getScreenDevices()[screenId - 1].getDisplayMode(); 
     d.setSize(mode.getWidth(), mode.getHeight()); 
    } 
    return d; 
} 

/** 
* Check, if Dialog can be displayed completely ... 
* @return true, if dialog can be displayed completely 
*/ 
private boolean pruefeDialogImSichtbarenBereich() { 
    int screenId = getActiveScreen(this); 
    Dimension dimOfScreen = getScreenDimension(screenId); 
    int xPos = this.getX(); 
    int yPos = this.getY(); 
    Dimension dimOfDialog = this.getSize(); 
    if (xPos + dimOfDialog.getWidth() > dimOfScreen.getWidth() || yPos + dimOfDialog.getHeight() > dimOfScreen.getHeight()) { 
     return false; 
    } 
    return true; 
} 

/** 
* Center Dialog... 
*/ 
private void zentriereDialogAufMonitor() { 
    this.setLocationRelativeTo(null); 
} 

Mientras se depura Yo como que encontramos en el hecho de que getActiveScreen() no parece funcionar de la manera que aunque; parece que siempre devuelve 2 (lo cual es una porquería, ya que significa que el diálogo siempre se muestra en el segundo monitor ... lo que por supuesto no es la verdad).

¿Alguien tiene alguna idea de cómo centrar mi cuadro de diálogo en la pantalla en la que en realidad se muestra?

+0

¿Cuántas pantallas se mostrarán en varias pantallas? –

+0

No estoy seguro si recibo tu pregunta, pero si la entendí correctamente, ... No sé. Ni siquiera importa, porque la posición de los cuadros de diálogo se guarda y se comprueba cada vez que el cuadro de diálogo se vuelve visible ... ¿responde esto a su pregunta? :-) – gilaras

+0

¿Por qué no especifica la ubicación en la pantalla para el diálogo? –

Respuesta

1

Su método getActiveScreen funcionó, excepto que utilizó la pantalla que contiene la esquina superior izquierda de la ventana. Si utiliza Component.getGraphicsConfiguration() en su lugar, le dará qué pantalla tiene la mayor cantidad de píxeles de la ventana. setLocationRelativeTo(null) no es de ayuda aquí porque siempre usa la pantalla principal. Así es como para resolverlo:

static boolean windowFitsOnScreen(Window w) { 
    return w.getGraphicsConfiguration().getBounds().contains(w.getBounds()); 
} 

static void centerWindowToScreen(Window w) { 
    Rectangle screen = w.getGraphicsConfiguration().getBounds(); 
    w.setLocation(
     screen.x + (screen.width - w.getWidth())/2, 
     screen.y + (screen.height - w.getHeight())/2 
    ); 
} 

entonces usted puede hacer:

JDialog jd; 
... 
if (!windowFitsOnScreen(jd)) centerWindowToScreen(jd); 

que centrar el diálogo para la pantalla más cercana (monitor). Es posible que deba asegurarse de que el cuadro de diálogo se haya mostrado/colocado primero.

+0

Gracias por su respuesta :-) No funciona al 100% como inicialmente quería que funcionara, pero el comportamiento está bastante bien ahora :-) ¡Muchas gracias! :-) – gilaras

0

Aquí está el código utilizado para centrar la ubicación de la ventana.

//Center the window 
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
    Dimension frameSize = frame.getSize(); 
    if (frameSize.height > screenSize.height) { 
    frameSize.height = screenSize.height; 
    } 
    if (frameSize.width > screenSize.width) { 
    frameSize.width = screenSize.width; 
    } 
    frame.setLocation((screenSize.width - frameSize.width)/2, (screenSize.height - frameSize.height)/2); 

con el frame puede utilizar el cuadro de diálogo también.

+2

Esto no responde la pregunta. Simplemente le dice cómo hacerlo en un entorno de pantalla única (que según OP ya está funcionando) ... – brimborium

+0

eso es verdad ...:-) – gilaras

1

No estoy seguro de cuánto de esto será útil, pero este es el código que uso cuando intento determinar los dispositivos gráficos para Windows.

Hago trampa un poco, tiendo a usar Component y dejo que los métodos de utilidad encuentren la ventana del nivel superior o utilicen el punto de pantalla Component.

/** 
* Returns the GraphicsDevice that the specified component appears the most on. 
*/ 
public static GraphicsDevice getGraphicsDevice(Component comp) { 

    GraphicsDevice device = null; 

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice lstGDs[] = ge.getScreenDevices(); 

    ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length); 
    if (comp != null && comp.isVisible()) { 
     Rectangle parentBounds = comp.getBounds(); 

     /* 
     * If the component is not a window, we need to find its location on the 
     * screen... 
     */ 
     if (!(comp instanceof Window)) { 
      Point p = new Point(0, 0); 
      SwingUtilities.convertPointToScreen(p, comp); 
      parentBounds.setLocation(p); 
     } 

     for (GraphicsDevice gd : lstGDs) { 
      GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
      Rectangle screenBounds = gc.getBounds(); 
      if (screenBounds.intersects(parentBounds)) { 
       lstDevices.add(gd); 
      } 
     } 

     if (lstDevices.size() == 1) { 
      device = lstDevices.get(0); 
     } else { 

      GraphicsDevice gdMost = null; 
      float maxArea = 0; 
      for (GraphicsDevice gd : lstDevices) { 
       int width = 0; 
       int height = 0; 

       GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
       Rectangle bounds = gc.getBounds(); 

       Rectangle2D intBounds = bounds.createIntersection(parentBounds); 

       float perArea = (float) ((intBounds.getWidth() * intBounds.getHeight())/(parentBounds.width * parentBounds.height)); 
       if (perArea > maxArea) { 
        maxArea = perArea; 
        gdMost = gd; 
       } 
      } 

      if (gdMost != null) { 
       device = gdMost; 
      } 
     } 
    } 
    return device; 
} 

/** 
* Returns the GraphicsDevice at the specified point 
*/ 
public static GraphicsDevice getGraphicsDeviceAt(Point pos) { 
    GraphicsDevice device = null; 
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice lstGDs[] = ge.getScreenDevices(); 

    List<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length); 
    for (GraphicsDevice gd : lstGDs) { 

     GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
     Rectangle screenBounds = gc.getBounds(); 
     if (screenBounds.contains(pos)) { 
      lstDevices.add(gd); 
     } 
    } 

    if (lstDevices.size() > 0) { 
     device = lstDevices.get(0); 
    } 

    return device; 
} 

/** 
* Returns the Point that would allow the supplied Window to be 
* centered on it's current graphics device. 
* 
* It's VERY important that the Window be seeded with a location 
* before calling this method, otherwise it will appear on the 
* device at 0x0 
* 
* @param window 
* @return 
*/ 
public static Point centerOfScreen(Window window) { 
    // Try and figure out which window we actually reside on... 
    GraphicsDevice gd = getGraphicsDeviceAt(window.getLocation()); 
    GraphicsConfiguration gc = gd.getDefaultConfiguration(); 

    Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); 
    Rectangle bounds = gc.getBounds(); 
    Dimension size = bounds.getSize(); 

    size.width -= (screenInsets.left + screenInsets.right); 
    size.height -= (screenInsets.top + screenInsets.bottom); 

    int width = window.getWidth(); 
    int height = window.getHeight(); 

    int xPos = screenInsets.left + ((size.width - width)/2); 
    int yPos = screenInsets.top + ((size.height - height)/2); 

    return new Point(xPos, yPos); 
} 
Cuestiones relacionadas