Java 如何使用 BoxLayout 在容器内设置组件大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18405660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:19:19  来源:igfitidea点击:

How to set component size inside container with BoxLayout

javaswinglayoutlayout-managerboxlayout

提问by Dumas45

I'm facing a problem with using BoxLayout.

我在使用BoxLayout.

In my example, I try to decrease the height of the text field and change the width of the buttons (as shown in green marker in the picture at the bottom). I know about the techniques setPreferredSize()and setMaximumSize(), but it did not work as it should. The line add(Box.createHorizontalGlue())also did not help.

在我的示例中,我尝试降低文本字段的高度并更改按钮的宽度(如底部图片中的绿色标记所示)。我知道这些技术setPreferredSize()setMaximumSize(),但它没有按预期工作。该行add(Box.createHorizontalGlue())也没有帮助。

Thanks for any ideas.

感谢您的任何想法。



public class Testy extends JPanel {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                constructGUI();
            }
        });
    }

    private static void constructGUI() {
        JFrame frame = new JFrame("Testy");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setBackground(Color.DARK_GRAY);
        centerPanel.setPreferredSize(new Dimension(100, 400));
        frame.add(centerPanel, BorderLayout.CENTER);

        Testy eastPanel = new Testy();
        frame.add(eastPanel, BorderLayout.EAST);

        frame.pack();
        frame.setVisible(true);
    }

    public Testy() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        JButton button = new JButton("Button ...... 1");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        add(button);

        button = new JButton("Button 2");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        add(button);

        button = new JButton("Button ........... 3");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        add(button);

        JLabel label = new JLabel("Label");
        //label.setPreferredSize(...);
        //label.setMaximumSize(...);
        add(label);

        JTextField textField = new JTextField();
        //textField.setPreferredSize(...);
        //textField.setMaximumSize(...);
        add(textField);

        button = new JButton("Button 4");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        add(button);

        //add(Box.createHorizontalGlue());
    }
}

picture

图片

采纳答案by Boris ?u?ka

First you have to realize that component position and size in Java Swing depends on Layout manager (if layout manager is set) not on the component itself. The component requests the manager for size.

首先,您必须意识到 Java Swing 中的组件位置和大小取决于布局管理器(如果设置了布局管理器)而不是组件本身。该组件向管理器请求大小。

For this case I would use different layout - combination of GridLayout and BorderLayout is enough and very simple and straightforward. But if want use BoxLayout, then...

对于这种情况,我将使用不同的布局 - GridLayout 和 BorderLayout 的组合就足够了,而且非常简单明了。但是如果想使用BoxLayout,那么......

  1. Documentation says:

    BoxLayout pays attention to a component's requested minimum, preferred, and maximum sizes. While you are fine-tuning the layout, you might need to adjust these sizes. ... For example, a button's maximum size is generally the same as its preferred size. If you want the button to be drawn wider when additional space is available, then you need to change its maximum size.

  2. Then set components maximum size: c.setMaximumSize(new Dimension(Integer.MAX_VALUE, c.getMinimumSize().height));(cmeans button, labeland textFieldin your example)

  1. 文档说:

    BoxLayout 关注组件请求的最小、首选和最大尺寸。在微调布局时,您可能需要调整这些尺寸。... 例如,按钮的最大尺寸通常与其首选尺寸相同。如果您希望在有额外空间时将按钮绘制得更宽,那么您需要更改其最大尺寸。

  2. 然后设置组件的最大尺寸:c.setMaximumSize(new Dimension(Integer.MAX_VALUE, c.getMinimumSize().height));c手段buttonlabeltextField在你的例子)

Edit 1:

编辑1:

Here is working source code:

这是工作源代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

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

public class Testy extends JPanel {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                constructGUI();
            }
        });
    }

    private static void constructGUI() {
        JFrame frame = new JFrame("Testy");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setBackground(Color.DARK_GRAY);
        centerPanel.setPreferredSize(new Dimension(100, 400));
        frame.add(centerPanel, BorderLayout.CENTER);

        Testy eastPanel = new Testy();
        frame.add(eastPanel, BorderLayout.EAST);

        frame.pack();
        frame.setVisible(true);
    }

    public Testy() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        JButton button = new JButton("Button ...... 1");
        //button.setPreferredSize(...);
        button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height));
        add(button);

        button = new JButton("Button 2");
        //button.setPreferredSize(...);
        button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height));
        add(button);

        button = new JButton("Button ........... 3");
        //button.setPreferredSize(...);
        button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height));
        add(button);

        JLabel label = new JLabel("Label");
        //label.setPreferredSize(...);
        label.setMaximumSize(new Dimension(Integer.MAX_VALUE, label.getMinimumSize().height));
        add(label);

        JTextField textField = new JTextField();
        //textField.setPreferredSize(...);
        textField.setMaximumSize(new Dimension(Integer.MAX_VALUE, textField.getMinimumSize().height));
        add(textField);

        button = new JButton("Button 4");
        //button.setPreferredSize(...);
        button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height));
        add(button);

        // add(Box.createVerticalGlue());
    }
}

