控制台程序。
java.awt.GridBagLayout管理器比前面介绍的其他布局管理器灵活得多,因此使用起来也比较复杂。基本机制就是在随意的矩形网格中布局组件,但网格的行和列不一定拥有相同的高度和宽度。
GridBagLayout中的每个组件都有自己的约束,在把组件添加到容器中之前,这些约束在GridBagConstrains类型的对象中指定,这种对象将关联到每个组件上。每个组件的位置、相对大小以及在网格中占据的区域都由与之关联的GridBagConstrains对象决定。
1 import javax.swing.*; 2 import java.awt.*; 3 import javax.swing.border.Border; 4 5 public class TryGridBagLayout { 6 7 public static void createWindow(){ 8 JFrame aWindow = new JFrame("This is the Window Title"); 9 Toolkit theKit = aWindow.getToolkit(); // Get the window toolkit 10 Dimension wndSize = theKit.getScreenSize(); // Get screen size 11 12 // Set the position to screen center & size to half screen size 13 aWindow.setSize(wndSize.width/2, wndSize.height/2); // Set window size 14 aWindow.setLocationRelativeTo(null); // Center window 15 aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 17 GridBagLayout gridbag = new GridBagLayout(); // Create a layout manager 18 GridBagConstraints constraints = new GridBagConstraints(); 19 aWindow.getContentPane().setLayout(gridbag); // Set the container layout mgr 20 21 // Set constraints and add first button 22 constraints.weightx = constraints.weighty = 10.0; 23 constraints.fill = GridBagConstraints.BOTH; // Fill the space 24 addButton(" Press ", constraints, gridbag, aWindow); // Add the button 25 26 // Set constraints and add second button 27 constraints.gridwidth = GridBagConstraints.REMAINDER; // Rest of the row 28 addButton("GO", constraints, gridbag, aWindow); // Create and add button 29 30 aWindow.setVisible(true); // Display the window 31 } 32 33 static void addButton(String label, 34 GridBagConstraints constraints, 35 GridBagLayout layout, 36 JFrame window) { 37 // Create a Border object using a BorderFactory method 38 Border edge = BorderFactory.createRaisedBevelBorder(); 39 40 JButton button = new JButton(label); // Create a button 41 button.setBorder(edge); // Add its border 42 layout.setConstraints(button, constraints); // Set the constraints 43 window.getContentPane().add(button); // Add button to content pane 44 } 45 46 public static void main(String[] args) { 47 SwingUtilities.invokeLater(new Runnable() { 48 public void run() { 49 createWindow(); 50 } 51 }); 52 } 53 }
当调用setConstrains()方法,使GridBagConstrains对象关联按钮对象时,会为传送为参数的constrains对象传送副本,并把对副本的引用存储在布局中,而不是存储对所创建对象的引用。这样就可以修改创建的constrains对象,将它用于第二个按钮,而不会影响用于第一个按钮的约束。
可以将第二个按钮的宽度设置为第一个的一半:
1 // Set constraints and add second button 2 constraints.weightx = 5.0; // Weight half of first 3 constraints.insets = new java.awt.Insets(10, 30, 10, 20); // Left 30 & right 20 4 constraints.gridwidth = GridBagConstraints.RELATIVE; // Rest of the row 5 addButton("GO", constraints, gridbag, aWindow); // Create and add button
现在,第二个按钮在x方向上占据了1/3的空间-对应于x方向上总可用空间的5/(5+10)。
假定要添加第三个按钮,宽度与Press按钮相同并且放在Press按钮的下面。可以在第二个按钮的下面添加如下代码:
1 // Set constraints and add third button 2 constraints.insets = new java.awt.Insets(0,0,0,0); // No insets 3 constraints.gridx = 0; // Begin new row 4 constraints.gridwidth = 1; // Width as "Press" 5 addButton("Push", constraints, gridbag, aWindow); // Add button to content pane
把gridx约束重置为0,从而把按钮放在下一行的开头。
如果GO按钮的高度是Press和Push按钮的高度之和,效果会更好。为此,需要使GO按钮的高度是另外两个按钮的高度的两倍。
1 // Set constraints and add second button 2 constraints.weightx = 5.0; // Weight half of first 3 constraints.insets = new java.awt.Insets(10, 30, 10, 20); // Left 30 & right 20 4 constraints.gridwidth = GridBagConstraints.RELATIVE; // Rest of the row 5 constraints.gridheight = 2; // Height 2x "Press" 6 addButton("GO", constraints, gridbag, aWindow); // Create and add button 7 8 // Set constraints and add third button 9 constraints.insets = new java.awt.Insets(0,0,0,0); // No insets 10 constraints.gridx = 0; // Begin new row 11 constraints.gridwidth = 1; // Width as "Press" 12 constraints.gridheight = 1; // Height as "Press" 13 addButton("Push", constraints, gridbag, aWindow); // Add button to content pane