You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/09/05 23:30:23 UTC
svn commit: r1165419 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/corelib/components/
main/java/org/apache/tapestry5/tree/ main/resources/org/apache/tapestry5/
test/groovy/org/apache/tapestry5/integration/app1/ test/...
Author: hlship
Date: Mon Sep 5 21:30:22 2011
New Revision: 1165419
URL: http://svn.apache.org/viewvc?rev=1165419&view=rev
Log:
TAP5-1629: A Tree component that does not have a selection model bound should not track selections on the client or server
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/StuffValueEncoder.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.tml
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeSelectionModel.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/TreeSelectionModel.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.css
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.js
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeDemo.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java Mon Sep 5 21:30:22 2011
@@ -14,12 +14,8 @@
package org.apache.tapestry5.corelib.components;
-import java.util.Arrays;
-import java.util.List;
-
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.*;
-import org.apache.tapestry5.corelib.internal.InternalFormSupport;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.func.F;
import org.apache.tapestry5.func.Flow;
@@ -31,17 +27,22 @@ import org.apache.tapestry5.runtime.Rend
import org.apache.tapestry5.runtime.RenderQueue;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.apache.tapestry5.tree.*;
+import org.slf4j.Logger;
+
+import java.util.List;
/**
* A component used to render a recursive tree structure, with expandable/collapsable/selectable nodes. The data that is displayed
* by the component is provided as a {@link TreeModel}. A secondary model, the {@link TreeExpansionModel}, is used
- * to track which nodes have been expanded. The {@link TreeSelectionModel} is used to track node selections.
+ * to track which nodes have been expanded. The optional {@link TreeSelectionModel} is used to track node selections (as currently
+ * implemented, only leaf nodes may be selected).
+ * <p/>
* The Tree component uses special tricks to support recursive rendering of the Tree as necessary.
- *
+ *
* @since 5.3
*/
@SuppressWarnings(
-{ "rawtypes", "unchecked", "unused" })
+ {"rawtypes", "unchecked", "unused"})
@Events({EventConstants.NODE_SELECTED, EventConstants.NODE_UNSELECTED})
public class Tree
{
@@ -78,12 +79,13 @@ public class Tree
private TreeExpansionModel expansionModel;
/**
- * Used to control the Tree's selections. By default, a persistent field inside the Tree
- * component stores a {@link DefaultTreeSelectionModel}. This parameter may be bound when more
- * control over the implementation of the selection model, or how it is stored, is
- * required.
+ * Used to control the Tree's selections. When this parameter is bound, then the client-side Tree
+ * will track what is selected or not selected, and communicate this (via Ajax requests) up to
+ * the server, where it will be recorded into the model. On the client-side, the Tree component will
+ * add or remove the {@code t-selected-leaf-node-label} CSS class from {@code span.t-tree-label}
+ * for the node.
*/
- @Parameter(allowNull = false, value = "defaultTreeSelectionModel")
+ @Parameter
private TreeSelectionModel selectionModel;
/**
@@ -111,9 +113,6 @@ public class Tree
@Persist
private TreeExpansionModel defaultTreeExpansionModel;
- @Persist
- private TreeSelectionModel defaultTreeSelectionModel;
-
private static RenderCommand RENDER_CLOSE_TAG = new RenderCommand()
{
public void render(MarkupWriter writer, RenderQueue queue)
@@ -130,15 +129,16 @@ public class Tree
}
};
+ @Inject
+ private Logger logger;
+
/**
* Renders a single node (which may be the last within its containing node).
* This is a mix of immediate rendering, and queuing up various Blocks and Render commands
* to do the rest. May recursively render child nodes of the active node.
- *
- * @param node
- * to render
- * @param isLast
- * if true, add "t-last" attribute to the LI element
+ *
+ * @param node to render
+ * @param isLast if true, add "t-last" attribute to the LI element
* @return command to render the node
*/
private RenderCommand toRenderCommand(final TreeNode node, final boolean isLast)
@@ -170,10 +170,16 @@ public class Tree
String clientId = jss.allocateClientId(resources);
- JSONObject spec = new JSONObject("clientId", clientId);
+ JSONObject spec = new JSONObject("clientId", clientId);
e.attribute("id", clientId);
+ logger.info(String.format("Selection model for %s is %s.",
+ resources.getCompleteId(),
+ selectionModel));
+
+ spec.put("leaf", node.isLeaf());
+
if (hasChildren)
{
Link expandChildren = resources.createEventLink("expandChildren", node.getId());
@@ -181,17 +187,31 @@ public class Tree
Link markCollapsed = resources.createEventLink("markCollapsed", node.getId());
spec.put("expandChildrenURL", expandChildren.toString())
- .put( "markExpandedURL", markExpanded.toString())
+ .put("markExpandedURL", markExpanded.toString())
.put("markCollapsedURL", markCollapsed.toString());
if (expanded)
spec.put("expanded", true);
- }
- else
+ } else
{
- Link toggleLeaf = resources.createEventLink("toggleLeaf", node.getId());
-
- spec.put("toggleLeafURL", toggleLeaf.toString());
+ if (selectionModel != null)
+ {
+ // May need to address this in the future; in other tree implementations I've constructed,
+ // folders are selectable, and selections even propagate up and down the tree.
+
+ Link selectLeaf = resources.createEventLink("select", node.getId());
+
+ spec.put("selectURL", selectLeaf.toString());
+ if (selectionModel.isSelected(node))
+ {
+ spec.put("selected", true);
+ }
+
+ logger.info(String.format("%s rendered node %s as selectable", resources.getCompleteId(), node.getId()));
+ } else
+ {
+ logger.info(String.format("%s rendered node %s as NOT selectable", resources.getCompleteId(), node.getId()));
+ }
}
jss.addInitializerCall("treeNode", spec);
@@ -204,6 +224,7 @@ public class Tree
queue.push(RENDER_CLOSE_TAG); // li
if (expanded)
+
{
queue.push(new RenderNodes(node.getChildren()));
}
@@ -213,10 +234,14 @@ public class Tree
queue.push(RENDER_LABEL_SPAN);
}
- };
+ }
+
+ ;
}
- /** Renders an <ul> element and renders each node recursively inside the element. */
+ /**
+ * Renders an <ul> element and renders each node recursively inside the element.
+ */
private class RenderNodes implements RenderCommand
{
private final Flow<TreeNode> nodes;
@@ -243,6 +268,7 @@ public class Tree
}
});
}
+
}
public String getContainerClass()
@@ -273,32 +299,31 @@ public class Tree
return new JSONObject();
}
- Object onToggleLeaf(String nodeId)
+ Object onSelect(String nodeId, @RequestParameter("t:selected") boolean selected)
{
TreeNode node = model.getById(nodeId);
String event;
- if(selectionModel.isSelected(node))
- {
- selectionModel.unselect(node);
-
- event = EventConstants.NODE_UNSELECTED;
- }
- else
+ if (selected)
{
selectionModel.select(node);
event = EventConstants.NODE_SELECTED;
+ } else
+ {
+ selectionModel.unselect(node);
+
+ event = EventConstants.NODE_UNSELECTED;
}
CaptureResultCallback<Object> callback = CaptureResultCallback.create();
- resources.triggerEvent(event, new Object [] { nodeId }, callback);
+ resources.triggerEvent(event, new Object[]{nodeId}, callback);
final Object result = callback.getResult();
- if(result != null)
+ if (result != null)
return result;
return new JSONObject();
@@ -312,14 +337,6 @@ public class Tree
return defaultTreeExpansionModel;
}
- public TreeSelectionModel getDefaultTreeSelectionModel()
- {
- if(defaultTreeSelectionModel == null)
- defaultTreeSelectionModel = new DefaultTreeSelectionModel();
-
- return defaultTreeSelectionModel;
- }
-
/**
* Returns the actual {@link TreeExpansionModel} in use for this Tree component,
* as per the expansionModel parameter. This is often, but not always, the same
@@ -345,7 +362,9 @@ public class Tree
return new RenderNodes(model.getRootNodes());
}
- /** Clears the tree's {@link TreeExpansionModel}. */
+ /**
+ * Clears the tree's {@link TreeExpansionModel}.
+ */
public void clearExpansions()
{
expansionModel.clear();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeSelectionModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeSelectionModel.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeSelectionModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeSelectionModel.java Mon Sep 5 21:30:22 2011
@@ -20,7 +20,7 @@ import org.apache.tapestry5.ioc.internal
import java.util.Set;
/**
- * Default implementation of {@link TreeSelectionModel}.
+ * Default implementation of {@link TreeSelectionModel}. This is simply a wrapper around a set of node ids.
*
* @param <T> type of node
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/TreeSelectionModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/TreeSelectionModel.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/TreeSelectionModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/tree/TreeSelectionModel.java Mon Sep 5 21:30:22 2011
@@ -15,15 +15,16 @@
package org.apache.tapestry5.tree;
/**
- * Tracks which nodes of a {@link TreeModel} are currently selected. The {@linkplain DefaultTreeExpansionModel default
+ * Tracks which <em>leaf</em> nodes of a {@link TreeModel} are currently selected. The {@linkplain DefaultTreeSelectionModel default
* implementation} simply stores a set of {@linkplain TreeNode#getId() unique node
- * ids} to identify expanded nodes. The expansion model is updated whenever folders are expanded or
- * collapsed on the client side.
+ * ids} to identify selected nodes. The selection model is updated whenever the user clicks on the label for a leaf node.
+ * <p/>
+ * In the future, new methods may be added that will support selection of folders as well as leafs, and define the rules for
+ * how selections and de-selections propagate down to children or up to parents.
*
* @param <T> type of node
- *
- * @since 5.3
* @see org.apache.tapestry5.corelib.components.Tree
+ * @since 5.3
*/
public interface TreeSelectionModel<T>
{
@@ -49,6 +50,8 @@ public interface TreeSelectionModel<T>
*/
void unselect(TreeNode<T> node);
- /** Clears the selection. */
+ /**
+ * Clears the selection.
+ */
void clear();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.css?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.css Mon Sep 5 21:30:22 2011
@@ -51,6 +51,10 @@ SPAN.t-tree-icon.t-leaf-node {
background-position: -32px -16px;
}
+SPAN.t-tree-label.t-selectable {
+ cursor: pointer;
+}
+
SPAN.t-tree-label.t-selected-leaf-node-label {
font-weight: bold;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.js?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tree.js Mon Sep 5 21:30:22 2011
@@ -76,14 +76,14 @@ T5.extendInitializers(function() {
}
function initializer(spec) {
- var loaded = spec.expanded;
+ var loaded = spec.expanded || spec.leaf;
var expanded = spec.expanded;
- var selected = false;
+ var loading = false;
if (expanded) {
$(spec.clientId).addClassName("t-tree-expanded")
}
- var loading = false;
+
function successHandler(reply) {
// Remove the Ajax load indicator
@@ -112,67 +112,29 @@ T5.extendInitializers(function() {
}
- function toggleLeafHandler(reply) {
- var response = reply.responseJSON;
-
- $(spec.clientId).update("");
-
- Tapestry.loadScriptsInReply(response, function() {
- loading = false;
- loaded = true;
- expanded = true;
- selected = !selected;
- });
- }
-
function doLoad() {
if (loading)
return;
loading = true;
- if (spec.expandChildrenURL) {
- $(spec.clientId).addClassName("t-empty-node");
- }
- else {
- $(spec.clientId).next("span.t-tree-label").addClassName("t-selected-leaf-node-label");
- }
- $(spec.clientId).update("<span class='t-ajax-wait'/>");
-
- var requestURL = spec.expandChildrenURL ? spec.expandChildrenURL : spec.toggleLeafURL;
+ $(spec.clientId).addClassName("t-empty-node");
- var handler = spec.expandChildrenURL ? successHandler : toggleLeafHandler;
-
- Tapestry.ajaxRequest(requestURL, handler);
+ $(spec.clientId).update("<span class='t-ajax-wait'/>");
+ Tapestry.ajaxRequest(spec.expandChildrenURL, successHandler);
}
$(spec.clientId).observe("click", function(event) {
event.stop();
- if (!loaded) {
+ if (!loaded && spec.expandChildrenURL) {
doLoad();
return;
}
- if (spec.toggleLeafURL) {
- var label = $(spec.clientId).next("span.t-tree-label");
-
- if (selected) {
- label.removeClassName("t-selected-leaf-node-label");
- }
- else {
- label.addClassName("t-selected-leaf-node-label");
- }
- selected = !selected;
-
- Tapestry.ajaxRequest(spec.toggleLeafURL, {});
-
- return;
- }
-
// Children have been loaded, just a matter of toggling
// between showing or hiding the children.
@@ -182,10 +144,48 @@ T5.extendInitializers(function() {
var url = expanded ? spec.markCollapsedURL : spec.markExpandedURL;
+ // Send request, ignore response.
+
Tapestry.ajaxRequest(url, {});
expanded = !expanded;
});
+
+
+ if (spec.selectURL) {
+
+ var selected = spec.selected;
+
+ var label = $(spec.clientId).next("span.t-tree-label");
+
+ label.addClassName("t-selectable");
+
+ if (selected) {
+ label.addClassName("t-selected-leaf-node-label");
+ }
+
+ label.observe("click", function(event) {
+ event.stop();
+
+
+ selected = ! selected;
+
+
+ if (selected) {
+ label.addClassName("t-selected-leaf-node-label");
+ }
+ else {
+ label.removeClassName("t-selected-leaf-node-label");
+ }
+
+ // TODO: In the future, we may want to select children when a parent is selected,
+ // or vice-versa. There's a lot of use cases. These will be directed from new methods
+ // on the TreeSelectionModel interface and encoded into the response. For now,
+ // the response is empty and ignored.
+
+ Tapestry.ajaxRequest(spec.selectURL, { parameters: { "t:selected": selected } });
+ });
+ }
}
return {
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy Mon Sep 5 21:30:22 2011
@@ -20,7 +20,8 @@ import org.testng.annotations.Test
class TreeTests extends SeleniumTestCase
{
@Test
- void basics() {
+ void basics()
+ {
openBaseURL()
@@ -33,7 +34,7 @@ class TreeTests extends SeleniumTestCase
sleep 25 // See if that helps with the intermittent test suite failures on the CI server
- waitForAjaxRequestsToComplete PAGE_LOAD_TIMEOUT
+ waitForAjaxRequestsToComplete PAGE_LOAD_TIMEOUT
assertTextPresent "Board Games"
@@ -41,7 +42,7 @@ class TreeTests extends SeleniumTestCase
click "//div[@class='t-tree-container test-hook']/ul/li[2]/ul/li/span[@class='t-tree-icon']"
//Assert the leafs are displayed
- waitForAjaxRequestsToComplete PAGE_LOAD_TIMEOUT
+ waitForAjaxRequestsToComplete PAGE_LOAD_TIMEOUT
clickAndWait "link=Redraw"
@@ -49,13 +50,14 @@ class TreeTests extends SeleniumTestCase
}
@Test
- void selectLeaf() {
+ void select_node()
+ {
openBaseURL()
- clickAndWait "link=Tree Component Demo"
+ clickAndWait "link=Tree Component Selection Demo"
- clickAndWait "link=clear expansions"
+ clickAndWait "link=clear all"
click "//span[@class='t-tree-icon']"
@@ -63,7 +65,14 @@ class TreeTests extends SeleniumTestCase
assertTextPresent "Oscar", "Gromit", "Max", "Roger", "Cooper"
- click "//span[@class='t-tree-icon t-leaf-node']"
+ // Click the first selectable node, probably Oscar
+ click "css=span.t-selectable"
+
+ waitForCSSSelectedElementToAppear "span.t-selected-leaf-node-label"
+
+ clickAndWait "link=Redraw"
+
+ // Make sure it is still there after a redraw
waitForCSSSelectedElementToAppear "span.t-selected-leaf-node-label"
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java Mon Sep 5 21:30:22 2011
@@ -14,11 +14,14 @@
package org.apache.tapestry5.integration.app1;
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.tree.DefaultTreeModel;
+import org.apache.tapestry5.tree.TreeModel;
+
import java.util.List;
import java.util.UUID;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-
public class Stuff
{
public final String uuid = UUID.randomUUID().toString();
@@ -64,4 +67,29 @@ public class Stuff
return null;
}
+
+ public static final Stuff ROOT = new Stuff("<root>");
+
+ static
+ {
+ ROOT.addChild(new Stuff("Pets").addChildrenNamed("Oscar", "Gromit", "Max", "Roger", "Cooper"));
+ ROOT.addChild(new Stuff("Games").addChild(
+ new Stuff("Board Games").addChildrenNamed("Settlers of Catan", "Agricola", "Ra", "Risk", "Dvonn"))
+ .addChild(new Stuff("Card Games").addChildrenNamed("Magic the Gathering", "Dominion", "Mu")));
+
+ Stuff numbers = new Stuff("Numbers");
+
+ for (int i = 0; i < 10000; i++)
+ {
+ numbers.addChild(new Stuff(Integer.toString(i)));
+ }
+
+ ROOT.addChild(numbers);
+ }
+
+ public static TreeModel<Stuff> createTreeModel() {
+ ValueEncoder<Stuff> encoder = new StuffValueEncoder();
+
+ return new DefaultTreeModel<Stuff>(encoder, new StuffTreeModelAdapter(), Stuff.ROOT.children);
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/StuffValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/StuffValueEncoder.java?rev=1165419&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/StuffValueEncoder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/StuffValueEncoder.java Mon Sep 5 21:30:22 2011
@@ -0,0 +1,16 @@
+package org.apache.tapestry5.integration.app1;
+
+import org.apache.tapestry5.ValueEncoder;
+
+public class StuffValueEncoder implements ValueEncoder<Stuff>
+{
+ public String toClient(Stuff value)
+ {
+ return value.uuid;
+ }
+
+ public Stuff toValue(String clientValue)
+ {
+ return Stuff.ROOT.seek(clientValue);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Mon Sep 5 21:30:22 2011
@@ -70,6 +70,8 @@ public class Index
new Item("TreeDemo", "Tree Component Demo", "Demo of Tree Component"),
+ new Item("TreeSelectionDemo", "Tree Component Selection Demo", "Demo of Selection with Tree Component"),
+
new Item("InvalidExpressionInDynamicTemplate", "Invalid Dynamic Expression",
"Invalid expression in a Dynamic Template"),
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeDemo.java?rev=1165419&r1=1165418&r2=1165419&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeDemo.java Mon Sep 5 21:30:22 2011
@@ -14,12 +14,9 @@
package org.apache.tapestry5.integration.app1.pages;
-import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.corelib.components.Tree;
import org.apache.tapestry5.integration.app1.Stuff;
-import org.apache.tapestry5.integration.app1.StuffTreeModelAdapter;
-import org.apache.tapestry5.tree.DefaultTreeModel;
import org.apache.tapestry5.tree.TreeModel;
public class TreeDemo
@@ -27,45 +24,14 @@ public class TreeDemo
@InjectComponent
private Tree tree;
- private static final Stuff rootStuff = new Stuff("<root>");
-
- static
- {
- rootStuff.addChild(new Stuff("Pets").addChildrenNamed("Oscar", "Gromit", "Max", "Roger", "Cooper"));
- rootStuff.addChild(new Stuff("Games").addChild(
- new Stuff("Board Games").addChildrenNamed("Settlers of Catan", "Agricola", "Ra", "Risk", "Dvonn"))
- .addChild(new Stuff("Card Games").addChildrenNamed("Magic the Gathering", "Dominion", "Mu")));
-
- Stuff numbers = new Stuff("Numbers");
-
- for (int i = 0; i < 10000; i++)
- {
- numbers.addChild(new Stuff(Integer.toString(i)));
- }
-
- rootStuff.addChild(numbers);
- }
-
public TreeModel<Stuff> getStuffModel()
{
- ValueEncoder<Stuff> encoder = new ValueEncoder<Stuff>()
- {
- public String toClient(Stuff value)
- {
- return value.uuid;
- }
-
- public Stuff toValue(String clientValue)
- {
- return rootStuff.seek(clientValue);
- }
- };
-
- return new DefaultTreeModel<Stuff>(encoder, new StuffTreeModelAdapter(), rootStuff.children);
+ return Stuff.createTreeModel();
}
void onActionFromClear()
{
tree.clearExpansions();
}
+
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.java?rev=1165419&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.java Mon Sep 5 21:30:22 2011
@@ -0,0 +1,88 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Log;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.corelib.components.Tree;
+import org.apache.tapestry5.integration.app1.Stuff;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.util.Stack;
+import org.apache.tapestry5.tree.DefaultTreeSelectionModel;
+import org.apache.tapestry5.tree.TreeModel;
+import org.apache.tapestry5.tree.TreeNode;
+import org.apache.tapestry5.tree.TreeSelectionModel;
+
+import java.util.List;
+
+/**
+ *
+ */
+public class TreeSelectionDemo
+{
+ @Persist
+ private TreeSelectionModel selectionModel;
+
+ @InjectComponent
+ private Tree tree;
+
+ @Property
+ private Stuff selectedObject;
+
+ void onActionFromClearAll()
+ {
+ tree.getExpansionModel().clear();
+ tree.getSelectionModel().clear();
+ }
+
+ public TreeModel<Stuff> getStuffModel()
+ {
+ return Stuff.createTreeModel();
+ }
+
+ @Log
+ public TreeSelectionModel<Stuff> getSelectionModel()
+ {
+ if (selectionModel == null)
+ {
+ selectionModel = new DefaultTreeSelectionModel();
+ }
+
+ return selectionModel;
+ }
+
+ public List<Stuff> getSelectedObjects()
+ {
+
+ List<Stuff> result = CollectionFactory.newList();
+ Stack<TreeNode<Stuff>> queue = CollectionFactory.newStack();
+
+ TreeModel<Stuff> model = getStuffModel();
+ TreeSelectionModel<Stuff> selectionModel = getSelectionModel();
+
+ for (TreeNode<Stuff> root : model.getRootNodes())
+ {
+ queue.push(root);
+ }
+
+
+ while (!queue.isEmpty())
+ {
+ TreeNode<Stuff> current = queue.pop();
+
+ if (selectionModel.isSelected(current))
+ {
+ result.add(current.getValue());
+ }
+
+ for (TreeNode<Stuff> child : current.getChildren())
+ {
+ queue.push(child);
+ }
+ }
+
+
+ return result;
+ }
+
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.tml?rev=1165419&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeSelectionDemo.tml Mon Sep 5 21:30:22 2011
@@ -0,0 +1,28 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
+
+ <h1>Tree Selection Demo</h1>
+
+ <t:tree class="test-hook" t:id="tree" model="stuffModel" selectionModel="selectionModel"/>
+
+ <p>
+ [
+ <t:pagelink page="treeSelectionDemo">Redraw</t:pagelink>
+ ]
+ [
+ <t:actionlink t:id="clearAll">clear all</t:actionlink>
+ ]
+ </p>
+
+ <h2>Selections</h2>
+
+ <ul>
+
+ <t:loop source="selectedObjects" value="selectedObject">
+
+ <li>${selectedObject.name}</li>
+ </t:loop>
+
+ </ul>
+
+
+</t:border>
\ No newline at end of file