【问题标题】:Filling a content pane with panels用面板填充内容窗格
【发布时间】:2014-06-24 17:54:53
【问题描述】:

我将 JFrame 的内容窗格设置为我创建的面板。此面板将Grid Bag Layout 用于其后续面板。我这样设置这个布局:

private void initPanel() {

    setLayout(new GridBagLayout());
    constraints = new GridBagConstraints();
    populateGUI();
}

这导致“游戏”喜欢这样:

我实际上想要做的是将这些面板(小方块)展开。 JFrame 的尺寸为 800 x 500,因此每个面板应占用 100 x 100,总共 40 个面板。问题是面板太小了。

我使用以下代码填充 JFrame 的内容窗格(由自己的面板替换 - 标记为红色):

private void populateGUI() {

    // Fill the frame with panels
    for (int rowPos = 0; rowPos < numColumns; rowPos++) {

        for (int colPos = 0; colPos < numRows; colPos++) {

            constraints.gridx = rowPos;
            constraints.gridy = colPos;

            // Add component
            add(new GameDummyPanel(gameUtil.generateRandomColour(),
                    panelWidth, panelHeight), constraints);
        }
    }
}

注意 - 这些是我实施的唯一约束。在 GameDummyPanel 类中,我使用以下设置大小:

    public GameDummyPanel( Color panelColor, int panelWidth, int panelHeight )
{
    dummyPanelWidth = panelWidth / 8;
    dummyPanelHeight = panelHeight / 5;

    setBackground( panelColor );
    setSize( new Dimension( dummyPanelWidth, dummyPanelHeight ) );
}

那么为什么不强制执行呢?它不像我在面板上调用 pack 和在充当 JFrame 的内容窗格的面板上。

谢谢

更新

检查并实施了答案之后需要做的事情——如果您不想在下面阅读——将约束的fill 属性设置为BOTH 并从面板类中删除所有基于大小的属性。这意味着我的约束看起来像这样:

    constraints = new GridBagConstraints();
    constraints.weightx = 1.0;
    constraints.weighty = 1.0;
    constraints.fill = GridBagConstraints.BOTH;

减去设置gridxgridy 的每个面板的实际唯一定位。然后实际上可以取消 JPanel 实现并让 JPanel 即时创建。

【问题讨论】:

标签: java swing jpanel gridbaglayout preferredsize


【解决方案1】:

为面板设置以下值:

constraints.weightx = 1.0;
constraints.weighty = 1.0;

来自http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

除非您为 weightx 或 weighty 指定至少一个非零值,否则所有组件都会在其容器的中心聚集在一起。这是因为当权重为 0.0(默认值)时,GridBagLayout 会在其单元格网格和容器边缘之间放置任何额外的空间。

此外,您不应该手动设置面板的大小,让 GridBagLayout 完成它的工作,只需根据自己的喜好配置约束,对于最简单的布局,您至少应该考虑以下变量:

gridx, gridy
fill
anchor
weightx, weighty

所有这些都在上一个链接中进行了解释。

【讨论】:

  • 不使用constraints.fill=GridBagConstraints.BOTH; 输出会有所不同。
  • @Braj 没错,我只是给出了他问题的核心罪犯,从那时起他应该根据自己的需要定制布局。因为据我们所知,正如您所指出的,GridLayout 会更合适。他还强制调整面板的大小,这样他就可以得到足够好的东西。
  • 结合你所说的和设置填充属性就可以了。如果没有填充属性,面板会相当小。
【解决方案2】:

尝试使用GridBagConstraints 的更多属性。

 constraints.weightx=1.0;
 constraints.weighty=1.0;
 constraints.fill=GridBagConstraints.BOTH;

在这种情况下使用GridLayout 而不是GridBagLayout

private void initPanel() {
    setLayout(new GridLayout(numRows, numColumns));
    populateGUI();
}

【讨论】:

    【解决方案3】:
    • 不要在面板上拨打setSize()

    • 覆盖面板的getPreferredSize()GridBagLayout 尊重首选尺寸。如果您不覆盖,它将对您的体验产生影响。

      @Override
      public Dimension getPreferredSize() {
          return new Dimension(SIZE, SIZE);
      }
      
    • 调用frame.pack(),以便尊重preferredSize(不要设置帧大小)

    • Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

    【讨论】:

    • 感谢您的回答 - 您的建议是否高于最佳实践?如果是这样,我在哪里可以了解它们?
    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    相关资源
    最近更新 更多