为什么JFrame的大小超过其ContentPane的大小,即使它具有已定义的大小?

我注意到swing上的容器之间有一种奇怪的行为。

为了举例说明测试,我创建了一个JFrame和一个JPanel,并将面板设置为contentPane。 我将首选和最大JPanel大小定义为400,300。 所有这些都可以在下面的例子中看到:

import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; public class ExcessiveSpacePanelTest { JFrame frame; JPanel panel; public void initGUI(){ frame = new JFrame(); panel = new JPanel(); panel.setBorder(BorderFactory.createLineBorder(Color.RED, 1)); panel.setPreferredSize(new Dimension(400, 300)); panel.setMaximumSize(new Dimension(400, 300)); frame.setContentPane(panel); frame.pack(); System.out.println("panel size: [" + panel.getSize().width + "," + panel.getSize().height +"]"); System.out.println("frame size: [" + frame.getSize().width + "," + frame.getSize().height+"]"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setResizable(false); frame.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(() ->{ new ExcessiveSpacePanelTest().initGUI(); }); } } 

结果是:

inserir描述da imagem aqui

令我惊讶的是,终端的输出是:

面板尺寸:[400,300]
框架尺寸:[416,338]

我不明白为什么框架增加了这个额外的空间,甚至在组件中没有任何东西强制框架resize。

我尝试通过添加行panel.setBorder (BorderFactory.createEmptyBorder(0, 0, 0, 0));在面板上设置归零边缘panel.setBorder (BorderFactory.createEmptyBorder(0, 0, 0, 0));pack();之前pack(); 但结果仍然相同。

这个问题是java给我一个错误的信息,因为面板缩放了框架的大小,从上面的结果,我们已经看到两者的大小不同。

这两项措施是否正确报告? 为什么会这样?

您可能会发现在不同平台上比较类似程序的结果会很有帮助。 尤其是,

  • 红色Border 面板内; 您的使用符合API 建议 ,“我们建议您将组件放在JPanel并在JPanel设置边框。”

  • 框架宽度与Mac OS X上的面板宽度相匹配,因为用于顶级容器的重量级对等在Mac OS X上没有垂直边框; Windows对等方有自己的边框。

  • 框架高度包括拖动条和框架边框:Widows上有38个像素,Mac OS X上有22个像素。

  • 当你真的想要覆盖getPreferredSize()时,不要使用setPreferredSize() getPreferredSize()

  • 另外,框架的add()方法转发到内容窗格。

 panel size: [400,300] frame size: [400,322] 

图片

 import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; public class ExcessiveSpacePanelTest { JFrame frame; JPanel panel; public void initGUI(){ frame = new JFrame(); panel = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(400, 300); } }; panel.setBorder(BorderFactory.createLineBorder(Color.RED, 1)); frame.add(panel); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setResizable(false); frame.setVisible(true); System.out.println("panel size: [" + panel.getSize().width + "," + panel.getSize().height +"]"); System.out.println("frame size: [" + frame.getSize().width + "," + frame.getSize().height+"]"); } public static void main(String[] args) { EventQueue.invokeLater(() ->{ new ExcessiveSpacePanelTest().initGUI(); }); } }