【问题标题】:How to make one component take as little space as possible with two side-by-side components?如何使用两个并排的组件使一个组件占用尽可能少的空间?
【发布时间】:2015-07-31 18:51:38
【问题描述】:

我正在努力完成以下工作:

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

我一直在测试各种 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);
  }

 ...

}

【问题讨论】:

  • 你在使用像 Netbeans 这样的 IDE 吗?

标签: java swing layout jpanel layout-manager


【解决方案1】:

“页脚”面板应该是BorderLayout

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

然后将标签添加到页脚面板的“BorderLayout.CENTER”。标签现在将占据所有可用的剩余空间。

类似:

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

【讨论】:

    【解决方案2】:

    根据@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();
        }
    }
    

    【讨论】:

    • 谢谢,这很有帮助
    【解决方案3】:

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

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

    现在MessageFooter的布局为空,我们可以设置按钮的位置,也可以和buttonPanel一样

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

    更多详情,您可以通过documentation

    【讨论】:

    • (1-) 从来都不是一个好的解决方案。布局管理器可以将组件定位在将考虑组件的首选大小的确切位置。您在 setBounds() 方法中使用的大小只是随机猜测,没有实际意义。
    • 为什么不是一个好的解决方案? @@LuxxMiner 当我必须进行自定义时,我发现它非常有用,这与我可以直接使用其中一个布局管理器的一般情况不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    相关资源
    最近更新 更多