【问题标题】:Java layout manager vertical centerJava 布局管理器垂直居中
【发布时间】:2010-10-28 05:30:20
【问题描述】:

我的面板使用组布局来组织一些标签。我想在调整大小时将此面板保持在屏幕中心。如果我使用流布局将面板放在另一个面板中,我可以使标签水平居中但不能垂直居中。哪个布局管理器允许我将面板保持在屏幕中间?

我也尝试了边框布局并将其放置在中心,但它会调整为窗口大小。

【问题讨论】:

    标签: java swing layout


    【解决方案1】:

    首先,我要提一下,请阅读我关于布局的文章:http://web.archive.org/web/20120420154931/http://java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/。它很旧但很有帮助(不幸的是,这篇文章早于 BoxLayout。当我在 JavaOne 上发表演讲时,我有一些幻灯片,其中包括 http://javadude.com/articles/javaone 的 BoxLayout)

    试试 BoxLayout:

    Box verticalBox = Box.createVerticalBox();
    verticalBox.add(Box.createVerticalGlue());
    verticalBox.add(stuffToCenterVertically);
    verticalBox.add(Box.createVerticalGlue());
    

    如果你想将这些东西居中,使用 Horizo​​ntalBox 作为 stuffToCenterVertically:

    Box horizontalBox = Box.createHorizontalBox();
    horizontalBox.add(Box.createHorizontalGlue());
    horizontalBox.add(stuffToCenter);
    horizontalBox.add(Box.createHorizontalGlue());
    

    在代码中“看到”比 gridbag 更容易

    【讨论】:

    • 我同意 GridBagLayout 通常更复杂,但是要使单个面板居中,它只有两行。
    • 问题是您在阅读代码时无法“看到”...(我已将答案编辑为“看到”而不是“更容易”...)
    • 我“看到”了......但另一方面,“createVerticalGlue()”对我来说也没有任何意义,没有阅读文档。
    • 公平...但比空的 GridBagConstraints 提供更多提示;)
    • 我同意您使用 BoxLayout 会更幸运。它们比 GridBag 更容易使用。而且无论您选择什么,阅读一下文档(至少是 Swing Layout 示例文档,它很短)总是一个好主意。
    【解决方案2】:

    面板本身的GroupLayout,GroupLayout.Alignment.CENTER,用于垂直和水平,setPreferredSize(new Dimension(yourChosenWidth,yourChosenHeight)) 将面板设置为不调整大小。

    为了安全起见,您也可以在面板上设置 setMinimumSize 和 setMaximum size。

    如果您觉得很时髦,您可以只使用一个 GroupLayout 来处理整个事情,方法是仔细选择并行/顺序组并对标签进行适当的分组。

    【讨论】:

      【解决方案3】:

      您可以构建自己的 LayoutManager 以使单个组件(两个轴或一个轴)居中。这是在两个轴上都执行此操作的一个,您可以轻松地将其更改为垂直或水平居中。

      当前实现布局第一个可见子,你也可以改变它...

      public class CentreLayout implements LayoutManager, java.io.Serializable {
      
      public void addLayoutComponent(String name, Component comp) {
      }
      
      public void removeLayoutComponent(Component comp) {
      }
      
      public Dimension preferredLayoutSize(Container target) {
          return target.getPreferredSize();
      }
      
      public Dimension minimumLayoutSize(Container target) {
          return target.getMinimumSize();
      }
      
      public void layoutContainer(Container target) {
          synchronized (target.getTreeLock()) {
              Insets insets = target.getInsets();
              Dimension size = target.getSize();
              int w = size.width - (insets.left + insets.right);
              int h = size.height - (insets.top + insets.bottom);
              int count = target.getComponentCount();
      
              for (int i = 0; i < count; i++) {
                  Component m = target.getComponent(i);
                  if (m.isVisible()) {
                      Dimension d = m.getPreferredSize();
                      m.setBounds((w - d.width) / 2, (h - d.height) / 2, d.width, d.height);
                      break;
                  }
              }
          }
      }
      
      }
      

      【讨论】:

      • 不幸的是,这对我不起作用。我在方法preferredLayoutSize 中得到了堆栈溢出(哈哈)。
      【解决方案4】:

      尝试使用GridBagLayout 并添加带有空GridBagConstrants 对象的面板。
      例如:

      public static void main(String[] args) {
          JFrame frame = new JFrame();
          frame.setLayout(new GridBagLayout());
          JPanel panel = new JPanel();
          panel.add(new JLabel("This is a label"));
          panel.setBorder(new LineBorder(Color.BLACK)); // make it easy to see
          frame.add(panel, new GridBagConstraints());
          frame.setSize(400, 400);
          frame.setLocationRelativeTo(null);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setVisible(true);
      }
      

      【讨论】:

      • 一直想知道怎么做,最后放弃了,改用了MigLayout。
      • 当容器小于子项的首选大小(但大于最小大小)时,GridBagLayout 会失败。
      猜你喜欢
      • 2019-06-02
      • 1970-01-01
      • 2012-02-15
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 2012-05-30
      相关资源
      最近更新 更多