Screenshot

截屏

Edit 2:

编辑2:

If you want laid out Button 4 at the bottom of right column add this line add(Box.createVerticalGlue());between add(textField);and button = new JButton("Button 4");.

如果您想在右列底部布置按钮 4,请add(Box.createVerticalGlue());add(textField);和之间添加此行button = new JButton("Button 4");

回答by Fernando

This should get close, based on your draw, just need to work on that component below the JLabel (using setPreferredSize()):

根据您的绘制,这应该很接近,只需要处理 JLabel 下方的该组件(使用 setPreferredSize()):

JPanel main = new JPanel(new GridLayout(1, 2));

JPanel left = new JPanel();
//left.setPreferredSize(some size);
JPanel right = new JPanel(new GridLayout(6, 1));
//right.setPreferredSize(some size);

right.add(new JButton("Button 1"));
//...
right.add(new JButton("Button 4"));

main.add(left);
main.add(right);

回答by nIcE cOw

As a quick remedy, you can use nested layouts, in the sense, that on the right side, create a JPanelwith BorderLayout, put a JPanel(say compPanel)at the CENTERand a JPanel(say buttonPanel)at PAGE_ENDlocation. Now use a new JPanel(say panel)with GridLayoutand put all the components on it, and place this compPanelinside centerPanel. Place JButton(button4)inside buttonPanelas is.

作为一个快速的补救措施,您可以使用嵌套布局,从某种意义上说,在右侧,创建一个JPanelwith BorderLayout,将 aJPanel(say compPanel)放在 theCENTER和 a JPanel(say buttonPanel)atPAGE_END位置。现在使用一个新的JPanel(say panel)withGridLayout并将所有组件放在上面,并将其compPanel放在centerPanel. 广场JButton(button4)buttonPanel原样。

BoxLayouton the contrary, respects the preferred size of a given JComponent, which is usually calculated based on the content the JComponentholds or given explicity, hence components do not tend to align well with respect to other given components.

BoxLayout相反,尊重给定 的首选大小JComponent,这通常是根据JComponent所持有的内容或明确给出的内容计算的,因此组件与其他给定组件往往不会很好地对齐。

Here is the working example :

这是工作示例:

import java.awt.*;
import javax.swing.*;

public class Testy extends JPanel {        

    private JPanel panel;
    private JPanel buttonPanel;

    public Testy() {
        setLayout(new BorderLayout(5, 5));

        JPanel compPanel = new JPanel();
        panel = new JPanel(new GridLayout(6, 1, 5, 5));     
        JButton button = new JButton("Button ...... 1");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        panel.add(button);

        button = new JButton("Button 2");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        panel.add(button);

        button = new JButton("Button ........... 3");
        //button.setPreferredSize(...);
        //button.setMaximumSize(...);
        panel.add(button);

        JLabel label = new JLabel("Label");
        //label.setPreferredSize(...);
        //label.setMaximumSize(...);
        panel.add(label);

        JTextField textField = new JTextField();
        //textField.setPreferredSize(...);
        //textField.setMaximumSize(...);
        panel.add(textField);
        compPanel.add(panel);

        buttonPanel = new JPanel();
        button = new JButton("Button 4");
        buttonPanel.add(button);

        add(compPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.PAGE_END);
    }

    private void constructGUI() {
        JFrame frame = new JFrame("Testy");
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        frame.getContentPane().setLayout(new BorderLayout(5, 5));
        centerPanel.setBackground(Color.DARK_GRAY);
        frame.add(centerPanel, BorderLayout.CENTER);

        frame.add(this, BorderLayout.LINE_END);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Testy().constructGUI();
            }
        });
    }
}

OUTPUT :

输出 :

LAYOUT EXAMPLE

布局示例