Java 我能';t获取BoxLayout';s setPreferredSize()方法以我希望的方式工作

Java 我能';t获取BoxLayout';s setPreferredSize()方法以我希望的方式工作,java,swing,layout-manager,boxlayout,Java,Swing,Layout Manager,Boxlayout,我想我解决了我的问题,但我不知道为什么会这样,所以我希望有人能给我解释一下,这样我以后就不会再犯同样的错误了 下面是一个可编译的示例,说明了我正在尝试做的事情: public class BoxLayoutTest extends JFrame { public BoxLayoutTest() { setSize(400,300); JPanel mainPanel = new JPanel(new FlowLayout()); setContentPane(ma

我想我解决了我的问题,但我不知道为什么会这样,所以我希望有人能给我解释一下,这样我以后就不会再犯同样的错误了

下面是一个可编译的示例,说明了我正在尝试做的事情:

public class BoxLayoutTest extends JFrame
{
  public BoxLayoutTest()
  {
    setSize(400,300);
    JPanel mainPanel = new JPanel(new FlowLayout());
    setContentPane(mainPanel);

    JPanel subPanel = new JPanel();
    subPanel.setLayout(new BoxLayout(subPanel, BoxLayout.PAGE_AXIS));
    subPanel.setBackground(Color.BLUE);

    JLabel labelTest = new JLabel("This is a test");
    subPanel.add(labelTest);

    labelTest.setPreferredSize(new Dimension(150, 20));
    mainPanel.add(subPanel);
    System.out.println(mainPanel.getSize());
  }

  public static void main( String[] args )
  {
    BoxLayoutTest testFrame = new BoxLayoutTest();
    testFrame.setVisible(true);
  }
}
起初,我对包含JLabel的面板有问题,因为它没有按照首选大小调整大小。我发现这是因为我使用了mainPanel.getSize()的一些变体作为子面板的首选大小。在这个例子中,我使用的是实际的数值,这是有效的

它不能以旧的方式工作的原因(事实上我希望有人解释一下),是因为,正如SOP行中所示,mainPanel.getSize()返回宽度和高度为0,而它显然占据了整个屏幕,即400x300


感谢@camickr告诉我不应该为面板设置首选大小,这帮助我找出了问题的根源。

很难说为什么代码不起作用,因为您没有发布代码。随机的几行代码并不能告诉我们在程序中如何使用代码的上下文

当你发表一个问题时,你需要发表你的文章来说明问题

胶水不应该解决这个问题。面板仍应显示,只是它可能不会显示在您期望的位置。BoxLayout将尝试调整添加到其中的组件的大小,以填充其可用的整个空间

您不应该在面板上使用setPreferredSize()。布局管理器的工作是根据添加到面板中的所有组件的首选尺寸计算面板的首选尺寸。所以我想说你的代码还是错的

键入this和this.getContentPane()之间有区别吗


某些方法调用会自动转发到框架的内容窗格,这就是最终结果相同的原因。阅读jframeapi。这在API描述或相关方法中有说明。

很难说为什么代码不工作,因为您没有发布代码。随机的几行代码并不能告诉我们在程序中如何使用代码的上下文

当你发表一个问题时,你需要发表你的文章来说明问题

胶水不应该解决这个问题。面板仍应显示,只是它可能不会显示在您期望的位置。BoxLayout将尝试调整添加到其中的组件的大小,以填充其可用的整个空间

您不应该在面板上使用setPreferredSize()。布局管理器的工作是根据添加到面板中的所有组件的首选尺寸计算面板的首选尺寸。所以我想说你的代码还是错的

键入this和this.getContentPane()之间有区别吗

某些方法调用会自动转发到框架的内容窗格,这就是最终结果相同的原因。阅读jframeapi。这在API说明或相关方法中有说明

为什么[code]返回0的宽度和高度

在“使该
窗口的大小符合其子组件的首选大小和布局”之前,尺寸将为零

System.out.println(mainPanel.getSize());
this.pack();
System.out.println(mainPanel.getSize());
控制台:

java.awt.Dimension[width=0,height=0] java.awt.Dimension[width=160,height=30] java.awt.Dimension[宽度=0,高度=0] java.awt.Dimension[宽度=160,高度=30] 为什么[code]
返回0的宽度和高度

在“使该
窗口的大小符合其子组件的首选大小和布局”之前,尺寸将为零

System.out.println(mainPanel.getSize());
this.pack();
System.out.println(mainPanel.getSize());
控制台:

java.awt.Dimension[width=0,height=0] java.awt.Dimension[width=160,height=30] java.awt.Dimension[宽度=0,高度=0] java.awt.Dimension[宽度=160,高度=30]
我知道我应该发布一个SSCCE,但是我发布了大多数(90%+)未注释的方法,其中包括变量声明。我对其余部分进行了评论,这就是我试图隔离问题并将其发布在这里的方式。胶水本身并没有修复它,但我可以用这种方式模拟一个更大的面板。要将其放到上下文中,这是一个标题栏,应该占据屏幕顶部的整个宽度。不过,它只是围绕着JLabel,这不是我想要的。当我将布局更改为flowLayout时,一切正常。如果我的代码示例不够清晰,很抱歉。我采纳了您的建议,从JPanel中删除了setPreferredSize,并将其用于JLabel。它不起作用。但是,如果我使用setMaximumSize,它会起作用,这意味着我实际上不了解preferredSize是如何工作的,因为我认为如果容器有足够的空间使用它,preferredSize将被使用。我知道我应该发布一个SSCCE,但我发布的大多数(90%+)未注释方法都会禁止变量声明。我对其余部分进行了评论,这就是我试图隔离问题并将其发布在这里的方式。胶水本身并没有修复它,但我可以用这种方式模拟一个更大的面板。要将其放到上下文中,这是一个标题栏,应该占据屏幕顶部的整个宽度。不过,它只是围绕着JLabel,这不是我想要的。当我将布局更改为flowLayout时,一切正常。如果我的代码示例不够清晰,很抱歉。我采纳了您的建议,从JPanel中删除了setPreferredSize,并将其用于JLabel。它不起作用。但是,如果我使用setMaximumSize,它会起作用,这意味着我实际上不了解preferredSize是如何工作的,因为我认为如果容器有足够的空间使用它,preferredSize就是所使用的。