2015-01-08 3 views
1

Хорошо, поэтому следующий код показывает JPanel в JFrame, когда программа запускается в первый раз. Если окно изменено, перетаскивая одну из сторон или углов рамки, JPanel изменяет размеры и поддерживает соотношение сторон монитора.Изменение размера JPanel при максимальном использовании JFrame

ПРИМЕЧАНИЕ: JPanel установлен, чтобы оставаться в пределах окна только на мониторе с разрешением 1920x1080. На любом другом размере монитора JPanel может быть отключен. См. Мой комментарий выше setPreferredSize() в методе updatePanelSize().

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 делает не переделывать, как должно. Метод Overridden 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

Спасибо, я не знал о 'перепроверить()' вызова метода. –

 Смежные вопросы

  • Нет связанных вопросов^_^