简体   繁体   中英

Resizing JPanel when JFrame is maximized

Alright, so the following code shows a JPanel within a JFrame when the program is first run. If the window is re-sized by dragging one of the sides or corners of the frame, the JPanel re-sizes itself and maintains the aspect ratio of the monitor.

NOTE: The JPanel is set to remain within the bounds of the window on a 1920x1080 resolution monitor only. On any other monitor size, the JPanel may get cut off. See my comment above setPreferredSize() in the updatePanelSize() method.

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

The problem I am having is that if I maximize the window by double clicking the window toolbar (or whatever the correct term for the top of the window would be) or by clicking the maximize button, the JPanel does not re-size like it ought to. The Overridden componentResized() method is called when the window is maximized, but the JPanel doesn't resize. Any help on solving this issue would be great.

On resize the panel is immediately accepting the new preferred dimensions in updatePanelSize() , but on maximize/restore the panel is apparently ignoring the new preferred dimensions.

I've added a call to revalidate() , to force the panel to update in those cases where it hasn't applied the new preferred dimensions.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM