как установить размер компонента внутри контейнера с BoxLayout

столкнулся с проблемой использования BoxLayout

в моем примере я пытаюсь уменьшить высоту текстового поля и изменить ширину кнопок (как показано зеленым маркером на рисунке). Я знаю о методах setPrefferedSize () и setMaximumSize (), но он не работал так, как должен. Строка add (Box.createHorizontalGlue ()) также не помог.

Спасибо за любые идеи!--2-->

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

3 ответов


сначала вы должны понять, что позиция и размер компонента в Java Swing зависят от менеджера макетов (если установлен менеджер макетов), а не от самого компонента. Компонент запрашивает у менеджера размер.

для этого случая я бы использовал другую компоновку-сочетание GridLayout и BorderLayout достаточно и очень просто и просто. Но если хотите использовать BoxLayout, то...

  1. документация говорит:

    boxlayout в обратить внимание к требуемым минимальным, предпочтительным и максимальным размерам компонента. В то время как вы настраиваете макет, вам может потребоваться настроить их размеры. ... Например, максимальный размер кнопки обычно равен такой же, как его предпочтительный размер. Если вы хотите, чтобы кнопка была нарисована шире когда дополнительное пространство будет доступно, то вам необходимо изменить его максимальный размер.

  2. затем установите максимальный размер компонентов:c.setMaximumSize(new Dimension(Integer.MAX_VALUE, c.getMinimumSize().height)); (c значит button, label и textField в вашем примере)

Edit 1:

вот рабочий исходный код:

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:

если вы хотите выложить кнопку 4 в нижней части правой колонки, добавьте эту строку add(Box.createVerticalGlue()); между add(textField); и button = new JButton("Button 4");.


в качестве быстрого решения вы можете использовать вложенные макеты в том смысле, что с правой стороны создайте JPanel С BorderLayout, поставил JPanel(say compPanel) на CENTER и JPanel(say buttonPanel) at PAGE_END расположение. Теперь используйте новый JPanel(say panel) С GridLayout и положите все компоненты на него, и поместите это compPanel внутри centerPanel. Место JButton(button4) внутри buttonPanel как есть.

BoxLayout напротив, уважает предпочтительный размер данного JComponent, который обычно рассчитывается на основе содержимого the JComponent удерживает или дает эксплицитность, поэтому компоненты не склонны хорошо выравниваться по отношению к другим данным компонентам.

вот рабочий пример :

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

выход :

LAYOUT EXAMPLE


Это должно быть близко, основываясь на вашей ничьей, просто нужно работать над этим компонентом ниже 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);