GridBagLayout с клеем: без фиксированной высоты ряда - PullRequest
0 голосов
/ 24 апреля 2020

Я хотел бы создать панель, к которой я могу динамически добавлять подпанели с фиксированной высотой. Я пытался использовать клеевой компонент, но он не работает. Я хотел бы добиться, чтобы субпанели были видны в верхней части сетки. Побочная проблема заключается в том, что, когда я продолжаю добавлять подпанели, они начинают перекрываться, потому что JScrollPane не корректируется. Однако, когда я изменяю размер рамки, обе проблемы решаются.

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

Это мой код SSCCE:

import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import jrdb.data.ProcessingCommand;

public class ProcessingPipelineBuilderSSCCE extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 2413084448601918744L;
    private JPanel interiorPanel = null;
    private GridBagConstraints gbc = null;
    private Component glue = null;

    public ProcessingPipelineBuilderSSCCE() {
        super("SSCCE");
        this.getContentPane().setLayout(new BorderLayout());

        gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 0, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.anchor = GridBagConstraints.PAGE_START;

        JPanel pipelineBuilder = new JPanel();
        pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));

        interiorPanel = new JPanel(new GridBagLayout());
        interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));
        JScrollPane scrollPane = new JScrollPane(interiorPanel);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setPreferredSize(new Dimension(500,300));
        pipelineBuilder.add(scrollPane);

        JButton btnNew = new JButton("Add new panel");
        btnNew.setPreferredSize(new Dimension(500, 30));
        btnNew.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (glue!=null) {
                    interiorPanel.remove(glue);
                } else {
                    glue = Box.createGlue();
                }
                gbc.gridy = gbc.gridy + 1;
                interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
                interiorPanel.add(glue,gbc);
                interiorPanel.validate();
                interiorPanel.repaint();
            }
        });
        this.getContentPane().add(btnNew, BorderLayout.PAGE_START);

        this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);


    }

    public class PipelineStep extends JPanel {
        int number;
        public PipelineStep (int n) {
            super();
            JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
            this.number = n;
            this.setLayout(new FlowLayout());
            JLabel lbl = new JLabel(new Integer(this.number).toString());
            lbl.setPreferredSize(new Dimension(45,45));
            lbl.setFont(lbl.getFont().deriveFont(26));
            this.add(lbl);
            this.setPreferredSize(new Dimension(450, 50));
            this.setBorder(BorderFactory.createLineBorder(Color.green));
        }
    }

    public static void main (String args[]) {
        ProcessingPipelineBuilderSSCCE frame = new ProcessingPipelineBuilderSSCCE();
        frame.pack();
        frame.setVisible(true);
    }

}

1 Ответ

1 голос
/ 24 апреля 2020

Почему клеящий компонент не занимает вертикальное пространство для того, чтобы sh боковые панели были сверху?

Компонент "клей" имеет значение только при использовании с BoxLayout. Это не имеет никакого эффекта с GridBagLayout.

Так что я предлагаю забыть о GridBagLayout и использовать BoxLayout.

Самый простой способ сделать это - преобразовать "interiorPanel" в вертикальную. Поставьте флажок и просто добавьте PipelineStep экземпляров на эту панель.

Попробуйте это. Однако вы заметите, что размеры панелей будут увеличиваться до тех пор, пока область прокрутки не заполнится, и в это время вы увидите полосы прокрутки. Это связано с тем, что BoxLayout изменит размеры компонентов до максимального размера компонента. Поэтому, чтобы предотвратить это изменение размера, вы можете переопределить метод getMaximumSize() вашего PipelineStep класса:

@Override
public Dimension getMaximumSize()
{
    return getPreferredSize();
}

Или другой вариант - использовать панель «обертка» для вашей «interiorPanel». Что-то вроде:

JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(interiorPanel, BorderLayout.PAGE_START);
//JScrollPane scrollPane = new JScrollPane(interiorPanel);
JScrollPane scrollPane = new JScrollPane(wrapper);

BorderLayout.PAGE_START учитывает предпочтительную высоту добавляемого к нему компонента, поэтому «interiorPanel» всегда будет отображаться на нужной высоте, а полосы прокрутки будут отображаться, когда видовой экран панели прокрутки full.

Я изменил ваш код, используя подход "обертка".

import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

//import jrdb.data.ProcessingCommand;

public class SSCCE1 extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 2413084448601918744L;
//    private JPanel interiorPanel = null;
    private Box interiorPanel = null;
    private GridBagConstraints gbc = null;
    private Component glue = null;

    public SSCCE1() {
        super("SSCCE");
        this.getContentPane().setLayout(new BorderLayout());

        gbc = new GridBagConstraints();
        //gbc.insets = new Insets(5, 5, 0, 5);
        //gbc.fill = GridBagConstraints.HORIZONTAL;
        //gbc.gridx = 0;
        //gbc.gridy = 0;
        //gbc.weightx = 1.0;
        //gbc.weighty = 1.0;
        //gbc.anchor = GridBagConstraints.PAGE_START;

        JPanel pipelineBuilder = new JPanel();
        pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));

//        interiorPanel = new JPanel(new GridBagLayout());
        interiorPanel = Box.createVerticalBox();
        interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));

        JPanel wrapper = new JPanel( new BorderLayout() );
        wrapper.add(interiorPanel, BorderLayout.PAGE_START);

//        JScrollPane scrollPane = new JScrollPane(interiorPanel);
        JScrollPane scrollPane = new JScrollPane(wrapper);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setPreferredSize(new Dimension(500,300));
        pipelineBuilder.add(scrollPane);

        JButton btnNew = new JButton("Add new panel");
        btnNew.setPreferredSize(new Dimension(500, 30));
        btnNew.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                if (glue!=null) {
//                    interiorPanel.remove(glue);
//                } else {
//                    glue = Box.createGlue();
//                }
                gbc.gridy = gbc.gridy + 1;
//                interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
                interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
//                interiorPanel.add(glue,gbc);
//                interiorPanel.validate();
                interiorPanel.revalidate();
                interiorPanel.repaint();
            }
        });
        this.getContentPane().add(btnNew, BorderLayout.PAGE_START);

        this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);


    }

    public class PipelineStep extends JPanel {
        int number;
        public PipelineStep (int n) {
            super();
            JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
            this.number = n;
            this.setLayout(new FlowLayout());
            JLabel lbl = new JLabel(new Integer(this.number).toString());
            lbl.setPreferredSize(new Dimension(45,45));
            lbl.setFont(lbl.getFont().deriveFont(26));
            this.add(lbl);
            this.setPreferredSize(new Dimension(450, 50));
            this.setBorder(BorderFactory.createLineBorder(Color.green));
        }
    }

    public static void main (String args[]) {
        SSCCE1 frame = new SSCCE1();
        frame.pack();
        frame.setVisible(true);
    }

}
...