2012-08-28 50 views
7

我有一個非常大的應用程序,它有多個對話框。我的任務是確保一個不完全可見的對話框(因爲用戶將它拉出可視屏幕區域)被移回到屏幕中心。如何找出顯示JDialog的屏幕

當我只處理一個屏幕時,這沒有問題。 它工作得很好...但是,這個應用程序的大多數用戶有兩個屏幕在他們的桌面上...

當我試圖找出在哪個屏幕上顯示對話框並將其居中在該特定屏幕上。 ..嗯,它實際上居中,但在主屏幕上(可能不是顯示對話框的屏幕)。

爲了告訴你什麼是我的想法是,到目前爲止,這裏的代碼...

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

在調試我有種跨越的事實,getActiveScreen()似乎並沒有在上班的路上我雖然來到;它似乎總是返回2(這是一種廢話,因爲這意味着對話總是顯示在第二個顯示器中......這當然不是事實)。

任何人都知道如何將我的對話框居中顯示在屏幕上?

+0

應用程序會在多個顯示器上顯示多少個屏幕? –

+0

我不太清楚如果我得到你的問題,但如果我理解正確,......我不知道。它甚至都不重要,因爲每當對話變得可見時,對話框的位置被保存並檢查......這是否回答你的問題? :-) – gilaras

+0

爲什麼不在屏幕上指定對話框的位置? –

回答

1

您的getActiveScreen方法工作,除了它使用包含窗口左上角的屏幕。如果使用Component.getGraphicsConfiguration(),它會給你哪個屏幕上的窗口像素最多。 setLocationRelativeTo(null)在這裏沒有幫助,因爲它總是使用主屏幕。以下是如何解決這個問題:

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

然後,你可以這樣做:

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

將居中對話框到最近的屏幕(顯示器)。您可能需要確保首先顯示/定位對話框。

+0

感謝您的答覆:-)它不能以我最初希望它工作的方式100%工作,但行爲現在相當好:-)非常感謝! :-) – gilaras

0

下面是用於居中窗口位置的代碼。

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

frame您也可以使用該對話框。

+2

這不回答這個問題。它只是告訴如何在單屏幕環境下完成它(OP聲明已經爲他工作)... – brimborium

+0

這是真的......:-) – gilaras

1

我不確定這有多大用處,但是這是我在嘗試確定Windows圖形設備時使用的代碼。

我作弊了一點,我傾向於使用Component並允許實用方法查找頂層窗口或使用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); 
}