0

我在具有空布局的 JPanel 顶部有一个带有垂直 BoxLayout 的 JPanel。

我希望带有 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 “盒子”随着我添加更多组件(垂直添加)而动态增加。

提前:我需要“框”的位置正好在 100,200,所以请不要建议我不使用空布局。我必须使用空布局。“总计”的空布局不应影响我的问题的答案,该问题侧重于“框”面板。

4

4 回答 4

9

通过丢弃布局管理器,您突然对它的工作负责。我可能会添加的工作,这并不容易......

基本上,给定你的例子,你没有设置子组件的大小......

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 的设计方式一致......

于 2013-01-12T05:31:55.100 回答
6

建议:

  • 几乎永远不要使用空布局。
  • 为什么不给总JPanela BorderLayout
  • 然后将BoxLayoutusing添加JPanelBorderLayout.NORTH(或也称为BorderLayout.PAGE_START)位置。

编辑
你的状态,

提前:我需要“框”的位置正好在 100,200,所以请不要建议我不使用空布局。我必须使用空布局。“总计”的空布局不应影响我的问题的答案,该问题侧重于“框”面板。

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

于 2013-01-12T03:46:51.580 回答
3

马上,我会改变什么:

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 开始消失。祝你好运!

于 2013-01-12T05:08:54.877 回答
2

也许是因为你还没有为 box JPanel 设置大小。

于 2013-01-12T04:35:12.987 回答