2011-09-01 85 views
13

到目前为止,我尽可能避免使用GridBagLayout(通过手工代码),但这次我无法避免,而我正在阅读SUN的教程GridBagLayout 到目前为止,它并不顺利。我想我是在误解一些事情。
比如我尝试下面的代码(类似于一个在SUN的职位):为什么GridBagLayout将我的组件放在中心而不是放在角落?

public class MainFrame extends JFrame { 


    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        MainFrame frame = new MainFrame(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame 
    */ 
    public MainFrame() { 
     super(); 
     setBounds(100, 100, 500, 375); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Container mainContainer = getContentPane(); 

     mainContainer.setLayout(new GridBagLayout());  

     //add label 
     JLabel someLabel = new JLabel("Label 1:"); 
     GridBagConstraints constraints = new GridBagConstraints(); 

     constraints.gridx = 0; 
     constraints.gridy = 0; 
     //constraints.anchor = GridBagConstraints.FIRST_LINE_START; 
     //constraints.weightx = 0.5; 
     mainContainer.add(someLabel, constraints);  

     JTextField someText = new JTextField(30); 

     constraints = new GridBagConstraints(); 

     constraints.gridx = 1; 
     constraints.gridy = 0; 
     constraints.weightx = 0.5; 
     mainContainer.add(someText, constraints); 

     // 
    } 

} 

我得到的标签,并在框架的中心旁边的其他文本字段之一。
但我期待他们会出现在左上角,因为gridx和gridy对于标签是0。
即使我设置constraints.anchor = GridBagConstraints.FIRST_LINE_START;仍然是相同的结果。
我错了吗?
来自SUN的文章:

指定组件左上角的行和列。 最左边一列的地址为gridx = 0,最上一行的地址为 gridy = 0。

+0

链接断开。 – mre

+1

@mre:固定链接 – Cratylus

+3

http://madbean.com/anim/totallygridbag/ – keuleJ

回答

11

constraints.weighty = 1;添加到JLabel约束条件并将constraints.anchor = GridBagConstraints.NORTHWEST;添加到TextField约束条件。

编辑:

从Oracle的GridBagLayout guide

较大的数字表明,该组件的行或列应该得到更多的空间。对于每一列,权重与该列中组件所指定的最高权重x相关,每个多列组件的权重在该组件所在的列之间以某种方式分割。类似地,每一行的权重与指定的最高权重该行内的组件。额外的空间倾向于走向最右边一列和最下一行。

+0

上面的代码片段如果我还将'constraints.weighty = 1'设置为标签并锚定到标签FIRST_LINE_START',重量值1实际上意味着什么? – Cratylus

+2

另外,在他们的代码示例中,带有注释的这行代码出现了:'c.weighty = 1.0; //请求任何额外的垂直空间' – BenCole

+0

对于JButton5,我可以看到它。但我不认为这是一个很好的表示。总之,为什么1而不是0.8。我不明白如何选择这些数字 – Cratylus

2

您可以通过使用技巧来实现此目的,在您的行之后添加一个虚拟组件并将其展开以填充垂直空间。你也可以重新使用约束,不需要创建一个新的对象:

编辑:好吧忘了把戏:(正确的方法是作为Deon Botha和BenCole说,我已经更新我的代码使用锚点

不要接受这个答案,接受要么出温的或本的

public class MainFrame extends JFrame { 
    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        MainFrame frame = new MainFrame(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

public MainFrame() { 
    super(); 
    setBounds(100, 100, 500, 375); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Container mainContainer = getContentPane(); 
    mainContainer.setLayout(new GridBagLayout());  

    JLabel someLabel = new JLabel("Label 1:"); 
    JTextField someText = new JTextField(30); 

    GridBagConstraints constraints = new GridBagConstraints(); 
    constraints.anchor = GridBagConstraints.FIRST_LINE_START; 

    constraints.gridx = 0; 
    constraints.gridy = 0;  
    constraints.weightx = 1.0; 
    mainContainer.add(someLabel, constraints);  

    constraints.gridx = 1;      
    constraints.weightx = 1.0; 
    constraints.weighty = 1.0;   
    mainContainer.add(someText, constraints);      
} 
} 
+0

但为什么我需要这个虚拟组件?这些组件应该放置在布局管理器的左上角吗?那么gridx = gridy = 0的含义是什么? – Cratylus

+0

你说得对,它应该可以工作,但GridBayLayout是纯粹的邪恶,实际上它非常好...只是很棘手,我不是纯粹主义者,如果它与虚拟标签一起工作,那么为什么不使用它呢? – eon

+2

或者你可以设置'constraints.weighty = 1.0; constraints.anchor = GridBagConstraints.FIRST_LINE_START;' – dbotha

2

我不能直接回答你的问题,但相信我,你应该做你的试验和误差修改与一个IDE布局。我个人建议Netbeans。在那里你可以拖放,然后看看属性。起初,您会在属性检查器中给出一些默认值,因此自动生成的代码较少。但是,一旦你开始使用布局,你可以看到代码,并很好地理解你做什么。

10

您需要在Swing教程上weightX/weightY的部分,在那里它规定进一步下跌阅读:

除非你至少指定一个非零的weightx或沉重的价值,所有的组件聚集在一起在他们的容器的中心。

您指定了权重X但不是权重y。

编辑,它比我想象的更复杂。看来你还需要指定:

constraints.anchor = GridBagConstraints.FIRST_LINE_START; 

两个组件在addiation的份量。

+0

来自SUN的报价说weightx或weighty(所以我没有想到它需要两个)。无论如何,我试过重量= 1的标签和重量= 0.5对于文本和重量= 0.5但两者相同的结果 – Cratylus

+0

weightx如果用于水平定位。重量是垂直定位。我同时使用了1.0和FIRST_LINE_START两个版本,它对我很有帮助。 – camickr

+0

是的,它现在可以工作了。但重量值1实际上意味着什么?我不明白它。对我来说(通过需要锚点),似乎网格已经存在,而不是通过放置组件在它上面。 – Cratylus

1

这为我工作:

public class NewJFrame extends javax.swing.JFrame { 

    public NewJFrame() { 
     initComponents(); 
    } 

    @SuppressWarnings("unchecked") 
    private void initComponents() { 
     java.awt.GridBagConstraints gridBagConstraints; 

     jPanel2 = new javax.swing.JPanel(); 
     jComboBox3 = new javax.swing.JComboBox(); 
     jComboBox4 = new javax.swing.JComboBox(); 
     jComboBox5 = new javax.swing.JComboBox(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     setBackground(new java.awt.Color(255, 204, 51)); 
     setMinimumSize(new java.awt.Dimension(800, 600)); 
     getContentPane().setLayout(null); 

     jPanel2.setLayout(new java.awt.GridBagLayout()); 

     jComboBox3.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); 
     gridBagConstraints = new java.awt.GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 0; 
     gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 
     gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 
     gridBagConstraints.weightx = 1.0; 
     jPanel2.add(jComboBox3, gridBagConstraints); 

     jComboBox4.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); 
     gridBagConstraints = new java.awt.GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 1; 
     gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 
     gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 
     gridBagConstraints.weightx = 1.0; 
     jPanel2.add(jComboBox4, gridBagConstraints); 

     jComboBox5.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); 
     gridBagConstraints = new java.awt.GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 2; 
     gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 
     gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 
     gridBagConstraints.weightx = 1.0; 
     gridBagConstraints.weighty = 1.0; 
     jPanel2.add(jComboBox5, gridBagConstraints); 

     getContentPane().add(jPanel2); 
     jPanel2.setBounds(30, 40, 150, 260); 

     pack(); 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new NewJFrame().setVisible(true); 
      } 
     }); 
    } 

    private javax.swing.JComboBox jComboBox3; 
    private javax.swing.JComboBox jComboBox4; 
    private javax.swing.JComboBox jComboBox5; 
    private javax.swing.JPanel jPanel2; 
} 
相关问题