private boolean selectable;
private boolean multiselect;
+ private HashMap keyToNode = new HashMap();
+
/**
* This map contains captions and icon urls for
* actions like:
return;
this.client = client;
+
+ if(uidl.hasAttribute("partialUpdate")) {
+ handleUpdate(uidl);
+ return;
+ }
+
this.paintableId = uidl.getId();
clear();
addTreeListener(new TreeListener() {
public void onTreeItemStateChanged(TreeItem item) {
+ if (item instanceof TreeNode) {
+ TreeNode tn = (TreeNode) item;
+ if(item.getState()) {
+ if(!tn.isChildrenLoaded()) {
+ String key = tn.key;
+ ITree.this.client.updateVariable(paintableId, "expand", new String[] {key}, true);
+ }
+ } else {
+ // TODO collapse
+ }
+ }
}
public void onTreeItemSelected(TreeItem item) {
}
+ private void handleUpdate(UIDL uidl) {
+ TreeNode rootNode = (TreeNode) keyToNode.get(uidl.getStringAttribute("rootKey"));
+ if(rootNode != null) {
+ rootNode.renderChildNodes(uidl.getChildIterator());
+ }
+
+ }
+
private class TreeNode extends TreeItem implements IActionOwner {
String key;
+ boolean isLeaf = false;
+
private String[] actionKeys = null;
+
+ private boolean childrenLoaded;
public TreeNode() {
super();
this.setText(uidl.getStringAttribute("caption"));
key = uidl.getStringAttribute("key");
+ keyToNode.put(key, this);
+
if(uidl.hasAttribute("al"))
actionKeys = uidl.getStringArrayAttribute("al");
- for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ if(uidl.getTag().equals("node")) {
+ isLeaf = false;
+ if(uidl.getChidlCount() == 0) {
+ TreeNode childTree = new TreeNode();
+ childTree.setText("Loading...");
+ childrenLoaded = false;
+ this.addItem(childTree);
+ } else {
+ renderChildNodes(uidl.getChildIterator());
+ }
+ } else {
+ isLeaf = true;
+ }
+
+ if(uidl.getBooleanAttribute("expanded") && !getState()) {
+ setState(true);
+ }
+
+ setSelected(uidl.getBooleanAttribute("selected"));
+
+ }
+
+ private void renderChildNodes(Iterator i) {
+ removeItems();
+ while (i.hasNext()) {
UIDL childUidl = (UIDL)i.next();
+ if("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
+ continue;
+ }
TreeNode childTree = new TreeNode();
this.addItem(childTree);
childTree.updateFromUIDL(childUidl, client);
}
- setState(uidl.getBooleanAttribute("expanded"));
- setSelected(uidl.getBooleanAttribute("selected"));
+ childrenLoaded = true;
+ }
+
+ public boolean isChildrenLoaded() {
+ return childrenLoaded;
}
public IAction[] getActions() {
return false;
};
}-*/;
-
}
}
* Is the tree selectable .
*/
private boolean selectable = true;
+
+ /**
+ * Flag to indicate sub-tree loading
+ */
+ private boolean partialUpdate = false;
+
+ /**
+ * Holds a itemId which was recently expanded
+ */
+ private Object expandedItemId;
/* Tree constructors ************************************************** */
// Expands
expanded.add(itemId);
- requestRepaint();
+
+ expandedItemId = itemId;
+ requestPartialRepaint();
fireExpandEvent(itemId);
return true;
}
+
+ public void requestRepaint() {
+ super.requestRepaint();
+ partialUpdate = false;
+ }
+ private void requestPartialRepaint() {
+ super.requestRepaint();
+ partialUpdate = true;
+ }
/**
* Expands the items recursively
* @see com.itmill.toolkit.ui.AbstractComponent#paintContent(PaintTarget)
*/
public void paintContent(PaintTarget target) throws PaintException {
-
- // Focus control id
- if (this.getFocusableId() > 0) {
- target.addAttribute("focusid", this.getFocusableId());
+
+ if(partialUpdate) {
+ target.addAttribute("partialUpdate", true);
+ target.addAttribute("rootKey", itemIdMapper.key(expandedItemId));
+ } else {
+
+ // Focus control id
+ if (this.getFocusableId() > 0) {
+ target.addAttribute("focusid", this.getFocusableId());
+ }
+
+ // The tab ordering number
+ if (this.getTabIndex() > 0)
+ target.addAttribute("tabindex", this.getTabIndex());
+
+ // Paint tree attributes
+ if (isSelectable())
+ target.addAttribute("selectmode", (isMultiSelect() ? "multi"
+ : "single"));
+ else
+ target.addAttribute("selectmode", "none");
+ if (isNewItemsAllowed())
+ target.addAttribute("allownewitem", true);
+
}
- // The tab ordering number
- if (this.getTabIndex() > 0)
- target.addAttribute("tabindex", this.getTabIndex());
-
- // Paint tree attributes
- if (isSelectable())
- target.addAttribute("selectmode", (isMultiSelect() ? "multi"
- : "single"));
- else
- target.addAttribute("selectmode", "none");
- if (isNewItemsAllowed())
- target.addAttribute("allownewitem", true);
-
// Initialize variables
Set actionSet = new LinkedHashSet();
String[] selectedKeys;
// Iterates through hierarchical tree using a stack of iterators
Stack iteratorStack = new Stack();
- Collection ids = rootItemIds();
+ Collection ids;
+ if(partialUpdate)
+ ids = getChildren(expandedItemId);
+ else
+ ids = rootItemIds();
+
if (ids != null)
iteratorStack.push(ids.iterator());
+
while (!iteratorStack.isEmpty()) {
// Gets the iterator for current tree level
target.endTag("actions");
}
- // Selected
- target.addVariable(this, "selected", selectedKeys);
+ if(partialUpdate) {
+ partialUpdate = false;
+ } else {
+ // Selected
+ target.addVariable(this, "selected", selectedKeys);
- // Expand and collapse
- target.addVariable(this, "expand", new String[] {});
- target.addVariable(this, "collapse", new String[] {});
+ // Expand and collapse
+ target.addVariable(this, "expand", new String[] {});
+ target.addVariable(this, "collapse", new String[] {});
- // New items
- target.addVariable(this, "newitem", new String[] {});
+ // New items
+ target.addVariable(this, "newitem", new String[] {});
+ }
}
/* Container.Hierarchical API ***************************************** */