You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2007/05/03 12:30:39 UTC
svn commit: r534781 - in /myfaces/tobago/trunk:
example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/
example/sandbox/src/main/webapp/
sandbox/src/main/java/org/apache/myfaces/tobago/component/
sandbox/src/main/java/org/apache/myface...
Author: lofwyr
Date: Thu May 3 03:30:36 2007
New Revision: 534781
URL: http://svn.apache.org/viewvc?view=rev&rev=534781
Log:
TOBAGO-377: Improved Tree
rendering on the server for better performance, less javascript
move expand state from TreeState to arbitrary position in model
Added:
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java
Modified:
myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Controller.java
myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Node.java
myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-menu.jsp
myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-normal.jsp
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITree.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNode.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNodeData.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTag.java
myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTagDeclaration.java
myfaces/tobago/trunk/sandbox/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/script/tobago-tree.js
myfaces/tobago/trunk/sandbox/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java
Modified: myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Controller.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Controller.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Controller.java (original)
+++ myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Controller.java Thu May 3 03:30:36 2007
@@ -37,20 +37,31 @@
public Controller() {
// tree
- tree = new DefaultMutableTreeNode(new Node("Category"));
- tree.insert(new DefaultMutableTreeNode(new Node("Sports")), 0);
- tree.insert(new DefaultMutableTreeNode(new Node("Movies")), 0);
- DefaultMutableTreeNode music = new DefaultMutableTreeNode(new Node("Music"));
- tree.insert(music, 0);
- tree.insert(new DefaultMutableTreeNode(new Node("Games")), 0);
- DefaultMutableTreeNode temp = new DefaultMutableTreeNode(new Node("Science"));
- temp.insert(new DefaultMutableTreeNode(new Node("Geography", STRONG)), 0);
- temp.insert(new DefaultMutableTreeNode(new Node("Mathematics", STRONG)), 0);
- DefaultMutableTreeNode temp2 = new DefaultMutableTreeNode(new Node("Astronomy"));
- temp2.insert(new DefaultMutableTreeNode(new Node("Education")), 0);
- temp2.insert(new DefaultMutableTreeNode(new Node("Pictures")), 0);
- temp.insert(temp2, 2);
- tree.insert(temp, 2);
+ tree = new DefaultMutableTreeNode(new Node("1 Category"));
+ tree.add(new DefaultMutableTreeNode(new Node("1.1 Sports")));
+ tree.add(new DefaultMutableTreeNode(new Node("1.2 Movies")));
+ DefaultMutableTreeNode temp = new DefaultMutableTreeNode(new Node("1.3 Science"));
+ tree.add(temp);
+ DefaultMutableTreeNode music = new DefaultMutableTreeNode(new Node("1.4 Music"));
+ tree.add(music);
+ tree.add(new DefaultMutableTreeNode(new Node("1.5 Games")));
+ temp.add(new DefaultMutableTreeNode(new Node("1.3.1 Geography", STRONG)));
+ temp.add(new DefaultMutableTreeNode(new Node("1.3.2 Mathematics", STRONG)));
+ DefaultMutableTreeNode temp2 = new DefaultMutableTreeNode(new Node("1.3.3 Pictures"));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.1 Education")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.2 Family")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.3 Comercial")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.4 Summer")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.5 Winter")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.6 Red")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.7 Black")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.8 White")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.9 Good")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.10 Evil")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.11 Flower")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.12 Animal")));
+ temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.13 Personal")));
+ temp.add(temp2);
// state
Modified: myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Node.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Node.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Node.java (original)
+++ myfaces/tobago/trunk/example/sandbox/src/main/java/org/apache/myfaces/tobago/example/sandbox/Node.java Thu May 3 03:30:36 2007
@@ -26,6 +26,7 @@
private String name;
private String markup;
+ private boolean expanded;
public Node(String name) {
this.name = name;
@@ -55,6 +56,14 @@
public void setMarkup(String markup) {
this.markup = markup;
+ }
+
+ public boolean isExpanded() {
+ return expanded;
+ }
+
+ public void setExpanded(boolean expanded) {
+ this.expanded = expanded;
}
public String getTip() {
Modified: myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-menu.jsp
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-menu.jsp?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-menu.jsp (original)
+++ myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-menu.jsp Thu May 3 03:30:36 2007
@@ -25,7 +25,7 @@
<tc:page label="Sandbox - Tree" id="page"
width="500px" height="800px">
<f:facet name="layout">
- <tc:gridLayout margin="10px" rows="300px;*"/>
+ <tc:gridLayout margin="10px" rows="600px;*"/>
</f:facet>
<tcs:tree state="#{controller.state}" id="menu"
@@ -34,23 +34,26 @@
showRootJunction="false"
showRoot="true"
mode="menu">
- <tcs:treeNode label="Root" id="root">
+ <tcs:treeNode label="Root" id="root" expanded="true">
<tcs:treeNodeData value="#{controller.tree}" var="node" id="data">
- <tcs:treeNode label="#{node.userObject.name}" id="template"
+ <tcs:treeNode label="#{node.userObject.name}"
+ id="template"
+ expanded="#{node.userObject.expanded}"
markup="#{node.userObject.markup}"
tip="#{node.userObject.tip}"
- action="#{node.userObject.action}" value="#{node}"/>
+ action="#{node.userObject.action}"
+ value="#{node}"/>
</tcs:treeNodeData>
- <tcs:treeNode label="Action 1" action="#{controller.action1}" id="action1"/>
- <tcs:treeNode label="Action 2" action="#{controller.action2}" id="action2"/>
- <tcs:treeNode label="Action 3" action="#{controller.action3}" id="action3">
- <tcs:treeNode label="On Click 1" onclick="alert('On Click 1');" id="click1"/>
- <tcs:treeNode label="On Click 2" onclick="alert('On Click 2');" id="click2">
- <tcs:treeNode label="On Click 3" onclick="alert('On Click 3');" id="click3"/>
+ <tcs:treeNode label="2 Action 1" action="#{controller.action1}" id="action1"/>
+ <tcs:treeNode label="3 Action 2" action="#{controller.action2}" id="action2"/>
+ <tcs:treeNode label="4 Action 3" action="#{controller.action3}" id="action3">
+ <tcs:treeNode label="4.1 On Click 1" onclick="alert('On Click 1');" id="click1"/>
+ <tcs:treeNode label="4.2 On Click 2" onclick="alert('On Click 2');" id="click2">
+ <tcs:treeNode label="4.2.1 On Click 3" onclick="alert('On Click 3');" id="click3"/>
</tcs:treeNode>
</tcs:treeNode>
- <tcs:treeNode label="Link" link="http://myfaces.apache.org/tobago/" id="link" tip="Subnode Link"/>
- <tcs:treeNode label="Target" action="#{controller.action2}" target="Target Window"/>
+ <tcs:treeNode label="5 Link" link="http://myfaces.apache.org/tobago/" id="link" tip="Subnode Link"/>
+ <tcs:treeNode label="6 Target" action="#{controller.action2}" target="Target Window"/>
</tcs:treeNode>
</tcs:tree>
Modified: myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-normal.jsp
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-normal.jsp?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-normal.jsp (original)
+++ myfaces/tobago/trunk/example/sandbox/src/main/webapp/tree-normal.jsp Thu May 3 03:30:36 2007
@@ -25,13 +25,18 @@
<tc:page label="Sandbox - Tree" id="page"
width="500px" height="800px">
<f:facet name="layout">
- <tc:gridLayout margin="10px" rows="300px;*"/>
+ <tc:gridLayout margin="10px" rows="600px;*"/>
</f:facet>
- <tcs:tree state="#{controller.state}" id="tree">
- <tcs:treeNode label="Root">
+ <tcs:tree state="#{controller.state}" id="tree"
+ showIcons="true"
+ showJunctions="true"
+ showRoot="true"
+ showRootJunction="true"
+ >
+ <tcs:treeNode label="Root" expanded="true">
<tcs:treeNodeData value="#{controller.tree}" var="node" id="data">
- <tcs:treeNode label="#{node.userObject.name}" id="template"
+ <tcs:treeNode label="#{node.userObject.name}" id="template" expanded="#{node.userObject.expanded}"
markup="#{node.userObject.markup}"
tip="#{node.userObject.tip}"
action="#{node.userObject.action}" value="#{node}"/>
Added: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java?view=auto&rev=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java (added)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java Thu May 3 03:30:36 2007
@@ -0,0 +1,17 @@
+package org.apache.myfaces.tobago.component;
+
+import org.apache.myfaces.tobago.model.MixedTreeModel;
+
+/**
+ * User: lofwyr
+ * Date: 23.04.2007 18:08:08
+ */
+public interface TreeModelBuilder {
+
+ void buildBegin(MixedTreeModel model);
+
+ void buildChildren(MixedTreeModel model);
+
+ void buildEnd(MixedTreeModel model);
+
+}
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITree.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITree.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITree.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITree.java Thu May 3 03:30:36 2007
@@ -27,6 +27,7 @@
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SHOW_ROOT_JUNCTION;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STATE;
import org.apache.myfaces.tobago.model.TreeState;
+import org.apache.myfaces.tobago.model.MixedTreeModel;
import org.apache.myfaces.tobago.util.MessageFactory;
import javax.faces.application.FacesMessage;
@@ -90,6 +91,7 @@
private boolean showRootJunctionSet = false;
private String mode;
+ private MixedTreeModel model;
public UITree() {
treeCommands = new Command[]{
@@ -178,6 +180,24 @@
// will be called from end.jsp
}
+ public void encodeEnd(FacesContext context) throws IOException {
+ model = new MixedTreeModel();
+
+ buildModel();
+ super.encodeEnd(context);
+ }
+
+ private void buildModel() {
+ for (Object child : getChildren()) {
+ if (child instanceof TreeModelBuilder) {
+ TreeModelBuilder builder = (TreeModelBuilder) child;
+ builder.buildBegin(model);
+ builder.buildChildren(model);
+ builder.buildEnd(model);
+ }
+ }
+ }
+
public boolean getRendersChildren() {
return true;
}
@@ -392,5 +412,8 @@
return command;
}
}
-}
+ public MixedTreeModel getModel() {
+ return model;
+ }
+}
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNode.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNode.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNode.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNode.java Thu May 3 03:30:36 2007
@@ -19,12 +19,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.tobago.model.MixedTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;
-public class UITreeNode extends UICommand implements SupportsMarkup {
+public class UITreeNode extends UICommand implements SupportsMarkup, TreeModelBuilder {
private static final Log LOG = LogFactory.getLog(UITreeNode.class);
@@ -46,6 +47,25 @@
@Override
public boolean getRendersChildren() {
return true;
+ }
+
+ public void buildBegin(MixedTreeModel model) {
+ model.beginBuildNode(this);
+ }
+
+ public void buildChildren(MixedTreeModel model) {
+ for (Object child : getChildren()) {
+ if (child instanceof TreeModelBuilder) {
+ TreeModelBuilder builder = (TreeModelBuilder) child;
+ builder.buildBegin(model);
+ builder.buildChildren(model);
+ builder.buildEnd(model);
+ }
+ }
+ }
+
+ public void buildEnd(MixedTreeModel model) {
+ model.endBuildNode(this);
}
@Override
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNodeData.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNodeData.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNodeData.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/component/UITreeNodeData.java Thu May 3 03:30:36 2007
@@ -21,7 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.tobago.model.TreeModel;
-import org.apache.myfaces.tobago.renderkit.RenderUtil;
+import org.apache.myfaces.tobago.model.MixedTreeModel;
import javax.faces.component.NamingContainer;
import javax.faces.context.FacesContext;
@@ -33,7 +33,7 @@
import java.io.IOException;
public class UITreeNodeData extends javax.faces.component.UIInput
- implements NamingContainer {
+ implements NamingContainer, TreeModelBuilder {
private static final Log LOG = LogFactory.getLog(UITreeNodeData.class);
@@ -57,8 +57,9 @@
// super.processDecodes(facesContext);
// }
+
@Override
- public void decode(FacesContext facesContext) {
+ public void processDecodes(FacesContext facesContext) {
// todo: does treeModel should be stored in the state?
// todo: what is, when the value has been changed since last rendering?
@@ -71,6 +72,11 @@
}
}
+ @Override
+ public void decode(FacesContext facesContext) {
+
+ }
+
public String getPathIndex() {
return pathIndex;
}
@@ -101,6 +107,25 @@
}
}
+ public void buildBegin(MixedTreeModel model) {
+ model.beginBuildNodeData(this);
+ }
+
+ public void buildChildren(MixedTreeModel model) {
+ for (Object child : getChildren()) {
+ if (child instanceof TreeModelBuilder) {
+ TreeModelBuilder builder = (TreeModelBuilder) child;
+ builder.buildBegin(model);
+ builder.buildChildren(model);
+ builder.buildEnd(model);
+ }
+ }
+ }
+
+ public void buildEnd(MixedTreeModel model) {
+ model.endBuildNodeData(this);
+ }
+
@Override
public void encodeChildren(FacesContext context)
throws IOException {
@@ -112,9 +137,14 @@
// todo: does treeModel should be stored in the state?
treeModel = new TreeModel((DefaultMutableTreeNode) getValue());
- for (String pathIndex : treeModel.getPathIndexList()) {
- setPathIndex(pathIndex);
- RenderUtil.encode(facesContext, getTemplateComponent());
+ for (TreeModel.Tag pathIndex : treeModel.getDoublePathIndexList()) {
+ setPathIndex(pathIndex.getName());
+ if (pathIndex.isStart()) {
+ getTemplateComponent().encodeBegin(facesContext);
+ } else {
+ getTemplateComponent().encodeEnd(facesContext);
+ }
+// RenderUtil.encode(facesContext, getTemplateComponent());
setPathIndex(null);
}
Added: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java?view=auto&rev=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java (added)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java Thu May 3 03:30:36 2007
@@ -0,0 +1,132 @@
+package org.apache.myfaces.tobago.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.myfaces.tobago.component.UITreeNode;
+import org.apache.myfaces.tobago.component.UITreeNodeData;
+import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LABEL;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.util.Stack;
+import java.util.List;
+import java.util.Collections;
+import java.util.ArrayList;
+
+/**
+ * User: lofwyr
+ * Date: 23.04.2007 16:10:22
+ */
+public class MixedTreeModel {
+
+ private DefaultMutableTreeNode root;
+ private DefaultMutableTreeNode current;
+ private Integer nextChildIndex;
+ private DefaultMutableTreeNode dataRoot;
+ private boolean isInData;
+ private Stack<Boolean> junctions = new Stack<Boolean>();
+
+ public void beginBuildNode(UITreeNode node) {
+ if (!isInData) {
+ DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(node.getAttributes().get(ATTR_LABEL));
+ if (root == null) {
+ root = newNode;
+ } else {
+ current.add(newNode);
+ current = newNode;
+ }
+ }
+ }
+
+ public void endBuildNode(UITreeNode node) {
+ if (!isInData) {
+ current = (DefaultMutableTreeNode) current.getParent();
+ }
+ }
+
+ public void beginBuildNodeData(UITreeNodeData data) {
+ current = new DefaultMutableTreeNode(data.getValue());
+ if (root == null) {
+ root = current;
+ } else {
+ root.add(current);
+ }
+ isInData = true;
+ }
+
+ public void endBuildNodeData(UITreeNodeData data) {
+ current = (DefaultMutableTreeNode) current.getParent();
+ isInData = false;
+ }
+
+ public void onEncodeBegin() {
+ if (current == null) {
+ current = root;
+ } else {
+ current = (DefaultMutableTreeNode) current.getChildAt(nextChildIndex);
+ if (!isInData && current.getUserObject() instanceof DefaultMutableTreeNode) {
+ isInData = true;
+ dataRoot = current;
+ current = (DefaultMutableTreeNode) current.getUserObject();
+ }
+ }
+ nextChildIndex = 0;
+
+ junctions.push(hasCurrentNodeNextSibling());
+ }
+
+ public void onEncodeEnd() {
+ if (isInData && current.isRoot()) {
+ current = dataRoot;
+ isInData = false;
+ }
+ DefaultMutableTreeNode parent = (DefaultMutableTreeNode) current.getParent();
+ if (parent != null) {
+ nextChildIndex = parent.getIndex(current) + 1;
+ current = parent;
+ } else {
+ nextChildIndex = null;
+ current = null;
+ }
+
+ junctions.pop();
+ }
+
+ public boolean hasCurrentNodeNextSibling() {
+ if (isInData && current.isRoot()) {
+ return dataRoot.getNextSibling() != null;
+ } else {
+ return current.getNextSibling() != null;
+ }
+ }
+
+ public boolean isFolder() {
+ return current.getChildCount() > 0;
+ }
+
+ public int getDepth() {
+ return junctions.size();
+ }
+
+ public List<Boolean> getJunctions() {
+ Boolean top = junctions.pop();
+ List<Boolean> result = Collections.unmodifiableList(new ArrayList<Boolean>(junctions));
+ junctions.push(top);
+ return result;
+ }
+
+}
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java Thu May 3 03:30:36 2007
@@ -29,6 +29,7 @@
import java.util.Collections;
// todo: make more general (e.g. support other trees)
+// todo: Should be the model for the whole tree, (also for tc:treeNode on the JSP)
public class TreeModel {
private static final Log LOG = LogFactory.getLog(TreeModel.class);
@@ -36,6 +37,9 @@
private Map<String, DefaultMutableTreeNode> nodes = new HashMap<String, DefaultMutableTreeNode>();
private List<String> keys = new ArrayList<String>();
+ // XXX not nice
+ private List<Tag> doubleKeys = new ArrayList<Tag>(); // with "begin tags" and "end tags"
+
public TreeModel(DefaultMutableTreeNode node) {
putNodes(node, "", 0);
}
@@ -51,6 +55,7 @@
position += "_" + index;
keys.add(position);
+ doubleKeys.add(new Tag(position, true));
nodes.put(position, node);
index = 0;
@@ -59,6 +64,8 @@
putNodes(subNode, position, index);
index++;
}
+
+ doubleKeys.add(new Tag(position, false));
}
public DefaultMutableTreeNode getNode(String pathIndex) {
@@ -69,6 +76,10 @@
return Collections.unmodifiableList(keys);
}
+ public List<Tag> getDoublePathIndexList() {
+ return Collections.unmodifiableList(doubleKeys);
+ }
+
public String getParentPathIndex(String pathIndex) {
int lastUnderscore = pathIndex.lastIndexOf('_');
switch (lastUnderscore) {
@@ -78,6 +89,34 @@
return null;
default:
return pathIndex.substring(0, lastUnderscore);
+ }
+ }
+
+ public static class Tag {
+
+ private String name;
+
+ private boolean start;
+
+ public Tag(String name, boolean start) {
+ this.name = name;
+ this.start = start;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isStart() {
+ return start;
+ }
+
+ public void setStart(boolean start) {
+ this.start = start;
}
}
}
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java Thu May 3 03:30:36 2007
@@ -22,34 +22,37 @@
* $Id$
*/
-import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ACTION_LINK;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_DISABLED;
+import static org.apache.myfaces.tobago.TobagoConstants.ATTR_EXPANDED;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LABEL;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ONCLICK;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SELECTABLE;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_CLASS;
-import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TARGET;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TIP;
import org.apache.myfaces.tobago.component.ComponentUtil;
import org.apache.myfaces.tobago.component.UITree;
import org.apache.myfaces.tobago.component.UITreeNode;
-import org.apache.myfaces.tobago.component.UITreeNodeData;
+import org.apache.myfaces.tobago.context.ResourceManagerUtil;
+import org.apache.myfaces.tobago.model.MixedTreeModel;
import org.apache.myfaces.tobago.model.TreeState;
import org.apache.myfaces.tobago.renderkit.CommandRendererBase;
-import org.apache.myfaces.tobago.renderkit.html.HtmlRendererUtil;
+import org.apache.myfaces.tobago.renderkit.html.CommandRendererHelper;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlConstants;
+import static org.apache.myfaces.tobago.renderkit.html.HtmlConstants.A;
+import static org.apache.myfaces.tobago.renderkit.html.HtmlConstants.DIV;
+import static org.apache.myfaces.tobago.renderkit.html.HtmlConstants.IMG;
import org.apache.myfaces.tobago.renderkit.html.HtmlStyleMap;
+import org.apache.myfaces.tobago.renderkit.html.StyleClasses;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
+import javax.faces.el.ValueBinding;
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
public class TreeNodeRenderer extends CommandRendererBase {
@@ -70,17 +73,24 @@
TreeState state = tree.getState();
String treeId = tree.getClientId(facesContext);
String nodeStateId = node.nodeStateId(facesContext);
- Map requestParameterMap
- = facesContext.getExternalContext().getRequestParameterMap();
+ Map requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
+ String id = node.getClientId(facesContext);
// expand state
- String expandState = (String) requestParameterMap.get(treeId);
- String searchString = ";" + nodeStateId + ";";
- if (StringUtils.contains(expandState, searchString)) {
- state.addExpandState((DefaultMutableTreeNode) node.getValue());
- }
+ boolean expanded = Boolean.parseBoolean((String) requestParameterMap.get(id + "-expanded"));
+// String expandState = (String) requestParameterMap.get(treeId);
+// String searchString = ";" + nodeStateId + ";";
+// if (StringUtils.contains(expandState, searchString)) {
+// if (expanded) {
+// state.addExpandState((DefaultMutableTreeNode) node.getValue());
+ ValueBinding binding = node.getValueBinding(ATTR_EXPANDED);
+ if (binding != null) {
+ binding.setValue(facesContext, expanded);
+ }
+// }
+ String searchString;
if (TreeRenderer.isSelectable(tree)) { // selection
String selected = (String) requestParameterMap.get(treeId + UITree.SELECT_STATE);
searchString = ";" + nodeStateId + ";";
@@ -101,278 +111,404 @@
}
@Override
- public void encodeBegin(FacesContext facesContext, UIComponent component)
- throws IOException {
+ public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
- UITreeNode treeNode = (UITreeNode) component;
+ UITreeNode node = (UITreeNode) component;
+ UITree root = node.findTree();
+ MixedTreeModel mixedModel = root.getModel();
- UIComponent parent = treeNode.getParent();
+ mixedModel.onEncodeBegin();
- boolean isFolder = treeNode.getChildCount() > 0;
+ TobagoResponseWriter writer = (TobagoResponseWriter) facesContext.getResponseWriter();
- String parentClientId = null;
- if (parent != null && parent instanceof UITreeNode) { // if not the root node
- parentClientId = treeNode.getParent().getClientId(facesContext);
- } else if (parent != null && parent instanceof UITreeNodeData) {
- String pci = parent.getClientId(facesContext);
- if (pci.endsWith(":_0")) {
- UIComponent superParent = parent.getParent();
- parentClientId = superParent.getClientId(facesContext);
- } else {
- parentClientId = pci.substring(0, pci.length() - 2) // fixme 2 is not correct for bitter trees
- + NamingContainer.SEPARATOR_CHAR + treeNode.getId();
- }
- DefaultMutableTreeNode currentNode =
- ((UITreeNodeData) parent).getCurrentNode();
- if (currentNode != null) {
- isFolder = currentNode.getChildCount() > 0;
+ TreeState treeState = root.getState();
+ String treeId = root.getClientId(facesContext);
+
+ DefaultMutableTreeNode modelNode = (DefaultMutableTreeNode) node.getValue();
+
+ boolean isFolder = mixedModel.isFolder();
+
+ boolean marked = treeState.isMarked(modelNode);
+ String id = node.getClientId(facesContext);
+ boolean expanded = ComponentUtil.getBooleanAttribute(node, ATTR_EXPANDED);
+ boolean menuMode = root.getMode().equals("menu");
+
+ boolean showIcons = root.isShowIcons();
+ boolean showJunctions = root.isShowJunctions();
+ boolean showRootJunction = root.isShowRootJunction();
+ boolean showRoot = root.isShowRoot();
+ int depth = mixedModel.getDepth();
+ boolean hasNextSibling = mixedModel.hasCurrentNodeNextSibling();
+ List<Boolean> junctions = mixedModel.getJunctions();
+
+ CommandRendererHelper helper = new CommandRendererHelper(facesContext, node);
+
+ writer.startElement(DIV);
+
+ // div id
+ writer.writeIdAttribute(id);
+
+ // div class (css)
+ StyleClasses styleClasses = StyleClasses.ensureStyleClasses(node);
+ styleClasses.removeTobagoClasses("treeNode");
+ styleClasses.addAspectClass("treeNode", StyleClasses.Aspect.DEFAULT);
+ if ("menu".equals(root.getMode())) {
+ styleClasses.addClass("treeNode", "menu");
+ if (marked) {
+ styleClasses.addClass("treeNode", "marker");
}
}
+ styleClasses.addMarkupClass(node, "treeNode");
+ writer.writeClassAttribute(styleClasses);
- UITree root = treeNode.findTree();
- String rootId = root.getClientId(facesContext);
+ // div style (width)
+ Integer width = null;
+ HtmlStyleMap style = (HtmlStyleMap) root.getAttributes().get(ATTR_STYLE);
+ if (style != null) {
+ width = style.getInt("width");
+ }
+ String widthString;
+ if (width != null) {
+ widthString = "width: " + Integer.toString(width - 4); // fixme: 4
+ } else {
+ widthString = "100%";
+ }
+ writer.writeAttribute("style", widthString, null);
- String clientId = treeNode.getClientId(facesContext);
-// clientId += pos != null ? pos : "";
+ if (isFolder) {
+ encodeExpandedHidden(writer, node, id, expanded);
+ }
- String jsClientId = TreeRenderer.createJavascriptVariable(clientId);
- String jsParentClientId = TreeRenderer.createJavascriptVariable(
- parentClientId);
-// rootId = HtmlUtils.createJavascriptVariable(rootId);
+ if (isFolder && menuMode) {
+ encodeMenuIcon(facesContext, writer, treeId, id, expanded);
+ }
- TreeState treeState = root.getState();
- if (treeState == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("No treeState found. clientId=" + clientId);
- }
- } else {
+ encodeIndent(facesContext, writer, menuMode, junctions);
- DefaultMutableTreeNode modelNode = (DefaultMutableTreeNode) treeNode.getValue();
+ encodeTreeJunction(facesContext, writer, id, treeId, showJunctions, showRootJunction, showRoot, expanded, isFolder,
+ depth, hasNextSibling);
- ResponseWriter writer = facesContext.getResponseWriter();
+ encodeTreeIcons(facesContext, writer, id, treeId, showIcons, expanded, isFolder);
- String debuging = "";
+ encodeLabel(writer, helper, node, marked, treeId);
- writer.writeText(" var ", null);
- writer.writeText(jsClientId, null);
- writer.writeText(" = new TreeNode('", null);
- // label
- Object label = treeNode.getAttributes().get(ATTR_LABEL);
- if (LOG.isDebugEnabled()) {
- debuging += label + " : ";
- }
- if (label != null) {
- writer.writeText(StringEscapeUtils.escapeJavaScript(label.toString()), null);
- } else {
- LOG.warn("label = null");
- }
- writer.writeText("',", null);
+ writer.endElement(DIV);
- // tip
- String tip = (String) treeNode.getAttributes().get(ATTR_TIP);
- if (tip != null) {
- tip = StringEscapeUtils.escapeJavaScript(tip);
- writer.writeText("'", null);
- writer.writeText(tip, null);
- writer.writeText("','", null);
- } else {
- writer.writeText("null,'", null);
- }
+ if (isFolder) {
+ String contentStyle = "display: " + (expanded ? "block" : "none") + ";";
+ writer.startElement(DIV);
+ writer.writeIdAttribute(id + "-cont");
+ writer.writeAttribute("style", contentStyle, null);
+ }
- // id
- writer.writeText(clientId, null);
- writer.writeText("','", null);
-
- // mode
- writer.writeText(root.getMode(), null);
- writer.writeText("',", null);
-
- // is folder
- writer.writeText(isFolder, null);
- writer.writeText(",", null);
-
- // show icons
- writer.writeText(Boolean.toString(!root.isShowIcons()), null);
- writer.writeText(",", null);
-
- // show junctions
- writer.writeText(Boolean.toString(!root.isShowJunctions()), null);
- writer.writeText(",", null);
-
- // show root junction
- writer.writeText(Boolean.toString(!root.isShowRootJunction()), null);
- writer.writeText(",", null);
-
- // show root
- writer.writeText(Boolean.toString(!root.isShowRoot()), null);
- writer.writeText(",'", null);
-
- // tree id
- writer.writeText(rootId, null);
- writer.writeText("',", null);
-
- //
- String selectable = ComponentUtil.getStringAttribute(root, ATTR_SELECTABLE);
- if (selectable != null
- && !("multi".equals(selectable) || "multiLeafOnly".equals(selectable)
- || "single".equals(selectable) || "singleLeafOnly".equals(selectable)
- || "sibling".equals(selectable) || "siblingLeafOnly".equals(selectable))) {
- selectable = null;
- }
- if (selectable != null) {
- writer.writeText("'", null);
- writer.writeText(selectable, null);
- writer.writeText("'", null);
- } else {
- writer.writeText("false", null);
- }
- writer.writeText(",", null);
- // mutable = false
- writer.writeText("false", null);
- writer.writeText(",'", null);
- writer.writeText(ComponentUtil.findPage(treeNode).getFormId(facesContext), null);
- writer.writeText("',", null);
- if (treeNode.getChildCount() == 0
- || (selectable != null && !selectable.endsWith("LeafOnly"))) {
- boolean selected = treeState.isSelected(modelNode);
- writer.writeText(Boolean.toString(selected), null);
- if (LOG.isDebugEnabled()) {
- debuging += selected ? "S" : "-";
- }
- } else {
- writer.writeText("false", null);
- if (LOG.isDebugEnabled()) {
- debuging += "-";
- }
- if (treeState.isSelected(modelNode)) {
- LOG.warn("Ignore selected FolderNode in LeafOnly selection tree!");
- }
- }
- writer.writeText(",", null);
+ String label = (String) node.getAttributes().get(ATTR_LABEL);
+ int level = modelNode.getLevel();
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < level; i++) {
+ builder.append(" ");
- // marked
- boolean marked = treeState.isMarked(modelNode);
- writer.writeText(Boolean.toString(marked), null);
- writer.writeText(",", null);
-
- // expanded
- boolean expanded = treeState.isExpanded(modelNode);
- writer.writeText(Boolean.toString(expanded), null);
- if (LOG.isDebugEnabled()) {
- debuging += expanded ? "E" : "-";
- }
-
- writer.writeText(",", null);
-
- // required
- writer.writeText(Boolean.toString(root.isRequired()), null);
- writer.writeText(",", null);
-
- // disabled
- writer.writeText(ComponentUtil.getBooleanAttribute(treeNode, ATTR_DISABLED), null);
- writer.writeText(",", null);
-
- // resources
- writer.writeText("treeResourcesHelp,", null);
-
- // action link
- String actionLink =
- (String) treeNode.getAttributes().get(ATTR_ACTION_LINK);
- if (actionLink != null) {
- writer.writeText("'", null);
- writer.writeText(actionLink, null);
- writer.writeText("',", null);
- } else {
- writer.writeText("null,", null);
- }
+ }
+ LOG.debug(builder + "<div name=" + label + ">");
+ }
- // target
- String target = (String) treeNode.getAttributes().get(ATTR_TARGET);
- if (target != null) {
- writer.writeText("'", null);
- writer.writeText(target, null);
- writer.writeText("',", null);
- } else {
- writer.writeText("null,", null);
- }
+ private void encodeExpandedHidden(TobagoResponseWriter writer, UITreeNode node, String clientId, boolean expanded)
+ throws IOException {
+ writer.startElement(HtmlConstants.INPUT, node);
+ writer.writeAttribute(HtmlAttributes.TYPE, "hidden", null);
+ writer.writeNameAttribute(clientId + "-expanded");
+ writer.writeIdAttribute(clientId + "-expanded");
+ writer.writeAttribute(HtmlAttributes.VALUE, expanded, null);
+ writer.endElement(HtmlConstants.INPUT);
+ }
- // onclick
- String onclick = (String) treeNode.getAttributes().get(ATTR_ONCLICK);
- if (onclick != null) {
- writer.writeText("'", null);
- onclick = onclick.replaceAll("\\'", "\\\\'");
- writer.writeText(onclick, null);
- writer.writeText("',", null);
- } else {
- writer.writeText("null,", null);
- }
+ private void encodeMenuIcon(
+ FacesContext facesContext, TobagoResponseWriter writer, String treeId, String id, boolean expanded)
+ throws IOException {
+ String menuOpen = ResourceManagerUtil.getImageWithPath(facesContext, "image/treeMenuOpen.gif");
+ String menuClose = ResourceManagerUtil.getImageWithPath(facesContext, "image/treeMenuClose.gif");
+ String onclick = "new_tobagoTreeNodeToggle(this.parentNode, '" + treeId + "', null, null, '" + menuOpen + "', '" + menuClose + "')";
+ String src = expanded ? menuOpen : menuClose;
+ writer.startElement(IMG);
+ writer.writeClassAttribute("tobago-tree-menu-icon");
+ writer.writeIdAttribute(id + "-menuIcon");
+ writer.writeAttribute("src", src, null);
+ writer.writeAttribute("onclick", onclick, null);
+ writer.writeAttribute("alt", "", null);
+ writer.endElement(IMG);
+ }
- // parent
- if (jsParentClientId != null) {
- writer.writeText(jsParentClientId, null);
- } else {
- writer.writeText("null", null);
- }
- writer.writeText(",", null);
+ private void encodeIndent(
+ FacesContext facesContext, TobagoResponseWriter writer, boolean menuMode, List<Boolean> junctions)
+ throws IOException {
- // icon (not implemented)
- writer.writeText("null", null);
- writer.writeText(",", null);
-
- // open folder icon (not implemented)
- writer.writeText("null", null);
- writer.writeText(", ", null);
-
- // width
- writer.writeText("'", null);
- Integer width = null;
- HtmlStyleMap style = (HtmlStyleMap) root.getAttributes().get(ATTR_STYLE);
- if (style != null) {
- width = style.getInt("width");
- }
- if (width != null) {
- writer.writeText(width - 4, null); // fixme: 4
+ String blank = ResourceManagerUtil.getImageWithPath(facesContext, "image/blank.gif");
+ String perpendicular = ResourceManagerUtil.getImageWithPath(facesContext, "image/I.gif");
+
+ for (Boolean junction : junctions) {
+ writer.startElement(IMG);
+ writer.writeClassAttribute("tree-junction");
+ if (junction && !menuMode) {
+ writer.writeAttribute("src", perpendicular, null);
} else {
- writer.writeText("100%", null);
+ writer.writeAttribute("src", blank, null);
}
- writer.writeText("', ", null);
+ writer.endElement(IMG);
+ }
+ }
- // css class
- writer.writeText("'", null);
- if ("menu".equals(root.getMode())) { // todo: clean up: think about composition of the style-class names
- HtmlRendererUtil.addCssClass(treeNode, "tobago-treeNode-menu");
- if (marked) {
- HtmlRendererUtil.addCssClass(treeNode, "tobago-treeNode-marker");
- }
- }
- StringBuilder treeNodeClass = new StringBuilder((String) treeNode.getAttributes().get(ATTR_STYLE_CLASS));
- if (LOG.isDebugEnabled()) {
- LOG.debug("styleClass='" + treeNodeClass + "'");
- }
- writer.writeText(treeNodeClass, null);
- writer.writeText("', ", null);
+ private void encodeTreeJunction(
+ FacesContext facesContext, TobagoResponseWriter writer, String id, String treeId,
+ boolean showJunctions, boolean showRootJunction, boolean showRoot,
+ boolean expanded, boolean isFolder, int depth, boolean hasNextSibling) throws IOException {
+ if (!(!showJunctions
+ || !showRootJunction && depth == 0
+ || !showRootJunction && !showRoot && depth == 1)) {
+ writer.startElement(IMG);
+ writer.writeClassAttribute("tree-junction");
+ writer.writeIdAttribute(id + "-junction");
+
+ String gif = expanded
+ ? (depth == 0
+ ? "Rminus.gif"
+ : (hasNextSibling ? "Tminus.gif" : "Lminus.gif"))
+ : ((depth == 0)
+ ? "Rplus.gif"
+ : (hasNextSibling)
+ ? (isFolder ? "Tplus.gif" : "T.gif")
+ : (isFolder ? "Lplus.gif" : "L.gif")
+ );
+
+ String src = ResourceManagerUtil.getImageWithPath(facesContext, "image/" + gif);
+ writer.writeAttribute("src", src, null);
+ if (isFolder) {
+ writer.writeAttribute("onclick", createOnclickForToggle(facesContext, treeId), null);
+ }
+ writer.writeAttribute("alt", "", null);
+// } else if (( !this.hideRoot && depth >0 ) || (this.hideRoot && depth > 1)) {
+// str += '<img class="tree-junction" id="' + this.id
+// + '-junction" src="' + this.treeResources.getImage("blank.gif")
+// + '" alt="">';
+ writer.endElement(IMG);
+ }
+ }
- // css class label
- writer.writeText("'", null);
- if (marked) {
- writer.writeText("tobago-treeNode-marker", null);
+ private void encodeTreeIcons(
+ FacesContext facesContext, TobagoResponseWriter writer, String id, String treeId,
+ boolean showIcons, boolean expanded, boolean isFolder)
+ throws IOException {
+
+ if (showIcons) {
+ writer.startElement(IMG);
+ writer.writeClassAttribute("tree-icon");
+ writer.writeIdAttribute(id + "-icon");
+
+ String gif = isFolder
+ ? (expanded ? "openfoldericon.gif" : "foldericon.gif")
+ : "new.gif";
+
+ String src = ResourceManagerUtil.getImageWithPath(facesContext, "image/" + gif);
+ writer.writeAttribute("src", src, null);
+ if (isFolder) {
+ writer.writeAttribute("onclick", createOnclickForToggle(facesContext, treeId), null);
}
- writer.writeText("'", null);
+ writer.writeAttribute("alt", "", null);
+ writer.endElement(IMG);
+ }
+ }
+
+ private String createOnclickForToggle(FacesContext facesContext, String treeId) {
+ return "new_tobagoTreeNodeToggle(this.parentNode, '" + treeId + "', '"
+ + ResourceManagerUtil.getImageWithPath(facesContext, "image/openfoldericon.gif") + "', '"
+ + ResourceManagerUtil.getImageWithPath(facesContext, "image/foldericon.gif") + "', null, null)";
+ }
+
- writer.writeText(");\n", null);
/*
- if (jsParentClientId != null) { // if not the root node
- writer.writeText(" ", null);
- writer.writeText(jsParentClientId, null);
- writer.writeText(".add(", null);
- writer.writeText(jsClientId, null);
- writer.writeText(");\n", null);
- }
+ if (this.isFolder) {
+ str += '<img class="tree-icon" id="' + this.id + '-icon" '
+ + 'src="' + (this.expanded ? this.openIcon : this.icon) + ' " '
+ + 'onclick="toggle(this.parentNode, \'' + this.treeHiddenId
+ + '\', \'' + this.treeResources.getImage("openfoldericon.gif")
+ + '\', \'' + this.treeResources.getImage("foldericon.gif")
+ + '\')"'
+ + ' alt="">';
+ } else {
+ str += '<img class="tree-icon" id="' + this.id
+ + '-icon" src="' + this.treeResources.getImage("new.gif") + '" alt="">';
+ }
*/
- if (LOG.isDebugEnabled()) {
- LOG.debug(debuging);
+
+
+ private void encodeLabel(
+ TobagoResponseWriter writer, CommandRendererHelper helper, UITreeNode node, boolean marked, String treeId)
+ throws IOException {
+
+ writer.startElement(A);
+ if (marked) {
+ StyleClasses classes = new StyleClasses();
+ classes.addClass("treeNode", "marker");
+ writer.writeClassAttribute(classes);
+ }
+ String tip = (String) node.getAttributes().get(ATTR_TIP);
+ if (tip != null) {
+//XXX is needed? tip = StringEscapeUtils.escapeJavaScript(tip);
+ writer.writeAttribute("title", tip, null);
+ }
+ writer.writeAttribute("href", helper.getHref(), null);
+ writer.writeAttribute("onclick", helper.getOnclick(), null);
+ writer.writeAttribute("onfocus", "storeMarker(this.parentNode, '" + treeId + "')", null);
+ String label = (String) node.getAttributes().get(ATTR_LABEL);
+ if (label == null) {
+ LOG.warn("label == null");
+ }
+ writer.writeText(label, null);
+ writer.endElement(A);
+ }
+
+ @Override
+ public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
+
+ UITreeNode node = (UITreeNode) component;
+ UITree root = node.findTree();
+ MixedTreeModel mixedModel = root.getModel();
+ boolean isFolder = mixedModel.isFolder();
+
+ mixedModel.onEncodeEnd();
+
+ String id = node.getClientId(facesContext);
+
+ TobagoResponseWriter writer = (TobagoResponseWriter) facesContext.getResponseWriter();
+
+ if (isFolder) {
+ writer.endElement(DIV);
+ writer.writeComment("\nend of " + id + "-cont ");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ String label = (String) node.getAttributes().get(ATTR_LABEL);
+ int level = mixedModel.getDepth();
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < level; i++) {
+ builder.append(" ");
+
}
+ LOG.debug(builder + "</div> <!-- " + label + " -->");
}
}
+
}
+/*
+
+TreeNode.prototype.toString = function (depth, last) {
+ if (!depth) depth = 0;
+
+ var str = '';
+ if (! this.hideRoot || depth > 0) {
+ str += '<div id="' + this.id + '" class="' + this.cssClass + '" '
+ + 'style="width: ' + this.width + ';">';
+ if (this.mode == "menu") {
+ if (this.isFolder) {
+ // FIXME: change the icons when klick on the icon
+ str += '<img class="tobago-tree-menu-icon" id="' + this.id + '-menuIcon"'
+ + 'src="' + (this.expanded ? this.treeResources.getImage("treeMenuOpen.gif") : this.treeResources.getImage("treeMenuClose.gif")) + ' " '
+ + 'onclick="toggle(this.parentNode, \'' + this.treeHiddenId
+ + '\', null, null, \'' + this.treeResources.getImage("treeMenuOpen.gif")
+ + '\', \'' + this.treeResources.getImage("treeMenuClose.gif")
+ + '\')"'
+ + ' alt="">';
+ }
+ }
+ str += this.indent(depth, last);
+ if (!( this.hideJunctions
+ || this.hideRootJunction && depth == 0
+ || this.hideRootJunction && this.hideRoot && depth == 1)) {
+ str += '<img class="tree-junction" id="' + this.id
+ + '-junction" src="' + (this.expanded
+ ? ((depth == 0)
+ ? this.treeResources.getImage("Rminus.gif")
+ : (last)
+ ? this.treeResources.getImage("Lminus.gif")
+ : this.treeResources.getImage("Tminus.gif"))
+ : ((depth == 0)
+ ? this.treeResources.getImage("Rplus.gif")
+ : (last)
+ ? this.treeResources.getImage(this.isFolder ? "Lplus.gif" : "L.gif")
+ : this.treeResources.getImage(this.isFolder ? "Tplus.gif" : "T.gif"))
+ )
+ + '" onclick="toggle(this.parentNode, \'' + this.treeHiddenId
+ + '\', \'' + this.treeResources.getImage("openfoldericon.gif")
+ + '\', \'' + this.treeResources.getImage("foldericon.gif")
+ + '\')"'
+ + ' alt="">';
+ } else if (( !this.hideRoot && depth >0 ) || (this.hideRoot && depth > 1)) {
+ str += '<img class="tree-junction" id="' + this.id
+ + '-junction" src="' + this.treeResources.getImage("blank.gif")
+ + '" alt="">';
+ }
+ if (! this.hideIcons) {
+ if (this.isFolder) {
+ str += '<img class="tree-icon" id="' + this.id + '-icon" '
+ + 'src="' + (this.expanded ? this.openIcon : this.icon) + ' " '
+ + 'onclick="toggle(this.parentNode, \'' + this.treeHiddenId
+ + '\', \'' + this.treeResources.getImage("openfoldericon.gif")
+ + '\', \'' + this.treeResources.getImage("foldericon.gif")
+ + '\')"'
+ + ' alt="">';
+ } else {
+ str += '<img class="tree-icon" id="' + this.id
+ + '-icon" src="' + this.treeResources.getImage("new.gif") + '" alt="">';
+ }
+ }
+ if (this.selectable) {
+ var markIcon = '';
+ var markIconOnClickFunction = '';
+ if (this.selectable.match(/LeafOnly$/) && this.isFolder) {
+ markIcon = this.treeResources.getImage("1x1.gif");
+ } else {
+ if (this.selected) {
+ markIcon = this.treeResources.getImage("checked" + (this.disabled ? "Disabled" : "") + ".gif");
+ } else {
+ markIcon = this.treeResources.getImage("unchecked" + (this.disabled ? "Disabled" : "") + ".gif");
+ }
+ if (!this.disabled) {
+ markIconOnClickFunction
+ = 'onclick="toggleSelect(this.parentNode, \'' + this.treeHiddenId
+ + '\', \'' + this.treeResources.getImage("unchecked.gif")
+ + '\', \'' + this.treeResources.getImage("checked.gif")
+ + '\')"';
+ }
+ }
+
+ str += '<img class="tree-icon" id="' + this.id
+ + '-markIcon" src="' + markIcon + '" ' + markIconOnClickFunction + ' alt="">';
+ }
+ str += '<a class="' + this.cssClassLabel + '"';
+ if (this.tip) {
+ str += ' title="' + this.tip + '"';
+ }
+ if (!this.disabled) {
+ str += ' href="' + Tobago.EMPTY_HREF + '"'
+ + ' onclick="Tobago.Tree.onClick(this)"'
+ + ' ondblclick="Tobago.Tree.onDblClick(this)"'
+ + ' onfocus="' + this.onfocus + '"';
+ }
+ str += '>'
+ + this.label + '</a>';
+ str += '</div>';
+ }
+ if (this.isFolder) {
+ str += '<div id="' + this.id
+ + '-cont" style="display: '
+ + (this.expanded ? 'block' : 'none') + ';">';
+ for (var i=0; i<this.childNodes.length; ++i) {
+ var lastChild = i+1 == this.childNodes.length;
+ var n = this.childNodes[i];
+ str += n.toString(depth+1, lastChild);
+ }
+ str += '</div>';
+ }
+
+ return str;
+ };
+*/
\ No newline at end of file
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java Thu May 3 03:30:36 2007
@@ -174,6 +174,8 @@
HtmlRendererUtil.writeScriptLoader(facesContext, scripts, scriptTexts);
}
+ RenderUtil.encode(facesContext, root);
+
writer.endElement(HtmlConstants.DIV);
}
@@ -204,7 +206,9 @@
sb.append(" }\n");
sb.append(" };\n \n");
- sb.append(getNodesAsJavascript(facesContext, root));
+ sb.append("/* disabled!!! \n");
+
+// sb.append(getNodesAsJavascript(facesContext, root));
sb.append(" var treeDiv = document.getElementById('");
sb.append(clientId);
@@ -216,6 +220,8 @@
sb.append(rootNode);
sb.append(".initSelection();\n");
+
+ sb.append("disabled!!! */");
sb.append("}");
// return sb.toString();
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTag.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTag.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTag.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTag.java Thu May 3 03:30:36 2007
@@ -17,6 +17,7 @@
* limitations under the License.
*/
+import static org.apache.myfaces.tobago.TobagoConstants.ATTR_EXPANDED;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TIP;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TARGET;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_VALUE;
@@ -32,6 +33,7 @@
private String markup;
private String tip;
private String target;
+ private String expanded;
@Override
public String getComponentType() {
@@ -46,6 +48,7 @@
ComponentUtil.setMarkup(component, markup);
ComponentUtil.setStringProperty(component, ATTR_TIP, tip);
ComponentUtil.setStringProperty(component, ATTR_TARGET, target);
+ ComponentUtil.setBooleanProperty(component, ATTR_EXPANDED, expanded);
}
@Override
@@ -55,6 +58,7 @@
markup = null;
tip = null;
target = null;
+ expanded = null;
}
public String getValue() {
@@ -79,5 +83,13 @@
public void setTarget(String target) {
this.target = target;
+ }
+
+ public String getExpanded() {
+ return expanded;
+ }
+
+ public void setExpanded(String expanded) {
+ this.expanded = expanded;
}
}
Modified: myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTagDeclaration.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTagDeclaration.java (original)
+++ myfaces/tobago/trunk/sandbox/src/main/java/org/apache/myfaces/tobago/taglib/sandbox/TreeNodeTagDeclaration.java Thu May 3 03:30:36 2007
@@ -20,6 +20,8 @@
import org.apache.myfaces.tobago.apt.annotation.BodyContentDescription;
import org.apache.myfaces.tobago.apt.annotation.Tag;
import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
import org.apache.myfaces.tobago.taglib.decl.HasIdBindingAndRendered;
import org.apache.myfaces.tobago.taglib.decl.HasLabel;
import org.apache.myfaces.tobago.taglib.decl.HasValue;
@@ -31,6 +33,7 @@
/**
* Creates a tree node.
*/
+@SuppressWarnings({"ALL"})
@Tag(name = "treeNode")
@BodyContentDescription(anyTagOf = "<tcs:treeNode>* <tcs:treeNodeData>*")
@UIComponentTag(
@@ -38,4 +41,11 @@
rendererType = "TreeNode")
public interface TreeNodeTagDeclaration
extends HasIdBindingAndRendered, HasLabel, HasValue, HasMarkup, AbstractCommandTagDeclaration, HasTip, HasTarget {
+
+ /**
+ * Flag indicating if the subnodes are to be displayed.
+ */
+ @TagAttribute(type = String.class)
+ @UIComponentTagAttribute(type = "java.lang.Boolean")
+ void setExpanded(String expanded);
}
Modified: myfaces/tobago/trunk/sandbox/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/script/tobago-tree.js
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/script/tobago-tree.js?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/script/tobago-tree.js (original)
+++ myfaces/tobago/trunk/sandbox/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/script/tobago-tree.js Thu May 3 03:30:36 2007
@@ -843,6 +843,53 @@
}
}
+//////////////////////////////////////////////////////////////////////////////////////////
+function new_tobagoTreeNodeOnclick() {
+}
+
+function new_tobagoTreeNodeToggle(node, treeHiddenId, openFolderIcon, folderIcon, openMenuIcon, closeMenuIcon) {
+ LOG.debug("toggle("+node+", "+treeHiddenId+", " + openFolderIcon + ", " + folderIcon + ", " + openMenuIcon + ", " + closeMenuIcon + ")");
+ var content = document.getElementById(node.id + "-cont");
+ if (content) {
+ var expandedState = document.getElementById(node.id + '-expanded');
+ var icon = document.getElementById(node.id + '-icon');
+ var menuIcon = document.getElementById(node.id + '-menuIcon');
+ var junction = document.getElementById(node.id + '-junction');
+ var hidden = document.getElementById(treeHiddenId);
+ if (content.style.display == 'none') {
+ content.style.display = 'block';
+ if (icon) {
+ icon.src = openFolderIcon;
+ }
+ if (menuIcon) {
+ menuIcon.src = openMenuIcon;
+ }
+ if (junction) {
+ junction.src = junction.src.replace(/plus\./, "minus.");
+ }
+ hidden.value = hidden.value + new_nodeStateId(node) + ";" ;
+ expandedState.value = "true";
+ } else {
+ content.style.display = 'none';
+ if (icon) {
+ icon.src = folderIcon;
+ }
+ if (menuIcon) {
+ menuIcon.src = closeMenuIcon;
+ }
+ if (junction) {
+ junction.src = junction.src.replace(/minus\./, "plus.");
+ }
+ hidden.value = hidden.value.replace(";" + new_nodeStateId(node) + ";" , ";");
+ expandedState.value = "false";
+ }
+ }
+}
+
+function new_nodeStateId(node) {
+ // this must do the same as nodeStateId() in TreeRenderer.java
+ return node.id.substring(node.id.lastIndexOf(':') + 1);
+}
Modified: myfaces/tobago/trunk/sandbox/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/sandbox/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java?view=diff&rev=534781&r1=534780&r2=534781
==============================================================================
--- myfaces/tobago/trunk/sandbox/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java (original)
+++ myfaces/tobago/trunk/sandbox/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java Thu May 3 03:30:36 2007
@@ -22,8 +22,6 @@
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.List;
-import org.apache.myfaces.tobago.model.TreeModel;
-
public class TreeModelUnitTest extends TestCase {
private DefaultMutableTreeNode tree;
@@ -64,6 +62,46 @@
assertEquals("Sports", "_0_0", pathIndexList.get(1));
assertEquals("Astronomy", "_0_2_2", pathIndexList.get(6));
assertEquals("Games", "_0_4", pathIndexList.get(10));
+ }
+
+ /*
+ cat
+ sport
+ /sport
+ movies
+ /movies
+ science
+ geo
+ /geo
+ math
+ /math
+ astro
+ edu
+ /edu
+ pict
+ /pict
+ /astro
+ music
+ /music
+ games
+ /games
+ /cat
+ */
+ public void testDoublePathIndexList() {
+ TreeModel model = new TreeModel(tree);
+ List<TreeModel.Tag> list = model.getDoublePathIndexList();
+ assertEquals("Count", 22, list.size());
+ assertEquals("Root", "_0", list.get(0).getName());
+ assertEquals("Root", "_0", list.get(21).getName());
+ assertEquals("Sports", "_0_0", list.get(1).getName());
+ assertEquals("Sports", "_0_0", list.get(2).getName());
+ assertEquals("Astronomy", "_0_2_2", list.get(10).getName());
+ assertEquals("Astronomy", "_0_2_2", list.get(15).getName());
+ assertEquals("Games", "_0_4", list.get(19).getName());
+ assertEquals("Games", "_0_4", list.get(20).getName());
+
+ assertTrue("Astronomy", list.get(10).isStart());
+ assertFalse("Astronomy", list.get(15).isStart());
}
public void testParentPathIndex() {