【问题标题】:Keeping preferred sizes of components in center of BorderLayout将组件的首选大小保持在 BorderLayout 的中心
【发布时间】:2012-03-02 16:42:01
【问题描述】:

我有一个使用 BorderLayout 的中型 UI;中心是一个选项卡式窗格,包含具有各种布局等的各种面板。

我希望此边框布局中心的面板根据 窗口,但我不希望面板中的组件拉伸。标签、组合框、文本字段、按钮——我希望它们保持首选大小,并允许包含它们的面板伸展。我将它们放在滚动窗格中,以防面板空间太小。

各种带有彩色词汇的海报警告在组件上使用任何 setXXXsize() 方法的危险。这就是我现在所做的,我想学习如何避免它。

GridBagLayout 不适用于我的某些面板。它本质上是围绕行和列定向的,并不是所有的东西都适合行和列。当然,我可以创建人工行和列来适应所有内容,但我真的希望 Swing 有更多的布局选项。

Vertical Glue 也不行。我已将它包含在 HFOE 心爱的 SSCE 中:

    package example;

    import java.awt.BorderLayout;

    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;

    public class BorderAndBox extends JFrame
    {
        public static void main(String args[])
        {
            BorderAndBox bnb = new BorderAndBox();
            bnb.createUI();
            bnb.setVisible(true);
        }

        public void createUI()
        {
            JPanel borderPanel = new JPanel(new BorderLayout());

            JLabel northLabel = new JLabel("Nawth");
            borderPanel.add(northLabel, BorderLayout.NORTH);

            String[] southComboChoices = { "one", "two", "three" };
            JComboBox southCombo = new JComboBox(southComboChoices);
            borderPanel.add(southCombo, BorderLayout.SOUTH);

            JPanel centerPanel = new JPanel();
            centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
            String[] firstChoices = { "first", "uno", "UN" };
            String[] secondChoices = { "second", "dos", "zwei" };
            String[] thirdChoices = { "third", "tres", "drei" };
            JComboBox firstCombo = new JComboBox(firstChoices);
            JComboBox secondCombo = new JComboBox(secondChoices);
            JComboBox thirdCombo = new JComboBox(thirdChoices);
            centerPanel.add(firstCombo);
            centerPanel.add(secondCombo);
            centerPanel.add(thirdCombo);
            centerPanel.add(Box.createVerticalGlue());  // first attempt; does NOT
            // take up available vertical space, instead it appears to create a space
            // that is shared equally among the (now) four components of this space.
            borderPanel.add(centerPanel, BorderLayout.CENTER);

            getContentPane().add(borderPanel);
            pack();
        }

    }

如果放大窗口,中心的组合框会放大;如前所述,它们下方的垂直胶块也会扩大,但不会占用所有可用空间。看起来它被赋予了和它们一样多的空间。

那么有什么好的方法来解决这个问题?

【问题讨论】:

  • "..beloved SSCE:" 我也喜欢它。它是 SSCCE (2 Cs)。 ;)
  • 不能只是一个独立的小例子吗?
  • “它不能只是一个独立的小例子吗?” Quoting我最喜欢的人之一:“在这个文档中,正确(或可编译,特别是与计算机源代码有关)意味着确保您的示例符合公认的标准和协议。” 最值得注意的子点 “确保您的示例正确。示例编译干净,或者导致您需要帮助的确切错误消息。” 代码编译并显示问题,很容易完成。它一个SSCCE。 :)
  • 我想我认为可编译是自包含的,假设执行是示例的一部分,但我很高兴使用稍长的缩写。如果我们能在结尾处找到另一个“E”字,那么我们可以一直使用双字母......
  • 哦,有些人已经够生气了,我用了 5 个字母来表示这个词。它需要所有类型。 ;)

标签: java swing border-layout


【解决方案1】:

import java.awt.BorderLayout;
import java.awt.GridBagLayout;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class BorderAndBox extends JFrame
{
public static void main(String args[])
{
    BorderAndBox bnb = new BorderAndBox();
    bnb.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    bnb.createUI();
    bnb.setVisible(true);
}

public void createUI()
{
    JPanel borderPanel = new JPanel(new BorderLayout());

    JLabel northLabel = new JLabel("Nawth");
    borderPanel.add(northLabel, BorderLayout.NORTH);

    String[] southComboChoices = { "one", "two", "three" };
    JComboBox southCombo = new JComboBox(southComboChoices);
    borderPanel.add(southCombo, BorderLayout.SOUTH);

    JPanel centerPanel = new JPanel();
    centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
    String[] firstChoices = { "first", "uno", "UN" };
    String[] secondChoices = { "second", "dos", "zwei" };
    String[] thirdChoices = { "third", "tres", "drei" };
    JComboBox firstCombo = new JComboBox(firstChoices);
    JComboBox secondCombo = new JComboBox(secondChoices);
    JComboBox thirdCombo = new JComboBox(thirdChoices);
    centerPanel.add(firstCombo);
    centerPanel.add(secondCombo);
    centerPanel.add(thirdCombo);
    centerPanel.add(Box.createVerticalGlue());  // first attempt; does NOT
    // take up available vertical space, instead it appears to create a space
    // that is shared equally among the (now) four components of this space.
    JPanel centerPanelConstrain = new JPanel(new GridBagLayout());
    centerPanelConstrain.add(centerPanel);
    borderPanel.add(centerPanelConstrain, BorderLayout.CENTER);

    getContentPane().add(borderPanel);
    pack();
}

}

另见this answer。解决这个问题的方法不止一种。

【讨论】:

  • 这是一个可爱的把戏;我假设我可以使用我的单个组件的 GridBagLayout 让它出现在左上角,就像我想要的那样。您愿意详细说明为什么会这样吗?
  • “您愿意详细说明为什么会这样吗?” 一个没有约束添加到 GBL 的单个组件最终位于中心。至于其他职位,我不确定。我只使用 GBL 将单个组件居中,并且很久以前用于元素周期表(排列每个元素)。今天我可能会使用GroupPlayout 做后者。我不是 GBL 方面的专家。
  • GroupPlayout ?大声笑,+1 虽然我也正要发布相同的逻辑,但似乎我为时已晚。
  • 这回答了我的问题,但我希望它出现在可用空间的左上角,而不是居中。我将 gridx=0、gridy=0 和 anchor=FIRST_LINE_START 添加到网格包约束实例,并将其添加到我的调用中以将面板添加到网格包面板,但它没有任何效果。如果有人要,我会再次发布。但是有人可以指导我以某种方式做到这一点吗?
  • Hovercraft 帮助我找到了另一种方法:添加到 GridBagLayout 时,将单个面板添加到 x 和 y 权重为 1.0 的 1x1 网格,定位到 NORTHWEST。您不必那样使用两个虚拟面板。
【解决方案2】:

我建议您使用 JPaneljavax.swing.GroupLayout。然而,通过编码来使用这种布局并不容易。如果您不想使用 IDE,请使用 Netbeans Matisse Builder 等代码生成器并将其复制粘贴到您想要的任何位置。

【讨论】:

  • GroupLayout 和 GridBagLayout 一样,都是关于行和列的;我可以像 Thompson 先生刚刚向我展示 GridBagLayout 一样使用 GroupLayout,我会看看它是否更容易按照我的意愿放在左上角。但我认为 Group 和 GridBag 布局对于具有许多组件但没有行/列外观的面板来说都是糟糕的选择。
猜你喜欢
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
相关资源
最近更新 更多