使用BoxLayout动态增长JPanel(在空布局上)

Cod*_*Guy 0 java swing jpanel absolutelayout boxlayout

我有一个JPanel,在JPanel顶部有一个垂直BoxLayout,其布局为null.

我希望带有BoxLayout的JPanel随着组件的添加而增长.

看到这段代码:

public static void main (String[] args) {
    JFrame f = new JFrame();
    f.setSize(500,500);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel total = new JPanel();
    total.setLayout(null);
    total.setSize(f.getWidth(),f.getHeight());
    total.setBackground(Color.green);
    JPanel box = new JPanel();
    box.setLocation(100,200);
    box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
    box.add(new JButton("test"));
    box.add(new JLabel("hey"));
    total.add(box);
    f.add(total);
    f.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)

您会注意到没有任何组件出现.

如何添加更多组件(垂直添加)时,如何使JPanel"框"大小动态增加.

提前:我需要"盒子"的位置正好是100,200所以请不要建议我不使用空布局.我必须使用null布局."total"的null布局不应影响我的问题的答案,该问题集中在"box"面板上.

Mad*_*mer 7

抛弃布局管理器,你突然对它的工作负责.我可能会添加一份工作,这并不容易......

基本上,举个例子,您未能设置子组件的大小......

JFrame f = new JFrame();
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel total = new JPanel();
total.setLayout(null);
total.setSize(f.getWidth(), f.getHeight());
total.setBackground(Color.green);

JPanel box = new JPanel();
box.setLocation(100, 200);
box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
box.add(new JButton("test"));
box.add(new JLabel("hey"));
box.setSize(100, 100);  // <-- Don't forget this..

total.add(box);
f.add(total);
f.setVisible(true);
Run Code Online (Sandbox Code Playgroud)

就个人而言,我认为你要求麻烦,但我知道什么......

一个更好的想法可能是使用像EmptyBorder提供填充...

在此输入图像描述

JFrame f = new JFrame();
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel total = new JPanel(new BorderLayout());
total.setSize(f.getWidth(), f.getHeight());
total.setBackground(Color.green);
total.setBorder(new EmptyBorder(100, 200, 100, 200));

JPanel box = new JPanel();
box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
box.add(new JButton("test"));
box.add(new JLabel("hey"));

total.add(box);
f.add(total);
f.setVisible(true);
Run Code Online (Sandbox Code Playgroud)

更新了布局管理器示例

现在,如果所有布局管理器都失败了,您可以尝试编写自己的布局管理器.这有您从需要的好处null布局管理器与积分到Swing的成分变更过程的好处,而无需求助于ComponentListenersContainerListeners

在此输入图像描述

JPanel total = new JPanel();
total.setLayout(new SuperAwesomeBetterThenYoursLayout());
Run Code Online (Sandbox Code Playgroud)

自定义布局管理器

public static class SuperAwesomeBetterThenYoursLayout implements LayoutManager {

    @Override
    public void addLayoutComponent(String name, Component comp) {
    }

    @Override
    public void removeLayoutComponent(Component comp) {
    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        return new Dimension(100, 300);
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        return new Dimension(100, 300);
    }

    @Override
    public void layoutContainer(Container parent) {
        boolean laidOut = false;
        for (Component child : parent.getComponents()) {
            if (child.isVisible() && !laidOut) {
                child.setLocation(200, 100);
                child.setSize(child.getPreferredSize());
            } else {
                child.setSize(0, 0);
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

这基本上代表了你无论如何都要做的工作,但是它与Swing的设计方式有关......


Hov*_*els 5

建议:

  • 几乎从不使用null布局.
  • 为什么不给总JPanel一个BorderLayout
  • 然后将BoxLayout使用添加JPanelBorderLayout.NORTH(或也称为BorderLayout.PAGE_START)位置.

编辑
你说,

提前:我需要"盒子"的位置正好是100,200所以请不要建议我不使用空布局.我必须使用null布局."total"的null布局不应影响我的问题的答案,该问题集中在"box"面板上.

我认为你再次对你的计划施加了不必要的限制.您可以通过在其周围放置一个大小的空边框或其他方式轻松地将"盒子"放置在100,200.但答案是不要抛弃使用null布局.

  • @CodeGuy在向容器添加组件时,容器无效,导致布局管理器被调用,请求它应该布局其内容.部分原因是确定容器的首选,最小和最大布局要求.通过删除更高容器的布局管理器,您已经破坏了这个过程,这意味着,当容器"试图"成长时,您不会让它.那就是问题所在... (3认同)
  • @CodeGuy _想想这个问题:"你如何制作一个带有垂直框布局的动态JPanel,当你添加更多组件时,它会增加大小"_这正是**正是布局管理器负责做的事情.如果你想浪费你的时间重新发明轮子,耸耸肩,独自一人:其他人可能不会那么热情浪费时间和精力......还有更多有趣的问题需要解决;-) (3认同)