带胶水的GridBagLayout:没有固定的行高 [英] GridBagLayout with glue : no fixed row height

查看:103
本文介绍了带胶水的GridBagLayout:没有固定的行高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个面板,可以在其中动态添加具有固定高度的子面板.我尝试使用胶水组件,但是它不起作用.我想实现子面板在gridbaglayout的顶部可见.另一个问题是,当我继续添加子面板时,由于JScrollPane不能调整,它们开始重叠.但是,当我调整框架大小时,两个问题都解决了.

I would like to create a panel, to which I can dynamically add sub-panels with fixed height. I tried using a glue component, but it does not work. I would like to achieve that the sub-panels are visible at the top of the gridbaglayout. Side problem is that when I keep adding sub-panels, they start to overlap because the JScrollPane isn't adjusting. However, when I resize the frame, both problems are solved.

此刻,我看不到哪里出了问题.为什么胶水组件不占用垂直空间以将侧面板推到顶部?

At this moment I don't see where I went wrong. Why does the glue component not take up the vertical space to push the side panels to the top?

这是我的SSCCE代码:

This is my SSCCE code:

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

}

推荐答案

为什么胶水组件不占用垂直空间以将侧面板推到顶部?

Why does the glue component not take up the vertical space to push the side panels to the top?

胶水"组件仅在与BoxLayout一起使用时才有意义.它对GridBagLayout无效.

The "glue" component only has meaning when used with the BoxLayout. It has no effect with the GridBagLayout.

所以我的建议是忘记GridBagLayout并使用BoxLayout.

So my suggestion is to forget about the GridBagLayout and use the BoxLayout.

最简单的方法是将"interiorPanel"转换为使用垂直Box,然后将您的PipelineStep实例添加到此面板中.

The easiest way to do this is to convert "interiorPanel" to use a vertical Box and just add your PipelineStep instances to this panel.

尝试一下.但是,您会注意到,在滚动窗格已满之前,面板的大小仍然会增加,这时您将看到滚动条出现.这是因为BoxLayout会将组件的大小调整为最大组件的大小.因此,为防止调整大小,您可以覆盖PipelineStep类的getMaximumSize()方法:

Try this. However, you will notice that the panels will still increase in size until the scroll pane is full, at which time you will see scrollbars appear. This is because the BoxLayout will resize components up to the maximum size of the component. So to prevent this resizing you could override the getMaximumSize() method of your PipelineStep class:

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

或者,另一种选择是为"interiorPanel"使用包装器"面板.像这样:

Or, another option is to use a "wrapper" panel for your "interiorPanel". Something like:

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"将始终以首选高度显示,并且在滚动窗格的视口已满时会显示滚动条.

BorderLayout.PAGE_START respects the preferred height of the component added to it so the "interiorPanel" will always be displayed at it preferred height and scrollbars will appear when the viewport of the scroll pane is full.

我使用包装器"方法修改了您的代码.

I modified you code using the "wrapper" approach.

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

}

这篇关于带胶水的GridBagLayout:没有固定的行高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