Java 带胶水的GridBagLayout:无固定行高
我想创建一个面板,我可以在其中动态添加具有固定高度的子面板。我尝试使用胶水组件,但它不起作用。我希望实现子面板在gridbaglayout的顶部可见。另一个问题是,当我不断添加子面板时,它们开始重叠,因为JScrollPane没有调整。然而,当我调整框架的大小时,这两个问题都得到了解决 此时此刻,我看不出我错在哪里了。为什么胶水组件不占用垂直空间将侧板推到顶部 这是我的SSCCE代码:Java 带胶水的GridBagLayout:无固定行高,java,swing,layout-manager,gridbaglayout,Java,Swing,Layout Manager,Gridbaglayout,我想创建一个面板,我可以在其中动态添加具有固定高度的子面板。我尝试使用胶水组件,但它不起作用。我希望实现子面板在gridbaglayout的顶部可见。另一个问题是,当我不断添加子面板时,它们开始重叠,因为JScrollPane没有调整。然而,当我调整框架的大小时,这两个问题都得到了解决 此时此刻,我看不出我错在哪里了。为什么胶水组件不占用垂直空间将侧板推到顶部 这是我的SSCCE代码: import javax.swing.*; import java.awt.GridBagLayout; im
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);
}
}
为什么胶水组件不占用垂直空间将侧板推到顶部
“粘合”组件仅在与BoxLayout一起使用时才有意义。它对GridBagLayout没有影响
所以我的建议是忘记GridBagLayout而使用BoxLayout
最简单的方法是将“interiorPanel”转换为使用垂直框,然后将您的PipelineStep
实例添加到此面板
试试这个。但是,您会注意到,在滚动窗格已满之前,面板的大小仍将增加,此时您将看到滚动条出现。这是因为BoxLayout会将组件的大小调整到组件的最大大小。因此,为了防止这种大小调整,您可以覆盖PipelineStep
类的getMaximumSize()
方法:
@Override
public Dimension getMaximumSize()
{
return getPreferredSize();
}
或者,另一种选择是使用“包装器”面板作为“内饰面板”。比如:
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”将始终以其首选高度显示,滚动窗格的视口已满时将显示滚动条
我使用“包装器”方法修改了您的代码
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);
}
}
您需要做的一件事是更改
validate()
。在按钮侦听器中执行revalidate()
。您好,WJS,谢谢您的回复!更改为revalidate()
确实解决了滚动条问题,但组件占用的空间仍然超出需要。您好,camickr,感谢您的回复。我将尝试实现它,并检查您的解决方案。我也希望能够拖放面板,但我仍然必须首先开始阅读。如果你有什么好的建议,它们总是受欢迎的…它成功了!我能不能让面板水平安装在水平方向上?我不知道你在问什么。如果使用“包装器”方法,面板将水平增长,框架宽度将增加。如果将帧缩小到小于首选宽度,则会自动显示滚动条。