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

我有一个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); } 

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

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

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

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

基本上,举个例子,你没能设置子组件的大小……

 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); 

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

一个更好的想法可能是使用类似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); 

更新了布局管理器示例

现在,如果所有布局管理器都失败了,您可以尝试编写自己的布局管理器。 这样就可以从null布局管理器中获得所需的好处,以及集成到Swing组件更改过程中的好处,而无需使用ComponentListenersContainerListeners

在此处输入图像描述

 JPanel total = new JPanel(); total.setLayout(new SuperAwesomeBetterThenYoursLayout()); 

自定义布局管理器

 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); } } } } 

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

建议:

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

编辑
你说,

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

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

蝙蝠,我会改变:

 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); //<-- this is usually a bad idea, but you can keep it // if you want to specify an EXACT location // for your JPanel total.setPreferredSize(500, 500); 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.pack(); f.setVisible(true); } 

一旦你有了这个基础,你需要做的就是动态改变JPanel的大小:

 panel.setSize(width, heightOfComponentWithin * numberOfComponents); container.repaint(); //<-- Im not sure if you also have to call panel.repaint(), // you probably don't have to. 

我还建议使用滚动视图,以防JPanel开始退出视图。 祝好运!

也许是因为你没有setSize for box JPanel。

Interesting Posts