📄 tree.java
字号:
ti.setLoaded(false); renderItem(ti,_model.getChild(node,index)); ti.setOpen(true); } } /** * Return the Tree or Treeitem component by a given associated node in model.<br> * This implmentation calls {@link TreeModel#getPath} method to locate assoicated * Treeitem (or Tree) via path. You can override this method to speed up * performance if possible. * @since 3.0.0 */ protected Component getChildByNode(Object node){ int[] path = _model.getPath(_model.getRoot(), node); //If path is null or empty, return root(Tree) if(path == null || path.length == 0) return this; else{ Treeitem ti = (Treeitem)this.getTreechildren().getChildren().get(path[0]); for(int i=1; i<path.length; i++){ ti = (Treeitem) ti.getTreechildren().getChildren().get(path[i]); } return ti; } } /* * Initial Tree data listener */ private void initDataListener() { if (_dataListener == null) _dataListener = new TreeDataListener() { public void onChange(TreeDataEvent event) { onTreeDataChange(event); } }; _model.addTreeDataListener(_dataListener); } /** Sets the tree model associated with this tree. * * @param model the tree model to associate, or null to dis-associate * any previous model. * @exception UiException if failed to initialize with the model * @since 3.0.0 */ public void setModel(TreeModel model) throws Exception{ _model = model; syncModel(); initDataListener(); } //--TreeModel dependent codes--// /** Returns the list model associated with this tree, or null * if this tree is not associated with any tree data model. * @return the list model associated with this tree * @since 3.0.0 */ public TreeModel getModel(){ return _model; } /** Synchronizes the tree to be consistent with the specified model. */ private void syncModel() throws Exception{ if (_renderer == null) _renderer = getRealRenderer(); renderTree(); } /** Sets the renderer which is used to render each item * if {@link #getModel} is not null. * * <p>Note: changing a render will not cause the tree to re-render. * If you want it to re-render, you could assign the same model again * (i.e., setModel(getModel())), or fire an {@link TreeDataEvent} event. * * @param renderer the renderer, or null to use the default. * @exception UiException if failed to initialize with the model * @since 3.0.0 */ public void setTreeitemRenderer(TreeitemRenderer renderer){ _renderer = renderer; } /** Returns the renderer to render each item, or null if the default * renderer is used. * @return the renderer to render each item, or null if the default * @since 3.0.0 */ public TreeitemRenderer getTreeitemRenderer(){ return _renderer; } /* * Render the root of Tree * Notice: _model.getRoot() is mapped to Tree, not first Treeitem */ private void renderTree(){ if(_treechildren != null) _treechildren =null; Treechildren children = new Treechildren(); children.setParent(this); Object node = _model.getRoot(); int childCount = _model.getChildCount(node); for(int i=0; i< childCount;i++ ){ renderTreeChild(node,i); } } /* * Helper method for renderTree */ private void renderTreeChild(Object node,int index){ Treeitem ti = new Treeitem(); Object data = _model.getChild(node, index); try { _renderer.render(ti, data); } catch (Throwable ex) { try { ti.setLabel(Exceptions.getMessage(ex)); } catch (Throwable t) { log.error(t); } ti.setOpen(true); } if(!_model.isLeaf(data)){ Treechildren ch = new Treechildren(); ch.setParent(ti); } ti.setParent(_treechildren); } private static final TreeitemRenderer getDefaultItemRenderer() { return _defRend; } private static final TreeitemRenderer _defRend = new TreeitemRenderer() { public void render(Treeitem ti, Object data){ Treecell tc = new Treecell(data.toString()); Treerow tr = null; if(ti.getTreerow()==null){ tr = new Treerow(); tr.setParent(ti); }else{ tr = ti.getTreerow(); tr.getChildren().clear(); } tc.setParent(tr); ti.setOpen(false); } }; /** Returns the renderer used to render items. */ private TreeitemRenderer getRealRenderer() { return _renderer != null ? _renderer: getDefaultItemRenderer(); } /** Used to render treeitem if _model is specified. */ private class Renderer implements java.io.Serializable { private final TreeitemRenderer _renderer; private boolean _rendered, _ctrled; private Renderer() { _renderer = getRealRenderer(); } private void render(Treeitem item) throws Throwable { if (!item.isOpen()) return; //nothing to do if (!_rendered && (_renderer instanceof RendererCtrl)) { ((RendererCtrl)_renderer).doTry(); _ctrled = true; } try { Object node = getAssociatedNode(item, Tree.this); _renderer.render(item, node); } catch (Throwable ex) { try { item.setLabel(Exceptions.getMessage(ex)); } catch (Throwable t) { log.error(t); } item.setOpen(true); throw ex; } item.setOpen(true); _rendered = true; } private void doCatch(Throwable ex) { if (_ctrled) { try { ((RendererCtrl)_renderer).doCatch(ex); } catch (Throwable t) { throw UiException.Aide.wrap(t); } } else { throw UiException.Aide.wrap(ex); } } private void doFinally() { if (_ctrled) ((RendererCtrl)_renderer).doFinally(); } } /** Renders the specified {@link Treeitem} if not loaded yet, * with {@link #getTreeitemRenderer}. * * <p>It does nothing if {@link #getModel} returns null. * * @see #renderItems * @since 3.0.0 */ public void renderItem(Treeitem item){ if(_model ==null) return; final Renderer renderer = new Renderer(); try { renderItem(item,getAssociatedNode(item,this)); } catch (Throwable ex) { renderer.doCatch(ex); } finally { renderer.doFinally(); } } /** Renders the specified {@link Treeitem} with data if not loaded yet, * with {@link #getTreeitemRenderer}. * * <p>It does nothing if {@link #getModel} returns null. * *<p>Note: Since the corresponding data is given, * This method has better performance than * renderItem(Treeitem item) due to not searching for its * corresponding data. * @see #renderItems * @since 3.0.0 * * */ public void renderItem(Treeitem item, Object data){ if(_model ==null) return; final Renderer renderer = new Renderer(); try { dfRenderItem(data,item); } catch (Throwable ex) { renderer.doCatch(ex); } finally { renderer.doFinally(); } } /** * Render the treetiem with given node and its children */ private void dfRenderItem(Object node, Treeitem item) throws Exception { //if treeitem is not loaded, load it if(!item.isLoaded()) { Treechildren children = null; if(item.getTreechildren()!=null){ children = item.getTreechildren(); /* * When the treeitem is rendered after 1st time, dropped all * the descending treeitems first. */ if(children.getItemCount()>0) children.getChildren().clear(); }else{ children = new Treechildren(); _renderer.render(item, node); } /* * After modified the node in tree model, if node is leaf, * its treechildren is needed to be dropped. */ if(_model.isLeaf(node)){ _renderer.render(item, node); if(item.getTreechildren()!=null) item.getTreechildren().detach(); }else{ /* * render children of item */ for(int i=0; i< _model.getChildCount(node);i++ ){ Treeitem ti = new Treeitem(); Object data = _model.getChild(node, i); _renderer.render(ti, data); if(!_model.isLeaf(data)){ Treechildren ch = new Treechildren(); ch.setParent(ti); } ti.setParent(children); } children.setParent(item); } //After the treeitem is loaded with data, set treeitem to be loaded item.setLoaded(true); } } /** Renders the specified {@link Treeitem}s with data if not loaded yet, * with {@link #getTreeitemRenderer}. * * <p>It does nothing if {@link #getModel} returns null. * * @see #renderItem * @since 3.0.0 */ public void renderItems(Set items) { if (_model == null) return; if (items.isEmpty()) return; //nothing to do final Renderer renderer = new Renderer(); try { for (Iterator it = items.iterator(); it.hasNext();){ Treeitem item = (Treeitem)it.next(); Object data = getAssociatedNode(item,this); dfRenderItem(data,item); } } catch (Throwable ex) { renderer.doCatch(ex); } finally { renderer.doFinally(); } } /** * Return a node which is an associated Treeitem ti in a Tree tree * @since 3.0.0 */ protected Object getAssociatedNode(Treeitem ti, Tree t){ return getNodeByPath(getTreeitemPath(t,ti),_model.getRoot()); } /** * return the path which is from ZK Component root to ZK Component lastNode */ private List getTreeitemPath(Component root, Component lastNode){ List al = new ArrayList(); Component curNode = lastNode; while(!root.equals(curNode)){ if(curNode instanceof Treeitem){ al.add(new Integer(((Treeitem)curNode).indexOf())); } curNode = curNode.getParent(); } return al; } /** * Get the node from tree by given path * @param path * @param root * @return the node from tree by given path * @since 3.0.0 */ private Object getNodeByPath(List path, Object root) { Object node = root; int pathSize = path.size()-1; for(int i=pathSize; i >= 0; i--){ node = _model.getChild(node, ((Integer)(path.get(i))).intValue()); } return node; } /** * Load treeitems through path <b>path</b> * <br>Note: By using this method, all treeitems in path will be rendered * @param path - an int[] path, see {@link TreeModel#getPath} * @return the treeitem from tree by given path * @since 3.0.0 */ public Treeitem renderItemByPath(int[] path){ if(path == null || path.length == 0) return null; //Start from root-Tree Treeitem ti = null; List children = this.getTreechildren().getChildren(); /* * Go through each stop in path and render corresponding treeitem */ for(int i=0; i<path.length; i++){ if(path[i] <0 || path[i] > children.size()) return null; ti = (Treeitem) children.get(path[i]); renderItem(ti); if(i<path.length-1) ti.setOpen(true); if(ti.getTreechildren()!=null){ children = ti.getTreechildren().getChildren(); }else{ if(i!=path.length-1){ return null; } } } return ti; } //TODO AREA JEFF ADDED END /** A utility class to implement {@link #getExtraCtrl}. * It is used only by component developers. */ protected class ExtraCtrl extends XulElement.ExtraCtrl implements InnerWidth, Selectable { //InnerWidth// public void setInnerWidthByClient(String width) { _innerWidth = width == null ? "100%": width; } //-- Selectable --// public void selectItemsByClient(Set selItems) { _noSmartUpdate = true; try { if (!_multiple || selItems == null || selItems.size() <= 1) { final Treeitem item = selItems != null && selItems.size() > 0 ? (Treeitem)selItems.iterator().next(): null; selectItem(item); } else { for (Iterator it = new ArrayList(_selItems).iterator(); it.hasNext();) { final Treeitem item = (Treeitem)it.next(); if (!selItems.remove(item)) removeItemFromSelection(item); } for (Iterator it = selItems.iterator(); it.hasNext();) addItemToSelection((Treeitem)it.next()); } } finally { _noSmartUpdate = false; } } } /** An iterator used by _heads. */ private class Iter implements Iterator { private final ListIterator _it = getChildren().listIterator(); public boolean hasNext() { while (_it.hasNext()) { Object o = _it.next(); if (o instanceof Treecols || o instanceof Auxhead) { _it.previous(); return true; } } return false; } public Object next() { for (;;) { Object o = _it.next(); if (o instanceof Treecols || o instanceof Auxhead) return o; } } public void remove() { throw new UnsupportedOperationException(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -