有时在Java中,一个布局管理器是不够的

在开发Java Swing应用程序时,最经常的是,我们需要在多个嵌套面板中使用多个布局管理器。 通常这不是问题,并且被认为是几乎所有人类已知语言的所有UI开发的常规做法。

但是,大多数情况下,对于UI中的每个面板,只需要一个布局管理器即可达到所需的效果,但是有时您需要根据容器中的组件数对同一容器使用多个布局管理器。

这样的示例之一是在创建类似居中网格的布局时。 大多数情况下,如果组件的数量固定,则GridLayout或GridBagLayout可能就足够了,但是如果组件的数量不断变化,则布局可能不理想。 今天下午我遇到了类似的问题,这是我想出的解决方案。

我想要实现的UI与Opera的快速拨号类似,但是拨号次数可变。 基本上,

  1. 您从一个组件开始,并且应该在面板中居中
  2. 添加另一个组件,它们都应该居中
  3. 添加三分之一,所有三个都应放在一行的中心
  4. 如果添加了第四个组件,则您应该有一个3 x 2的矩阵,第一行中有三项,第二行中有一项
  5. 对于最多六个组件,应保留3 x 2矩阵
  6. 对于6个以上的组件,矩阵应为4 x 3,因此我们最多可以容纳12个组件,这将是最大

最初,这个要求看起来很棘手,但解决方案通常是仅使用两个JPanels的布局管理器的组合。 基本上,是一个用于使内部内容物居中的外部容器,以及一个用于根据需要创建矩阵的内部容器。

使用哪个布局管理器

随之而来的问题是,哪个布局管理器可以提供所需的结果? 经过几分钟的试验,我终于意识到GridBagLayout给了我所需的居中内容外观,但是有时是不一致的。 因此,我选择通过netbeans设计器使用GroupLayout。 因此,将其应用于外部容器。

接下来,我试图找到一个可以有效满足第一个要求的布局管理器。 选项为FlowLayout和GridLayout。 但是,尽管FlowLayout倾向于将其内容垂直对齐到顶部,但在这种情况下就足够了,因为GroupLayout将FlowLayout内容垂直居中,并满足了1-3的要求。

接下来,对于需求4,再次选择了GridLayout,但是这次将其设置为anx 3矩阵,其中n是任意数量的行。 这使GridLayout可以按预期增长,并且还可以在垂直放置之前先水平放置其组件。 这也自动满足了要求5。

最后,当组件大于6时,将创建一个新的GridLayout,其大小为nx 4,需要有效地对齐内容。 可以进一步添加新组件,直到最多达到12个组件为止,并且禁止进一步添加。

这是该过程的示例代码。

JPanel container = new JPanel();
container.setName("container"); // NOI18N
container.setOpaque(false);

JPanel content = new JPanel();
content.setBorder(javax.swing.BorderFactory.createEmptyBorder(50, 50, 50, 50));
content.setName("content"); // NOI18N
content.setOpaque(false);
content.setLayout(new java.awt.GridLayout(0, 3));

javax.swing.GroupLayout containerLayout = new javax.swing.GroupLayout(container);
container.setLayout(containerLayout);
containerLayout.setHorizontalGroup(
    containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(containerLayout.createSequentialGroup()
        .addContainerGap(346, Short.MAX_VALUE)
        .addComponent(content, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(347, Short.MAX_VALUE))
);
containerLayout.setVerticalGroup(
    containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(containerLayout.createSequentialGroup()
        .addContainerGap(223, Short.MAX_VALUE)
        .addComponent(content, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(224, Short.MAX_VALUE))
);

然后,每添加一个新组件,就会运行以下代码:

getContent().removeAll();

int gridSize = organisations.size();

switch( gridSize ) {
    case 1:
    case 2:
    case 3:
        getContent().setLayout( new FlowLayout(FlowLayout.CENTER) );
        break;
    case 4:
    case 5:
    case 6:
        getContent().setLayout( new GridLayout(0,3) );
        break;
    case 7:
    case 8:
        getContent().setLayout( new GridLayout(0,4) );
        break;
    default:
        getContent().setLayout( new GridLayout(0, 4) );
}

for (Organisation org : organisations) {
    getContent().add(createOrgSelectionComponent(org));
}

getContent().validate();
getContent().repaint();

这是最终布局的屏幕截图。

参考: 有时在Java中,我们的JCG合作伙伴 Francis在“ Ice in Code”博客中 还没有一个Layout Manager

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/09/sometimes-in-java-one-layout-manager-is.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值