当前页面: 开发资料首页 → Netbeans 专题 → Building a Tree From Database Data
摘要: This tutorial shows you how to dynamically build a tree structure from data in a database. Using NetBeans Visual Web Pack 5.5, you build a two-page application, the first page of which includes a Tree component. You populate the first-level nodes in the Tree with names from a database, and the second-level nodes with the trips for that person. The trip nodes are links to a second page, which displays the details for that trip
This tutorial works with the following technologies and resources
JavaServer Faces Components/ Java EE Platform |
![]() ![]() | |||
Travel Database | ![]() |
|||
BluePrints AJAX Component Library | ![]() |
* As of the date this tutorial was published, only the Sun Java System Application Server supported Java EE 5.
This tutorial has been tailored for use with the Sun Java Application Server PE 9.0 Update Release 1 and with Tomcat 5.5.17. If you are using a different server, consult the Release Notes and FAQs for known problems and workarounds. For detailed information about the supported servers and Java EE platform, see the Release Notes.
You begin by building a home page that includes the Tree component and the TRIP database table. The following figure shows the page.
![]() Figure 1: Page Design |
DatabaseTree
.
From the Basic section of the Palette, drag a Tree component onto the Page, type Travel Information
, and press Enter. In the Properties window, set the id
property to displayTree
and the clientSide
property to True
.
clientSide
is True
, every child node (expanded or not) is sent to the client, but is not made visible unless the
parent node is expanded. When clientSide
is False
, only the child nodes of the expanded parent nodes are rendered.
Select Tree Node 1, right-click, and choose Delete from the pop-up menu.
For this application, you do not need the initial tree node that the IDE creates because you are populating the tree programmatically. If you do not remove the node, the values set in the JSP tag attributes take precedence over the runtime settings, and the page displays the node.Open the Runtime window, expand the Databases node and verify that the Travel database is connected.
If the jdbc node for the TRAVEL database's badge is broken and you cannot expand the node,
the IDE is not connected to the database. To connect to the TRAVEL database, right-click the jdbc node for TRAVEL and choose Connect from the pop-up menu. If the Connect dialog box appears, enter travel
for the Password, select Remember Password During This Session, and click OK. If you do not see a jdbc node for the TRAVEL database, see the
NetBeans Visual Web Pack Installation Instructions for information about making the database available to the IDE.
derbyClient.jar
file to the <tomcat_install>/common/lib
directory before you try to connect to the database.
Expand the jdbc node for the TRAVEL database, then expand the Tables node as seen in the following figure.
![]() Figure 2: Travel Database |
Drag the TRIP node onto the Visual Designer.
The Outline window shows a tripDataProvider node in the Page1 section and a tripRowSet node in the SessionBean1 section.In the Outline window, right-click the tripRowSet node and choose Edit SQL Statement.
The Query Editor appears in the editing area, with a TRIP table diagram.From the Runtime window, drag the Travel > Tables > PERSON node and drop it next to the Trip table diagram in the Query Editor, as shown in Figure 3.
Another table diagram appears with a link, or join, between the two table diagrams.In the Design Grid of the Query Editor, find the NAME row for the TRAVEL.PERSON table. Click in the Sort Type cell and choose Ascending from the drop-down list.
This action sorts the names in the database table alphabetically by last name.Find the DEPDATE row for the TRAVEL.TRIP table. Click in the Sort Type cell and choose Ascending from the drop-down list.
This action sorts the trip dates from earliest date to latest date. The following figure shows the Query Editor.
![]() Figure 3: Query Editor |
prerender()
method to dynamically build the Tree component from the TRIP and PERSON database tables.Open Page1 so that the Outline window is visible. In the Outline window, right-click the RequestBean1 node and choose Add > Property. Name the property personId
, enter Integer
as the type, and click OK.
This property stores the ID of a traveler, as shown in the following figure. Later, you build a Trip detail page that uses this property to pass the current traveler's id to Page 1. When this property is set, Page1 expands the node for that person.
![]() Figure 4: Adding a New Property |
Open Page1 in the Java Editor and scroll to the prerender
method. Replace the body of the prerender
method with the following code shown in bold:
Code Sample 1: prerender Method for Page1 |
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);
}
}
|
tripNode_action
method, which you create later in this section.
Run the project.
The web browser opens and displays a Tree component with each first-level node showing the name of a person, as shown in the following figure. Expand a node to show the travel dates for that person. Note that the names appear alphabetically by last name and the dates appear in chronological order, as shown in the following figure. In the next section, you add code to navigate to a second page when the user clicks a trip node. The second page shows the details for the trip that the user selected.
![]() Figure 5: Dynamic Tree Node |
Here you add a second page to the application, as shown in the following figure. This page uses a Property Sheet component to dynamically show the details of the trip that the user selected on the first page.
![]() Figure 6: Detail Page |
Trip
.
Open the Runtime Window and drag the Tables > TRIP node onto the Visual Designer for the Trip page. In the dialog box, select the radio button next to Create SessionBean1 tripRowSet1, as shown in the following figure. Click OK.
![]() Figure 7 : Adding a New Data Provider with RowSet |
In the Design Grid of the Query Editor, right-click any cell in the TRIPID row and choose Add Query Criteria. In the dialog box, set the Comparison drop-down list to =Equals and select the Parameter radio button. Click OK.
You see =? in the Criteria column for TRIPID, which adds the following WHERE clause in the SQL query.WHERE TRAVEL.TRIP.TRIPID = ?
Home
,
and press Enter.In the Properties window for the Hyperlink component, click the ellipsis
(...) button for the action
property, select hyperlink1_action
from
the drop-down list, and click OK.
From the Layout section of the Palette, drag a Property Sheet component onto the page. Place it below the Hyperlink component.
The Property Sheet component provides a container for laying out the trip information. The Property Sheet component contains a Property Sheet Section, which in turn contains a Property component.Select Property Sheet Section 1. In the Properties window,
set the label
property to Trip Details
.
label
property to Departure Date:
and press Enter.
label
property to Departure City:
and press Enter.
Drag a Static Text component from the Palette and drop it on the property1 node in the Outline window.
The Static Text becomes a subnode of property1. The Static Text also appears in the Visual Designer.Right-click the Static Text component and choose Bind to Data from the pop-up menu. If necessary, click the Bind to Data Provider tab to bring that tab to the front. In the dialog box, select TRIP.DEPDATE in the Data field, as shown in the following figure, and click OK.
The current date appears in the Static Text component in the Visual Designer.
![]() Figure 8: Bind to Data Dialog Box |
Open the Trip page in the Java Editor and scroll to the prerender
method. Add the following code
(shown in bold) so that the method gets the tripId that was stored in Page1.
Code Sample 2: prerender Method for Trip page |
public void prerender() {
// Get the person id from the request parameters
String parmTripId = (String)
getExternalContext().getRequestParameterMap().get("tripId");
if (parmTripId != null) {
Integer tripId = new Integer(parmTripId);
try {
getSessionBean1().getTripRowSet1().setObject(1, tripId);
tripDataProvider1.refresh();
} catch (Exception e) {
error("Cannot display trip " + tripId);
log("Cannot display trip " + tripId, e);
}
}else {
error("No trip id specified.");
}
}
|
setObject
method sets the trip query's first argument
to the tripId. That is, the method replaces the ? in the query with
the tripId. This query only has one argument so you only have to call
setObject
once. The call to tripDataProvider1.refresh()
calls CachedRowSet.release()
and resets the CachedRowSetDataProvider's cursor. It does not execute the CachesRowSet at this time.
Scroll to the hyperlink1_action
method. Add the following code (shown in bold) to pass the personId to Page1:
Code Sample 3: hyperlink1_action Method for Trip Page |
public String hyperlink1_action() {
getRequestBean1().setPersonId(
(Integer)tripDataProvider1.getValue("trip.personid"));
return null;
}
|
Click the Trip.jsp icon to enlarge it and drag a connector from the Hyperlink component to the Page1.jsp icon. The following figure shows the page navigation setup.
![]() Figure 9 : Page Navigation |
Run the application. On the Home page, expand an traveler name and click a trip date.
The Trip page opens with details for that trip, as shown in the following figure.
![]() Figure 10: Detail Page at Runtime |
getSelected()
method to determine which node was clicked, as illustrated in the following steps.Add the following method to the Java source for Page1:
Code Sample 4: tripNode_action Method for Page1 |
public String tripNode_action() { // Get the id of the currently selected tree node String nodeId = displayTree.getSelected(); // Find the tree node component with the given id TreeNode selectedNode = (TreeNode) this.getForm1().findComponentById(nodeId); try { // Node's id property is composed of "trip" plus the trip id // Extract the trip id and save it for the next page Integer tripId = Integer.valueOf(selectedNode.getId().substring(4)); getRequestBean1().setTripId(tripId); } catch (Exception e) { error("Can't convert node id to Integer: " + selectedNode.getId().substring(4)); return null; } return "case1"; } |
prerender
method, replace the following code with the code in Code Sample 5. tripNode.setUrl("/faces/Trip.jsp?tripId=" + tripDataProvider.getValue("TRIP.TRIPID").toString());
Code Sample 5: Tweaking the prerender Method |
ExpressionFactory exFactory = getApplication().getExpressionFactory(); ELContext elContext = getFacesContext().getELContext(); tripNode.setActionExpression( exFactory.createMethodExpression( elContext, "#{Page1.tripNode_action}", String.class, new Class<?>[0])); |
In the Trip page prerender()
method, replace the body with the following code:
Code Sample 6: prerender Method for Trip Page |
public void prerender() { Integer tripId = getRequestBean1().getTripId(); try { getSessionBean1().getTripRowSet1().setObject(1, tripId); tripDataProvider1.refresh(); } catch (Exception e) { error("Cannot display trip " + tripId); log("Cannot display trip " + tripId, e); } } |
If your project is a J2EE 1.4 project, here are some things you should know about the selection of Tree nodes:
getSelected
method or the getCookieSelectedTreeNode
method to determine which node was selected.
If users have their browser cookies turned off, these methods will not return the correct
values. Also, for browsers with the cookies turned on, the cookie might return the wrong
value the first time the user visits a page and clicks a node. If there are leftover
cookies from a previous visit, the previously selected value might be returned. Because the
JavaServer Faces 1.2 version of the Tree component does not use cookies to save the
selected value, this is not an issue for the 1.2 version. In this tutorial, you built a tree structure from data in a database. You built a two-page application, the first page of which included a Tree component. You populated the first-level nodes in the Tree with names from a database, and the second-level nodes with the trips for that person. You linked each trip on the first page to a second page, which displayed the details for that trip.
See Also: