Java JFrame在内容周围显示白色条

Java JFrame在内容周围显示白色条,java,swing,jframe,jpanel,contentpane,Java,Swing,Jframe,Jpanel,Contentpane,因此,我创建了一个类WindowDisp,它扩展了JFrame: public class WindowDisp extends JFrame{ private static final long serialVersionUID = 3245091489595286109L; private int height, width; private JPanel panel; private JLabel mainPane; public Window

因此,我创建了一个类
WindowDisp
,它扩展了
JFrame

public class WindowDisp extends JFrame{

    private static final long serialVersionUID = 3245091489595286109L;

    private int height, width;
    private JPanel panel;
    private JLabel mainPane;

    public WindowDisp(int a, int b, int pw, int ph){
        height = a;
        width = b;

        Container c = getContentPane();
        c.setPreferredSize(new Dimension(width, height));
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);

        mainPane = new JLabel();
        mainPane.setPreferredSize(new Dimension(pw, ph));
        mainPane.setFont(new Font("Monospaced", Font.PLAIN, 10));

        panel = new JPanel();
        panel.setPreferredSize(getSize());
        panel.add(mainPane);
        add(panel);

        setVisible(true);
        pack();
    }

    public static void main(String[] args){
        WindowDisp win = new WindowDisp(400, 400, 400, 400);
    }
}
在我的
Main
类中,我声明了一个
WindowDisp
,其中它的
高度和
宽度等于它的
ph
pw
。然而,问题是,在运行我的程序时,在帧中默认的背景色
JPanel
周围会出现白色的“条”。它们似乎从右侧和底部填充面板,好像面板没有占用框架中的空间,但是,如果我的编码正确,面板应该与框架的
ContentPane
大小相同,不是吗

我发现删除这两个
pack()中的任何一个命令不会删除这些条,尽管删除第一条会将其更改为黑色,删除第二条会使右侧的条变宽。当然,删除这两个选项会导致框架与其
ContentPane
的大小不同。此外,移除
add(面板)完全没有效果


我不知道这段代码中的什么导致了帧中出现看似空白的空间,同样,在我的程序中,传递给
窗口的所有四个值都是相等的。真正奇怪的是,即使我只是删除了
add(面板),完全不会改变白色填充。事实上,我可以注释掉从
mainPane=…
add(panel)的所有内容这一点也不影响它。

我似乎无法准确地复制问题,但我认为我可以复制所需的结果

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class WindowDisp extends JFrame {

    private static final long serialVersionUID = 3245091489595286109L;

    private JPanel panel;
    private JLabel mainPane;

    public WindowDisp(int width, int height) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        mainPane = new JLabel();
        mainPane.setBorder(new LineBorder(Color.BLUE));
        mainPane.setFont(new Font("Monospaced", Font.PLAIN, 10));

        panel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(width, height);
            }
        };
        panel.setLayout(new BorderLayout());
        panel.setBorder(new EmptyBorder(4, 4, 4, 4));
        panel.add(mainPane);
        add(panel);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        System.out.println(getSize());
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                WindowDisp win = new WindowDisp(400, 400);
            }
        });
    }
}

向我扑来的东西(一直是个问题)

  • panel.setPreferredSize(getSize())-窗的大小通常大于窗的大小,这是因为窗具有在框架边界内绘制的装饰
    pack
    使用布局信息(以及组件的
    preferredSize
    间接)来确保内容具有所需的空间量,然后围绕此调整窗口大小以容纳框架装饰。通过调用
    getContentPane().setPreferredSize
    可以替换布局管理器可能提供的任何信息,并忽略其他组件的要求。这是我们建议您永远不要调用
    setPreferredSize
    ,永远不要
重申

Container c = getContentPane();
c.setPreferredSize(new Dimension(width, height));
强制将窗口的可视空间设置为
宽度
/
高度
值(400x400)。此容器将不再能够对其内容的更改做出反应,并且将始终首选
400x400

mainPane.setPreferredSize(new Dimension(pw, ph));
主窗格的首选大小设置为
400x400
(基于您的示例)。同样,它总是希望是
400x400
,但设置内容窗格的简单事实意味着该值实际上被忽略

panel.setPreferredSize(getSize());
现在,棺材上的钉子。这将
面板
设置为与框架大小相同,但是,框架大于
内容窗格
(400x400+框架装饰),它也在框架内偏移(它不会定位在0x0,但会偏移,以便显示在框架标题和右边框下方),但可能会超出框架边界

这一系列问题都对你不利。不要担心帧的大小,而是担心帧显示的大小需要/要求


每个操作系统都使用不同的框架装饰,因此不同操作系统的实际、物理和框架大小会有所不同,但是如果你关注内容的要求,你就不会在意了,我似乎无法准确地复制这个问题,但我想我可以复制期望的结果

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class WindowDisp extends JFrame {

    private static final long serialVersionUID = 3245091489595286109L;

    private JPanel panel;
    private JLabel mainPane;

    public WindowDisp(int width, int height) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        mainPane = new JLabel();
        mainPane.setBorder(new LineBorder(Color.BLUE));
        mainPane.setFont(new Font("Monospaced", Font.PLAIN, 10));

        panel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(width, height);
            }
        };
        panel.setLayout(new BorderLayout());
        panel.setBorder(new EmptyBorder(4, 4, 4, 4));
        panel.add(mainPane);
        add(panel);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        System.out.println(getSize());
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                WindowDisp win = new WindowDisp(400, 400);
            }
        });
    }
}

向我扑来的东西(一直是个问题)

  • panel.setPreferredSize(getSize())-窗的大小通常大于窗的大小,这是因为窗具有在框架边界内绘制的装饰
    pack
    使用布局信息(以及组件的
    preferredSize
    间接)来确保内容具有所需的空间量,然后围绕此调整窗口大小以容纳框架装饰。通过调用
    getContentPane().setPreferredSize
    可以替换布局管理器可能提供的任何信息,并忽略其他组件的要求。这是我们建议您永远不要调用
    setPreferredSize
    ,永远不要
重申

Container c = getContentPane();
c.setPreferredSize(new Dimension(width, height));
强制将窗口的可视空间设置为
宽度
/
高度
值(400x400)。此容器将不再能够对其内容的更改做出反应,并且将始终首选
400x400

mainPane.setPreferredSize(new Dimension(pw, ph));
主窗格的首选大小设置为
400x400
(基于您的示例)。同样,它总是希望是
400x400
,但设置内容窗格的简单事实意味着该值实际上被忽略

panel.setPreferredSize(getSize());
现在,棺材上的钉子。这将
面板
设置为与框架大小相同,但是,框架大于
内容窗格
(400x400+框架装饰),它也在框架内偏移(它不会定位在0x0,但会偏移,以便显示在框架标题和右边框下方),但可能会超出框架边界

这一系列问题都对你不利。不要担心帧的大小,而是担心帧显示的大小需要/要求

每个操作系统使用不同的框架装饰,因此实际的、物理的、框架大小在不同的操作系统上是不同的