在本教程中,我们将向我们介绍如何通过数据库中的数据动态地构建树结构。我们将使用 netbeans ide 6.0 构建一个由两个页面组成的应用程序,其中第一页包含一个 jsf 1.2 ( woodstock ) 树组件。接下来,我们将用数据库中的人物姓名填充树结构的一级节点,然
在本教程中,我们将向我们介绍如何通过数据库中的数据动态地构建树结构。我们将使用netbeans ide 6.0构建一个由两个页面组成的应用程序,其中第一页包含一个jsf 1.2(woodstock)树组件。接下来,我们将用数据库中的人物姓名填充树结构的一级节点,然后用此人的行程信息来填充二级节点。trip节点将链接到第二个页面,其中显示该行程的详细信息。
目录
-
设计主页
-
连接数据库
-
通过数据库表构建树结构
-
添加详细信息页
-
添加代码
-
定义页面导航
-
更多功能:将action方法与树节点绑定
-
关于树节点选择的注意事项
本教程将涉及以下技术和资源
javaserver faces组件/
java ee平台
1.2 with java ee 5*
1.1 with j2ee 1.4
travel数据库
必需
要利用netbeans ide 6.0的java ee 5的性能,我们需要一个与java ee 5规范完全兼容的应用服务器,比如说sun java system application server 9(glassfish项目)。
本教程适用于glassfish v2应用服务器。如果我们使用的是其他服务器,请参阅发行说明 和常见问题解答 了解各类问题和解决途径。有关所支持的服务器和java ee平台的详细信息,请参阅发行说明。
设计主页
首先,我们将构建一个包含树组件和trip数据库表的主页。
创建一个新的visual web jsf应用程序项目,将其命名为databasetree,然后启动viual web jsf框架。
从组件面板的basic部分拖动一个树组件到页面上,键入“travel信息”,然后按回车键。在“属性”窗口中,将id属性设置为displaytree,将clientside属性设置为true。
当clientside属性为true时,每个子节点(无论展开与否)都将发送给客户机,但它们只有在父节点展开时才可见。当clientside为false时,仅呈现那些展开的父节点的子节点。
选择tree node 1,单击鼠标右键,然后从弹出菜单中选择“删除”。
在本应用程序中,我们将通过编程填充树中的节点,因此不需要初始化由ide创建的树节点。如果未移除该节点,则jsp标记属性中设置的值将优先于运行时设置,并且页面将显示节点。
从组件面板拖动一个“消息组”组件到页面的边缘位置,如页面的右上角。
连接数据库
接下来,将该页与travel数据源中的数据库表相连接,然后使用查询编辑器修改用于检索数据的sql查询,使游客的姓名按字母顺序显示,旅行日期按时间顺序显示。
打开“服务”窗口,展开数据库节点,然后验证是否已连接到travel数据库。
如果travel数据库的jdbc节点标记显示为断开,并且无法展开该节点,则表明ide未连接到该数据库。要连接travel数据库,请右键单击travel数据库的jdbc节点,然后从弹出菜单中选择“连接”。如果出现“连接”对话框,在输入travel作为口令,选中“在此期间记住密码”,然后单击“确定”按钮。
注:如果我们使用的是apache tomcat应用服务器,请将derbyclient.jar文件复制到/common/lib目录,然后再尝试连接到该数据库。
展开travel数据库的jdbc节点,然后展开“表”节点
将“trip”节点拖放到可视编辑器中。
导航窗口净土在页面1部分显示“tripdataprovider”节点,在“sessionbean1”部分显示“triprowset”节点。
在导航窗口中,展开“sessionbean1”节点,右键单击“triprowset”节点,然后选择“编辑sql语句”。
在编辑区域将显示带有trip表格图的查询编辑器。
从“服务”窗口拖出“行程 > 表 > 人员”节点,并将其放置在查询编辑器中的“trip”表图的旁边,如图3所示。
此时将出现另一个表图,且两个表图之间有链接或连接。
在“person”表中,取消选中personid复选框。
在查询编辑器的“设计网格”中,找到“travel.person”表中的“name”行。单击“排序类型”单元格,然后从下拉列表中选择“升序”。
此操作将使数据库表中的名字按姓氏的字母顺序排列。
找到“travel.trip”表中的“depdate”行。单击“排序类型”单元格,然后从下拉列表中选择“升序”。
此操作将行程日期按照从早到晚的顺序排列。
通过数据库表构建树结构
现在,我们已经在存储停息中添加了一个请求bean属性,可供应用程序的中两个页面使用。然后,我将在prerender()方法中添加代码,用于通过trip和person数据库表动态地构建树组件。
打开页面1,使导航窗口可见。在导航窗口中,右键单击“requestbean1”节点,然后选择“编辑java源代码”。
在“public class requestbean1 extends abstractrequestbean”构建函数中声明属性,如下所示:
private integer personid;
在java编辑器中单击鼠标右键,选择“重构 > 封装”字段。
在“封装字段”对话框中,选择创建getter和setter方法,如下图所示。确保变量声明中字段可见性为“私有”,存取器可见性是“公有”,然后单击“重构”按钮。
在java编辑器中打开页面1,然后找到prerender方法。用以下粗体显示的代码替换prerender方法的主体部分:
代码示例1:页面1的prerender方法
public void prerender() {
// if the request bean's personid is set, then
// we just came back from the trip page
// and had displayed a selected trip.
// we use the personid later to determine whether
// to expand a person's node
integer expandedpersonid = getrequestbean1().getpersonid();
try {
// set up the variables we will need
integer currentpersonid = new integer(-1);
// if nbrchildren is not 0 then this is a
// postback and we have our tree already
int nbrchildren = displaytree.getchildcount();
if (nbrchildren == 0) {
// list of outer (person) nodes
list outerchildren = displaytree.getchildren();
// erase previous contents
outerchildren.clear();
// list of inner (trip) nodes
list innerchildren = null;
// execute the sql query
tripdataprovider.refresh();
// iterate over the rows of the result set.
// every time we encounter a new person, add first level node.
// add second level trip nodes to the parent person node.
boolean hasnext = tripdataprovider.cursorfirst();
while (hasnext) {
integer newpersonid =
(integer) tripdataprovider.getvalue(
trip.personid);
if (!newpersonid.equals(currentpersonid)) {
currentpersonid = newpersonid;
treenode personnode = new treenode();
personnode.setid(person + newpersonid.tostring());
personnode.settext(
(string)tripdataprovider.getvalue(
person.name));
// if the request bean passed a person id,
// expand that person's node
personnode.setexpanded(newpersonid.equals
(expandedpersonid));
outerchildren.add(personnode);
innerchildren = personnode.getchildren();
}
// create a new trip node
treenode tripnode = new treenode();
tripnode.setid(trip +
tripdataprovider.getvalue(trip.tripid).tostring());
tripnode.settext(
tripdataprovider.getvalue(trip.depdate).tostring());
tripnode.seturl(/faces/trip.jsp?tripid= +
tripdataprovider.getvalue(trip.tripid).tostring());
innerchildren.add(tripnode);
hasnext = tripdataprovider.cursornext();
}
}
} catch (exception ex) {
log(exception gathering tree data, ex);
error(exception gathering tree data: + ex);
}
}
此代码读取按照personid排序的行程记录。对于每个personid,此代码会在树结构中创建一个新的一级节点。然后,为每一个与该personid关联的行程创建一个二级节点(嵌套节点)。最后,将二级行程节点与tripnode_action方法(稍后在本部分中创建)绑定在一起。
在源代码中单击鼠标右键,然后从弹出菜单中选择fix imports修复“无法找到类”的错误。在“fix all imports”对话框中,请确保java.util.list出现在列出的字段中,然后单击“确定”按钮。
运行项目。
web浏览器将打开并显示一个树组件,其中每个一级节点显示人名,如下图所示。展开节点可显示此人的旅行日期。请注意,人名按姓氏的字母顺序显示,日期按时间顺序显示。在下一节中,我们将添加一些代码,以便用户在单击trip节点时导航至第二页。第二个页面将显示用户所选行程的详细信息。
添加详细信息页
现在,我们需要为应用程序添加第二个页面,如下图所示。此页使用“属性表单”组件动态地显示用户在第一页上所选行程的详细信息。