当前位置: 首页 > 知识库问答 >
问题:

当父帧设置为不可调整大小时,JPanel会调整大小

尹晟
2023-03-14

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

寻找为什么要调整大小,以及可以做什么来保持主面板和框架的大小,以仅包围两个内部面板,而不是更多,一旦框架被冻结。

谢谢你的帮助和洞察力!

编辑:显示此问题在JRE8中。在JRE9中,它消失了,但引入了一个缩放问题。整个应用程序在运行Windows10的4K显示器上得到放大。

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:
在框架调整大小之前禁用应用程序

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

共有1个答案

管景天
2023-03-14

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

    JFrame myFrame = new JFrame(appTitle);
    myFrame.setResizable(false);
 类似资料:
  • 起初,我只有文本栏和状态栏,如下例所示(我不需要父容器): 这是应该的。但是,请记住状态栏的高度。现在,如果您将StatusBar类更改为下面的类,那么高度几乎会增加一倍。为什么会这样? 这种设置并不需要更多的垂直空间: 我可以让这成为一个新问题,但我觉得不值得...

  • 框架设计采用NetBeans进行。我尝试了所有的解决方案,比如将布局从BorderLayout更改为GridBagLayout,甚至是这里提到的那个。

  • 我制作了一个包含三个jpanel的jframe,这三个panel将jframe分成三个相等的部分。每一个面板都包含一个图像。我想调整图像和面板的大小,当帧的大小从高到低的时候。有人能告诉我如何做吗。

  • 问题内容: 我有一个与作为布局经理。 在南边界中,我有一个,我希望用户可以调整其大小,即用户可以单击边界的边缘并将其向上拖动以使其变大。 您是否知道我可以做到这一点? 问题答案: 为了使框架中的面板可单独调整大小,您需要将其添加到。 而不是将其放置在框架的南部,而是将其放置在中心。拆分窗格将使拆分中的底部面板看起来像在南方,而拆分中的顶部面板将位于框架的中心。 确保使用设置两个面板的方向。 然后,

  • jQueryUI提供resizable()方法来调整任何DOM元素的大小。 这种方法简化了元素的大小调整,否则需要花费大量时间和HTML编码。 resizable()方法在项目的右下角显示一个图标以调整大小。 语法 (Syntax) resizable()方法可以使用两种形式 - $(selector,context).resizable(options)方法 $(selector, contex

  • 我正在尝试构建一个包含6个窗格(作为父级添加到GridPane布局中)的简单Java项目。我必须在开始时设置窗口大小,并通过参考根布局的宽度和高度,设法将它们均匀地拆分。 但我想要他们调整大小,因为我改变了窗口的大小(使用鼠标,现在他们得到固定的大小)。 下面是我的代码: