如何使用两个并排组件使一个组件占用尽可能少的 space?

How to make one component take as little space as possible with two side-by-side components?

我正在努力完成以下任务:

  1. JFrame 底部的页脚,包含两个组件:左侧的 JLabel 和右侧的面板,其中包含三个按钮
  2. 我希望右侧按钮面板占用的空间尽可能少 space,同时 JLabel 填满托管 JFrame 的宽度减去按钮面板的宽度。
  3. JLabel 周围有斜角边框,按钮没有
  4. 按钮之间几乎没有 space

我一直在测试各种 Swing 布局以使其正常工作,但到目前为止运气不佳。目前我正在按照教程尝试 GridBagConstraints;这是现在的样子:

如您所见,它不起作用,我不知道为什么。

这是我当前的代码:

public class MessageFooter extends JPanel {

  private static final int BORDER_WIDTH = 5;

  private final JLabel _recentMessage = new JLabel();

  private int _footerHeight;

  /*package*/ MessageFooter() {

    // Set the size of the footer
    _footerHeight = FlowFramePrefs.getUserPrefFontSize() + (BORDER_WIDTH * 2);

    this.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;

    this.setMaximumSize(new java.awt.Dimension(java.lang.Integer.MAX_VALUE, _footerHeight));
    this.setMinimumSize(new java.awt.Dimension(0, _footerHeight));
    this.setPreferredSize(new Dimension(_footerHeight, _footerHeight));
    this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

    // JLabel
    JPanel labelPanel = new JPanel();
    _recentMessage.setText("   Blahhhhh");
    labelPanel.add(_recentMessage);//, BorderLayout.CENTER);
    labelPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
    //_recentMessage.setAlignmentX(Component.LEFT_ALIGNMENT);

    // Buttons
    JPanel buttonPanel = new JPanel();
    buttonPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
    //buttonPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
    // Create the buttons
    JButton upprB = new JButton("U");
    upprB.setMargin(new Insets(0, 0, 0, 0));
    upprB.setBorder(new EmptyBorder(0, 0, 0, 0));
    JButton downB = new JButton("D");
    downB.setMargin(new Insets(0, 0, 0, 0));
    downB.setBorder(new EmptyBorder(0, 0, 0, 0));
    JButton openB = new JButton("O");
    openB.setMargin(new Insets(0, 0, 0, 0));
    openB.setBorder(new EmptyBorder(0, 0, 0, 0));
    buttonPanel.add(upprB);
    buttonPanel.add(downB);
    buttonPanel.add(openB);

    // Add both
    c.weightx = 1.0;
    c.gridx = 0;
    c.gridy = 0;
    this.add(labelPanel, c);
    c.weightx = 0.0;
    c.gridx = 1;
    c.gridy = 0;
    this.add(buttonPanel, c);
  }

 ...

}

"footer" 面板应该是 BorderLayout

然后创建一个 "buttons" 面板并将按钮添加到该面板。然后这个面板将被添加到页脚面板的 "BorderLayout.LINE_END" 中。这意味着按钮将全部以其首选大小显示。

然后将标签添加到页脚面板的 "BorderLayout.CENTER"。该标签现在将占据所有可用的剩余 space.

类似于:

JPanel buttons = new JPanel();
buttons.add(button1);
...

JPanel footer = new JPanel( new BorderLayout() );
footer.add(label, BorderLayout.CENTER);
footer.add(buttons, BorderLayout.LINE_END);

frame.add(footer, BorderLayout.PAGE_END);

根据@camickr 的回答我创建了一个示例:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

public class MessageFooter extends JFrame {

    public MessageFooter() {

        setLayout(new BorderLayout());

        JPanel footer = new JPanel();
        footer.setLayout(new BorderLayout());

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1,3));

        JPanel labelPanel = new JPanel();
        labelPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));

        JButton u = new JButton("U");
        u.setMargin(new Insets(0,0,0,0));

        JButton d = new JButton("D");
        d.setMargin(new Insets(0,0,0,0));

        JButton o = new JButton("O");
        o.setMargin(new Insets(0,0,0,0));

        JLabel label = new JLabel("Sample Text");

        buttonPanel.add(u);
        buttonPanel.add(d);
        buttonPanel.add(o);
        labelPanel.add(label);
        footer.add(labelPanel, BorderLayout.CENTER);
        footer.add(buttonPanel, BorderLayout.LINE_END);

        add(footer, BorderLayout.SOUTH);    
        setSize(500,500);
        setVisible(true);

    }

    public static void main(String[] args) {
        new MessageFooter();
    }
}

尝试使用绝对布局,即 this.setLayout(null) 现在您可以为您正在使用的每个组件指定数量 space。

假设 MessageFooter 的尺寸 - 1000(宽度),50(高度)

现在 MessageFooter 的布局为 null,我们可以设置按钮的位置或 buttonPanel

this.setLayout(null);
this.setSize(new Dimension(1000,50));
labelPanel.setBounds(0,0,800,50);
buttonPanel.setBounds(800,0,200,50);

有关详细信息,您可以阅读此 documentation