Thanks for the example. Fix is in SVN (both 1-x and 2.0), would you mind trying it? I also fixed the refresh of item before the added ( or removed) item, so that the tree lines are changed properly.
-Matej Karl M. Davis wrote: > Matej, > > Ended up with some extra free time today. > > I took a look at the existing unit tests and didn't see any that jumped out > at me for testing the tree component. So instead of a unit test, I put > together a modified version of > wicket.examples.ajax.builtin.tree.BaseTreePage that has an added link that > will insert a node, select it in the tree state, and then try to update the > tree via Ajax. It's throwing the same exception. The java & html files are > attached, though I'm not sure the mailing list accepts attachments so I'm > also pasting them in below. > > -- Karl > > BaseTreePage.html > ----------------- > <wicket:extend> > > <div style="border-bottom: 1px solid gray; width: 30em; > margin-bottom: 1em; padding-bottom: 0.3em; margin-top: -2.89em; margin-left: > 10em;"> > <wicket:link> > <a href="SimpleTreePage.html">Simple tree</a> > > <a href="TreeTablePage.html">Tree table</a> > > <a href="EditableTreeTablePage.html">Editable tree table</a> > > </wicket:link> > </div> > > <a wicket:id="expandAll">Expand all nodes</a> > <a wicket:id="collapseAll">Collapse all nodes</a> > <a wicket:id="switchRootless">Switch rootless mode</a> > <a wicket:id="insertSingleNode">Insert New Node "Bob"</a> > <wicket:child/> > > </wicket:extend> > > > BaseTreePage.java > ----------------- > package wicket.examples.ajax.builtin.tree; > > import java.util.ArrayList; > import java.util.Iterator; > import java.util.List; > > import javax.swing.tree.DefaultMutableTreeNode; > import javax.swing.tree.DefaultTreeModel; > import javax.swing.tree.TreeModel; > import javax.swing.tree.TreeNode; > > import wicket.ajax.AjaxRequestTarget; > import wicket.ajax.markup.html.AjaxLink; > import wicket.examples.ajax.builtin.BasePage; > import wicket.extensions.markup.html.tree.AbstractTree; > > /** > * This is a base class for all pages with tree example. > * > * @author Matej Knopp > */ > public abstract class BaseTreePage extends BasePage > { > > /** > * Default constructor > */ > public BaseTreePage() > { > add(new AjaxLink("expandAll") > { > public void onClick(AjaxRequestTarget target) > { > getTree().getTreeState().expandAll(); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("collapseAll") > { > public void onClick(AjaxRequestTarget target) > { > getTree().getTreeState().collapseAll(); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("switchRootless") > { > public void onClick(AjaxRequestTarget target) > { > > getTree().setRootLess(!getTree().isRootLess()); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("insertSingleNode") > { > public void onClick(AjaxRequestTarget target) > { > CustomTreeModel treeModel = > (CustomTreeModel)getTree().getModelObject(); > DefaultMutableTreeNode bob = > treeModel.insertSingleNode((DefaultMutableTreeNode)treeModel.getRoot(), > "Bob"); > getTree().getTreeState().selectNode(bob, > true); > > if(target != null) > getTree().updateTree(target); > } > }); > } > > /** > * Returns the tree on this pages. This is used to collapse, expand > the tree > * and to switch the rootless mode. > * > * @return > * Tree instance on this page > */ > protected abstract AbstractTree getTree(); > > /** > * Creates the model that feeds the tree. > * @return > * New instance of tree model. > */ > protected TreeModel createTreeModel() > { > List l1 = new ArrayList(); > l1.add("test 1.1"); > l1.add("test 1.2"); > l1.add("test 1.3"); > List l2 = new ArrayList(); > l2.add("test 2.1"); > l2.add("test 2.2"); > l2.add("test 2.3"); > List l3 = new ArrayList(); > l3.add("test 3.1"); > l3.add("test 3.2"); > l3.add("test 3.3"); > > l2.add(l3); > > l2.add("test 2.4"); > l2.add("test 2.5"); > l2.add("test 2.6"); > > l3 = new ArrayList(); > l3.add("test 3.1"); > l3.add("test 3.2"); > l3.add("test 3.3"); > l2.add(l3); > > l1.add(l2); > > l2 = new ArrayList(); > l2.add("test 2.1"); > l2.add("test 2.2"); > l2.add("test 2.3"); > > l1.add(l2); > > l1.add("test 1.3"); > l1.add("test 1.4"); > l1.add("test 1.5"); > > return convertToTreeModel(l1); > } > > private TreeModel convertToTreeModel(List list) > { > TreeModel model = null; > DefaultMutableTreeNode rootNode = new > DefaultMutableTreeNode(new ModelBean("ROOT")); > add(rootNode, list); > model = new CustomTreeModel(rootNode); > return model; > } > > private void add(DefaultMutableTreeNode parent, List sub) > { > for (Iterator i = sub.iterator(); i.hasNext();) > { > Object o = i.next(); > if (o instanceof List) > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean("subtree...")); > parent.add(child); > add(child, (List)o); > } > else > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean(o.toString())); > parent.add(child); > } > } > } > > private class CustomTreeModel extends DefaultTreeModel > { > public CustomTreeModel(TreeNode root) > { > super(root); > // TODO Auto-generated constructor stub > } > > protected DefaultMutableTreeNode > insertSingleNode(DefaultMutableTreeNode parent, String nodeText) > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean(nodeText)); > parent.add(child); > fireTreeNodesInserted(this, parent.getPath(), new > int[]{parent.getIndex(child)}, new Object[]{child}); > return child; > } > } > } > > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Karl M. > Davis > Sent: Tuesday, September 26, 2006 2:12 AM > To: wicket-user@lists.sourceforge.net > Subject: Re: [Wicket-user] Problem Selecting Tree Nodes > > Matej, > > I got and installed the latest SVN rev right before I sent the email. I > should have some time Wed. to put together a quick test case for you. > Should I just mimic one of the existing Junit tests or can I just send you a > class & html file? > > -- Karl > > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Matej Knopp > Sent: Tuesday, September 26, 2006 12:33 AM > To: wicket-user@lists.sourceforge.net > Subject: Re: [Wicket-user] Problem Selecting Tree Nodes > > Please send a test case, I'll look at it. your code seems to be fine, it's > nothing illegal, it can be bug in tree. > > Would you mind testing svn version first, it _might_ be already fixed. > > Thanks, > > -Matej > > Karl M. Davis wrote: >> Matej, >> >> I'm getting an ArrayIndexOutOfBounds when I go to select a tree node >> right after it has been inserted into the tree when I call >> Tree.updateTree(target); (my tree model is firing the correct events). >> If you'd like, I can get you a test case for this in a day or two, but >> I just wanted to make sure I wasn't trying to do something I can't >> first. >> >> *Dummy Code:* >> myTreeModel.insertNewNode(parentNode, newNode); >> myTree.getTreeState().selectNode(newNode, true); if(target != null) >> myTree.updateTree(target); >> >> *Dump:* >> 00:25:18.609 ERROR! [SocketListener0-1] >> wicket.RequestCycle.step(RequestCycle.java:1009) >20> -2 >> java.lang.ArrayIndexOutOfBoundsException: -2 at >> java.util.ArrayList.get(ArrayList.java:323) >> at >> wicket.extensions.markup.html.tree.AbstractTree.updateTree(AbstractTre >> e.java:753) >> at >> simplepersistence.feature.dynamicPages.PageEditorPanel$SaveButton.onSu >> bmit(PageEditorPanel.java:240) >> at >> wicket.ajax.markup.html.form.AjaxSubmitButton$1.onSubmit(AjaxSubmitBut >> ton.java:60) >> at >> wicket.ajax.form.AjaxFormSubmitBehavior.onEvent(AjaxFormSubmitBehavior >> .java:92) at >> wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:167) >> at >> wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxB >> ehavior.java:236) >> at >> wicket.request.target.component.listener.BehaviorRequestTarget.process >> Events(BehaviorRequestTarget.java:98) >> at >> wicket.request.compound.DefaultEventProcessorStrategy.processEvents(De >> faultEventProcessorStrategy.java:65) >> at >> wicket.request.compound.AbstractCompoundRequestCycleProcessor.processE >> vents(AbstractCompoundRequestCycleProcessor.java:57) >> at >> wicket.RequestCycle.doProcessEventsAndRespond(RequestCycle.java:862) >> at wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:900) >> at wicket.RequestCycle.step(RequestCycle.java:976) >> at wicket.RequestCycle.steps(RequestCycle.java:1050) >> at wicket.RequestCycle.request(RequestCycle.java:454) >> at wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:217) >> at wicket.protocol.http.WicketServlet.doPost(WicketServlet.java:260) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:616) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) >> at >> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:428) >> at >> org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicatio >> nHandler.java:473) at >> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:56 >> 8) at org.mortbay.http.HttpContext.handle(HttpContext.java:1530) >> at >> org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationC >> ontext.java:633) at >> org.mortbay.http.HttpContext.handle(HttpContext.java:1482) >> at org.mortbay.http.HttpServer.service(HttpServer.java:909) >> at org.mortbay.http.HttpConnection.service(HttpConnection.java:820) >> at >> org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:986) >> at org.mortbay.http.HttpConnection.handle(HttpConnection.java:837) >> at >> org.mortbay.http.SocketListener.handleConnection(SocketListener.java:2 >> 45) at >> org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:357) >> at org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:534) >> >> -- Karl >> >> >> ---------------------------------------------------------------------- >> -- >> >> ---------------------------------------------------------------------- >> --- Take Surveys. Earn Cash. Influence the Future of IT Join >> SourceForge.net's Techsay panel and you'll get the chance to share >> your opinions on IT & business topics through brief surveys -- and >> earn cash >> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEV >> DEV >> >> >> ---------------------------------------------------------------------- >> -- >> >> _______________________________________________ >> Wicket-user mailing list >> Wicket-user@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/wicket-user > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's > Techsay panel and you'll get the chance to share your opinions on IT & > business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Wicket-user mailing list > Wicket-user@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/wicket-user > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's > Techsay panel and you'll get the chance to share your opinions on IT & > business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Wicket-user mailing list > Wicket-user@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/wicket-user > > > ------------------------------------------------------------------------ > > package wicket.examples.ajax.builtin.tree; > > import java.util.ArrayList; > import java.util.Iterator; > import java.util.List; > > import javax.swing.tree.DefaultMutableTreeNode; > import javax.swing.tree.DefaultTreeModel; > import javax.swing.tree.TreeModel; > import javax.swing.tree.TreeNode; > > import wicket.ajax.AjaxRequestTarget; > import wicket.ajax.markup.html.AjaxLink; > import wicket.examples.ajax.builtin.BasePage; > import wicket.extensions.markup.html.tree.AbstractTree; > > /** > * This is a base class for all pages with tree example. > * > * @author Matej Knopp > */ > public abstract class BaseTreePage extends BasePage > { > > /** > * Default constructor > */ > public BaseTreePage() > { > add(new AjaxLink("expandAll") > { > public void onClick(AjaxRequestTarget target) > { > getTree().getTreeState().expandAll(); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("collapseAll") > { > public void onClick(AjaxRequestTarget target) > { > getTree().getTreeState().collapseAll(); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("switchRootless") > { > public void onClick(AjaxRequestTarget target) > { > getTree().setRootLess(!getTree().isRootLess()); > getTree().updateTree(target); > } > }); > > add(new AjaxLink("insertSingleNode") > { > public void onClick(AjaxRequestTarget target) > { > CustomTreeModel treeModel = > (CustomTreeModel)getTree().getModelObject(); > DefaultMutableTreeNode bob = > treeModel.insertSingleNode((DefaultMutableTreeNode)treeModel.getRoot(), > "Bob"); > getTree().getTreeState().selectNode(bob, true); > > if(target != null) > getTree().updateTree(target); > } > }); > } > > /** > * Returns the tree on this pages. This is used to collapse, expand the > tree > * and to switch the rootless mode. > * > * @return > * Tree instance on this page > */ > protected abstract AbstractTree getTree(); > > /** > * Creates the model that feeds the tree. > * @return > * New instance of tree model. > */ > protected TreeModel createTreeModel() > { > List l1 = new ArrayList(); > l1.add("test 1.1"); > l1.add("test 1.2"); > l1.add("test 1.3"); > List l2 = new ArrayList(); > l2.add("test 2.1"); > l2.add("test 2.2"); > l2.add("test 2.3"); > List l3 = new ArrayList(); > l3.add("test 3.1"); > l3.add("test 3.2"); > l3.add("test 3.3"); > > l2.add(l3); > > l2.add("test 2.4"); > l2.add("test 2.5"); > l2.add("test 2.6"); > > l3 = new ArrayList(); > l3.add("test 3.1"); > l3.add("test 3.2"); > l3.add("test 3.3"); > l2.add(l3); > > l1.add(l2); > > l2 = new ArrayList(); > l2.add("test 2.1"); > l2.add("test 2.2"); > l2.add("test 2.3"); > > l1.add(l2); > > l1.add("test 1.3"); > l1.add("test 1.4"); > l1.add("test 1.5"); > > return convertToTreeModel(l1); > } > > private TreeModel convertToTreeModel(List list) > { > TreeModel model = null; > DefaultMutableTreeNode rootNode = new > DefaultMutableTreeNode(new ModelBean("ROOT")); > add(rootNode, list); > model = new CustomTreeModel(rootNode); > return model; > } > > private void add(DefaultMutableTreeNode parent, List sub) > { > for (Iterator i = sub.iterator(); i.hasNext();) > { > Object o = i.next(); > if (o instanceof List) > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean("subtree...")); > parent.add(child); > add(child, (List)o); > } > else > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean(o.toString())); > parent.add(child); > } > } > } > > private class CustomTreeModel extends DefaultTreeModel > { > public CustomTreeModel(TreeNode root) > { > super(root); > // TODO Auto-generated constructor stub > } > > protected DefaultMutableTreeNode > insertSingleNode(DefaultMutableTreeNode parent, String nodeText) > { > DefaultMutableTreeNode child = new > DefaultMutableTreeNode(new ModelBean(nodeText)); > parent.add(child); > fireTreeNodesInserted(this, parent.getPath(), new > int[]{parent.getIndex(child)}, new Object[]{child}); > return child; > } > } > } > > > ------------------------------------------------------------------------ > > Simple tree <SimpleTreePage.html> Tree table <TreeTablePage.html> > Editable tree table <EditableTreeTablePage.html> > Expand all nodes Collapse all nodes Switch rootless mode Insert > New Node "Bob" > > > ------------------------------------------------------------------------ > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > > > ------------------------------------------------------------------------ > > _______________________________________________ > Wicket-user mailing list > Wicket-user@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/wicket-user ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Wicket-user mailing list Wicket-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wicket-user