how to set component size inside container with BoxLayout

吃可爱长大的小学妹 提交于 2019-12-05 22:43:11

问题


Faced with the problem of using 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). I know about the techniques setPrefferedSize () and setMaximumSize (), but it did not work as it should. The line add(Box.createHorizontalGlue ()) also did not help.

Thanks for any idea

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


回答1:


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.

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...

  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)); (c means button, label and textField in your example)

Edit 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());
    }
}

Edit 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");.




回答2:


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

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

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 :




回答3:


This should get close, based on your draw, just need to work on that component below the JLabel (using 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);


来源:https://stackoverflow.com/questions/18405660/how-to-set-component-size-inside-container-with-boxlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!