📄 abstracttree.java
字号:
* @param node * The node to inspect * @return true if the node is expanded, false otherwise */ protected final boolean isNodeExpanded(TreeNode node) { // In root less mode the root node is always expanded if (isRootLess() && rootItem != null && rootItem.getModelObject().equals(node)) { return true; } return getTreeState().isNodeExpanded(node); } /** * Creates the TreeState, which is an object where the current state of tree (which nodes are * expanded / collapsed, selected, ...) is stored. * * @return Tree state instance */ protected ITreeState newTreeState() { return new DefaultTreeState(); } /** * Called after the rendering of tree is complete. Here we clear the dirty flags. */ protected void onAfterRender() { super.onAfterRender(); // rendering is complete, clear all dirty flags and items updated(); } /** * This method is called after creating every TreeItem. This is the place for adding components * on item (junction links, labels, icons...) * * @param item * newly created tree item. The node can be obtained as item.getModelObject() * * @param level * how deep the component is in tree hierarchy (0 for root item) */ protected abstract void populateTreeItem(WebMarkupContainer item, int level); /** * Builds the children for given TreeItem. It recursively traverses children of it's TreeNode * and creates TreeItem for every visible TreeNode. * * @param item * The parent tree item */ private final void buildItemChildren(TreeItem item) { List items; // if the node is expanded if (isNodeExpanded((TreeNode)item.getModelObject())) { // build the items for children of the items' treenode. items = buildTreeItems(nodeChildren((TreeNode)item.getModelObject()), item.getLevel() + 1); } else { // it's not expanded, just set children to an empty list items = new ArrayList(0); } item.setChildren(items); } /** * Builds (recursively) TreeItems for the given Iterator of TreeNodes. * * @param nodes * The nodes to build tree items for * @param level * The current level * @return List with new tree items */ private final List buildTreeItems(Iterator nodes, int level) { List result = new ArrayList(); // for each node while (nodes.hasNext()) { TreeNode node = (TreeNode)nodes.next(); // create tree item TreeItem item = newTreeItem(node, level); itemContainer.add(item); // builds it children (recursively) buildItemChildren(item); // add item to result result.add(item); } return result; } /** * Checks whether the model has been changed, and if so unregister and register listeners. */ private final void checkModel() { // find out whether the model object (the TreeModel) has been changed TreeModel model = (TreeModel)getModelObject(); if (model != previousModel) { if (previousModel != null) { previousModel.removeTreeModelListener(this); } previousModel = model; if (model != null) { model.addTreeModelListener(this); } // model has been changed, redraw whole tree invalidateAll(); } } /** * Removes all TreeItem components. */ private final void clearAllItem() { visitItemAndChildren(rootItem, new IItemCallback() { public void visitItem(TreeItem item) { item.remove(); } }); rootItem = null; } /** * Returns the javascript used to delete removed elements. * * @return The javascript */ private String getElementsDeleteJavascript() { // build the javascript call final AppendingStringBuffer buffer = new AppendingStringBuffer(100); buffer.append("Wicket.Tree.removeNodes(\""); // first parameter is the markup id of tree (will be used as prefix to // build ids of child items buffer.append(getMarkupId() + "_\",["); // append the ids of elements to be deleted buffer.append(deleteIds); // does the buffer end if ','? if (buffer.endsWith(",")) { // it does, trim it buffer.setLength(buffer.length() - 1); } buffer.append("]);"); return buffer.toString(); } // // State and Model callbacks // /** * returns the short version of item id (just the number part). * * @param item * The tree item * @return The id */ private String getShortItemId(TreeItem item) { // show much of component id can we skip? (to minimize the length of // javascript being sent) final int skip = getMarkupId().length() + 1; // the length of id of // tree and '_'. return item.getMarkupId().substring(skip); } private final static ResourceReference JAVASCRIPT = new JavascriptResourceReference( AbstractTree.class, "res/tree.js"); /** * Initialize the component. */ private final void init() { setVersioned(false); // we need id when we are replacing the whole tree setOutputMarkupId(true); // create container for tree items itemContainer = new TreeItemContainer("i"); add(itemContainer); add(HeaderContributor.forJavaScript(JAVASCRIPT)); checkModel(); } /** * INTERNAL * * @param node */ public final void markNodeDirty(TreeNode node) { invalidateNode(node, false); } /** * Invalidates single node (without children). On the next render, this node will be updated. * Node will not be rebuilt, unless forceRebuild is true. * * @param node * The node to invalidate * @param forceRebuild */ private final void invalidateNode(TreeNode node, boolean forceRebuild) { if (dirtyAll == false) { // get item for this node TreeItem item = (TreeItem)nodeToItemMap.get(node); if (item != null) { boolean createDOM = false; if (forceRebuild) { // recreate the item int level = item.getLevel(); List children = item.getChildren(); String id = item.getId(); // store the parent of old item TreeItem parent = item.getParentItem(); // if the old item has a parent, store it's index int index = parent != null ? parent.getChildren().indexOf(item) : -1; createDOM = dirtyItemsCreateDOM.contains(item); dirtyItems.remove(item); dirtyItemsCreateDOM.remove(item); item.remove(); item = newTreeItem(node, level, id); itemContainer.add(item); item.setChildren(children); // was the item an root item? if (parent == null) { rootItem = item; } else { parent.getChildren().set(index, item); } } dirtyItems.add(item); if (createDOM) { dirtyItemsCreateDOM.add(item); } } } } /** * Invalidates node and it's children. On the next render, the node and children will be * updated. Node children will be rebuilt. * * @param node * The node to invalidate */ private final void invalidateNodeWithChildren(TreeNode node) { if (dirtyAll == false) { // get item for this node TreeItem item = (TreeItem)nodeToItemMap.get(node); // is the item visible? if (item != null) { // go though item children and remove every one of them visitItemChildren(item, new IItemCallback() { public void visitItem(TreeItem item) { removeItem(item); } }); // set children to null so that they get rebuild item.setChildren(null); // add item to dirty items dirtyItems.add(item); } } } /** * Returns whether the given node is visible, e.g. all it's parents are expanded. * * @param node * The node to inspect * @return true if the node is visible, false otherwise */ private final boolean isNodeVisible(TreeNode node) { while (node.getParent() != null) { if (isNodeExpanded(node.getParent()) == false) { return false; } node = node.getParent(); } return true; } /** * Creates a tree item for given node. * * @param node * The tree node * @param level * The level * @return The new tree item */ private final TreeItem newTreeItem(TreeNode node, int level) { return new TreeItem("" + idCounter++, node, level); } /** * Creates a tree item for given node with specified id. * * @param node * The tree node * @param level * The level * @param id * the component id * @return The new tree item */ private final TreeItem newTreeItem(TreeNode node, int level, String id) { return new TreeItem(id, node, level); } /** * Return the representation of node children as Iterator interface. * * @param node * The tree node * @return iterable presentation of node children */ private final Iterator nodeChildren(TreeNode node) { return toIterator(node.children()); } /** * Rebuilds children of every item in dirtyItems that needs it. This method is called for * non-partial update. */ private final void rebuildDirty() { // go through dirty items for (Iterator i = dirtyItems.iterator(); i.hasNext();) { TreeItem item = (TreeItem)i.next(); // item children need to be rebuilt if (item.getChildren() == null) { buildItemChildren(item); } } } /** * Removes the item, appends it's id to deleteIds. This is called when a items parent is being * deleted or rebuilt. * * @param item * The item to remove */ private void removeItem(TreeItem item) { // even if the item is dirty it's no longer necessary to update id dirtyItems.remove(item); // if the item was about to be created if (dirtyItemsCreateDOM.contains(item)) { // we needed to create DOM element, we no longer do dirtyItemsCreateDOM.remove(item); } else { // add items id (it's short version) to ids of DOM elements that // will be // removed deleteIds.append(getShortItemId(item)); deleteIds.append(","); } // remove the id // note that this doesn't update item's parent's children list item.remove(); } /** * Calls after the tree has been rendered. Clears all dirty flags. */ private final void updated() { dirtyAll = false; dirtyItems.clear(); dirtyItemsCreateDOM.clear(); deleteIds.clear(); // FIXME: Recreate it to save some space? } /** * Call the callback#visitItem method for the given item and all it's children. * * @param item * The tree item * @param callback * item call back */ private final void visitItemAndChildren(TreeItem item, IItemCallback callback) { callback.visitItem(item); visitItemChildren(item, callback); } /** * Call the callback#visitItem method for every child of given item. * * @param item * The tree item * @param callback * The callback */ private final void visitItemChildren(TreeItem item, IItemCallback callback) { if (item.getChildren() != null) { for (Iterator i = item.getChildren().iterator(); i.hasNext();) { TreeItem child = (TreeItem)i.next(); visitItemAndChildren(child, callback); } } } /** * Returns the component associated with given node, or null, if node is not visible. This is * useful in situations when you want to touch the node element in html. * * @param node * Tree node * @return Component associated with given node, or null if node is not visible. */ public Component getNodeComponent(TreeNode node) { return (Component)nodeToItemMap.get(node); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -