框式布局

利用无序网格布局,几乎可以产生任意复杂的布局模型。除了这一个AWT布局管理器之外,Swing还引入了另外一个叫做框式布局(Box Layout)的结构。框式布局能够生成复杂的布局结构,但却没有像使用无序网格布局那样麻烦。编程者不必处理任何权值,也不用采用反复试验的方法。使用框式布局,可以像使用流式布局一样简单地将组件安排在一个容器内。包含框式布局的容器可以嵌套使用,最终达到类似于无序网格布局那样的效果。

框式布局模式有两种类型:水平模式和垂直模式。水平模式把组件在容器内从左到右排列。垂直模式把组件在容器内从上到下进行排列。框式布局所取的水平方向和垂直方向分别由x轴和y轴表示。因此,对于一个给定的框式布局来说,x轴和y轴将成为主轴方向。

任何时候,当用框式布局把一个组件加到容器内时,该组件的大小将会保持不变。这就是说,框式布局与网格布局不同,它允许组件沿主轴方向占据不同的空间大小。

在非主轴方向上,如果几个组件大小不同,那么框式布局就会以尺寸最大的那个组件的大小来布置所有的组件。例如,在水平框式布局中,如果所有的组件的高度不同(非主轴方向上),则布局管理器就会力图使所有组件都与最高的组件具有同样的高度。

如果不能沿非主轴方向调整尺寸,则组件就会以该轴为中心线进行排列。也就是说,在非主轴方向上,任何一个组件的中心坐标与其他组件的中心坐标是一致的。

如果改变了容器的大小,框式布局不会把任何组件折到下一行去。例如,在一个包括一些按钮的水平框式布局中,改变当前容器的大小时,位于一行上的按钮将不会被折到下一行上。

BoxLayout类

BoxLayout类实现了产生于抽象窗口工具库(AWT)的LayoutManager2接口。该类是Swing库的成员,存放在javax.swing包中。除java.lang.Object以外,这个类不作为其他任何类的子类。

通常,不用BoxLayout类来处理框式布局,而是用下一节将要介绍的Box类。然而,BoxLayout类有几个重要特性需加以注意。

要创建框式布局来从上到下或者从左到右排列组件,可以使用下面的构造函数:

public BoxLayout(Container target, int axis)

这里,target是布局的容器,axis指定框式布局的方向为水平的或者垂直的,并取下列静态常数之一:BoxLayout.X_AXIS、BoxLayout.Y_AXIS

Box容器

Box类表示一个轻量级容器,它只能使用框式布局。试图把任何其他类型的布局管理器赋给它时,将会产生一个AWTError。Box容器允许组件根据指定的方向水平排列组件或者垂直排列。Box对象由取axis参数的构造函数或者用很方便的静态方法创建。下面是Box类的构造函数:

public Box(int axis)

参数axis取值为BoxLayout.X_AXIS或BoxLayout.Y_AXIS。下面是两个很方便的静态方法,它们无需任何参数就可分别创建水平的或垂直的方框容器:

public static Box createHorizontalBox()

public static Box createVerticalBox()

Box类还提供了有用的方法,这些方法增加了一些特性,如产生组件内部的间隔、当容器改变大小时将组件重新定位,等等。这些特性的实现都用到了诸如glues、fillers、struts、rigid区域这样的不可见组件(invisible components)。

glue组件可扩充到必要的大小,以便填满框式布局中相邻组件之间的空间。这就导致在水平组件中会产生最大宽度,在垂直布局中产生最大高度。利用glues组件,可以使组件与组件之间以及组件与容器之间的额外空间得到平均分布。可以用一下两个静态方法分别创建针对水平布局和垂直布局的glue组件:

public static Component createHorizontalGlue()

public static Component createVerticalGlue()

strut大小是固定的。可以用这个组件向框式布局内的两个组件之间加入固定数量的间隔。例如,在一个水平布局中,这个组件就可以子两个组件之间加入一定的间隔。strut也可以用来使方框本身具有一定的大小。例如,在一个垂直放置的方框中,strut可用来使方框的宽度独有某个特定的值。strut的尺寸在没有指定的方向上基本上是无限制的。所以,对水平方向的方框来说,其高度就没有限制。

rigid区域占有一定的尺寸。rigid区域组件的功能类似于struts组件。可以指定该组件的宽度和高度。下面是创建rigid区域组件的静态方法:

public static Component createRigidArea(Dimension d)

fillers组件允许指定尺寸的最小值,最大值以及某个期望的值。过滤器是一些内部类Box.Filler对象。当把一个过滤器添加到水平方框中的两个组件之间时,它就会保持最小的宽度值,并且保证容器的高度最小。可以用以下所示的方法创建过滤器对象:

Box.Filler(new Dimension(w1, h1), //mininum size
                new Dimension(w2, h2), //prefered size
                new Dimension(w3, h3))//maxnum size

BoxLayout代码示例(利用不可见的组件放置其他组件)

下面的程序清单用框式布局创建了一个小程序,其中分别在不同的窗格里显示了几对按钮:B1和B2,B3和B4,等等,以此演示像glue、filler、rigid以及strut这样的不可见组件的效果。

