2012-08-28 7 views
7

Mam naprawdę dużą aplikację, która ma wiele okien dialogowych. Moim zadaniem jest upewnienie się, że okno dialogowe, które nie jest całkowicie widoczne (ponieważ użytkownik wyciągnął je z widocznego obszaru ekranu), zostaje przeniesione z powrotem na środek ekranu.Jak ustalić, na którym ekranie jest wyświetlany JDialog

Nie ma problemu, gdy mam do czynienia tylko z jednym ekranem. Działa to dobrze ... jednak większość użytkowników tej aplikacji ma dwa ekrany na swoim pulpicie ...

Kiedy próbuję ustalić, na którym ekranie jest wyświetlane okno dialogowe i wyśrodkować je na tym ekranie,. ... cóż, faktycznie TO wyśrodkowuje, ale na głównym ekranie (który może nie być ekranem, na którym wyświetlane jest okno dialogowe).

Aby pokazać, co moje myśli były tak daleko, oto kod ...

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

Podczas debugowania rodzaj natknął się na fakt, że getActiveScreen() nie wydają się działać tak, jak ja chociaż; wydaje się, że zawsze zwraca 2 (co jest rodzajem bzdur, ponieważ oznaczałoby to, że dialog jest zawsze pokazywany na drugim monitorze ... co oczywiście nie jest prawdą).

Ktoś ma pomysł, jak wyśrodkować moje okno dialogowe na ekranie, na którym faktycznie jest wyświetlany?

+0

Ile ekranów będzie wyświetlać się na wielu ekranach? –

+0

Nie jestem pewien, czy dostanę twoje pytanie, ale jeśli zrozumiałem to poprawnie, ... nie wiem. Nie ma to znaczenia, ponieważ pozycja dialogów jest zapisywana i sprawdzana za każdym razem, gdy okno staje się widoczne ... czy to odpowiada na twoje pytanie? :-) – gilaras

+0

Dlaczego nie określisz lokalizacji na ekranie dla okna dialogowego? –

Odpowiedz

1

Zadziałała Twoja metoda getActiveScreen, z wyjątkiem tego, że używany był ekran zawierający lewy górny róg okna. Jeśli zamiast tego użyjesz Component.getGraphicsConfiguration(), zobaczysz, który ekran ma najwięcej pikseli okna. setLocationRelativeTo(null) nie stanowi tu żadnej pomocy, ponieważ zawsze używa ekranu głównego. Oto jak go rozwiązać:

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

Następnie można zrobić:

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

skupiającymi się okno do najbliższej ekranie (monitora). Może być konieczne upewnienie się, że okno dialogowe zostało początkowo wyświetlone/ustawione jako pierwsze.

+0

Dziękuję za odpowiedź :-) To nie działa w 100% tak, jak początkowo chciałem, żeby działało, ale zachowanie jest teraz całkiem w porządku :-) Dziękuję bardzo! :-) – gilaras

0

Oto kod służący do wyśrodkowania położenia okna.

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

z frame można użyć okna, jak również.

+2

To nie odpowiada na pytanie. Po prostu mówi, jak to zrobić w środowisku z jednym ekranem (które OP stwierdził już działa dla niego) ... – brimborium

+0

to prawda ...:-) – gilaras

1

Nie jestem pewien, ile z tego będzie użyteczne, ale jest to kod, którego używam podczas próby określenia urządzeń graficznych dla systemu Windows.

Trochę oszukuję, zwykle używam Component i pozwalam metodom narzędziowym albo znaleźć okno najwyższego poziomu, albo użyć punktu ekranu 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); 
} 
Powiązane problemy