4.9 使用面板组件进行分组和布局
如果你曾用过Swing,或者诸如Visual Basic、Delphi之类的工具,那么可能很熟悉面板的概念。面板通常用于组织相关组件。一旦将一些组件放置在面板中,你便可以通过与面板交互将这些组件作为整体单元来操作。你也可以通过边框之类的属性对面板进行格式化,或者根据应用的状态隐藏或显示它(以及它的子控件)。
JSF 中的面板也类似于这些面板,但是有些不同。它们的主要目标是将组件进行分组,但是有时也处理布局问题。事实上,面板是在单一视图中处理布局的唯一的标准手段。通过结合应用不同的面板,你可以对页面中的控件进行复杂的组织。
JSF 随带了两个面板组件:HtmlPanelGroup 和HtmlPanelGrid。HtmlPanelGroup 只是简单的组织所有子组件,并且可选择应用CSS 样式。HtmlPanelGrid则可用于更加具有可配置性的布局,就像Swing中的GridLayout一样,它被呈现为HTML <table> 元素。
在下面的小节中,我们将详细讨论这些组件。
4.9.1 使用HtmlPanelGroup分组组件
HtmlPanelGroup组件将一些组件归组,以使它们可被当作单独实体进行处理。它并不直接对应到HTML元素。事实上,只有在指定了标识符或者样式时,它才会输入内容,这种情况下,其所有子组件都会被包围在<span>元素中。但是,它的确会毫无修改地显示其所有子组件。该组件被总结在表4-27中。
表4-27 HtmlPanelGroup概要
组件 | HtmlPanelGroup |
组件族 | javax.faces.Panel |
可能的IDE显示名 | Panel – Group Box,Group Box |
显示行为 | 所有子组件都按原样显示。如果指定了id、style或者styleClass属性,所有子组件都将包围在<span>元素中。用于将子组件组织在一起 |
标签库 | HTML |
JSP标签 | <h:panelGroup> |
直通属性 | style |
通用属性 | id、rendered、styleClass、binding(见表4-2) |
看表4-28中的简单示例。其中,HtmlPanelGroup并无内容显示——其子组件只是按其原样显示。通常你将按这种方式用它来将组件归组到facet中;这很常见,比如,在定义HtmlPanelGrid或者HtmlDataTable中的表头或者表脚时(见那些小节中的例子)。
表4-28 HtmlPanelGroup示例:将三个组件组织成组,没有使用样式
HTML | |
组件标签 |
|
浏览器显示 |
提示 HtmlPanelGroup也是有用的占位符。当在HtmlPanelGrid 或者 HtmlDataTable中想要呈现空单元格时,可以使用它。
HtmlPanelGroup也可以用于为一组组件添加简单的格式化,如表4-29所示。
表4-29 HtmlPanelGroup 示例:将三个组件组织成组,使用样式
HTML | |
组件标签 |
|
浏览器显示 |
在这个例子中,该组件输出具有客户端标识符的<span>元素,并指定了CSS类为子组件提供了漂亮的背景和边框。这类格式化用在简单场合是很好的,但是对于布局组件,却应该使用HtmlPanelGrid。
4.9.2 使用HtmlPanelGrid创建表格
HtmlPanelGrid主要用于创建任意的、静态的组件布局(它对应于<table> 元素)。也可以通过分别对应于<thead> 和<tfoot> 子元素的facet来配置表格的表头和表脚。表4-30总结了这个组件。
也可以指望工具来实时呈现表格,而你只需在设计时从组件选用板中拖放控件到HtmlPanelGrid中(如图4-9)。你可以看到,这个组件最常用之处就是对表单(比如login 表单)进行布局。
图4-9 大多数JSF IDE,比如Java Studio Creator [Sun,Creator],都允许将组件拖放到HtmlPanelGrid中,并且通过修改组件属性来修改表格的布局
我们将研究针对更复杂些的视图的JSP,比如第二部分的login表单。现在,首先从简单的3列2行的表格开始,该表格的每个单元格都包含HtmlOutputText组件。如表4-31所示。
如你所见,子组件都根据指定的列数进行组织。因为我们指定了3个列,头3个组件便形成了第1行(每列一个),次3个组件则形成第2行,依次类推。Width、border和cellpadding属性都是直通的。注意,与HTML表格不同,你不需要明确地指定行和列——只需将子组件嵌入到面板中,余下的它自己会搞定。
表4-30 HtmlPanelGrid 总结
组件 | HtmlPanelGrid | |||
组件族 | javax.faces.Panel | |||
可能的IDE显示名 | Grid Panel | |||
显示行为 | 显示具有指定列数的HTML <table>元素。每个单元格布局一个子组件,显示完等于列数的组件后再开始新行。如果指定了header facet,将显示包含表头内容的<thead>元素。如果指定了footer facet ,将显示包含表脚内容的<tfoot>元素 | |||
标签库 | HTML | |||
JSP标签 | <h:panelGrid> | |||
直通属性 | <table>的HTML属性 | |||
通用属性 | id、rendered、styleClass、binding(见表4-2) | |||
属 性 | 类 型 | 默认值 | 必需? | 说 明 |
columns | int | 无 | 否 | 要显示的列数 |
headerClass | String | 无 | 否 | header facet 的CSS 样式类的名称 |
footerClass | String | 无 | 否 | footer facet的CSS 样式类的名称 |
rowClasses | String | 无 | 否 | 用于行的逗号分隔的CSS样式类的列表。你可以为一行指定多个格式,中间用空格分隔。每个样式都重复应用后,再重新开始。例如,如果有两个样式类(style1和style2),第一个将是style1,第二个是style2,第3个是style1,第4个又是style2;以此类推 |
columnClasses | String | 无 | 否 | 用于列的逗号分隔的CSS样式类的列表。你可以对一列指定多个格式,中间用空格分隔。每个样式都重复应用后,再重新开始。例如,如果有两个样式类(style1和style2),第一个将是style1,第二个是style2,第3个是style1,第4个又是style2;以此类推 |
Facet | 说 明 | |||
header | 显示表头的子组件 | |||
footer | 显示表脚的子组件 |
表4-31 HtmlPanelGrid示例:简单的3列2行的表格
HTML |
(续)
组件标签 |
| ||
浏览器显示 |
|
提示 目前,并没有确定的默认列数(RI默认为1)。所以,如果想在不同的实现中都保持同样的行为,记得总是要指定列数。
也可很容易地添加样式到不同的行或者列中,以及添加样式到表头和表脚中。表4-32对此做了展示。
表4-32 HtmlPanelGrid示例:带有表头、表脚及可选样式的表格列
HTML |
|
(续)
| |
组件标签 | |
浏览器显示 |
注解 可以通过rowClasses属性为行添加样式,其行为与columnClasses类似。
你可以看到,styleClass 属性指定了整个表格的CSS 类。表格列的class 属性则交替使用columnClasses 属性中指定的两个值。至于可以指定多少个样式类并没有限制。表头将显示为跨越所有列的单独行,并且应用headerClass属性指定的CSS 样式类。表脚也跨越所有的列,但是其应用footerClass属性中指定的CSS 类。
注意,header facet使用了HtmlPanelGroup 组件;如果想在facet中包含多个组件,这是必需的(也可以再使用一个容器,比如另一个HtmlPanelGrid)。footer facet 只有一个子组件,所以不需要嵌套HtmlPanelGroup。
在此例子中,我们对列交替应用了不同的样式。值得注意的是,可以有不只两种不同的样式。另外,与styleClass一样,所有其他类属性,包括针对列和行的,都可以有多种样式。
这个例子中有两件事情需要注意。第一,headerClass有两个类:page-header和extra-border。它们都应用到header facet。另外,columnClasses 属性具有为四个列指定的类。第1列具有额外的样式应用到其上,因此它将显示为两种样式的结合。其他三个列使用不同的样式,第2列到最后一列也具有额外的样式应用。如果多于四列,这些样式将重复使用。
你可以像使用columnClasses 属性一样使用rowClasses属性,或者同时使用它们。这将导致交叉样式的结合,这可能是好事也可能是坏事,取决于你如何设置样式类(如果不仔细,可能会造成一些冲突)。
这些简单的例子可以给你一个对HtmlPanelGrid的初步印象。你可以通过嵌套使用多个面板来完成复杂的布局,就像使用HTML表格一样