2015-01-08 113 views
1

好的,所以下面的代碼顯示了當程序第一次運行時JFrame中的JPanel。如果窗口通過拖動邊框的一個邊或邊角來重新調整大小,JPanel會自行調整大小並保持顯示器的高寬比。當JFrame最大化時調整JPanel的大小

NOTE: JPanel設置爲僅保留在1920x1080分辨率顯示器的窗口範圍內。在任何其他顯示器尺寸上,JPanel可能會被切斷。請參閱updatePanelSize()方法中的setPreferredSize()之上的註釋。

public class Frame extends JFrame { 

    Panel panel = new Panel(); 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Frame(); 
      } 
     }); 
    } 

    // Setup the window, add the panel, and initialize a "window" listener. 
    public Frame() {    
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setSize(1280, 720); 
     setLocationRelativeTo(null); 
     setVisible(true); 
     setTitle("Frame"); 
     setLayout(new GridBagLayout()); 

     add(panel); 
     initListeners(); 
    } 

    public void initListeners() { 

     /** When the window is resized, the panel size is updated. */ 
     addComponentListener(new ComponentListener() { 

      @Override 
      public void componentResized(ComponentEvent e) {   
       panel.updatePanelSize(); 
      } 

      @Override 
      public void componentHidden(ComponentEvent evt) {} 

      @Override 
      public void componentShown(ComponentEvent evt) {} 

      @Override 
      public void componentMoved(ComponentEvent evt) {} 
     }); 
    } 
} 

public class Panel extends JPanel { 

    public Panel() { 
     setBackground(new Color(100, 0, 0)); 
     setPreferredSize(new Dimension(1052, 592)); 
    } 

    // Resizes the JPanel while maintaining the same aspect ratio 
    // of the monitor. 
    public void updatePanelSize() { 

     GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); 
     float monitorWidth = gd.getDisplayMode().getWidth(); 
     float monitorHeight = gd.getDisplayMode().getHeight(); 

     // Aspect ratio of the monitor in decimal form. 
     float monitorRatio = monitorWidth/monitorHeight; 

     JComponent parent = (JComponent) getParent(); 
     float width = parent.getWidth(); 
     float height = parent.getHeight(); 

     width = Math.min(width, height * monitorRatio); 
     height = width/monitorRatio; 

     // I am subtracting the width and height by their respected aspect ratio 
     // coefficients (1920x1080 -> 16:9 (width:height)) and multiplying them 
     // by some scale (in this case 10) to add a "padding" to the JPanel. 
     // The ratio coefficients and scale will need to be edited based upon the 
     // resolution of your monitor. 
     setPreferredSize(new Dimension((int)width - (16 * 10), (int)height - (9 * 10))); 

     System.out.println("PanelRes: " + ((int)width - (16 * 10)) + "x" + ((int)height - (9 * 10))); 
     System.out.println("PanelRatio: " + getWidth()/getHeight()); 
    } 
} 

我遇到的問題是,如果我通過雙擊窗口工具欄(或其他的窗口頂部,正確的說法是),或通過點擊最大化按鈕將窗口最大化,JPanel的呢不應該像它應該重新調整大小。覆蓋的componentResized()方法在窗口最大化時調用,但JPanel不調整大小。解決這個問題的任何幫助都會很大。

回答

2

在調整面板大小時,立即接受updatePanelSize()中的新首選尺寸,但在最大化/恢復面板時顯然忽略了新的首選尺寸。

我添加了對revalidate()的調用,以強制在未應用新的首選尺寸的情況下更新面板。

public void updatePanelSize() { 

    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment() 
      .getDefaultScreenDevice(); 
    float monitorWidth = gd.getDisplayMode().getWidth(); 
    float monitorHeight = gd.getDisplayMode().getHeight(); 

    // Aspect ratio of the monitor in decimal form. 
    float monitorRatio = monitorWidth/monitorHeight; 

    JComponent parent = (JComponent) getParent(); 
    float width = parent.getWidth(); 
    float height = parent.getHeight(); 

    width = Math.min(width, height * monitorRatio); 
    height = width/monitorRatio; 

    // I am subtracting the width and height by their respective aspect ratio... 
    int paddedWidth = (int) width - (16 * 10); 
    int paddedHeight = (int) height - (9 * 10); 
    setPreferredSize(new Dimension(paddedWidth, paddedHeight)); 

    int resultWidth = getWidth(); 
    int resultHeight = getHeight(); 
    if (paddedWidth != resultWidth && paddedHeight != resultHeight) { 
     revalidate(); // preferred dimensions not applied, so force them 
    } 

    System.out.println("PreferredSize: " + paddedWidth + "x" + paddedHeight); 
    System.out.println("PanelRes: " + resultWidth + "x" + resultHeight); 
    System.out.println("PanelRatio: " + (float)resultWidth/resultHeight); 
} 
+0

謝謝你,我不知道'重新驗證()'方法調用。 –