Dynamically growing JPanel with BoxLayout (on a null layout)

后端 未结 4 1567
灰色年华
灰色年华 2021-01-16 18:38

I have a JPanel with a vertical BoxLayout on top of a JPanel with a null layout.

I would like the JPanel with the BoxLayout to grow as the components are being added

4条回答
  •  别那么骄傲
    2021-01-16 19:08

    By throwing away the layout manager, you suddenly become responsible for it's job. A job I might add, which isn't easy ...

    Basically, given you example, you've failed to set the size of the child component...

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

    Personally, I think your asking for trouble, but what would I know...

    A better idea might be to use something like an EmptyBorder to providing padding...

    enter image description here

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

    Updated with Layout Manager example

    Now, if all the layout managers are failing you, you could try writing your own. This has the benefits you need from the null layout manager and the benefits of intergrating into Swing's component changing process, without the need to resort to ComponentListeners and ContainerListeners

    enter image description here

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

    Custom Layout Manager

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

    This basically represents the work you are going have to do anyway, but does in away that works with how Swing was designed...

提交回复
热议问题