java - 当父框架设置为不可调整大小时,JPanel 会调整大小

标签 java swing jframe

构建了一个包含三个面板的小型测试 SWING 应用程序。一个主 JPanel,其中包含两个较小的 JPanel。一个在左边(板面板),另一个在右边(侧面板)。通过调用 min、preferred 和 max size 方法,将两个内部面板设置为请求的特定大小。右侧面板中的按钮将父 JFrame 设置为不可调整大小。在将父框架设置为不可调整大小之前,一切看起来都很棒,这会导致(?!)调整框架和主面板的大小,使其变大。

寻找调整大小的原因,以及如何保持主面板和框架的大小以仅包含两个内部面板,一旦框架被卡住,就不再包含其他面板。

已突出显示面板边框并添加了绘制事件日志记录以调试大小问题。

感谢您的帮助和见解!

编辑: 这个问题出现在 JRE 8 中。在 JRE 9 中它消失了,但引入了缩放问题。整个应用程序在我的 4k 显示器上放大,运行 Windows 10。

package org.fubar;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class PanelTest {

    private static final String appTitle    = "JPanel Test by Fubar.org(c)";

    public static JFrame myFrame                    = null;
    public static JPanel mainPanel                  = null;
    public static JPanel boardPanel                 = null;
    public static JPanel sidePanel                  = null;

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI() {

        System.out.println("Create and show GUI");

        JFrame myFrame = new JFrame(appTitle);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainPanel = new MainPanel();
        myFrame.add(mainPanel);

        myFrame.pack();
        centreWindow(myFrame);
        myFrame.setVisible(true);
    }

    public static void centreWindow(Window frame) {
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
        int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
        frame.setLocation(x, y);
    }

    public static void barfSize(JPanel panel, String panelName) {
        Dimension panelSize = panel.getSize();
        System.out.println(String.format("%s size:(%d,%d);",panelName,panelSize.width,panelSize.height));
    }

}

class MainPanel extends JPanel {

    static final long serialVersionUID = 1;

    public MainPanel() {

        setBorder(BorderFactory.createLineBorder(Color.green));

        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

        PanelTest.boardPanel = new BoardPanel();
        PanelTest.boardPanel.setAlignmentY(TOP_ALIGNMENT);
        add(PanelTest.boardPanel);

        PanelTest.sidePanel = new SidePanel();
        PanelTest.sidePanel.setAlignmentY(TOP_ALIGNMENT);
        add(PanelTest.sidePanel);

    }

    public void paintComponent(Graphics gooey) {
        super.paintComponent(gooey);
        PanelTest.barfSize(this, "Main Panel");
    }

}

class BoardPanel extends JPanel {

    static final long serialVersionUID = 1;

    public BoardPanel() {

        setBorder(BorderFactory.createLineBorder(Color.red));

        Dimension mySize = new Dimension(400,200);
        setMinimumSize(mySize);
        setPreferredSize(mySize);
        setMaximumSize(mySize);

        JLabel lblText = new JLabel("Board Panel");
        add(lblText);

    }

    public void paintComponent(Graphics gooey) {
        super.paintComponent(gooey);
        PanelTest.barfSize(this, "Board Panel");
    }
}

class SidePanel extends JPanel implements ActionListener {

    static final long serialVersionUID = 1;

    public SidePanel() {

        setBorder(BorderFactory.createLineBorder(Color.blue));

        Dimension mySize = new Dimension(200,200);
        setMinimumSize(mySize);
        setPreferredSize(mySize);
        setMaximumSize(mySize);

        JLabel lblText = new JLabel("Side Panel");
        add(lblText);

        JButton btnFreeze = new JButton("Freeze");
        btnFreeze.setActionCommand("Freeze");      
        btnFreeze.setToolTipText("Click me to freeze frame");
        btnFreeze.setBorderPainted(true);
        btnFreeze.setEnabled(true);
        btnFreeze.addActionListener(this);
        add(btnFreeze);

    }

    public void actionPerformed(ActionEvent action) {
        String command = action.getActionCommand();
        if ( command == "Freeze") {
            freezeFrame();
            System.out.println("Froze frame.");
        }
        Dimension panelSize = getSize();
        System.out.println(String.format("Side Panel size:(%d,%d);",panelSize.width,panelSize.height));
    }

    public void paintComponent(Graphics gooey) {
        super.paintComponent(gooey);
        PanelTest.barfSize(this, "Side Panel");
    }

    public void freezeFrame() {
        JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
        Dimension parentSize = this.getParent().getSize();
        topFrame.setMaximumSize(parentSize);
        topFrame.setResizable(false);
    }

}

屏幕截图 1:
App before frame resize disabled

屏幕截图 2:
App after frame resize disabled

运行日志

Create and show GUI
Main Panel size:(602,202);
Side Panel size:(200,200);
Board Panel size:(400,200);
Main Panel size:(602,202);
Side Panel size:(200,200);
Board Panel size:(400,200);
Froze frame.
Side Panel size:(200,200);
Main Panel size:(618,218);
Side Panel size:(200,200);
Board Panel size:(400,200);
Main Panel size:(618,218);
Side Panel size:(200,200);
Board Panel size:(400,200);

最佳答案

如果您在首次创建 JFrame 时将其设置为 setResizable(false),则不会出现该问题。

    JFrame myFrame = new JFrame(appTitle);
    myFrame.setResizable(false);

关于java - 当父框架设置为不可调整大小时,JPanel 会调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47298042/

相关文章:

Java:空指针异常

Java - 是否可以将 JMenuBar 添加到 JFrame 的装饰窗口?

java - 收集器 lambda 返回可观察列表

java - JTextPane插入大文本问题

java - 如何在 Java Swing 应用程序中安排任务?

java - 无法弄清楚 flattnes 参数在 PathIterator 中的作用?

java - 如果我为 JPanel setOpaque(false) ,它的组件会发生什么

java - 如何在 JFrame 框中显示用户输入?

java - 如何向 JFrame 添加椭圆边框

java - 如何在 Java 中查找 double 'n' 的多少次方才能得到 double 'n'。 Python 中 Math.log 的等效项