SpringLayout声称非常强大。我尝试使用SpringLayout实现我认为相当简单的布局,但是我失败了。
减少到最低限度,我想在我的JFrame上并排4个JButton:
*=====================*
| +--+ +--+ +--+ +--+ |
| |b1| |b2| |b3| |b4| |
| +--+ +--+ +--+ +--+ |
*=====================*
我希望所有4个都具有相同的大小,无论不同的文本。
我希望最外层的(b1和b4)与容器的边界相距5 px的恒定水平距离,以及按钮的北部和南部的5 px边界,它们都是相同的高度。
我希望按钮之间的间隙也是5像素。
到目前为止,这么容易。我有更多限制:
当框架变宽(用户/鼠标)时,我希望按钮(b1 / b2,b2 / b3,b3 / b4)之间的间隙加宽,而不是按钮。
如果框架变小,我希望按钮之间的间隙缩小到1或0,然后其他东西必须让路。
我希望框架上的pack()
为我提供一个合适尺寸的窗口,默认的5px间隙和5px边框。
我编写了以下相当简单的代码,结果非常糟糕。间隙不会收缩,扩展只发生在最右边的按钮上(b4)。
现在我有自定义按钮来统一调整自己的大小,我可以使用GridBagLayout轻松地满足这些要求,使用MigLayout可能更容易。这不是我正在寻找的答案。具体来说,我的问题是:
使用SpringLayout可以使此布局正常工作吗?怎么样?
布局甚至忽略了我的按钮“getMaximumSize()
。我做错了还是SpringLayout被窃听?
非常感谢。
public class SpringLayoutTest extends JFrame {
public SpringLayoutTest() {
setLocation(100,100);
setSize(400, 300);
Container cp = getContentPane();
SpringLayout layout = new SpringLayout();
cp.setLayout(layout);
SiblingButton b1, b2, b3, b4;
cp.add(b1 = new SiblingButton("..."));
cp.add(b2 = new SiblingButton("iii"));
cp.add(b3 = new SiblingButton("xxx"));
cp.add(b4 = new SiblingButton("WWW"));
layout.putConstraint(NORTH, b1, 5, NORTH, cp);
layout.putConstraint(SOUTH, b1, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b2, 5, NORTH, cp);
layout.putConstraint(SOUTH, b2, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b3, 5, NORTH, cp);
layout.putConstraint(SOUTH, b3, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b4, 5, NORTH, cp);
layout.putConstraint(SOUTH, b4, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(WEST, b1, 5, WEST, cp);
layout.putConstraint(WEST, b2, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b1);
layout.putConstraint(WEST, b3, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b2);
layout.putConstraint(WEST, b4, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b3);
layout.putConstraint(EAST, b4, Spring.minus(Spring.constant(5)), EAST, cp);
layout.putConstraint(WEST, cp, Spring.minus(Spring.constant(5)), WEST, b1);
}
public static void main(String[] args) {
(new SpringLayoutTest()).setVisible(true);
}
SiblingButton是一个非常无艺术的实现。请忽略其设计缺陷,这仅用于演示目的。
class SiblingButton extends JButton {
static ArrayList<SiblingButton> siblings = new ArrayList<SiblingButton>();
public SiblingButton(String text) {
super(text);
siblings.add(this);
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
Dimension mx = new Dimension(0, 0);
for (SiblingButton sb : siblings) {
mx = new Dimension(Math.max(mx.width, sb.originalPreferredSize().width),
Math.max(mx.height, sb.originalPreferredSize().height));
}
return mx;
}
Dimension originalPreferredSize() {
return super.getPreferredSize();
}
}
现在已经24小时了,而且反响非常热烈。唯一的回应(谢谢,Camickr!)甚至没有尝试触及SpringLayout。我不认为这不会反映在SO社区上,而是反映SpringLayout的效用!
我的印象是,SpringLayout是布局管理器的红头发子孙,在某些方面很有用,但很少使用,没有人有工作经验,没有人愿意向Sun报告错误。
对我来说,事实证明GroupLayout可以完成我所需要的一切,并且允许我通过合理的编码完成我想要的任务。 GridBagLayout的一个受欢迎的变化,我需要采取的步骤来实现我的预期布局,从一开始我就清楚了,我只需要坐下来编写代码。
对于任何关心的人来说,这些是GroupLayout的特征,使它对我如此有用:
答案 0 :(得分:1)
您可以使用BoxLayout:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class BoxExample extends JFrame
{
public BoxExample()
{
Box box = Box.createHorizontalBox();
box.setBorder( new EmptyBorder(5, 5, 5, 5) );
Dimension size = new Dimension(100, 25);
box.add( createButton("Button1", size) );
box.add( createStrut() );
box.add( createButton("Button2", size) );
box.add( createStrut() );
box.add( createButton("Button3", size) );
box.add( createStrut() );
box.add( createButton("Button4", size) );
add( box );
}
private JButton createButton(String text, Dimension size)
{
JButton button = new JButton(text);
button.setPreferredSize( size );
button.setMinimumSize( size );
button.setMaximumSize( size );
return button;
}
private Component createStrut()
{
JComponent component = (JComponent)Box.createHorizontalStrut(5);
component.setMinimumSize(new Dimension(0, 0));
component.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
return component;
}
public static void main(String[] args)
{
BoxExample frame = new BoxExample();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
答案 1 :(得分:0)
您需要设置容器的约束(框架的内容窗格),更确切地说是设置其东部和南部的约束。
阅读本教程:
http://java.sun.com/docs/books/tutorial/uiswing/layout/spring.html
SpringDemo3解释了所有