Изменение размера jpanel в соответствии с присутствующими в нем компонентами

В приведенном ниже примере в западной части макета границы есть родительская панель, внутри которой есть BoxLayout и несколько панелей. Проблема в том, что западная панель покрывает всю площадь сверху донизу. FlowLayout, используемые для дочерних панелей внутри родительской панели, занимают много места. Можно ли сжать каждый JPanel по компонентам? Кроме того, он должен оставаться прежним, даже когда окно развернуто?

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.BoxLayout;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.JButton;

public class Sample extends JFrame {

    private JPanel contentPane;
    private JTextField textField;
    private JTextField textField_1;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Sample frame = new Sample();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Sample() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.NORTH);

        JLabel lblNewLabel = new JLabel("New label");
        panel.add(lblNewLabel);

        JPanel panel_1 = new JPanel();
        contentPane.add(panel_1, BorderLayout.WEST);
        panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS));

        JPanel panel_2 = new JPanel();
        panel_1.add(panel_2);

        textField = new JTextField();
        panel_2.add(textField);
        textField.setColumns(2);

        textField_1 = new JTextField();
        panel_2.add(textField_1);
        textField_1.setColumns(2);

        JPanel panel_3 = new JPanel();
        panel_1.add(panel_3);

        JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
        panel_3.add(chckbxNewCheckBox);

        JPanel panel_4 = new JPanel();
        panel_1.add(panel_4);

        JButton btnNewButton = new JButton("New");
        panel_4.add(btnNewButton);

        JButton btnNewButton_1 = new JButton("New");
        panel_4.add(btnNewButton_1);
    }

}

person Mercenary    schedule 30.03.2014    source источник
comment
Попробуйте GridBagLayout   -  person Braj    schedule 30.03.2014


Ответы (1)


Один из подходов состоит в том, чтобы добавить panel_1 к закрывающей панели. FlowLayout по умолчанию соответствует предпочтительному размеру вложенных компонентов, когда вы pack() вкладываете Window. Я добавил серую панель к CENTER в качестве заполнителя; измените размер кадра, чтобы увидеть эффект.

JPanel flowPanel = new JPanel();
flowPanel.add(panel_1);

изображение

Как проверено:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.BoxLayout;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.JButton;

public class Sample extends JFrame {

    private JPanel contentPane;
    private JTextField textField;
    private JTextField textField_1;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Sample frame = new Sample();
                    frame.pack();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Sample() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.NORTH);

        JLabel lblNewLabel = new JLabel("New label");
        panel.add(lblNewLabel);

        JPanel panel_1 = new JPanel();
        panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS));

        JPanel panel_2 = new JPanel();
        panel_1.add(panel_2);

        textField = new JTextField();
        panel_2.add(textField);
        textField.setColumns(2);

        textField_1 = new JTextField();
        panel_2.add(textField_1);
        textField_1.setColumns(2);

        JPanel panel_3 = new JPanel();
        panel_1.add(panel_3);

        JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
        panel_3.add(chckbxNewCheckBox);

        JPanel panel_4 = new JPanel();
        panel_1.add(panel_4);

        JButton btnNewButton = new JButton("New");
        panel_4.add(btnNewButton);

        JButton btnNewButton_1 = new JButton("New");
        panel_4.add(btnNewButton_1);

        JPanel flowPanel = new JPanel();
        flowPanel.add(panel_1);
        contentPane.add(flowPanel, BorderLayout.WEST);
        contentPane.add(new JPanel(){

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(320, 240);
            }

            @Override
            public Color getBackground() {
                return Color.lightGray;
            }

        }, BorderLayout.CENTER);
    }

}
person trashgod    schedule 30.03.2014
comment
Спасибо. Это сработало! Также нужно знать, что, если мне придется снова добавить тот же набор компонентов ниже этого? Поскольку это FlowLayout, есть ли другой способ сделать это? - person Mercenary; 30.03.2014
comment
Да; добавить два экземпляра панели потока в вертикальную Box или GridLayout; см. также этот NestedLayoutExample. - person trashgod; 30.03.2014
comment
Мм да. Понятно! Спасибо - person Mercenary; 30.03.2014