使用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组件更改过程中的好处,而无需使用ComponentListeners
和ContainerListeners
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
? - 然后使用
JPanel
将BoxLayout
添加到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。