Application Techniques



Constructing a Hierarchical View Using AgoTreeDataManager

How to construct a hierarchical view and populate it using an AgoTreeDataManager.

About this technique

Details

Category

Java Client Techniques> Java-based views

Description

You'll learn about:

You can run this technique code from:

NOTE   First make sure that database is running on your localhost SilverStream server

Related reading

See the chapter on using Java-based views in the Programmer's Guide

How this technique is organized   Top of page

This technique shows an AgcView control that can display a single-level view of employee records or a master/detail view of employees organized by department.

The AgcView is comprised of three AgoBandFormats, one for each of the three kinds of rows it displays: a band format for header rows, a band format for department rows, and a band format for employee rows. All of the columns that comprise the header and employee band formats are text columns (AgoColumnText). The department band format uses text columns plus a single hierarchical column (AgoColumnHierarchy). The AgoColumnHierarchy is the first column appended to the department band format, and it displays the twistie indicating child rows.

The data for the hierarchical view is obtained from the department and employee tables. The data is managed by two AgoTreeDataManager objects: one is defined as the parent node (for department rows) and the other is defined as a child node (for employee rows). AgoTreeDataManager is the SilverStream object that allows you to manage hierarchical data. Each AgoTreeDataManager is used to construct and manage a node of data. You can construct trees of data with multiple levels of nested nodes for multilevel hierarchies.

You can use AgoTreeDataManager to display static data as well as data that is derived dynamically from any data source accessible to the SilverStream server. (For the single-level view in this example, you could just pass in the AgcData control bound to the customer table on the initView() method instead of using the AgoTreeDataManager.)

Creating an AgcView with hierarchical columns   Top of page

This example defines view formats in separate custom methods.

The getDepartmentFormat() method creates the view format for the master/detail view only and is described in this technique. The example also includes a getEmployeeFormat() method which creates the view format for the single-level view. It is not described in this technique.

The getDepartmentFormat() method includes code that:

The following code includes the basic setup for an AgoViewFormat, the master and detail band formats, and the department ID column (the hierarchical column). See the online example for the code to set up the header band and the employee columns:

  // Create a view format, set background and caret color 
     AgoViewFormat viewFormat = new AgoViewFormat(); 
     viewFormat.setBackgroundColor(Color.white); 
     viewFormat.setCaretColor(new Color(184, 203, 215)); 
  // Create a format for the data band 
     AgoBandFormat band = new AgoBandFormat("department"); 
     band.setGridIdentifier(band); 
  // Create a format for the child data band 
     AgoBandFormat child = new AgoBandFormat("employees"); 
     child.setGridIdentifier(child); 
  // Create the department column, init it, and add it to the band 
     AgoColumnHierarchy department = new 
        AgoColumnHierarchy(474,true,false,Color.white, 
        AgoColumnBase.BORDER_3D); 
     department.initColumnTextProperty("Department",  
        new AgoFontIdentifier("Helvetica", 0, 11), Color.black, 
        AgoColumnBase.ALIGN_LEFT); 
     band.appendColumnFormat(department); 

Notes about the code

Creating a multinode AgoTreeDataManager   Top of page

An AgoTreeDataManager can manage a data tree containing one or more nodes of data. To create an AgoTreeDataManager, you need to supply:

To specify column names

You can specify different column names for each node of the tree. This String Array defines the column names for the department data:

  private final static String m_departmentColumns[]=  
  { 
     "Department" 
  }; 

This String Array defines the column names for the employee data:

  private final static String m_employeeColumns[]= 
  { 
     "FirstName","LastName","EmailAddress" 
  }; 

Constructing the tree data manager

The parent node of the AgoTreeDataManager obtains its data from the agcDepartments control. Because the data has not been retrieved when the AgoTreeDataManager is instantiated, you pass null as the data parameter and the m_departmentColumns String array just described:

  AgoTreeDataManager m_mgr; 
  m_mgr = new AgoTreeDataManager(null, m_departmentColumns); 

Getting the root row cursor

The AgoTreeDataManager class does not implement AgiRowCursor itself but rather provides a getRootRowCursor() method. This method returns an AgiRowCursor that points to the root of the data tree managed by the AgoTreeDataManager:

  AgiRowCursor data = m_mgr.getRootRowCursor(); 

Obtaining the department data

To obtain the department data, query the AgcData control (agcDepartments) and add the records to the AgiRowCursor that points to the AgoTreeDataManager's root:

  // Query the AgcData object 
  agcDepartments.query(null); 
  // Go to the first record... 
  boolean rows = agcDepartments.gotoFirst(); 
  // Loop through all the departments and add them to the dataset 
  while (rows) 
  { 
  data.insertAfter(); 
  Integer id = (Integer) agcDepartments.getProperty("departmentid"); 
  data.setProperty("Department", agcDepartments.getProperty("departmentname")); 
   
  // Check to see if this department has any employees 
  addEmployees(data,id); 
   
  rows = agcDepartments.gotoNext(); 
  } 
  . 
  . 
  . 

To accumulate the detail rows (the employees per department), call the custom method addEmployees() and pass in the current AgiRowCursor (containing the department information) and the current department ID:

  addEmployees(data,id); 

Obtaining the employee data

You obtain employee records (for each department ID) by calling the addEmployees() custom method while looping through department rows. (The call to addEmployees() is shown in the code fragment just above.)

The addEmployees() method looks like this:

  try 
  { 
  // Query the AgcData object 
    agcEmployees.query("employees.deptid = " + id.toString()); 
  // Go to the first record... 
    boolean rows = agcEmployees.gotoFirst(); 
     if (rows) 
   { 
  // Create an AgoTreeDataManager for the child data 
     AgoTreeDataManager childmgr = new AgoTreeDataManager(null, 
      m_employeeColumns, "employees"); 
  // Set the data for the child 
     m_mgr.setChildDataManager(parentData, childmgr); 
   
     AgiRowCursor dc = childmgr.getRootRowCursor(); 
   
  // Loop through all the customer and add them to the dataset 
     while (rows) 
      { 
       dc.insertAfter(); 
       dc.setProperty("FirstName",      agcEmployees.getProperty("firstname")); 
      dc.setProperty("LastName", 
       agcEmployees.getProperty("lastname")); 
      dc.setProperty("EmailAddress",      agcEmployees.getProperty("emailaddress")); 
   
  // Get the next row 
     rows = agcEmployees.gotoNext(); 
     } 
   } 
   
  } 
  catch (Exception e) 
   { 
  agDialog.displayError(e); 
  return; 
   } 
  } 

Notes about the code

You can create as many child nodes (AgoTreeDataManagers) as needed for your hierarchy. Just make sure to pass the appropriate parent node as the parentData parameter.

Initializing the view

When you return to the getDepartmentFormat() method (from the addEmployees() method), call the initView() method and pass in the AgiRowCursor for the parent node (departments) and the AgoViewFormat m_deptformat:

  // Init the view with the data 
  vwEmployees.initView(data, m_deptformat); 





Copyright © 2000, SilverStream Software, Inc. All rights reserved.