1. import
2. import
3. import
4.  
5. public class TBox1 extends
6. null;  
7.       
8. public void
9.         String lookAndFeel = UIManager.getSystemLookAndFeelClassName();  
10. try
11.             UIManager.setLookAndFeel(lookAndFeel);  
12. catch(Exception e) {  
13.             e.printStackTrace();  
14.         }  
15.           
16. //1.Get the handle on the applet's content pane. 
17.         container = getContentPane();  
18.           
19. //2.Create a vertical box and add it to the applet. 
20.         Box basebox = Box.createVerticalBox();  
21.         container.add(basebox);  
22.           
23. //3.Create the demo panel1 with box layout to display 
24. //buttons B1 and B2. 
25. //a)Create the panel and set the box layout. 
26. new
27. new
28. //b)Set the title border around the panel. 
29. new
30. new LineBorder(Color.black), "Glue Component: Demo-1");  
31.         border1.setTitleColor(Color.black);  
32.         glueDemoPanel1.setBorder(border1);  
33. //c)Add the buttons B1 and B2 with a glue component between them. 
34. new JButton("B1"));  
35.         glueDemoPanel1.add(Box.createHorizontalGlue());  
36. new JButton("B2"));  
37. //d)Add the panel to the base box. 
38.         basebox.add(glueDemoPanel1);  
39.           
40. //4.Create the demo panel-2, assign box layout and add 
41. //buttons B3 and B4. 
42. //a)Create the glue panel 2 and assign the box layout. 
43. new
44. new
45. //b)Add a titled border to the panel. 
46. new TitledBorder(new LineBorder(Color.black),"Glue Component: Demo-2");  
47.         glueDemoPanel2.setBorder(border2);  
48. //c)Add the buttons B3 and B4 to the panel; also add 
49. //the glue components between the buttons, and the 
50. //buttons and panel. 
51.         glueDemoPanel2.add(Box.createHorizontalGlue());  
52. new JButton("B3"));  
53.         glueDemoPanel2.add(Box.createHorizontalGlue());  
54. new JButton("B4"));  
55.         glueDemoPanel2.add(Box.createHorizontalGlue());  
56. //d)Add the panel to the base box. 
57.         basebox.add(glueDemoPanel2);  
58.           
59. //5.Create a filler panel and add buttons B5 and B6. 
60. //a)Create the panel object and assign box layout. 
61. new
62. new
63. //b)Set the titled border to the above panel. 
64. new
65. new
66. "Filler Component Demo");  
67.         border3.setTitleColor(Color.black);  
68.         fillerDemoPanel.setBorder(border3);  
69. //c)Add buttons B5 and B6 to the panel; also add the 
70. //filler component between the buttons. 
71. new JButton("B5"));  
72. new
73. new Dimension(50, 75),  
74. new Dimension(50, 75),  
75. new Dimension(Short.MAX_VALUE, 75)));  
76. new JButton("B6"));  
77. //d)Attach the panel to the base box. 
78.         basebox.add(fillerDemoPanel);  
79.           
80. //6.Create rigid area and add buttons B7 and B8. 
81. //a)Create a panel and assign the box layout. 
82. new
83. new
84. //b)Assign the title border around the panel. 
85. new
86. new
87. "Rigid Area Component Demo");  
88.         border4.setTitleColor(Color.black);  
89.         rigidDemoPanel.setBorder(border4);  
90. //c)Add buttons B7 and B8 to the rigid area panel. 
91. //Also add a rigid area in the middle of the buttons. 
92. new JButton("B7"));  
93. new Dimension(150, 0)));  
94. new JButton("B8"));  
95. //d)Add the panel to the base box. 
96.         basebox.add(rigidDemoPanel);  
97.           
98. //7.Create the strut panel, assign the box layout, and add 
99. //the buttons B9 and B10. 
100. //a)Create the panel and assign the box layout 
101. new
102. new
103. //b)Set the titled border around the pane. 
104. new
105. new
106. "Strut Component Demo");  
107.         border5.setTitleColor(Color.black);  
108. //c)Add buttons B9  and B10 to the panel. Also assign the 
109. //horizontal strut in the middle of the buttons. 
110.         strutDemoPanel.setBorder(border5);  
111. new JButton("B9"));  
112. 150));  
113. new JButton("B10"));  
114. //d)Add the panel to the base box. 
115.         basebox.add(strutDemoPanel);  
116.     }   
117. }

运行结果:



重叠布局:

1. import
2. import
3.  
4. public class TBox2 extends
5. null;  
6.       
7. public void
8. //1.Get the handle on the applet's content pane. 
9. //and set the background color to white. 
10.         container = getContentPane();  
11.         container.setBackground(Color.white);  
12.           
13. //2.Create a horizontal box and add it to the applet. 
14.         Box baseBox = Box.createHorizontalBox();  
15.         container.add(baseBox);  
16.           
17. //3.Create a vertical box and add it to the base box. 
18.         Box vBox = Box.createVerticalBox();  
19.         baseBox.add(vBox);  
20.           
21. //4.Create button B1 and add it to vBox. 
22. new JButton("B1");  
23.         b1.setAlignmentX(Component.CENTER_ALIGNMENT);  
24. new Dimension(150, 150));  
25.         vBox.add(b1);  
26.           
27. //5.Create a horizontal box and add it to vBox. 
28.         Box hBox = Box.createHorizontalBox();  
29.         vBox.add(hBox);  
30.           
31. //6.Create button B2 and add it to hBox. 
32. new JButton("B2");  
33.         b2.setAlignmentY(Component.CENTER_ALIGNMENT);  
34. new Dimension(75, 100));  
35.         hBox.add(b2);  
36.           
37. //7.Create another button B3 and add it to hBox. 
38. new JButton("B3");  
39.         b3.setAlignmentY(Component.CENTER_ALIGNMENT);  
40. new Dimension(75, 100));  
41.         hBox.add(b3);  
42.           
43. //8.Create the vertical box (vBox1) and add it to the base box. 
44.         Box vBox1 = Box.createVerticalBox();  
45.         baseBox.add(vBox1);  
46.           
47. //9.Create the button B4 and add it to vBox1. 
48. new JButton("B4");  
49.         b4.setAlignmentX(Component.CENTER_ALIGNMENT);  
50. new Dimension(100, 250));  
51.         vBox.add(b4);  
52.     }  
53. }


运行结果: