Java的GridBagLayout中不工作

问题描述:

我试图使用GridBagLayout,但我没有得到我的期望,并在此代码,我找不到错误:Java的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); 
    } 
} 

这张照片说明我需要什么:

Programmers love paint

黄色的按钮名称,红色的行和列。

这到底发生了什么: Whats wrong here?

谁能解释一下什么是错在我的代码?

+4

我无法解释这个问题呢,但必须指出你的问题是很好的呈现,谢谢你和1+。 – 2014-09-28 19:32:56

+0

@HovercraftFullOfEels谢谢 – Emax 2014-09-28 19:35:23

+0

'c.fill = BOTH;'应该是'c.fill = GridBagConstraints.BOTH;'和'c.anchor = CENTER;'是相同的代码才能编译。 – user1803551 2014-09-28 20:18:26

问题是没有什么能说服第二个网格列(gridx = 1)具有任何宽度,因为没有组件需要在第二列中适合只有。因此,第二列的宽度为0,因此虽然Button1跨越前两列,但它看起来并不那样,因为它的所有宽度需求都由第一列满足;尽管Button5和Button7跨越第二和第三列,但它们的所有宽度需求都由第三列满足。

要修复它,你必须说服按钮应该是更宽(1,5,7)占用更多的空间。在这里,我通过设置c.ipadx = 35;向这些按钮添加了填充。 (我也删除了weightx = 1.0约束的原因,我不太了解,也没有那个留在工作的时候。):

screenshot

来源:

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

编辑:正如在评论中指出的那样,上述方法并不合适,因为它阻止了动态调整布局。为了使布局扩大以填充其容器的大小,需要weightxweighty约束,但第二列没有得到任何宽度。

这是一个替代解决方案的尝试。它使得在第二塔的底部插入的不可见部件的肮脏的黑客以迫使柱具有宽度:

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按比例与其他组件按比例放大。尽管如此,它仍然不完美。也许有更好的解决方案,但我找不到它。

+0

我可以看到源代码吗? – Emax 2014-09-28 21:05:37

+0

@FilipB.Vondrášek我不认为这是一个特定的(相当复杂的)布局管理员的特例,并且认为Swing是一种可憎的东西。当然,Swing有它的缺点和优点,但它不像是一个秘密,每个人都知道。 – icza 2014-09-28 21:08:08

+0

@Emax新增 – Boann 2014-09-28 21:08:35

我管理,没有任何黑客,支持动态调整大小来设计需要布局使用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"); 
     } 
    } 
+0

我会试试这个解决方案,谢谢你的帮助! – Emax 2014-10-09 21:55:28