Basic Customization > User Interface Customization > Presenting Information in the UI > Windchill Client Architecture Tree > Solution > Procedure — Configuring JCA Tree > Implementing ComponentConfigBuiler and ComponentDataBuilder > Separate Builder Approach > Using Asynchronous DataSource
  
Using Asynchronous DataSource
Implementing ComponentConfigBuilder
Example:
@ComponentBuilder(value = "custom.treeExample.seperate", type = ComponentBuilderType.CONFIG_ONLY)
public class TreeExampleConfigBuilder extends AbstractComponentConfigBuilder {
private static final String RESOURCE = "com.ptc.carambola.carambolaResource";
@Override
public ComponentConfig buildComponentConfig(ComponentParams params)
throws WTException {
ComponentConfigFactory factory = getComponentConfigFactory();

//Create TreeConfig
TreeConfig tree = factory.newTreeConfig();
// Need to set DataSOurceModes explicitely to DataSourceMode.ASYNCHRONOUS
((JcaTreeConfig) tree).setDataSourceMode(DataSourceMode.ASYNCHRONOUS);

// Set expansion level . Default is TableTreeProperties.ONE_EXPAND
(expand by one level)
((JcaTreeConfig) tree).setExpansionLevel(TableTreeProperties.FULL_EXPAND);

tree.setLabel((new ResourceBundleClientMessageSource(RESOURCE)).getMessage
("PART_TREE_LABEL"));


//Add Columns to the config
tree.addComponent(factory.newColumnConfig(NAME, true));
tree.addComponent(factory.newColumnConfig(NUMBER, true));

//Set column to which expand/collapse norgie should appear
tree.setNodeColumn(NUMBER);
return tree;
}
}
Important Points:
1. To use Asynchronous DataSource, DataSource mode should be explicitely set to DataSourceMode.ASYNCHRONOUS.
2. setNodeColumn method, allows to choose the column for which expand/collapse norgie is required. Default is “name ” column.
Implementing ComponentDataBuilder
The concrete class should implement interface com.ptc.mvc.components.TreeDataBuilderAsync. Please check Java API documentation for more details.
Example:
@ComponentBuilder(value = "custom.treeExample.seperate", type =
ComponentBuilderType.DATA_ONLY)
public class TreeExampleComponentDataBuilder
implements TreeDataBuilderAsync {
@Override
public void buildNodeData(Object node,
ComponentResultProcessor resultProcessor)
throws Exception {
if (node == TreeNode.RootNode) {
List<Object> objects = getRootNodes();
resultProcessor.addElements(objects);
} else {
List nodeList = new ArrayList();
nodeList.add(node);
Map<Object, List> map = getNodes(nodeList);
Set keySet = map.keySet();
for (Object key : keySet) {
resultProcessor.addElements(map.get(key));
}
}
}
private List<Object> getRootNodes(){ // Add code to find RootNodes}
private List<Object> getNodes(List<Object> nodeList){ // Add code to find ChildNodes}
}
Advanced Configurations by implementing TreeExpansionStateManager
TreeExpansionStateManager provides following APIs
boolean isExpandNeeded(DefaultMutableTreeNode node, ComponentConfig config,
ComponentParams params) throws WTException;

void addExpandedNode(Object node, ComponentConfig config,
ComponentParams params)
throws WTException;


Set getExpandedOids(ComponentConfig config, ComponentParams params)
throws WTException;

boolean hasChildren(Object node, ComponentResultProcessor resultProcessor,
TreeDataBuilderAsync builder) throws Exception;

List<DefaultMutableTreeNode> getDynamicExpandedNodes(ComponentConfig config,
ComponentParams params) throws WTException;
Please refer to JavaDoc for details.
Concrete implmenetation of TreeExpansionStateManager is provided by DefaultTreeExpansionStateManager. This implementation can be extended to customize the APIs as per requirement or TreeExpansionStateManager can be implemented directly. The concrete implementation can be injected into the builder by using ExpansionStateManager annotation.
Example:
@ComponentBuilder ("folderbrowser_tree")
@ExpansionStateManager (FolderTreeExpansionStateHandler.class)
//
public class FolderTreeBuilder extends AbstractComponentConfigBuilder implements TreeDataBuilderAsync{…}
Here FolderTreeExpansionStateHandler implements DefaultTreeExpansionStateManager and is injected into the FolderTreebuilder
These APIs are useful for customizing the tree expansion state behavior. E.g. IsExpandNeeded API can be used to override the default logic which decides whether the node should be expanded.