【问题标题】:Resizing JPanel when JFrame is maximized最大化 JFrame 时调整 JPanel 的大小
【发布时间】:2015-01-08 22:40:03
【问题描述】:

好的,下面的代码在程序第一次运行时显示了 JFrame 中的 JPanel。如果通过拖动框架的边或角之一来重新调整窗口大小,则 JPanel 会重新调整自身大小并保持监视器的纵横比。

注意: 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 不会重新调整大小就像它应该的那样。窗口最大化时调用 Overridden componentResized() 方法,但 JPanel 不会调整大小。解决这个问题的任何帮助都会很棒。

【问题讨论】:

    标签: java resize jframe jpanel maximize


    【解决方案1】:

    在调整大小时,面板会立即接受 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);
    }
    

    【讨论】:

    • 谢谢,我不知道revalidate() 方法调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2011-10-03
    • 2012-09-01
    • 1970-01-01
    相关资源
    最近更新 更多