You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2012/02/05 23:02:55 UTC
[9/9] WICKET-4240 moved old tree together into extensions
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/BaseTree.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/BaseTree.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/BaseTree.java
new file mode 100644
index 0000000..f96514a
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/BaseTree.java
@@ -0,0 +1,478 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.IClusterable;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.IAjaxLink;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * An abstract Tree component that should serve as a base for custom Tree Components.
+ *
+ * It has one abstract method - {@link #newNodeComponent(String, IModel)} that needs to be
+ * overridden.
+ *
+ * @author Matej Knopp
+ */
+@Deprecated
+public abstract class BaseTree extends AbstractTree
+{
+ /**
+ * Construct.
+ *
+ * @param id
+ */
+ public BaseTree(String id)
+ {
+ this(id, null);
+ }
+
+ /**
+ * Construct.
+ *
+ * @param id
+ * @param model
+ */
+ public BaseTree(String id, IModel<? extends TreeModel> model)
+ {
+ super(id, model);
+ }
+
+ // default stylesheet resource
+ private static final ResourceReference CSS = new PackageResourceReference(BaseTree.class,
+ "res/base-tree.css");
+
+ /**
+ * Returns the stylesheet reference
+ *
+ * @return stylesheet reference
+ */
+ protected ResourceReference getCSS()
+ {
+ return CSS;
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String JUNCTION_LINK_ID = "junctionLink";
+ private static final String NODE_COMPONENT_ID = "nodeComponent";
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.AbstractTree#populateTreeItem(org.apache.wicket.markup.html.WebMarkupContainer,
+ * int)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void populateTreeItem(WebMarkupContainer item, int level)
+ {
+ // add junction link
+ Object node = item.getDefaultModelObject();
+ Component junctionLink = newJunctionLink(item, JUNCTION_LINK_ID, node);
+ junctionLink.add(new JunctionBorder(node, level));
+ item.add(junctionLink);
+
+ // add node component
+ Component nodeComponent = newNodeComponent(NODE_COMPONENT_ID,
+ (IModel<Object>)item.getDefaultModel());
+ item.add(nodeComponent);
+
+ // add behavior that conditionally adds the "selected" CSS class name
+ item.add(new Behavior()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onComponentTag(Component component, ComponentTag tag)
+ {
+ Object node = component.getDefaultModelObject();
+ String klass = getItemClass(node);
+ if (!Strings.isEmpty(klass))
+ {
+ CharSequence oldClass = tag.getAttribute("class");
+ if (Strings.isEmpty(oldClass))
+ {
+ tag.put("class", klass);
+ }
+ else
+ {
+ tag.put("class", oldClass + " " + klass);
+ }
+ }
+ }
+ });
+ }
+
+ protected String getItemClass(Object node)
+ {
+ if (getTreeState().isNodeSelected(node))
+ {
+ return getSelectedClass();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the class name that will be added to row's CSS class for selected rows
+ *
+ * @return CSS class name
+ */
+ protected String getSelectedClass()
+ {
+ return "selected";
+ }
+
+ /**
+ * Creates a new component for the given TreeNode.
+ *
+ * @param id
+ * component ID
+ * @param model
+ * model that returns the node
+ * @return component for node
+ */
+ protected abstract Component newNodeComponent(String id, IModel<Object> model);
+
+ /**
+ * Returns whether the provided node is last child of it's parent.
+ *
+ * @param node
+ * The node
+ * @return whether the provided node is the last child
+ */
+ private boolean isNodeLast(Object node)
+ {
+ Object parent = getParentNode(node);
+ if (parent == null)
+ {
+ return true;
+ }
+ else
+ {
+ return getChildAt(parent, getChildCount(parent) - 1).equals(node);
+ }
+ }
+
+ /**
+ * Class that wraps a link (or span) with a junction table cells.
+ *
+ * @author Matej Knopp
+ */
+ private class JunctionBorder extends Behavior
+ {
+ private static final long serialVersionUID = 1L;
+
+ // TODO this field is not serializable but nested inside an serializable component
+ private final Object node;
+ private final int level;
+
+ /**
+ * Construct.
+ *
+ * @param node
+ * @param level
+ */
+ public JunctionBorder(Object node, int level)
+ {
+ this.node = node;
+ this.level = level;
+ }
+
+ /**
+ * @see org.apache.wicket.behavior.AbstractBehavior#onRendered(org.apache.wicket.Component)
+ */
+ @Override
+ public void afterRender(final Component component)
+ {
+ component.getResponse().write("</td>");
+ }
+
+ /**
+ * @see org.apache.wicket.behavior.Behavior#beforeRender(org.apache.wicket.Component)
+ */
+ @Override
+ public void beforeRender(final Component component)
+ {
+ Response response = component.getResponse();
+ Object parent = getParentNode(node);
+
+ CharSequence classes[] = new CharSequence[level];
+ for (int i = 0; i < level; ++i)
+ {
+ if (parent == null || isNodeLast(parent))
+ {
+ classes[i] = "spacer";
+ }
+ else
+ {
+ classes[i] = "line";
+ }
+
+ parent = getParentNode(parent);
+ }
+
+ for (int i = level - 1; i >= 0; --i)
+ {
+ response.write("<td class=\"" + classes[i] + "\"><span></span></td>");
+ }
+
+ if (isNodeLast(node))
+ {
+ response.write("<td class=\"half-line\">");
+ }
+ else
+ {
+ response.write("<td class=\"line\">");
+ }
+ }
+ }
+
+ /**
+ * Creates the junction link for given node. Also (optionally) creates the junction image. If
+ * the node is a leaf (it has no children), the created junction link is non-functional.
+ *
+ * @param parent
+ * parent component of the link
+ * @param id
+ * wicket:id of the component
+ * @param node
+ * tree node for which the link should be created.
+ * @return The link component
+ */
+ protected Component newJunctionLink(MarkupContainer parent, final String id, final Object node)
+ {
+ final MarkupContainer junctionLink;
+
+ if (isLeaf(node) == false)
+ {
+ junctionLink = newLink(id, new ILinkCallback()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ if (isNodeExpanded(node))
+ {
+ getTreeState().collapseNode(node);
+ }
+ else
+ {
+ getTreeState().expandNode(node);
+ }
+ onJunctionLinkClicked(target, node);
+
+ if (target != null)
+ {
+ updateTree(target);
+ }
+ }
+ });
+ junctionLink.add(new Behavior()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onComponentTag(Component component, ComponentTag tag)
+ {
+ if (isNodeExpanded(node))
+ {
+ tag.put("class", "junction-open");
+ }
+ else
+ {
+ tag.put("class", "junction-closed");
+ }
+ }
+ });
+ }
+ else
+ {
+ junctionLink = new WebMarkupContainer(id)
+ {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag)
+ */
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ super.onComponentTag(tag);
+ tag.setName("span");
+ tag.put("class", "junction-corner");
+ }
+ };
+
+ }
+
+ return junctionLink;
+ }
+
+ /**
+ * Callback function called after user clicked on an junction link. The node has already been
+ * expanded/collapsed (depending on previous status).
+ *
+ * @param target
+ * Request target - may be null on non-ajax call
+ *
+ * @param node
+ * Node for which this callback is relevant
+ */
+ protected void onJunctionLinkClicked(AjaxRequestTarget target, Object node)
+ {
+ }
+
+ /**
+ * Helper class for calling an action from a link.
+ *
+ * @author Matej Knopp
+ */
+ public interface ILinkCallback extends IAjaxLink, IClusterable
+ {
+ }
+
+ /**
+ * Creates a link of type specified by current linkType. When the links is clicked it calls the
+ * specified callback.
+ *
+ * @param id
+ * The component id
+ * @param callback
+ * The link call back. {@code null} is passed for its onClick(AjaxRequestTarget) for
+ * {@link LinkType#REGULAR} and eventually for {@link LinkType#AJAX_FALLBACK}.
+ * @return The link component
+ */
+ public MarkupContainer newLink(String id, final ILinkCallback callback)
+ {
+ if (getLinkType() == LinkType.REGULAR)
+ {
+ return new Link<Void>(id)
+ {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see org.apache.wicket.markup.html.link.Link#onClick()
+ */
+ @Override
+ public void onClick()
+ {
+ callback.onClick(null);
+ }
+ };
+ }
+ else if (getLinkType() == LinkType.AJAX)
+ {
+ return new AjaxLink<Void>(id)
+ {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see org.apache.wicket.ajax.markup.html.AjaxLink#onClick(org.apache.wicket.ajax.AjaxRequestTarget)
+ */
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ callback.onClick(target);
+ }
+ };
+ }
+ else
+ {
+ return new AjaxFallbackLink<Void>(id)
+ {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see org.apache.wicket.ajax.markup.html.AjaxFallbackLink#onClick(org.apache.wicket.ajax.AjaxRequestTarget)
+ */
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ callback.onClick(target);
+ }
+ };
+ }
+ }
+
+ /**
+ * Returns the current type of links on tree items.
+ *
+ * @return The link type
+ */
+ public LinkType getLinkType()
+ {
+ return linkType;
+ }
+
+ /**
+ * Sets the type of links on tree items. After the link type is changed, the whole tree must be
+ * rebuilt (call invalidateAll).
+ *
+ * @param linkType
+ * type of links
+ */
+ public void setLinkType(LinkType linkType)
+ {
+ if (this.linkType != linkType)
+ {
+ this.linkType = linkType;
+ }
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.AbstractTree#isForceRebuildOnSelectionChange()
+ */
+ @Override
+ protected boolean isForceRebuildOnSelectionChange()
+ {
+ return false;
+ }
+
+ @Override
+ public void renderHead(IHeaderResponse response)
+ {
+ super.renderHead(response);
+ ResourceReference css = getCSS();
+ if (css != null)
+ {
+ response.render(CssHeaderItem.forReference(css));
+ }
+
+ }
+
+ private LinkType linkType = LinkType.AJAX;
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java
index 34d0772..c46c05d 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java
@@ -32,9 +32,6 @@ import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.link.Link;
-import org.apache.wicket.markup.html.tree.AbstractTree;
-import org.apache.wicket.markup.html.tree.LinkType;
-import org.apache.wicket.markup.html.tree.WicketTreeModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.Response;
@@ -57,6 +54,7 @@ import org.apache.wicket.request.resource.ResourceReference;
*
* @author Matej Knopp
*/
+@Deprecated
public abstract class DefaultAbstractTree extends AbstractTree
{
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultTreeState.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultTreeState.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultTreeState.java
new file mode 100644
index 0000000..a26113a
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultTreeState.java
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.IClusterable;
+import org.apache.wicket.model.IDetachable;
+
+/**
+ * Default implementation of TreeState.
+ * <p>
+ * This implementation tries to be as lightweight as possible. By default all nodes are collapsed.
+ *
+ * @author Matej Knopp
+ */
+public class DefaultTreeState implements ITreeState, IClusterable, IDetachable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** Whether multiple selections can be done. */
+ private boolean allowSelectMultiple = false;
+
+ /** Tree state listeners. */
+ private final List<ITreeStateListener> listeners = new ArrayList<ITreeStateListener>(1);
+
+ /**
+ * set of nodes which are collapsed or expanded (depends on nodesCollapsed variable).
+ */
+ private final Set<Object> nodes = new HashSet<Object>();
+
+ /** Whether the nodes set should be treated as set of collapsed or expanded nodes. */
+ private boolean nodesCollapsed = false; // by default treat the node set as expanded nodes
+
+ /** Set selected nodes. */
+ private final Set<Object> selectedNodes = new HashSet<Object>();
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#addTreeStateListener(org.apache.wicket.extensions.markup.html.tree.ITreeStateListener)
+ */
+ @Override
+ public void addTreeStateListener(ITreeStateListener l)
+ {
+ if (listeners.contains(l) == false)
+ {
+ listeners.add(l);
+ }
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#collapseAll()
+ */
+ @Override
+ public void collapseAll()
+ {
+ if (nodes.isEmpty() && nodesCollapsed == false)
+ {
+ // all nodes are already collapsed, do nothing
+ }
+ else
+ {
+ // clear all nodes from the set and sets the nodes as expanded
+ nodes.clear();
+ nodesCollapsed = false;
+
+ for (ITreeStateListener listener : listeners)
+ listener.allNodesCollapsed();
+ }
+ }
+
+ @Override
+ public void collapseNode(Object node)
+ {
+ if (nodesCollapsed == true)
+ {
+ nodes.add(node);
+ }
+ else
+ {
+ nodes.remove(node);
+ }
+
+ for (ITreeStateListener listener : listeners)
+ listener.nodeCollapsed(node);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#expandAll()
+ */
+ @Override
+ public void expandAll()
+ {
+ if (nodes.isEmpty() && nodesCollapsed == true)
+ {
+ // all nodes are already expanded, do nothing
+ }
+ else
+ {
+ // clear node set and set nodes policy as collapsed
+ nodes.clear();
+ nodesCollapsed = true;
+
+ for (ITreeStateListener listener : listeners)
+ listener.allNodesExpanded();
+ }
+ }
+
+ @Override
+ public void expandNode(Object node)
+ {
+ if (nodesCollapsed == false)
+ {
+ nodes.add(node);
+ }
+ else
+ {
+ nodes.remove(node);
+ }
+
+ for (ITreeStateListener listener : listeners)
+ listener.nodeExpanded(node);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#getSelectedNodes()
+ */
+ @Override
+ public Collection<Object> getSelectedNodes()
+ {
+ return Collections.unmodifiableList(new ArrayList<Object>(selectedNodes));
+ }
+
+ protected void removeSelectedNodeSilent(Object node)
+ {
+ selectedNodes.remove(node);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#isAllowSelectMultiple()
+ */
+ @Override
+ public boolean isAllowSelectMultiple()
+ {
+ return allowSelectMultiple;
+ }
+
+ @Override
+ public boolean isNodeExpanded(Object node)
+ {
+ if (nodesCollapsed == false)
+ {
+ return nodes.contains(node);
+ }
+ else
+ {
+ return nodes.contains(node) == false;
+ }
+ }
+
+ @Override
+ public boolean isNodeSelected(Object node)
+ {
+ return selectedNodes.contains(node);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#removeTreeStateListener(org.apache.wicket.extensions.markup.html.tree.ITreeStateListener)
+ */
+ @Override
+ public void removeTreeStateListener(ITreeStateListener l)
+ {
+ listeners.remove(l);
+ }
+
+
+ /**
+ * If <code>node</code> is currently selected, it will be deselected and the
+ * <code>nodeUnselected</code> method will be called on all registered
+ * <code>ITreeStateListeners</code>.
+ *
+ * @param node
+ * the node to be deselected
+ */
+ private void deselectNode(Object node)
+ {
+ if (selectedNodes.remove(node))
+ {
+ for (ITreeStateListener listener : listeners.toArray(new ITreeStateListener[listeners.size()]))
+ {
+ listener.nodeUnselected(node);
+ }
+ }
+ }
+
+ /**
+ * Selects <code>node</code> and calls the <code>nodeSelected</code> method on all registered
+ * <code>ITreeStateListeners</code>. If <code>isAllowSelectMultiple</code> is <code>false</code>
+ * , any currently selected nodes are deselected.
+ *
+ * @param node
+ * the node to be selected
+ */
+ private void selectNode(Object node)
+ {
+ // if multiple selections are not allowed, deselect current selections
+ if (selectedNodes.size() > 0 && !isAllowSelectMultiple())
+ {
+ for (Object currentlySelectedNode : selectedNodes.toArray())
+ {
+ if (!currentlySelectedNode.equals(node))
+ {
+ deselectNode(currentlySelectedNode);
+ }
+ }
+ }
+
+ if (!selectedNodes.contains(node))
+ {
+ selectedNodes.add(node);
+ for (ITreeStateListener listener : listeners.toArray(new ITreeStateListener[listeners.size()]))
+ {
+ listener.nodeSelected(node);
+ }
+ }
+ }
+
+ /**
+ * Selects or deselects <code>node</code> and calls the corresponding method on all registered
+ * <code>ITreeStateListeners</code>. If <code>isAllowSelectMultiple</code> is <code>false</code>
+ * , any currently selected nodes are deselected.
+ *
+ * @param node
+ * the node to be selected
+ * @param selected
+ * true if node is to be selected, false if node is to be deselected
+ */
+ @Override
+ public void selectNode(Object node, boolean selected)
+ {
+ if (selected)
+ {
+ selectNode(node);
+ }
+ else
+ {
+ deselectNode(node);
+ }
+ }
+
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.ITreeState#setAllowSelectMultiple(boolean)
+ */
+ @Override
+ public void setAllowSelectMultiple(boolean value)
+ {
+ allowSelectMultiple = value;
+ }
+
+ @Override
+ public void detach()
+ {
+ for (Object node : nodes)
+ {
+ if (node instanceof IDetachable)
+ {
+ ((IDetachable)node).detach();
+ }
+ }
+ for (Object node : selectedNodes)
+ {
+ if (node instanceof IDetachable)
+ {
+ ((IDetachable)node).detach();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeState.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeState.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeState.java
new file mode 100644
index 0000000..b06b671
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeState.java
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * Tree state holds information about a tree such as which nodes are expanded / collapsed and which
+ * nodes are selected, It can also fire callbacks on listener in case any of the information
+ * changed.
+ *
+ * @author Matej Knopp
+ */
+@Deprecated
+public interface ITreeState extends Serializable
+{
+ /**
+ * Adds a tree state listener. On state change events on the listener are fired.
+ *
+ * @param l
+ * Listener to add
+ */
+ void addTreeStateListener(ITreeStateListener l);
+
+ /**
+ * Collapses all nodes of the tree.
+ */
+ void collapseAll();
+
+ /**
+ * Collapses the given node.
+ *
+ * @param node
+ * Node to collapse
+ */
+ void collapseNode(Object node);
+
+ /**
+ * Expands all nodes of the tree.
+ */
+ void expandAll();
+
+ /**
+ * Expands the given node.
+ *
+ * @param node
+ * Node to expand
+ */
+ void expandNode(Object node);
+
+ /**
+ * Returns the collection of all selected nodes.
+ *
+ * @return The collection of selected nodes
+ */
+ Collection<Object> getSelectedNodes();
+
+ /**
+ * Returns whether multiple nodes can be selected.
+ *
+ * @return True if multiple nodes can be selected
+ */
+ boolean isAllowSelectMultiple();
+
+ /**
+ * Returns true if the given node is expanded.
+ *
+ * @param node
+ * The node to inspect
+ * @return True if the node is expanded
+ */
+ boolean isNodeExpanded(Object node);
+
+ /**
+ * Returns true if the given node is selected, false otherwise.
+ *
+ * @param node
+ * The node to inspect
+ * @return True if the node is selected
+ */
+ boolean isNodeSelected(Object node);
+
+ /**
+ * Removes a tree state listener.
+ *
+ * @param l
+ * The listener to remove
+ */
+ void removeTreeStateListener(ITreeStateListener l);
+
+
+ /**
+ * Marks given node as selected (or unselected) according to the selected value.
+ * <p>
+ * If tree is in single selection mode and a new node is selected, old node is automatically
+ * unselected (and the event is fired on listeners).
+ *
+ * @param node
+ * The node to select or deselect
+ * @param selected
+ * If true, the node will be selected, otherwise, the node will be unselected
+ */
+ void selectNode(Object node, boolean selected);
+
+ /**
+ * Sets whether multiple nodes can be selected.
+ *
+ * @param value
+ * If true, multiple nodes can be selected. If false, only one node at a time can be
+ * selected
+ */
+ void setAllowSelectMultiple(boolean value);
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeStateListener.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeStateListener.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeStateListener.java
new file mode 100644
index 0000000..ad6fb2b
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/ITreeStateListener.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import java.io.Serializable;
+
+/**
+ * Methods this interface are called when tree state is changing.
+ *
+ * @author Matej Knopp
+ */
+@Deprecated
+public interface ITreeStateListener extends Serializable
+{
+ /**
+ * Fired when all nodes are collapsed.
+ */
+ void allNodesCollapsed();
+
+ /**
+ * Fired when all nodes are expanded.
+ */
+ void allNodesExpanded();
+
+ /**
+ * Fired when given node is collapsed.
+ *
+ * @param node
+ * The node that was collapsed
+ */
+ void nodeCollapsed(Object node);
+
+ /**
+ * Fired when given node is expanded.
+ *
+ * @param node
+ */
+ void nodeExpanded(Object node);
+
+ /**
+ * Fired when given node gets selected.
+ *
+ * @param node
+ * The node that was selected
+ */
+ void nodeSelected(Object node);
+
+ /**
+ * Fired when given node gets unselected.
+ *
+ * @param node
+ * The node that was unselected
+ */
+ void nodeUnselected(Object node);
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.html
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.html b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.html
new file mode 100644
index 0000000..2c10b30
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+<wicket:panel xmlns:wicket="http://wicket.apache.org">
+<table class="icon-panel"><tr><td><img wicket:id="icon" /></td><td wicket:id="content" class="content"></td></tr></table>
+</wicket:panel>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.java
new file mode 100644
index 0000000..76b339e
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelIconPanel.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.image.Image;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+
+/**
+ * Simple panel that contains an icon next to a label.
+ *
+ * @author Matej Knopp
+ */
+public class LabelIconPanel extends Panel
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs the panel.
+ *
+ * @param id
+ * component id
+ * @param model
+ * model that is used to access the TreeNode
+ * @param tree
+ */
+ public LabelIconPanel(String id, IModel<Object> model, BaseTree tree)
+ {
+ super(id, model);
+
+ addComponents(model, tree);
+ }
+
+ /**
+ * Adds the icon and content components to the panel. You can override this method if you want
+ * custom components to be added
+ *
+ * @param model
+ * model that can be used to retrieve the TreeNode
+ *
+ * @param tree
+ */
+ protected void addComponents(IModel<Object> model, BaseTree tree)
+ {
+ add(newImageComponent("icon", tree, model));
+ add(newContentComponent("content", tree, model));
+ }
+
+ /**
+ * Creates the icon component for the node
+ *
+ * @param componentId
+ * @param tree
+ * @param model
+ * @return icon image component
+ */
+ protected Component newImageComponent(String componentId, final BaseTree tree,
+ final IModel<Object> model)
+ {
+ return new Image(componentId)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected ResourceReference getImageResourceReference()
+ {
+ return LabelIconPanel.this.getImageResourceReference(tree, model.getObject());
+ }
+
+ @Override
+ protected boolean shouldAddAntiCacheParameter()
+ {
+ return false;
+ }
+ };
+ }
+
+ /**
+ * Creates the content component (label in this case) for the node
+ *
+ * @param componentId
+ * @param tree
+ * @param model
+ * @return content component
+ */
+ protected Component newContentComponent(String componentId, BaseTree tree, IModel<?> model)
+ {
+ return new Label(componentId, model);
+ }
+
+ /**
+ * Returns the image resource reference based on the give tree node type.
+ *
+ * @param tree
+ * @param node
+ * @return image resource reference
+ */
+ protected ResourceReference getImageResourceReference(BaseTree tree, Object node)
+ {
+ TreeModel model = (TreeModel)tree.getDefaultModelObject();
+ if (model.isLeaf(node))
+ {
+ return getResourceItemLeaf(node);
+ }
+ else
+ {
+ if (tree.getTreeState().isNodeExpanded(node))
+ {
+ return getResourceFolderOpen(node);
+ }
+ else
+ {
+ return getResourceFolderClosed(node);
+ }
+ }
+ }
+
+ /**
+ * Optional method for wrapping (creating an intermediate model) for the tree node model
+ *
+ * @param nodeModel
+ * @return wrapped model
+ */
+ protected IModel<Object> wrapNodeModel(IModel<Object> nodeModel)
+ {
+ return nodeModel;
+ }
+
+ /**
+ * Returns resource reference for closed folder icon.
+ *
+ * @param node
+ * @return resource reference
+ */
+ protected ResourceReference getResourceFolderClosed(Object node)
+ {
+ return RESOURCE_FOLDER_CLOSED;
+ }
+
+ /**
+ * Returns resource reference for open folder icon.
+ *
+ * @param node
+ * @return resource reference
+ */
+ protected ResourceReference getResourceFolderOpen(Object node)
+ {
+ return RESOURCE_FOLDER_OPEN;
+ }
+
+ /**
+ * Returns resource reference for a leaf icon.
+ *
+ * @param node
+ * @return resource reference
+ */
+ protected ResourceReference getResourceItemLeaf(Object node)
+ {
+ return RESOURCE_ITEM;
+ }
+
+ private static final ResourceReference RESOURCE_FOLDER_OPEN = new PackageResourceReference(
+ LabelIconPanel.class, "res/folder-open.gif");
+ private static final ResourceReference RESOURCE_FOLDER_CLOSED = new PackageResourceReference(
+ LabelIconPanel.class, "res/folder-closed.gif");
+ private static final ResourceReference RESOURCE_ITEM = new PackageResourceReference(
+ LabelIconPanel.class, "res/item.gif");
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelTree.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelTree.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelTree.java
new file mode 100644
index 0000000..2c1e6ff
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LabelTree.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+/**
+ * Simple tree component that uses label to render tree node.
+ *
+ * @author Matej Knopp
+ */
+@Deprecated
+public class LabelTree extends BaseTree
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct.
+ *
+ * @param id
+ */
+ public LabelTree(String id)
+ {
+ super(id);
+ }
+
+ /**
+ * Construct.
+ *
+ * @param id
+ * @param model
+ * model that provides the {@link TreeModel}
+ */
+ public LabelTree(String id, IModel<? extends TreeModel> model)
+ {
+ super(id, model);
+ }
+
+ /**
+ * Construct.
+ *
+ * @param id
+ * @param model
+ * Tree model
+ */
+ public LabelTree(String id, TreeModel model)
+ {
+ super(id, new WicketTreeModel());
+ setModelObject(model);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.BaseTree#newNodeComponent(java.lang.String,
+ * org.apache.wicket.model.IModel)
+ */
+ @Override
+ protected Component newNodeComponent(String id, IModel<Object> model)
+ {
+ return new LabelIconPanel(id, model, this)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected Component newContentComponent(String componentId, BaseTree tree,
+ IModel<?> model)
+ {
+ return super.newContentComponent(componentId, tree, getNodeTextModel(model));
+ }
+ };
+ }
+
+ /**
+ * Provides the model that will be used to feed the node text.
+ *
+ * Example implementation: <code>return new PropertyModel(nodeModel, "object.name");</code>
+ * which will translate to <code>YourTreeNodeSubclass.getObject().getName();</code>
+ *
+ * NOTE: remember that the nodeModel represents the TreeNode object, not the model object inside
+ * it
+ *
+ * NOTE: this method is called from the default implementation of
+ * {@link #newNodeComponent(String, IModel)}, so if it is subclassed this method may no longer
+ * be called unless the subclassing code maintains the callback explicitly
+ *
+ * @param nodeModel
+ * model representing the current tree node
+ * @return model used for text
+ */
+ protected IModel<?> getNodeTextModel(IModel<?> nodeModel)
+ {
+ return nodeModel;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.html
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.html b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.html
new file mode 100644
index 0000000..a18bbec
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+<wicket:panel xmlns:wicket="http://wicket.apache.org">
+<table class="icon-panel"><tr><td wicket:id="iconLink"><img wicket:id="icon" class="icon"/></td><td class="content"><a wicket:id="contentLink"><span wicket:id="content" class="content"></span></a></td></tr></table>
+</wicket:panel>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.java
new file mode 100644
index 0000000..ed230d3
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkIconPanel.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.model.IModel;
+
+/**
+ * Simple panel that contains a link with icon and a link with a label.
+ *
+ * @author Matej Knopp
+ */
+public class LinkIconPanel extends LabelIconPanel
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs the panel.
+ *
+ * @param id
+ * component id
+ * @param model
+ * model that is used to access the TreeNode
+ * @param tree
+ */
+ public LinkIconPanel(String id, IModel<Object> model, BaseTree tree)
+ {
+ super(id, model, tree);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.LabelIconPanel#addComponents(org.apache.wicket.model.IModel,
+ * org.apache.wicket.extensions.markup.html.tree.BaseTree)
+ */
+ @Override
+ protected void addComponents(final IModel<Object> model, final BaseTree tree)
+ {
+ BaseTree.ILinkCallback callback = new BaseTree.ILinkCallback()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ onNodeLinkClicked(model.getObject(), tree, target);
+ }
+ };
+
+ MarkupContainer link = tree.newLink("iconLink", callback);
+ add(link);
+ link.add(newImageComponent("icon", tree, model));
+
+ link = tree.newLink("contentLink", callback);
+ add(link);
+ link.add(newContentComponent("content", tree, model));
+ }
+
+ /**
+ * Handler invoked when the link is clicked. By default makes the node selected
+ *
+ * @param node
+ * @param tree
+ * @param target
+ */
+ protected void onNodeLinkClicked(Object node, BaseTree tree, AjaxRequestTarget target)
+ {
+ tree.getTreeState().selectNode(node, !tree.getTreeState().isNodeSelected(node));
+
+ if (target != null)
+ {
+ tree.updateTree(target);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkTree.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkTree.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkTree.java
new file mode 100644
index 0000000..5b917df
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkTree.java
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.IModel;
+
+/**
+ * Simple tree component that provides node panel with link allowing user to select individual
+ * nodes.
+ *
+ * @author Matej Knopp
+ */
+@Deprecated
+public class LinkTree extends LabelTree
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct.
+ *
+ * @param id
+ */
+ public LinkTree(String id)
+ {
+ super(id);
+ }
+
+ /**
+ *
+ * Construct.
+ *
+ * @param id
+ * @param model
+ * model that provides the {@link TreeModel}
+ */
+ public LinkTree(String id, IModel<? extends TreeModel> model)
+ {
+ super(id, model);
+ }
+
+ /**
+ *
+ * Construct.
+ *
+ * @param id
+ * @param model
+ * Tree model
+ */
+ public LinkTree(String id, TreeModel model)
+ {
+ super(id, new WicketTreeModel());
+ setModelObject(model);
+ }
+
+ /**
+ * @see org.apache.wicket.extensions.markup.html.tree.BaseTree#newNodeComponent(java.lang.String,
+ * org.apache.wicket.model.IModel)
+ */
+ @Override
+ protected Component newNodeComponent(String id, IModel<Object> model)
+ {
+ return new LinkIconPanel(id, model, LinkTree.this)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void onNodeLinkClicked(Object node, BaseTree tree, AjaxRequestTarget target)
+ {
+ super.onNodeLinkClicked(node, tree, target);
+ LinkTree.this.onNodeLinkClicked(node, tree, target);
+ }
+
+ @Override
+ protected Component newContentComponent(String componentId, BaseTree tree,
+ IModel<?> model)
+ {
+ return new Label(componentId, getNodeTextModel(model));
+ }
+ };
+ }
+
+ /**
+ * Method invoked after the node has been selected / unselected.
+ *
+ * @param node
+ * @param tree
+ * @param target
+ */
+ protected void onNodeLinkClicked(Object node, BaseTree tree, AjaxRequestTarget target)
+ {
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkType.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkType.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkType.java
new file mode 100644
index 0000000..50cda47
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/LinkType.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import org.apache.wicket.util.lang.EnumeratedType;
+
+/**
+ * The type of junction links and node selection links.
+ * <dl>
+ * <dt>Regular link</dt>
+ * <dd>Non-ajax link, always refreshes the whole page. Works with javascript disabled.</dd>
+ * <dt>Ajax link</dt>
+ * <dd>Links that supports partial updates. Doesn't work with javascript disabled</dd>
+ * <dt>Ajax fallback link</dt>
+ * <dd>Link that supports partial updates. With javascript disabled acts like regular link. The
+ * drawback is that generated url (thus the entire html) is larger then using the other two</dd>
+ * </dl>
+ */
+public final class LinkType extends EnumeratedType
+{
+
+ /** partial updates with no fallback. */
+ public static final LinkType AJAX = new LinkType("AJAX");
+
+ /**
+ * partial updates that falls back to a regular link in case the client does not support
+ * javascript.
+ */
+ public static final LinkType AJAX_FALLBACK = new LinkType("AJAX_FALLBACK");
+
+ /**
+ * non-ajax version that always re-renders the whole page.
+ */
+ public static final LinkType REGULAR = new LinkType("REGULAR");
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct.
+ *
+ * @param name
+ * the name of the type of the link
+ */
+ public LinkType(String name)
+ {
+ super(name);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/Tree.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/Tree.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/Tree.java
index 41a0d57..b9337b0 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/Tree.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/Tree.java
@@ -34,6 +34,7 @@ import org.apache.wicket.model.IModel;
*
* @author Matej Knopp
*/
+@Deprecated
public class Tree extends DefaultAbstractTree
{
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/WicketTreeModel.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/WicketTreeModel.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/WicketTreeModel.java
new file mode 100644
index 0000000..de9e758
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/WicketTreeModel.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.model.util.GenericBaseModel;
+
+/**
+ * @author Timo Rantalaiho
+ */
+@Deprecated
+public class WicketTreeModel extends GenericBaseModel<TreeModel>
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct.
+ */
+ public WicketTreeModel()
+ {
+ }
+
+ /**
+ * Construct.
+ *
+ * @param treeModel
+ */
+ public WicketTreeModel(final TreeModel treeModel)
+ {
+ setObject(treeModel);
+ }
+
+ /**
+ * @see org.apache.wicket.model.util.GenericBaseModel#createSerializableVersionOf(java.lang.Object)
+ */
+ @Override
+ protected TreeModel createSerializableVersionOf(TreeModel object)
+ {
+ return object;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/package.html
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/package.html b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/package.html
new file mode 100644
index 0000000..75c7655
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/package.html
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 3.2 Final//NL">
+<html>
+<head>
+<title>wicket.extensions.markup.html.tree package</title>
+</head>
+<body>
+<p>
+Package for Tree components.
+</p>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree-images.png
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree-images.png b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree-images.png
new file mode 100644
index 0000000..361644d
Binary files /dev/null and b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree-images.png differ
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree.css
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree.css b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree.css
new file mode 100644
index 0000000..a5c0b9a
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/base-tree.css
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+table.wicket-tree-content {
+ border-collapse: collapse;
+ empty-cells: show;
+}
+
+table.wicket-tree-content,
+table.wicket-tree-content td,
+table.wicket-tree-content tr,
+table.wicket-tree-content th {
+ padding: 0;
+ margin: 0;
+}
+
+table.wicket-tree-content td.spacer {
+ width: 18px;
+ height: 100%;
+}
+
+table.wicket-tree-content td.spacer span,
+table.wicket-tree-content td.line span {
+ display: block;
+ width: 18px;
+ height: 18px;
+}
+
+table.wicket-tree-content td.line {
+ width: 18px;
+ height: 100%;
+ background: url("base-tree-images.png") repeat-y -36px center;
+}
+
+table.wicket-tree-content td.half-line {
+ width: 18px;
+ height: 100%;
+ background: url("base-tree-images.png") no-repeat -72px center;
+}
+
+table.wicket-tree-content a.junction-open,
+table.wicket-tree-content a.junction-closed,
+table.wicket-tree-content span.junction-corner {
+ width: 18px;
+ height: 18px;
+ display: block;
+ background: url("base-tree-images.png") no-repeat;
+ margin: 0;
+ padding: 0;
+ border-width: 0;
+}
+
+table.wicket-tree-content a.junction-open {
+ background-position: -18px center;
+}
+
+table.wicket-tree-content a.junction-closed {
+ background-position: 0 center;
+}
+
+table.wicket-tree-content span.junction-corner {
+ background-position: -54px center;
+}
+
+table.wicket-tree-content table.icon-panel {
+ border-collapse: collapse;
+ empty-cells: show;
+}
+
+table.wicket-tree-content table.icon-panel,
+table.wicket-tree-content table.icon-panel tr,
+table.wicket-tree-content table.icon-panel td {
+ margin: 0;
+ padding: 0;
+}
+
+table.wicket-tree-content table.icon-panel img {
+ padding: 0;
+ margin: -1px 0 0 2px;
+ display: block;
+ border-width: 0;
+}
+
+table.wicket-tree-content.selected {
+ background-color: #E0E8FF;
+ font-weight: bold;
+}
+
+table.wicket-tree-content.selected .content {
+ font-weight: bold;
+}
+
+table.wicket-tree-content table.icon-panel a {
+ text-decoration: none;
+ color: #3311aa;
+}
+
+table.wicket-tree-content table.icon-panel a:hover {
+ text-decoration: underline;
+ color: #3311aa;
+}
+
+table.wicket-tree-content table.icon-panel img.icon {
+ cursor: pointer;
+}
+
+table.icon-panel {
+ width: 100%;
+}
+
+table.icon-panel td.content {
+ width: 100%;
+}
+
+table.icon-panel td.content a {
+ padding-right: 0.4em;
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/tree.js
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/tree.js b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/tree.js
new file mode 100644
index 0000000..0273dfe
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/res/tree.js
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+if (typeof(Wicket) == "undefined")
+ Wicket = { };
+
+Wicket.Tree = { };
+
+Wicket.Tree.askForReload = function()
+{
+ if (confirm("There was a problem updating the tree. It might be caused be the old page being cached by the browser. \n" +
+ "It is recommended to reload the page. Do you want to reload it?"))
+ {
+ window.location.reload();
+ }
+};
+
+Wicket.Tree.removeNodes = function(prefix, nodeList)
+{
+ var problem = false;
+ for (var i = 0; i < nodeList.length; i++)
+ {
+ var e = document.getElementById(prefix + nodeList[i]);
+ if (e != null)
+ {
+ e.parentNode.removeChild(e);
+ }
+ else
+ {
+ // while developing alert a warning
+ problem = true;
+ Wicket.Log.error("Can't find node with id " + prefix + nodeList[i] +
+ ". This shouldn't happen - possible bug in tree?");
+ }
+ }
+ if (problem == true)
+ {
+ Wicket.Tree.askForReload();
+ }
+};
+
+Wicket.Tree.createElement = function(elementId, afterId)
+{
+ var existing = Wicket.$(elementId);
+ if (typeof(existing) != "undefined" && existing != null)
+ {
+ Wicket.Tree.askForReload();
+ }
+
+ var after = document.getElementById(afterId);
+ var newNode = document.createElement(after.tagName);
+ newNode.setAttribute("id", elementId);
+
+ var p = after.parentNode;
+
+ for (var i = 0; i < p.childNodes.length; ++i)
+ {
+ if (after == p.childNodes[i])
+ break;
+ }
+ if (i == p.childNodes.length - 1)
+ {
+ p.appendChild(newNode);
+ }
+ else
+ {
+ p.insertBefore(newNode, p.childNodes[i + 1]);
+ }
+};
+
+Wicket.TreeTable = { };
+
+/* Javascript that resizes the tree table header so that it matches size of the content.
+ This is needed when the scrollbar next to content is show, so that the columns are
+ properly aligned */
+Wicket.TreeTable.update = function(elementId)
+{
+
+ var element = document.getElementById(elementId);
+
+ if (element != null && typeof(element) != "undefined")
+ {
+
+ try
+ {
+
+ /// find the div containing the inner header div
+ var headerParent = element.getElementsByTagName("div")[1];
+
+ // find the inner header div
+ var header = headerParent.getElementsByTagName("div")[0];
+
+ // body div should be next div after header parent
+ var body = headerParent.nextSibling;
+
+ // interate until div is found
+ while (body.tagName != "DIV")
+ {
+ body = body.nextSibling;
+ }
+
+ // last check to find out if we are updating the right component
+ if (body.className == "wicket-tree-table-body")
+ {
+
+ // get the right padding from header - we need to substract it from new width
+ var padding;
+ if (document.defaultView && document.defaultView.getComputedStyle)
+ {
+ padding = document.defaultView.getComputedStyle(headerParent, '').getPropertyValue("padding-right");
+ } else if (headerParent.currentStyle)
+ {
+ padding = headerParent.currentStyle.paddingRight;
+ }
+ else
+ {
+ padding = 6;
+ }
+
+ padding = parseInt(padding, 10);
+
+ // set the new width
+ var w = (body.getElementsByTagName("div")[0].clientWidth - padding) + "px";
+
+ if (w == (-padding) + "px")
+ { // this can happen if the first row is hidden (e.g. rootless mode)
+ // try to get the width from second row
+ w = (body.getElementsByTagName("div")[1].clientWidth - padding) + "px";
+
+ }
+
+ if (w != "0px")
+ {
+ header.style.width = w;
+ }
+
+ }
+ }
+ catch (ignore)
+ {
+ }
+ }
+};
+
+Wicket.TreeTable.attached = new Object();
+
+Wicket.TreeTable.attachUpdate = function(treeTableId)
+{
+ // get the object that contains ids of elements on which the update method was already attached
+ var attached = Wicket.TreeTable.attached;
+
+ // force updating the element
+ Wicket.TreeTable.update(treeTableId);
+
+ // if the update has not been attached to this tree table yet...
+ if (typeof(attached[treeTableId]) == "undefined")
+ {
+ // ... attach it
+ attached[treeTableId] = window.setInterval(function()
+ {
+ Wicket.TreeTable.update(treeTableId);
+ }, 100);
+ }
+};
+
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/table/TreeTable.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/table/TreeTable.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/table/TreeTable.java
index 50fb913..ae8cc89 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/table/TreeTable.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/table/TreeTable.java
@@ -23,16 +23,16 @@ import org.apache.wicket.Component;
import org.apache.wicket.IClusterable;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.extensions.markup.html.tree.AbstractTree;
import org.apache.wicket.extensions.markup.html.tree.DefaultAbstractTree;
+import org.apache.wicket.extensions.markup.html.tree.WicketTreeModel;
import org.apache.wicket.extensions.markup.html.tree.table.ColumnLocation.Alignment;
import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Fragment;
-import org.apache.wicket.markup.html.tree.AbstractTree;
-import org.apache.wicket.markup.html.tree.WicketTreeModel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.PackageResourceReference;
@@ -45,6 +45,7 @@ import org.apache.wicket.request.resource.ResourceReference;
*
* @author Matej Knopp
*/
+@Deprecated
public class TreeTable extends DefaultAbstractTree
{
/**
@@ -207,7 +208,7 @@ public class TreeTable extends DefaultAbstractTree
public void renderHead(final Component component, final IHeaderResponse response)
{
response.render(OnDomReadyHeaderItem.forScript("Wicket.TreeTable.attachUpdate(\"" +
- getMarkupId() + "\")"));
+ getMarkupId() + "\")"));
}
});
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/567a5932/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/tree/TreeTest.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/tree/TreeTest.java b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/tree/TreeTest.java
new file mode 100644
index 0000000..68dab56
--- /dev/null
+++ b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/tree/TreeTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.extensions.markup.html.tree;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.markup.html.tree.AbstractTree;
+import org.apache.wicket.extensions.markup.html.tree.LinkTree;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+import org.junit.Test;
+
+/**
+ * @author Pedro Santos
+ */
+public class TreeTest extends WicketTestCase
+{
+
+ /**
+ * Asserting that {@link AbstractTree#treeNodesInserted(javax.swing.event.TreeModelEvent)} adds
+ * the new item to the dirtyItemsCreateDOM, since there is no parent node at client to be
+ * recreated.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/WICKET-3309">WICKET-3309</a>
+ */
+ @Test
+ public void addChildOnRootAtAnOnRootLessTree()
+ {
+ TestPage testPage = new TestPage();
+ testPage.tree.setRootLess(true);
+ tester.startPage(testPage);
+ tester.clickLink("addToRoot", true);
+ assertTrue(tester.getLastResponseAsString().contains("rootChild"));
+ }
+
+ /**
+ * Asserting that {@link AbstractTree#treeNodesInserted(javax.swing.event.TreeModelEvent)} don't
+ * add and not presented node to the AJAX response by invalidating it.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/WICKET-3309">WICKET-3309</a>
+ */
+ @Test
+ public void addGrandchildOnRootAtAnRootLessTree()
+ {
+ TestPage testPage = new TestPage();
+ testPage.tree.setRootLess(true);
+ DefaultMutableTreeNode rootChild = new DefaultMutableTreeNode("rootChild");
+ testPage.rootNode.add(rootChild);
+ testPage.tree.getTreeState().selectNode(rootChild, true);
+ tester.startPage(testPage);
+ tester.clickLink("addChildToSelected", true);
+ assertTrue(tester.getLastResponseAsString().contains("newNode"));
+ }
+
+ /**
+ * Asserting the old leaf root node gets a junction link when adding its first child
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/WICKET-3449">WICKET-3449</a>
+ */
+ @Test
+ public void junctionLinkRendered()
+ {
+ TestPage testPage = new TestPage();
+ tester.startPage(testPage);
+ tester.clickLink("addToRoot", true);
+ assertTrue(tester.getLastResponseAsString().contains("junctionLink"));
+ }
+
+ /** */
+ public static class TestPage extends WebPage implements IMarkupResourceStreamProvider
+ {
+ private static final long serialVersionUID = 1L;
+
+ AbstractTree tree;
+ DefaultTreeModel treeModel;
+ DefaultMutableTreeNode rootNode;
+
+ /** */
+ public TestPage()
+ {
+ rootNode = new DefaultMutableTreeNode("ROOT");
+ treeModel = new DefaultTreeModel(rootNode);
+ tree = new LinkTree("tree", treeModel);
+ add(tree);
+ add(new AjaxLink<Void>("addToRoot")
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ DefaultMutableTreeNode child = new DefaultMutableTreeNode("rootChild");
+ treeModel.insertNodeInto(child, rootNode, rootNode.getChildCount());
+ tree.updateTree(target);
+ }
+ });
+ add(new AjaxLink<Void>("addChildToSelected")
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)tree.getTreeState()
+ .getSelectedNodes()
+ .iterator()
+ .next();
+ treeModel.insertNodeInto(new DefaultMutableTreeNode("newNode"), selectedNode,
+ selectedNode.getChildCount());
+ tree.updateTree(target);
+ }
+ });
+ }
+
+ @Override
+ public IResourceStream getMarkupResourceStream(MarkupContainer container,
+ Class<?> containerClass)
+ {
+ return new StringResourceStream("<html><body>" + "<div wicket:id=\"tree\"></div>"
+ + "<a wicket:id=\"addToRoot\"></a><a wicket:id=\"addChildToSelected\"></a>"
+ + "</body></html>");
+ }
+
+ }
+}