【问题标题】:Nested layouts - FlowLayout inside BoxLayout嵌套布局 - BoxLayout 内的 FlowLayout
【发布时间】:2013-06-02 07:37:23
【问题描述】:

我有一个controlPanel (BoxLayout):

controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));

现在我构建两个FlowLayout 并将它们添加到contolPanel 面板:

JPanel fromDatePanel = new JPanel(new FlowLayout());
JPanel untilDatePanel = new JPanel(new FlowLayout());

fromDatePanel.add(new JLabel("From - "));
fromDatePanel.add(new JButton("..."));
untilDatePanel.add(new JLabel("Until - "));
untilDatePanel.add(new JButton("..."));

controlPanel.add(fromDatePanel);
controlPanel.add(untilDatePanel);

我明白了:

为什么它会在布局之间产生间隙?例如,如果我插入一个JButton,它可以正常工作(它插入它们时没有间隙)。

如何消除两个FlowLayout 之间的差距? (所以它会像蓝色的差距)

【问题讨论】:

  • 如果您想保留BoxLayout 并消除差距,请覆盖JPanelgetMaximumSize() 并返回getPreferredSize。请参阅下面的答案。
  • @GuillaumePolet 谢谢,这有帮助!

标签: java swing layout flowlayoutpanel boxlayout


【解决方案1】:

您可以使用GridBagLayout 实现垂直布局(垂直居中)(并使用GridBagConstraintgridwidth=REMAINDER):

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGridBagLayout {

    protected void initUI() {
        JFrame frame = new JFrame();
        JPanel controlPanel = (JPanel) frame.getContentPane();
        controlPanel.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, gbc);
        controlPanel.add(untilDatePanel, gbc);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestGridBagLayout testMultiplePanels = new TestGridBagLayout();
                testMultiplePanels.initUI();

            }
        });
    }

}

关于JButtonJPanel 添加到BoxLayout 时的区别,这是由于getMaximumSize() 的实现方式不同,BoxLayout 已将其考虑在内。 JButton 返回首选大小,而 JPanel 将返回 nullBoxLayout 将其解释为无限维度。

如果你想保留你的BoxLayout,你可以覆盖JPanel.getMaximumSize()并返回getPreferredSize()

import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGridBagLayout {

    protected void initUI() {
        JFrame frame = new JFrame();
        JPanel controlPanel = (JPanel) frame.getContentPane();
        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel fromDatePanel = new JPanel(new FlowLayout()) {
            @Override
            public Dimension getMaximumSize() {
                return getPreferredSize();
            }
        };
        JPanel untilDatePanel = new JPanel(new FlowLayout()) {
            @Override
            public Dimension getMaximumSize() {
                return super.getMaximumSize();
            }
        };

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel);
        controlPanel.add(untilDatePanel);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestGridBagLayout testMultiplePanels = new TestGridBagLayout();
                testMultiplePanels.initUI();

            }
        });
    }

}

【讨论】:

  • 这就解释了!谢谢我的朋友。
  • @MarounMaroun 我试过了,它有效:\ 发布SSCCE。查看我的编辑。
【解决方案2】:

关于Box.createVerticalGlue(),请参阅Using Invisible Components as Filler

【讨论】:

  • 这行不通。我想做相反的事情——让两个FlowLayouts 正好在彼此下方(没有间隙)。
  • 然后使用GridBagLayoutGroupLayout;后者可见here
  • 谢谢,我会的。不过有意思的是,我还是想为上面的问题找到解决办法。这让我很烦:D
  • 贴出所有代码。任何时候,只要你有一个像这样的小、容易包含的例子,就麻烦地创建一个完整的小程序来说明你的问题并将其全部发布。一半或更多的时间,你会回答你自己的问题;另一半,你会给别人更好的机会来回答它。
【解决方案3】:

我使用了BorderLayout,它成功了。

        JPanel controlPanel = new JPanel();
        //  controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        controlPanel.setLayout(new BorderLayout());

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, BorderLayout.NORTH);
        controlPanel.add(untilDatePanel, BorderLayout.CENTER);

Edit-1:

您可以在每个面板内添加嵌套面板。

        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        // controlPanel.setLayout(new BorderLayout());

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());
        JPanel thirdPnl = new JPanel(new FlowLayout());
        JPanel fourthPnl = new JPanel(new FlowLayout());

        JPanel thrdForthPnl = new JPanel(new BorderLayout()); 

        fourthPnl.add(new JLabel("Fourth"));
        fourthPnl.add(new JButton("4.1"));

        thirdPnl.add(new JLabel("Third"));
        thirdPnl.add(new JButton("3.1"));

        thrdForthPnl.add(thirdPnl, BorderLayout.NORTH);
        thrdForthPnl.add(fourthPnl, BorderLayout.CENTER);

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, BorderLayout.NORTH);
        controlPanel.add(untilDatePanel, BorderLayout.CENTER);
        controlPanel.add(thrdForthPnl, BorderLayout.SOUTH);

【讨论】:

  • 谢谢。但这仅适用于两个面板。我使用BoxLayout 是因为我想添加两个以上的按钮。
  • @MarounMaroun 您可以在每个面板中添加任意数量的面板广告。并将所有面板的母亲添加到 contentPane。通过明智地设计面板,您甚至可以在以后重复使用这些面板。
猜你喜欢
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多