我尝试使用GridBagLayout
,但我没有得到我期望的结果,而且我无法在此代码中找到错误:
public class GridBagEx1 extends JPanel {
private static final long serialVersionUID = 1L;
protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) {
JButton button = new JButton(name);
gridbag.setConstraints(button, c);
add(button);
}
public void init() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag);
c.fill = BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
c.anchor = CENTER;
c.insets.top = 5;
c.insets.bottom = 5;
c.insets.left = 5;
c.insets.right = 5;
c.gridx = 0;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 2;
makebutton("Button1", gridbag, c);
c.gridx = 2;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 1;
makebutton("Button2", gridbag, c);
c.gridx = 3;
c.gridy = 0;
c.gridheight = 2;
c.gridwidth = 2;
makebutton("Button3", gridbag, c);
c.gridx = 0;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 1;
makebutton("Button4", gridbag, c);
c.gridx = 1;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 2;
makebutton("Button5", gridbag, c);
c.gridx = 0;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
makebutton("Button6", gridbag, c);
c.gridx = 1;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 2;
makebutton("Button7", gridbag, c);
c.gridx = 3;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
makebutton("Button8", gridbag, c);
c.gridx = 4;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
makebutton("Button9", gridbag, c);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
GridBagEx1 ex1 = new GridBagEx1();
ex1.init();
frame.add(ex1);
frame.pack();
frame.setVisible(true);
}
}
这张照片说明了我的需求:
黄色是按钮名称,红色是行和列。
这才是真正发生的事情:
有人能解释我的代码中有什么问题吗?
答案 0 :(得分:8)
问题在于没有任何东西说服第二个网格列(gridx = 1)具有任何宽度,因为没有组件需要在第二列中仅适合 。因此第二列的宽度为0,因此尽管Button1确实跨越前两列,但它看起来并不那样,因为第一列满足了它的所有宽度需求;虽然Button5和Button7跨在第二列和第三列,但第三列都满足了它们的所有宽度需求。
要修复它,你必须说服应该更宽的按钮(1,5,7)以占用更多空间。在这里,我通过设置c.ipadx = 35;
为这些按钮添加了填充。 (我也删除了weightx = 1.0
约束。由于我不太了解的原因,当它留在原因时它没有用。):
来源:
public void init() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag);
c.fill = c.BOTH;
//c.weightx = 1.0;
//c.weighty = 1.0;
c.anchor = c.CENTER;
c.insets.top = 5;
c.insets.bottom = 5;
c.insets.left = 5;
c.insets.right = 5;
c.gridx = 0;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 2;
c.ipadx = 35;
makebutton("Button1", gridbag, c);
c.gridx = 2;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 1;
c.ipadx = 0;
makebutton("Button2", gridbag, c);
c.gridx = 3;
c.gridy = 0;
c.gridheight = 2;
c.gridwidth = 2;
c.ipadx = 0;
makebutton("Button3", gridbag, c);
c.gridx = 0;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 1;
c.ipadx = 0;
makebutton("Button4", gridbag, c);
c.gridx = 1;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 2;
c.ipadx = 35;
makebutton("Button5", gridbag, c);
c.gridx = 0;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
c.ipadx = 0;
makebutton("Button6", gridbag, c);
c.gridx = 1;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 2;
c.ipadx = 35;
makebutton("Button7", gridbag, c);
c.gridx = 3;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
c.ipadx = 0;
makebutton("Button8", gridbag, c);
c.gridx = 4;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 1;
c.ipadx = 0;
makebutton("Button9", gridbag, c);
}
编辑:正如评论中所指出的,上述方法并不合适,因为它会阻止布局动态调整大小。要扩展布局以填充其容器的大小,需要weightx
和weighty
约束,但第二列不会获得任何宽度。
以下是对替代解决方案的尝试。这是一个肮脏的黑客,在第二列的底部插入一个不可见的组件,以强制列具有宽度:
c.gridx = 1;
c.gridy = 3;
c.gridheight = 1;
c.gridwidth = 1;
c.insets.set(0, 0, 0, 0);
c.weighty = 0;
add(Box.createRigidArea(new Dimension(50, 0)), c);
当调整窗口大小时,这很好地应对,因为尽管组件具有固定的初始大小,但GridBagLayout会按比例缩放它与其他组件。但它仍然不完美。也许有一个更好的解决方案,但我无法找到它。
答案 1 :(得分:2)
我设法使用JGoodies FormLayout设计了所需的布局而没有任何黑客并支持动态调整大小:
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JPanel;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
public class FormLayoutPanel extends JPanel
{
public FormLayoutPanel()
{
setAlignmentY( Component.BOTTOM_ALIGNMENT );
setAlignmentX( Component.RIGHT_ALIGNMENT );
setLayout( new FormLayout( new ColumnSpec[] {
ColumnSpec.decode( "41px:grow" ),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
ColumnSpec.decode( "25px:grow" ),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
ColumnSpec.decode( "41px:grow" ),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
ColumnSpec.decode( "41px:grow" ),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
ColumnSpec.decode( "41px:grow" ), },
new RowSpec[] {
RowSpec.decode( "25px:grow" ),
FormFactory.LINE_GAP_ROWSPEC,
RowSpec.decode( "25px:grow" ),
FormFactory.LINE_GAP_ROWSPEC,
RowSpec.decode( "25px:grow" ), } ) );
JButton button1 = new JButton( "1" );
add( button1, "1, 1, 3, 1, fill, fill" );
JButton button2 = new JButton( "2" );
add( button2, "5, 1, fill, fill" );
JButton button3 = new JButton( "3" );
add( button3, "7, 1, 3, 3, fill, fill" );
JButton button4 = new JButton( "4" );
add( button4, "1, 3, fill, fill" );
JButton button5 = new JButton( "5" );
add( button5, "3, 3, 3, 1, fill, fill" );
JButton button6 = new JButton( "6" );
add( button6, "1, 5, fill, fill" );
JButton button7 = new JButton( "7" );
add( button7, "3, 5, 3, 1, fill, fill" );
JButton button8 = new JButton( "8" );
add( button8, "7, 5, fill, fill" );
JButton button9 = new JButton( "9" );
add( button9, "9, 5, fill, fill" );
}
}