2012-08-28 9 views
7

Ho un'applicazione veramente grande che ha più finestre di dialogo. Il mio compito è quello di assicurarmi che una finestra di dialogo, che non è completamente visibile (perché l'utente l'abbia estratto dall'area dello schermo visibile), sia spostata al centro dello schermo.Come capire su quale schermata viene mostrato un JDialog

Questo non è un problema quando ho a che fare con uno solo schermo. Funziona bene ... tuttavia, la maggior parte degli utenti di questa applicazione ha due schermi sul desktop ...

Quando provo a capire su quale schermata viene mostrata la finestra di dialogo e la centrano su quella schermata specifica,. .. beh, in realtà fa centro, ma sulla schermata principale (che potrebbe non essere la schermata in cui viene mostrata la finestra di dialogo).

per mostrare ciò che i miei pensieri erano finora, ecco il codice ...

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

Durante il debug I tipi di sono imbattuto nel fatto che getActiveScreen() non sembra lavorare il mio modo però; sembra sempre restituire 2 (che è una specie di schifo, dal momento che significherebbe che il dialogo è sempre mostrato nel secondo monitor ... che ovviamente non è la verità).

Qualcuno ha idea di come centrare il mio dialogo sullo schermo in cui è effettivamente mostrato?

+0

Quante schermate verranno visualizzate su più schermi? –

+0

Non sono sicuro di avere la tua domanda, ma se ho capito bene, ... non lo so. Non ha nemmeno importanza, perché la posizione delle finestre di dialogo viene salvata e controllata ogni volta che la finestra di dialogo diventa visibile ... questo risponde alla tua domanda? :-) – gilaras

+0

Perché non si specifica la posizione sullo schermo per la finestra di dialogo? –

risposta

1

Il metodo getActiveScreen ha funzionato, tranne che per utilizzare lo schermo che contiene l'angolo in alto a sinistra della finestra. Se usi Component.getGraphicsConfiguration(), invece, ti darà quale schermo ha la maggior parte dei pixel della finestra. setLocationRelativeTo(null) non è utile qui perché utilizza sempre la schermata principale. Ecco come risolverlo:

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

allora si può fare:

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

che centrare la finestra di dialogo per lo schermo più vicino (monitor). Potrebbe essere necessario assicurarsi che la finestra di dialogo sia stata inizialmente visualizzata/posizionata per prima.

+0

Grazie per la tua risposta :-) Non funziona al 100% nel modo in cui inizialmente volevo che funzionasse, ma il comportamento è abbastanza ok ora :-) Grazie mille! :-) – gilaras

0

Ecco il codice utilizzato per centrare la posizione della finestra.

//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 la frame è possibile utilizzare la finestra di dialogo pure.

+2

Questo non risponde alla domanda. Indica solo come farlo in un ambiente a schermo singolo (che OP ha dichiarato funziona già per lui) ... – brimborium

+0

questo è vero ...:-) – gilaras

1

Non sono sicuro di quanto sarà utile, ma questo è il codice che utilizzo durante il tentativo di determinare i dispositivi grafici per Windows.

ho imbrogliare un po ', tendo a usare Component e consentire i metodi di utilità per trovare sia la finestra in primo piano o utilizzare il punto dello schermo s' il 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); 
} 
Problemi correlati