我正在尝试创建自定义JDialog
。我希望将组件堆叠在彼此顶部并具有其首选高度,但宽度应该填充容器。与Android中的LinearLayout
类似。我希望组件在调整窗口大小时保持其首选高度。
场景:您需要在自然尺寸的紧凑行中显示一些组件。
考虑使用JPanel对组件进行分组,并使用JPanel的默认FlowLayout管理器或BoxLayout管理器。 SpringLayout对此也有好处。
E.g。我希望JTextField
高于JTabbedPane
。我已经尝试了所有建议的布局管理器FlowLayout,BoxLayout,SpringLayout,但是当JDialog
窗口的高度增加时,它们不会保留组件的自然大小。
Java Swing中是否有可以用于我的情况的布局管理器?
这是一个小例子,显示我的Swing布局问题:
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class TestDialog extends JDialog {
public TestDialog() {
setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
//setLayout(new SpringLayout());
JTextField field1 = new JTextField();
JTextField field2 = new JTextField();
JTextField field3 = new JTextField();
JTextField field4 = new JTextField();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.PAGE_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
panel1.add(field2);
panel2.add(field3);
panel2.add(field4);
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Tab 1", panel1);
tabs.addTab("Tab 2", panel2);
add(field1);
add(tabs);
//field1.setMaximumSize(field1.getPreferredSize());
//SpringUtilities.makeCompactGrid(this.getContentPane(), 2, 1, 2, 2, 2, 2);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new TestDialog();
}
}
答案 0 :(得分:2)
我想在JTabbedPane上面有一个JTextField。我尝试了所有建议的布局管理器
垂直BoxLayout应该可以正常工作。如果在增加帧大小时组件增长,则可能需要添加:
textField.setMaximumSize( textField.getPreferredSize() );
tabbedPane.setMaximumSize( tabbedPane.getPreferredSize() );
如果您需要更多帮助,请发布展示问题的SSCCE。
编辑:
您需要为文本字段指定首选大小。这可以通过使用:
完成JTextField textField = new JTextField(10);
答案 1 :(得分:1)
null布局(基本上是x / y)可能是你要找的,或者可能是Group Layout。
MigLayout也可以开箱即用你想要的东西(你必须给它一个特定的指令来与窗口一起成长,否则它不会。)
从概念上讲,我认为您对布局最终决定组件大小的事实感到困惑,因此“自然”大小有点误导。我想你所追求的是组件上设置的大小?或者,如果没有在组件上调用任何setSize方法,那么你的意思是默认值?
无论哪种方式,使用Swing,您必须更明确地确定您的尺寸预期,以获得良好的效果。
答案 2 :(得分:1)
我完全没理解你的自然组件的大小。但是如果您不希望布局管理器弄乱组件的大小,我建议您使用setMaximumSize(int width,int height)
或将布局设置为null并使用setBounds(int x,int y,int width,int height)
方法来调整组件的大小。
如果您想调整组件的大小相对于彼此的变化,那么我建议您查看GridBagLayout并使用weightx和weighty属性。
答案 3 :(得分:1)
我最终实现了自己的 StackLayout ,代码如下。这就是我的问题中的相同应用程序的样子。这些组件从顶部到底部堆叠,占据整个宽度,类似于Android的LinearLayout
。
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
public class StackLayout implements LayoutManager {
@Override
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
int maxWidth = parent.getWidth() - (insets.left + insets.right);
int y = insets.top;
for(int n = 0; n < parent.getComponentCount(); n++) {
Component c = parent.getComponent(n);
int height = c.getPreferredSize().height;
c.setBounds(0, y, maxWidth, height);
y += height;
}
}
@Override
public Dimension minimumLayoutSize(Container c) {
int sumHeight = 0;
int maxWidth = 0;
for(int n = 0; n < c.getComponentCount(); n++) {
Dimension preferredSize = c.getComponent(n).getPreferredSize();
if(n == 0) {
maxWidth = preferredSize.width;
} else {
maxWidth += preferredSize.width;
}
sumHeight += preferredSize.height;
}
// add the containers insets
Insets insets = c.getInsets();
sumHeight += insets.top + insets.bottom;
maxWidth += insets.left + insets.right;
return new Dimension(maxWidth, sumHeight);
}
@Override
public Dimension preferredLayoutSize(Container c) {
return minimumLayoutSize(c);
}
@Override
public void addLayoutComponent(String arg0, Component c) {}
@Override
public void removeLayoutComponent(Component c) {}
}
答案 4 :(得分:0)
如果你使用GridBagLayout
并且没有指定填充或重量,你应该得到你想要的。基本上你将有一个2列2行网格袋布局。只需创建GridBagConstraints
并在添加组件时仅设置x和y选项 - 不要设置任何其他选项。
答案 5 :(得分:0)
我会建议一个更简单的布局管理器 - BorderLayout() - 来自你所描述的内容。代码如下:您需要指定至少1个JTextField的宽度来设置JDialog的宽度。如果需要一些间距,可以使用EmptyBorder。希望这会有所帮助, - M.S。
import java.awt。*;
导入javax.swing。*;
公共类TestDialog扩展了JDialog {
private JTextField field1 = new JTextField(20),
field2 = new JTextField(),
field3 = new JTextField(),
field4 = new JTextField();
public TestDialog(Frame f) {
super (f, "Test Dialog");
Container cp = getContentPane();
cp.setLayout (new BorderLayout());
cp.add (northPanel(), "North");
cp.add (tabbedPane(), "Center");
pack();
}
private JPanel northPanel () {
JPanel nPanel = new JPanel(new BorderLayout());
nPanel.add (field1, "Center");
// nPanel.setBorder (...);
return nPanel;
}
private JTabbedPane tabbedPane () {
JTabbedPane tp = new JTabbedPane();
tp.add ("Tab 1", panel1());
tp.add ("Tab 2", panel2());
return tp;
}
private JPanel panel1 () {
JPanel tfPanel = new JPanel(new BorderLayout());
tfPanel.add (field2, "North");
return tfPanel;
}
private JPanel panel2 () {
JPanel tfPanel = new JPanel(new BorderLayout()),
t2Panel = new JPanel(new BorderLayout());
t2Panel.add (field3, "North");
t2Panel.add (field4, "Center");
tfPanel.add (t2Panel, "North");
return tfPanel;
}
public static void main (String[] args) {
new TestDialog (null).setVisible (true);
}}