Source Code Cross Referenced for Tree.java in  » J2EE » wicket » wicket » markup » html » tree » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » wicket » wicket.markup.html.tree 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: Tree.java 460577 2006-05-09 16:39:14Z ehillenius $
003:         * $Revision: 460577 $ $Date: 2006-05-09 18:39:14 +0200 (Tue, 09 May 2006) $
004:         * 
005:         * ==============================================================================
006:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007:         * use this file except in compliance with the License. You may obtain a copy of
008:         * the License at
009:         * 
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015:         * License for the specific language governing permissions and limitations under
016:         * the License.
017:         */
018:        package wicket.markup.html.tree;
019:
020:        import java.util.ArrayList;
021:        import java.util.Enumeration;
022:        import java.util.List;
023:
024:        import javax.swing.event.TreeModelEvent;
025:        import javax.swing.event.TreeModelListener;
026:        import javax.swing.tree.DefaultMutableTreeNode;
027:        import javax.swing.tree.TreeModel;
028:        import javax.swing.tree.TreePath;
029:
030:        import wicket.AttributeModifier;
031:        import wicket.Component;
032:        import wicket.ResourceReference;
033:        import wicket.WicketRuntimeException;
034:        import wicket.behavior.HeaderContributor;
035:        import wicket.markup.html.PackageResourceReference;
036:        import wicket.markup.html.basic.Label;
037:        import wicket.markup.html.image.Image;
038:        import wicket.markup.html.link.Link;
039:        import wicket.markup.html.list.ListItem;
040:        import wicket.markup.html.list.ListView;
041:        import wicket.markup.html.list.Loop;
042:        import wicket.markup.html.panel.Panel;
043:        import wicket.model.AbstractReadOnlyDetachableModel;
044:        import wicket.model.IModel;
045:
046:        /**
047:         * An tree that renders as a flat (not-nested) list, using spacers for
048:         * indentation and nodes at the end of one row.
049:         * <p>
050:         * The visible tree rows are put in one flat list. For each row, a list is
051:         * constructed with fillers, that can be used to create indentation. After the
052:         * fillers, the actual node content is put.
053:         * </p>
054:         * <p>
055:         * </p>
056:         * 
057:         * @author Eelco Hillenius
058:         */
059:        public class Tree extends AbstractTree implements  TreeModelListener {
060:            /**
061:             * The default node panel. If you provide your own panel by overriding
062:             * Tree.newNodePanel, but only want to override the markup, not the
063:             * components that are added, you <i>may</i> extend this class. If you want
064:             * to use other components than the default, provide a panel or fragment
065:             * instead (and that's probably what you want as the look and feel of what
066:             * this panel renders may be adjusted by overriding
067:             * {@link Tree#createJunctionLink(DefaultMutableTreeNode)} and
068:             * {@link Tree#createNodeLink(DefaultMutableTreeNode)}.
069:             */
070:            public static class DefaultNodePanel extends Panel {
071:                private static final long serialVersionUID = 1L;
072:
073:                /**
074:                 * Construct.
075:                 * 
076:                 * @param panelId
077:                 *            The component id
078:                 * @param tree
079:                 *            The containing tree component
080:                 * @param node
081:                 *            The tree node for this panel
082:                 */
083:                public DefaultNodePanel(String panelId, Tree tree,
084:                        DefaultMutableTreeNode node) {
085:                    super (panelId);
086:                    // create a link for expanding and collapsing the node
087:                    Link expandCollapsLink = tree.createJunctionLink(node);
088:                    add(expandCollapsLink);
089:                    // create a link for selecting a node
090:                    Link selectLink = tree.createNodeLink(node);
091:                    add(selectLink);
092:                }
093:            }
094:
095:            /**
096:             * Renders spacer items.
097:             */
098:            private static final class SpacerList extends Loop {
099:                private static final long serialVersionUID = 1L;
100:
101:                /**
102:                 * Construct.
103:                 * 
104:                 * @param id
105:                 *            component id
106:                 * @param size
107:                 *            size of loop
108:                 */
109:                public SpacerList(String id, int size) {
110:                    super (id, size);
111:                }
112:
113:                /**
114:                 * @see wicket.markup.html.list.Loop#populateItem(LoopItem)
115:                 */
116:                protected void populateItem(final Loop.LoopItem loopItem) {
117:                    // nothing needed; we just render the tags and use CSS to indent
118:                }
119:            }
120:
121:            /**
122:             * List view for tree paths.
123:             */
124:            private final class TreePathsListView extends ListView {
125:                private static final long serialVersionUID = 1L;
126:
127:                /**
128:                 * Construct.
129:                 * 
130:                 * @param name
131:                 *            name of the component
132:                 */
133:                public TreePathsListView(String name) {
134:                    super (name, treePathsModel);
135:                }
136:
137:                /**
138:                 * @see wicket.markup.html.list.ListView#getReuseItems()
139:                 */
140:                public boolean getReuseItems() {
141:                    return Tree.this .getOptimizeItemRemoval();
142:                }
143:
144:                /**
145:                 * @see wicket.markup.html.list.ListView#newItem(int)
146:                 */
147:                protected ListItem newItem(final int index) {
148:                    IModel listItemModel = getListItemModel(getModel(), index);
149:
150:                    // create a list item that is smart enough to determine whether
151:                    // it should be displayed or not
152:                    return new ListItem(index, listItemModel) {
153:                        private static final long serialVersionUID = 1L;
154:
155:                        public boolean isVisible() {
156:                            TreeState treeState = getTreeState();
157:                            DefaultMutableTreeNode node = (DefaultMutableTreeNode) getModelObject();
158:                            final TreePath path = new TreePath(node.getPath());
159:                            final int row = treeState.getRowForPath(path);
160:
161:                            // if the row is -1, it is not visible, otherwise it is
162:                            return (row != -1);
163:                        }
164:                    };
165:                }
166:
167:                /**
168:                 * @see wicket.markup.html.list.ListView#populateItem(wicket.markup.html.list.ListItem)
169:                 */
170:                protected void populateItem(ListItem listItem) {
171:                    // get the model object which is a tree node
172:                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) listItem
173:                            .getModelObject();
174:
175:                    // add spacers
176:                    int level = node.getLevel();
177:                    listItem.add(new SpacerList("spacers", level));
178:
179:                    // add node panel
180:                    Component nodePanel = newNodePanel("node", node);
181:                    if (nodePanel == null) {
182:                        throw new WicketRuntimeException(
183:                                "node panel must be not-null");
184:                    }
185:                    if (!"node".equals(nodePanel.getId())) {
186:                        throw new WicketRuntimeException(
187:                                "panel must have id 'node' assigned");
188:                    }
189:
190:                    listItem.add(nodePanel);
191:
192:                    // add attr modifier for highlighting the selection
193:                    listItem.add(new AttributeModifier("class", true,
194:                            new SelectedPathReplacementModel(Tree.this , node)));
195:                }
196:            }
197:
198:            /**
199:             * Model for the paths of the tree.
200:             */
201:            private final class TreePathsModel extends
202:                    AbstractReadOnlyDetachableModel {
203:                private static final long serialVersionUID = 1L;
204:
205:                /** whether this model is dirty. */
206:                boolean dirty = true;
207:
208:                /** tree paths. */
209:                private List paths = new ArrayList();
210:
211:                /**
212:                 * @see wicket.model.AbstractDetachableModel#getNestedModel()
213:                 */
214:                public IModel getNestedModel() {
215:                    // TODO General: Check calls to this method; original: return paths;
216:                    return null;
217:                }
218:
219:                /**
220:                 * @see wicket.model.AbstractDetachableModel#onAttach()
221:                 */
222:                protected void onAttach() {
223:                    if (dirty) {
224:                        paths.clear();
225:                        TreeModel model = getTreeState().getModel();
226:                        DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model
227:                                .getRoot();
228:                        Enumeration e = rootNode.preorderEnumeration();
229:                        while (e.hasMoreElements()) {
230:                            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) e
231:                                    .nextElement();
232:                            // TreePath path = new TreePath(treeNode.getPath());
233:                            paths.add(treeNode);
234:                        }
235:                        dirty = false;
236:                    }
237:                }
238:
239:                /**
240:                 * @see wicket.model.AbstractDetachableModel#onDetach()
241:                 */
242:                protected void onDetach() {
243:                }
244:
245:                /**
246:                 * @see wicket.model.AbstractDetachableModel#onGetObject(wicket.Component)
247:                 */
248:                protected Object onGetObject(Component component) {
249:                    return paths;
250:                }
251:
252:                /**
253:                 * Inserts the given node in the path list with the given index.
254:                 * 
255:                 * @param index
256:                 *            the index where the node should be inserted in
257:                 * @param node
258:                 *            node to insert
259:                 */
260:                void add(int index, DefaultMutableTreeNode node) {
261:                    paths.add(index, node);
262:                }
263:
264:                /**
265:                 * Gives the index of the given node withing this tree.
266:                 * 
267:                 * @param node
268:                 *            node to look for
269:                 * @return the index of the given node withing this tree
270:                 */
271:                int indexOf(DefaultMutableTreeNode node) {
272:                    return paths.indexOf(node);
273:                }
274:
275:                /**
276:                 * Removes the given node from the path list.
277:                 * 
278:                 * @param node
279:                 *            the node to remove
280:                 */
281:                void remove(DefaultMutableTreeNode node) {
282:                    paths.remove(node);
283:                }
284:            }
285:
286:            /** Name of the junction image component; value = 'junctionImage'. */
287:            public static final String JUNCTION_IMAGE_NAME = "junctionImage";
288:
289:            /** Name of the node image component; value = 'nodeImage'. */
290:            public static final String NODE_IMAGE_NAME = "nodeImage";
291:
292:            /** Blank image. */
293:            private static final ResourceReference BLANK = new PackageResourceReference(
294:                    Tree.class, "blank.gif");
295:
296:            /**
297:             * Reference to the css file.
298:             */
299:            private static final PackageResourceReference CSS = new PackageResourceReference(
300:                    Tree.class, "tree.css");
301:
302:            /** Minus sign image. */
303:            private static final ResourceReference MINUS = new PackageResourceReference(
304:                    Tree.class, "minus.gif");
305:
306:            /** Plus sign image. */
307:            private static final ResourceReference PLUS = new PackageResourceReference(
308:                    Tree.class, "plus.gif");
309:
310:            private static final long serialVersionUID = 1L;
311:
312:            /**
313:             * If true, re-rendering the tree is more efficient if the tree model
314:             * doesn't get changed. However, if this is true, you need to push changes
315:             * to this tree. This can easility be done by registering this tree as the
316:             * listener for tree model events (TreeModelListener), but you should <b>be
317:             * carefull</b> not to create a memory leak by doing this (e.g. when you
318:             * store the tree model in your session, the tree you registered cannot be
319:             * GC-ed). TRUE by default.
320:             */
321:            private boolean reuseItems = true;
322:
323:            /** List view for tree paths. */
324:            private TreePathsListView treePathsListView;
325:
326:            /** Model for the paths of the tree. */
327:            private TreePathsModel treePathsModel;
328:
329:            /**
330:             * Constructor.
331:             * 
332:             * @param id
333:             *            The id of this container
334:             * @param model
335:             *            the underlying tree model
336:             */
337:            public Tree(final String id, final TreeModel model) {
338:                super (id, model);
339:                this .treePathsModel = new TreePathsModel();
340:                add(treePathsListView = createTreePathsListView());
341:
342:                PackageResourceReference css = getCss();
343:                add(HeaderContributor.forCss(css.getScope(), css.getName()));
344:            }
345:
346:            /**
347:             * Construct using the given tree state that holds the model to be used as
348:             * the tree model.
349:             * 
350:             * @param id
351:             *            The id of this container
352:             * @param treeState
353:             *            treeState that holds the underlying tree model
354:             */
355:            public Tree(String id, TreeState treeState) {
356:                super (id, treeState);
357:                this .treePathsModel = new TreePathsModel();
358:                add(treePathsListView = createTreePathsListView());
359:
360:                PackageResourceReference css = getCss();
361:                add(HeaderContributor.forCss(css.getScope(), css.getName()));
362:            }
363:
364:            /**
365:             * Gets whether item removal should be optimized. If true, re-rendering the
366:             * tree is more efficient if the tree model doesn't get changed. However, if
367:             * this is true, you need to push changes to this tree. This can easility be
368:             * done by registering this tree as the listener for tree model events
369:             * (TreeModelListener), but you should <b>be carefull</b> not to create a
370:             * memory leak by doing this (e.g. when you store the tree model in your
371:             * session, the tree you registered cannot be GC-ed). TRUE by default.
372:             * 
373:             * @return whether item removal should be optimized
374:             * @deprecated Will be replaced by {@link #getReuseItems()}
375:             */
376:            // TODO Post 1.2: Remove
377:            public boolean getOptimizeItemRemoval() {
378:                return getReuseItems();
379:            }
380:
381:            /**
382:             * Gets whether items should be reused. If true, re-rendering the tree is
383:             * more efficient if the tree model doesn't get changed. However, if this is
384:             * true, you need to push changes to this tree. This can easility be done by
385:             * registering this tree as the listener for tree model events
386:             * (TreeModelListener), but you should <b>be carefull</b> not to create a
387:             * memory leak by doing this (e.g. when you store the tree model in your
388:             * session, the tree you registered cannot be GC-ed). TRUE by default.
389:             * 
390:             * @return whether items should be reused
391:             */
392:            public boolean getReuseItems() {
393:                return reuseItems;
394:            }
395:
396:            /**
397:             * Sets whether items should be reused. If true, re-rendering the tree is
398:             * more efficient if the tree model doesn't get changed. However, if this is
399:             * true, you need to push changes to this tree. This can easility be done by
400:             * registering this tree as the listener for tree model events
401:             * (TreeModelListener), but you should <b>be carefull</b> not to create a
402:             * memory leak by doing this (e.g. when you store the tree model in your
403:             * session, the tree you registered cannot be GC-ed). TRUE by default.
404:             * 
405:             * @param optimizeItemRemoval
406:             *            whether the child items should be reused
407:             * @deprecated Will be replaced by {@link #setReuseItems(boolean)}
408:             */
409:            // TODO Post 1.2: Remove
410:            public void setOptimizeItemRemoval(boolean optimizeItemRemoval) {
411:                setReuseItems(optimizeItemRemoval);
412:            }
413:
414:            /**
415:             * Sets whether item removal should be optimized. If true, re-rendering the
416:             * tree is more efficient if the tree model doesn't get changed. However, if
417:             * this is true, you need to push changes to this tree. This can easility be
418:             * done by registering this tree as the listener for tree model events
419:             * (TreeModelListener), but you should <b>be carefull</b> not to create a
420:             * memory leak by doing this (e.g. when you store the tree model in your
421:             * session, the tree you registered cannot be GC-ed). TRUE by default.
422:             * 
423:             * @param reuseItems
424:             *            whether the child items should be reused
425:             * @return This
426:             */
427:            public Tree setReuseItems(boolean reuseItems) {
428:                this .reuseItems = reuseItems;
429:                return this ;
430:            }
431:
432:            /**
433:             * Sets the current tree model.
434:             * 
435:             * @param treeModel
436:             *            the tree model to set as the current one
437:             */
438:            public void setTreeModel(final TreeModel treeModel) {
439:                super .setTreeModel(treeModel);
440:                this .treePathsModel = new TreePathsModel();
441:                treePathsListView = createTreePathsListView();
442:                replace(treePathsListView);
443:            }
444:
445:            /**
446:             * Sets the current tree state to the given tree state.
447:             * 
448:             * @param treeState
449:             *            the tree state to set as the current one
450:             */
451:            public void setTreeState(final TreeState treeState) {
452:                super .setTreeState(treeState);
453:                this .treePathsModel = new TreePathsModel();
454:                treePathsListView = createTreePathsListView();
455:                replace(treePathsListView);
456:            }
457:
458:            /**
459:             * @see javax.swing.event.TreeModelListener#treeNodesChanged(javax.swing.event.TreeModelEvent)
460:             */
461:            public void treeNodesChanged(TreeModelEvent e) {
462:                // nothing to do here
463:            }
464:
465:            /**
466:             * @see javax.swing.event.TreeModelListener#treeNodesInserted(javax.swing.event.TreeModelEvent)
467:             */
468:            public void treeNodesInserted(TreeModelEvent e) {
469:                modelChanging();
470:                Object[] newNodes = e.getChildren();
471:                int len = newNodes.length;
472:                for (int i = 0; i < len; i++) {
473:                    DefaultMutableTreeNode newNode = (DefaultMutableTreeNode) newNodes[i];
474:                    DefaultMutableTreeNode previousNode = newNode
475:                            .getPreviousSibling();
476:                    int insertRow;
477:                    if (previousNode == null) {
478:                        previousNode = (DefaultMutableTreeNode) newNode
479:                                .getParent();
480:                    }
481:                    if (previousNode != null) {
482:                        insertRow = treePathsModel.indexOf(previousNode) + 1;
483:                        if (insertRow == -1) {
484:                            throw new IllegalStateException("node "
485:                                    + previousNode
486:                                    + " not found in backing list");
487:                        }
488:                    } else {
489:                        insertRow = 0;
490:                    }
491:                    treePathsModel.add(insertRow, newNode);
492:                }
493:                modelChanged();
494:            }
495:
496:            /**
497:             * @see javax.swing.event.TreeModelListener#treeNodesRemoved(javax.swing.event.TreeModelEvent)
498:             */
499:            public void treeNodesRemoved(TreeModelEvent e) {
500:                modelChanging();
501:                Object[] deletedNodes = e.getChildren();
502:                int len = deletedNodes.length;
503:                for (int i = 0; i < len; i++) {
504:                    DefaultMutableTreeNode deletedNode = (DefaultMutableTreeNode) deletedNodes[i];
505:                    treePathsModel.remove(deletedNode);
506:                }
507:                modelChanged();
508:            }
509:
510:            /**
511:             * @see javax.swing.event.TreeModelListener#treeStructureChanged(javax.swing.event.TreeModelEvent)
512:             */
513:            public void treeStructureChanged(TreeModelEvent e) {
514:                treePathsModel.dirty = true;
515:                modelChanged();
516:            }
517:
518:            /**
519:             * Creates a junction link.
520:             * 
521:             * @param node
522:             *            the node
523:             * @return link for expanding/ collapsing the tree
524:             */
525:            protected Link createJunctionLink(final DefaultMutableTreeNode node) {
526:                final Link junctionLink = new Link("junctionLink") {
527:                    private static final long serialVersionUID = 1L;
528:
529:                    public void onClick() {
530:                        junctionLinkClicked(node);
531:                    }
532:                };
533:                junctionLink.add(getJunctionImage(node));
534:                return junctionLink;
535:            }
536:
537:            /**
538:             * Creates a node link.
539:             * 
540:             * @param node
541:             *            the model of the node
542:             * @return link for selection
543:             */
544:            protected Link createNodeLink(final DefaultMutableTreeNode node) {
545:                final Link nodeLink = new Link("nodeLink") {
546:                    private static final long serialVersionUID = 1L;
547:
548:                    public void onClick() {
549:                        nodeLinkClicked(node);
550:                    }
551:                };
552:                nodeLink.add(getNodeImage(node));
553:                nodeLink.add(new Label("label", getNodeLabel(node)));
554:                return nodeLink;
555:            }
556:
557:            /**
558:             * Creates the tree paths list view.
559:             * 
560:             * @return the tree paths list view
561:             */
562:            protected final TreePathsListView createTreePathsListView() {
563:                final TreePathsListView treePaths = new TreePathsListView(
564:                        "tree");
565:                return treePaths;
566:            }
567:
568:            /**
569:             * Returns whether the path and the selected path are equal. This method is
570:             * used by the {@link AttributeModifier}that is used for setting the CSS
571:             * class for the selected row.
572:             * 
573:             * @param path
574:             *            the path
575:             * @param selectedPath
576:             *            the selected path
577:             * @return true if the path and the selected are equal, false otherwise
578:             */
579:            protected boolean equals(final TreePath path,
580:                    final TreePath selectedPath) {
581:                Object pathNode = path.getLastPathComponent();
582:                Object selectedPathNode = selectedPath.getLastPathComponent();
583:                return (pathNode != null && selectedPathNode != null && pathNode
584:                        .equals(selectedPathNode));
585:            }
586:
587:            /**
588:             * Gets the stylesheet.
589:             * 
590:             * @return the stylesheet
591:             */
592:            protected PackageResourceReference getCss() {
593:                return CSS;
594:            }
595:
596:            /**
597:             * Get image for a junction; used by method createExpandCollapseLink. If you
598:             * use the packaged panel (Tree.html), you must name the component using
599:             * JUNCTION_IMAGE_NAME.
600:             * 
601:             * @param node
602:             *            the tree node
603:             * @return the image for the junction
604:             */
605:            protected Image getJunctionImage(final DefaultMutableTreeNode node) {
606:                if (!node.isLeaf()) {
607:                    // we want the image to be dynamically, yet resolving to a static
608:                    // image.
609:                    return new Image(JUNCTION_IMAGE_NAME) {
610:                        private static final long serialVersionUID = 1L;
611:
612:                        protected ResourceReference getImageResourceReference() {
613:                            if (isExpanded(node)) {
614:                                return MINUS;
615:                            } else {
616:                                return PLUS;
617:                            }
618:                        }
619:                    };
620:                } else {
621:                    return new Image(JUNCTION_IMAGE_NAME, BLANK);
622:                }
623:            }
624:
625:            /**
626:             * Get image for a node; used by method createNodeLink. If you use the
627:             * packaged panel (Tree.html), you must name the component using
628:             * NODE_IMAGE_NAME.
629:             * 
630:             * @param node
631:             *            the tree node
632:             * @return the image for the node
633:             */
634:            protected Image getNodeImage(final DefaultMutableTreeNode node) {
635:                return new Image(NODE_IMAGE_NAME, BLANK);
636:            }
637:
638:            /**
639:             * Gets the label of the node that is used for the node link. Defaults to
640:             * treeNodeModel.getUserObject().toString(); override to provide a custom
641:             * label
642:             * 
643:             * @param node
644:             *            the tree node
645:             * @return the label of the node that is used for the node link
646:             */
647:            protected String getNodeLabel(final DefaultMutableTreeNode node) {
648:                return String.valueOf(node.getUserObject());
649:            }
650:
651:            /**
652:             * @see wicket.Component#internalOnAttach()
653:             */
654:            protected void internalOnAttach() {
655:                // if we don't optimize, rebuild the paths on every request
656:                if (!getOptimizeItemRemoval()) {
657:                    treePathsModel.dirty = true;
658:                }
659:            }
660:
661:            /**
662:             * Handler that is called when a junction link is clicked; this
663:             * implementation sets the expanded state to one that corresponds with the
664:             * node selection.
665:             * 
666:             * @param node
667:             *            the tree node
668:             */
669:            protected void junctionLinkClicked(final DefaultMutableTreeNode node) {
670:                setExpandedState(node);
671:            }
672:
673:            /**
674:             * Create a new panel for a tree node. This method can be overriden to
675:             * provide a custom panel. This way, you can effectively nest anything you
676:             * want in the tree, like input fields, images, etc.
677:             * <p>
678:             * <strong> you must use the provide panelId as the id of your custom panel
679:             * </strong><br>
680:             * for example, do:
681:             * 
682:             * <pre>
683:             * return new MyNodePanel(panelId, node);
684:             * </pre>
685:             * 
686:             * </p>
687:             * <p>
688:             * You can choose to either let your own panel extend from DefaultNodePanel
689:             * when you just want to provide different markup but want to reuse the
690:             * default components on this panel, or extend from NodePanel directly, and
691:             * provide any component structure you like.
692:             * </p>
693:             * 
694:             * @param panelId
695:             *            the id that the panel MUST use
696:             * @param node
697:             *            the tree node for the panel
698:             * @return a new Panel
699:             */
700:            protected Component newNodePanel(String panelId,
701:                    DefaultMutableTreeNode node) {
702:                return new DefaultNodePanel(panelId, this , node);
703:            }
704:
705:            /**
706:             * Handler that is called when a node link is clicked; this implementation
707:             * sets the expanded state just as a click on a junction would do. Override
708:             * this for custom behavior.
709:             * 
710:             * @param node
711:             *            the tree node model
712:             */
713:            protected void nodeLinkClicked(final DefaultMutableTreeNode node) {
714:                setSelected(node);
715:            }
716:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.