【问题标题】:How to keep JPanel at top of parent container at runtime?如何在运行时将 JPanel 保持在父容器的顶部?
【发布时间】:2015-04-29 03:26:27
【问题描述】:

我创建了一个父容器,在该容器上放置了多个 JPanel 对象,每个对象都包含多个 JButton 对象。

我创建父面板,添加GridBagConstraints,然后将每个子面板添加到父面板:

final JPanel options = new JPanel(new GridBagLayout());
        options.setBorder(new TitledBorder("Select Option"));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1.0;
        gbc.anchor = GridBagConstraints.NORTH;

        options.add(findPanel, gbc);
        options.add(addPanel, gbc);
        options.add(changePanel, gbc);
        options.add(dropPanel, gbc);
        gbc.weighty = 1.0;
        options.add(new JPanel(), gbc);

options.add(new JPanel(), gbc); 用来占用我想要的面板下的额外空间。效果很好....直到我想在用户交互后更改父级的内容:

partnoFai.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent ae){
                    options.remove(findPanel);
                    options.remove(addPanel);
                    options.remove(changePanel);
                    options.remove(dropPanel);
                    options.add(partnoFaiInp, gbc);
                    gbc.weighty = 1.0;
                    options.add(new JPanel(), gbc);
                    frame.pack();
                    frame.validate();
                } 
            } );

当我希望它位于顶部时,它将新面板 options.add(partnoFaiInp, gbc); 添加到父级的中间。为什么gbc.anchor = GridBagConstraint.NORTH; 不将新面板保留在面板的NORTH 中?

感谢任何帮助。

【问题讨论】:

  • 您可以将“填充”组件放置在您可能需要的任何位置下方的 gridy 位置(例如 100),或者您可以使用 add(Component, Object, int) 指定您想要的索引位置在继承中添加的组件
  • “为什么不 gbc.anchor = GridBagConstraint.NORTH; 将新面板保持在面板的 NORTH 中?” 问题在于,“填充物” " 面板没有布置在任何其他组件之前,因为 add 就是这样做的,它将组件“添加”到组件容器列表的末尾
  • 我没看懂,所以“填充”面板应该加在内容面板之前?
  • 没关系。当您第一次设置options 面板时,您将JPanel 添加到最后一个位置,用于将内容“推送”到options 面板的顶部,这很好。但是,当您移除所有面板时,“填充”面板将向上移动并成为容器组件列表中的第一个和最后一个组件。当您添加partnoFaiInp 面板时,它是在容器组件列表中的“填充”之后添加的,因此当布置options 时,首先布置填充面板,然后是partnoFaiInp,然后是第二个“填充”面板...
  • partnoFaiInp 放在中间。您不需要第二个“填充”面板,只需在第一个 filler 之前插入 partnoFaiInp 面板

标签: java swing user-interface layout-manager gridbaglayout


【解决方案1】:

你必须从堆栈的角度来考虑Container

当您第一次使用...设置面板时

options.add(findPanel, gbc);
options.add(addPanel, gbc);
options.add(changePanel, gbc);
options.add(dropPanel, gbc);
gbc.weighty = 1.0;
options.add(new JPanel(), gbc);

容器有一个看起来像{findPanel, addPanel, changePanel, dropPanel, JPanel}的组件列表

当您使用类似...的方式移除组件时

options.remove(findPanel);
options.remove(addPanel);
options.remove(changePanel);
options.remove(dropPanel);

容器现在有一个看起来像{JPanel}的组件列表

然后,当您使用...添加新组件时

options.add(partnoFaiInp, gbc);
gbc.weighty = 1.0;
options.add(new JPanel(), gbc);

容器现在有一个看起来像{JPanel, partnoFaiInp, JPanel}的组件列表

因此,您可以在添加时指定面板的插入点,而不是添加另一个“填充”组件...

options.add(partnoFaiInp, gbc, 0);
frame.pack();
frame.validate();

容器现在有一个看起来像 {partnoFaiInp, JPanel} 的组件列表

【讨论】:

  • 我使用 -1 作为底部,0 作为中心,1 作为顶部......不用说我被误导了。 .add(partnoFaiInp, gbc, 0); 将子 JPanel 对象放在父对象的顶部。非常感谢您的帮助。
  • 还有其他选择。您可以查看来自 SwingLabs、SwingX 库的 VerticalLayout,甚至可以使用 CardLayout (How to Use CardLayout),但没有足够的上下文来提出适当的建议
  • 过去我一直被CardLayout 吓到,我需要完成这个应用程序的基本操作,然后我才能使用一些适当的布局管理器让它看起来更好。感谢您的宝贵时间。
猜你喜欢
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
相关资源
最近更新 更多