Source Code Cross Referenced for DefaultAbstractTree.java in  » J2EE » wicket » wicket » extensions » 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.extensions.markup.html.tree 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id$ $Revision$ $Date$
003:         * 
004:         * ==============================================================================
005:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
006:         * use this file except in compliance with the License. You may obtain a copy of
007:         * the License at
008:         * 
009:         * http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014:         * License for the specific language governing permissions and limitations under
015:         * the License.
016:         */
017:        package wicket.extensions.markup.html.tree;
018:
019:        import java.io.Serializable;
020:
021:        import javax.swing.tree.TreeModel;
022:        import javax.swing.tree.TreeNode;
023:
024:        import wicket.Component;
025:        import wicket.MarkupContainer;
026:        import wicket.RequestCycle;
027:        import wicket.ResourceReference;
028:        import wicket.Response;
029:        import wicket.ajax.AjaxRequestTarget;
030:        import wicket.ajax.markup.html.AjaxFallbackLink;
031:        import wicket.ajax.markup.html.AjaxLink;
032:        import wicket.behavior.HeaderContributor;
033:        import wicket.markup.ComponentTag;
034:        import wicket.markup.MarkupStream;
035:        import wicket.markup.html.PackageResourceReference;
036:        import wicket.markup.html.WebMarkupContainer;
037:        import wicket.markup.html.link.Link;
038:        import wicket.model.IModel;
039:        import wicket.model.Model;
040:        import wicket.util.lang.EnumeratedType;
041:
042:        /**
043:         * Tree class that contains convenient functions related to presentation of the
044:         * tree, which includes junction link, tree item selection link, spacers (with
045:         * lines) and default tree item and folder icons.
046:         * <p>
047:         * The class itself adds no component to tree items. If you use this class
048:         * directly, you have to implement populateTreeItem() on your own. If you want
049:         * to use an existing (complete) tree class, use {@link Tree}
050:         * <p>
051:         * This class allows you to choose between 3 types of links.
052:         * {@link DefaultAbstractTree#setLinkType(wicket.extensions.markup.html.tree.DefaultAbstractTree.LinkType)}
053:         * 
054:         * @author Matej Knopp
055:         */
056:        public abstract class DefaultAbstractTree extends AbstractTree {
057:            /**
058:             * The type of junction links and node selection links.
059:             * <dl>
060:             * <dt>Regular link</dt>
061:             * <dd>Non-ajax link, always refreshes the whole page. Works with
062:             * javascript disabled.</dd>
063:             * <dt>Ajax link</dt>
064:             * <dd>Links that supports partial updates. Doesn't work with javascript
065:             * disabled</dd>
066:             * <dt>Ajax fallback link</dt>
067:             * <dd>Link that supports partial updates. With javascript disabled acts
068:             * like regular link. The drawback is that generated url (thus the entire
069:             * html) is larger then using the other two</dd>
070:             * </dl>
071:             */
072:            public static final class LinkType extends EnumeratedType {
073:
074:                /** partial updates with no fallback. */
075:                public static final LinkType AJAX = new LinkType("AJAX");
076:
077:                /**
078:                 * partial updates that falls back to a regular link in case the client
079:                 * does not support javascript.
080:                 */
081:                public static final LinkType AJAX_FALLBACK = new LinkType(
082:                        "AJAX_FALLBACK");
083:
084:                /**
085:                 * non-ajax version that always re-renders the whole page.
086:                 */
087:                public static final LinkType REGULAR = new LinkType("REGULAR");
088:
089:                private static final long serialVersionUID = 1L;
090:
091:                /**
092:                 * Construct.
093:                 * 
094:                 * @param name
095:                 */
096:                public LinkType(String name) {
097:                    super (name);
098:                }
099:            }
100:
101:            /**
102:             * Helper class for calling an action from a link.
103:             * 
104:             * @author Matej Knopp
105:             */
106:            protected interface ILinkCallback extends Serializable {
107:                /**
108:                 * Called when the click is executed.
109:                 * 
110:                 * @param target
111:                 *            The ajax request target
112:                 */
113:                void onClick(AjaxRequestTarget target);
114:            }
115:
116:            /**
117:             * Reference to the css file.
118:             */
119:            private static final PackageResourceReference CSS = new PackageResourceReference(
120:                    DefaultAbstractTree.class, "res/tree.css");
121:
122:            /** Reference to the icon of closed tree folder */
123:            private static final PackageResourceReference FOLDER_CLOSED = new PackageResourceReference(
124:                    DefaultAbstractTree.class, "res/folder-closed.gif");
125:
126:            /** Reference to the icon of open tree folder */
127:            private static final PackageResourceReference FOLDER_OPEN = new PackageResourceReference(
128:                    DefaultAbstractTree.class, "res/folder-open.gif");
129:
130:            /** Reference to the icon of tree item (not a folder) */
131:            private static final PackageResourceReference ITEM = new PackageResourceReference(
132:                    DefaultAbstractTree.class, "res/item.gif");
133:
134:            /** The link type, default is {@link LinkType#AJAX ajax}. */
135:            private LinkType linkType = LinkType.AJAX;
136:
137:            /**
138:             * Tree contructor.
139:             * 
140:             * @param id
141:             *            The component id
142:             */
143:            public DefaultAbstractTree(String id) {
144:                super (id);
145:                init();
146:            }
147:
148:            /**
149:             * Tree constructor.
150:             * 
151:             * @param id
152:             *            The component id
153:             * @param model
154:             *            The tree model
155:             */
156:            public DefaultAbstractTree(String id, IModel model) {
157:                super (id, model);
158:                init();
159:            };
160:
161:            /**
162:             * Tree constructor.
163:             * 
164:             * @param id
165:             *            The component id
166:             * @param model
167:             *            The tree model
168:             */
169:            public DefaultAbstractTree(String id, TreeModel model) {
170:                super (id, new Model((Serializable) model));
171:                init();
172:            }
173:
174:            /**
175:             * Returns the current type of links on tree items.
176:             * 
177:             * @return The link type
178:             */
179:            public LinkType getLinkType() {
180:                return linkType;
181:            }
182:
183:            /**
184:             * Sets the type of links on tree items. After the link type is changed, the
185:             * whole tree is rebuild and re-rendered.
186:             * 
187:             * @param linkType
188:             *            type of links
189:             */
190:            public void setLinkType(LinkType linkType) {
191:                if (this .linkType != linkType) {
192:                    this .linkType = linkType;
193:                    invalidateAll();
194:                }
195:            }
196:
197:            /**
198:             * Returns the resource reference of default stylesheet.
199:             * 
200:             * @return The package resource reference
201:             */
202:            protected PackageResourceReference getCSS() {
203:                return CSS;
204:            }
205:
206:            /**
207:             * Returns the resource reference of default closed tree folder.
208:             * 
209:             * @return The package resource reference
210:             */
211:            protected ResourceReference getFolderClosed() {
212:                return FOLDER_CLOSED;
213:            }
214:
215:            /**
216:             * Returns the resource reference of default open tree folder.
217:             * 
218:             * @return The package resource reference
219:             */
220:            protected ResourceReference getFolderOpen() {
221:                return FOLDER_OPEN;
222:            };
223:
224:            /**
225:             * Returns the resource reference of default tree item (not folder).
226:             * 
227:             * @return The package resource reference
228:             */
229:            protected ResourceReference getItem() {
230:                return ITEM;
231:            }
232:
233:            /**
234:             * Returns the resource reference for icon of specified tree node.
235:             * 
236:             * @param node
237:             *            The node
238:             * @return The package resource reference
239:             */
240:            protected ResourceReference getNodeIcon(TreeNode node) {
241:                if (node.isLeaf() == true) {
242:                    return getItem();
243:                } else {
244:                    if (isNodeExpanded(node)) {
245:                        return getFolderOpen();
246:                    } else {
247:                        return getFolderClosed();
248:                    }
249:                }
250:            }
251:
252:            /**
253:             * Creates the indentation element. This element should be placed as first
254:             * element in the tree item markup to ensure proper indentaion of the tree
255:             * item. This implementation also takes care of lines that connect nodes.
256:             * 
257:             * @param parent
258:             *            The component parent
259:             * @param id
260:             *            The component id
261:             * @param node
262:             *            The tree node for which to create the identation element
263:             * @param level
264:             *            The current level
265:             * @return The indentation component
266:             */
267:            protected Component newIndentation(MarkupContainer parent,
268:                    String id, final TreeNode node, final int level) {
269:                WebMarkupContainer result = new WebMarkupContainer(id) {
270:                    private static final long serialVersionUID = 1L;
271:
272:                    /**
273:                     * @see wicket.MarkupContainer#onComponentTagBody(wicket.markup.MarkupStream,
274:                     *      wicket.markup.ComponentTag)
275:                     */
276:                    protected void onComponentTagBody(
277:                            MarkupStream markupStream, ComponentTag openTag) {
278:                        Response response = RequestCycle.get().getResponse();
279:                        TreeNode parent = node.getParent();
280:
281:                        CharSequence urls[] = new CharSequence[level];
282:                        for (int i = 0; i < level; ++i) {
283:                            if (isNodeLast(parent)) {
284:                                urls[i] = "indent-blank";
285:                            } else {
286:                                urls[i] = "indent-line";
287:                            }
288:
289:                            parent = parent.getParent();
290:                        }
291:
292:                        for (int i = level - 1; i >= 0; --i) {
293:                            response.write("<span class=\"" + urls[i]
294:                                    + "\"></span>");
295:                        }
296:                    }
297:                };
298:                result.setRenderBodyOnly(true);
299:                return result;
300:            }
301:
302:            /**
303:             * Creates an image placed on junction link. This image actually consists of
304:             * two spans with different css classes. These classes are specified
305:             * according to the stylesheet to make the junction image look well together
306:             * with lines connecting nodes.
307:             * 
308:             * @param parent
309:             *            The component parent
310:             * @param id
311:             *            The component id
312:             * @param node
313:             *            The tree node
314:             * @return The component that resprents a junction
315:             */
316:            protected MarkupContainer newJunctionImage(MarkupContainer parent,
317:                    final String id, final TreeNode node) {
318:                return (MarkupContainer) new WebMarkupContainer(id) {
319:                    private static final long serialVersionUID = 1L;
320:
321:                    /**
322:                     * @see wicket.Component#onComponentTag(wicket.markup.ComponentTag)
323:                     */
324:                    protected void onComponentTag(ComponentTag tag) {
325:                        super .onComponentTag(tag);
326:
327:                        final String cssClassInner;
328:                        if (node.isLeaf() == false) {
329:                            cssClassInner = isNodeExpanded(node) ? "minus"
330:                                    : "plus";
331:                        } else {
332:                            cssClassInner = "corner";
333:                        }
334:
335:                        final String cssClassOuter = isNodeLast(node) ? "junction-last"
336:                                : "junction";
337:
338:                        Response response = RequestCycle.get().getResponse();
339:                        response.write("<span class=\"" + cssClassOuter
340:                                + "\"><span class=\"" + cssClassInner
341:                                + "\"></span></span>");
342:                    }
343:                }.setRenderBodyOnly(true);
344:            }
345:
346:            /**
347:             * Creates the junction link for given node. Also (optionally) creates the
348:             * junction image. If the node is a leaf (it has no children), the created
349:             * junction link is non-functional.
350:             * 
351:             * @param parent
352:             *            parent component of the link
353:             * 
354:             * @param id
355:             *            wicket:id of the component
356:             * 
357:             * @param imageId
358:             *            wicket:id of the image. this can be null, in that case image
359:             *            is not created. image is supposed to be placed on the link
360:             *            (link is parent of image)
361:             * 
362:             * @param node
363:             *            tree node for which the link should be created.
364:             * @return The link component
365:             */
366:            protected Component newJunctionLink(MarkupContainer parent,
367:                    final String id, final String imageId, final TreeNode node) {
368:                final MarkupContainer junctionLink;
369:
370:                if (node.isLeaf() == false) {
371:                    junctionLink = newLink(parent, id, new ILinkCallback() {
372:                        private static final long serialVersionUID = 1L;
373:
374:                        public void onClick(AjaxRequestTarget target) {
375:                            if (isNodeExpanded(node)) {
376:                                getTreeState().collapseNode(node);
377:                            } else {
378:                                getTreeState().expandNode(node);
379:                            }
380:                            onJunctionLinkClicked(target, node);
381:                            updateTree(target);
382:                        }
383:                    });
384:                } else {
385:                    junctionLink = new WebMarkupContainer(id) {
386:                        private static final long serialVersionUID = 1L;
387:
388:                        /**
389:                         * @see wicket.Component#onComponentTag(wicket.markup.ComponentTag)
390:                         */
391:                        protected void onComponentTag(ComponentTag tag) {
392:                            super .onComponentTag(tag);
393:                            tag.put("onclick", "return false");
394:                        }
395:                    };
396:
397:                }
398:
399:                if (imageId != null) {
400:                    junctionLink.add(newJunctionImage(junctionLink, imageId,
401:                            node));
402:                }
403:
404:                return junctionLink;
405:            }
406:
407:            /**
408:             * Creates a link of type specified by current linkType. When the links is
409:             * clicked it calls the specified callback.
410:             * 
411:             * @param parent
412:             *            The parent component
413:             * @param id
414:             *            The component id
415:             * @param callback
416:             *            The link call back
417:             * @return The link component
418:             */
419:            protected MarkupContainer newLink(MarkupContainer parent,
420:                    String id, final ILinkCallback callback) {
421:                if (getLinkType() == LinkType.REGULAR) {
422:                    return new Link(id) {
423:                        private static final long serialVersionUID = 1L;
424:
425:                        /**
426:                         * @see wicket.markup.html.link.Link#onClick()
427:                         */
428:                        public void onClick() {
429:                            callback.onClick(null);
430:                        }
431:                    };
432:                } else if (getLinkType() == LinkType.AJAX) {
433:                    return new AjaxLink(id) {
434:                        private static final long serialVersionUID = 1L;
435:
436:                        /**
437:                         * @see wicket.ajax.markup.html.AjaxLink#onClick(wicket.ajax.AjaxRequestTarget)
438:                         */
439:                        public void onClick(AjaxRequestTarget target) {
440:                            callback.onClick(target);
441:                        }
442:                    };
443:                } else {
444:                    return new AjaxFallbackLink(id) {
445:                        private static final long serialVersionUID = 1L;
446:
447:                        /**
448:                         * @see wicket.ajax.markup.html.AjaxFallbackLink#onClick(wicket.ajax.AjaxRequestTarget)
449:                         */
450:                        public void onClick(AjaxRequestTarget target) {
451:                            callback.onClick(target);
452:                        }
453:                    };
454:                }
455:            }
456:
457:            /**
458:             * Creates the icon for current node. By default uses image reference
459:             * specified by {@link DefaultAbstractTree#getNodeIcon(TreeNode)}.
460:             * 
461:             * @param parent
462:             *            The parent component
463:             * @param id
464:             *            The component id
465:             * @param node
466:             *            The tree node
467:             * @return The web component that represents the icon of the current node
468:             */
469:            protected Component newNodeIcon(MarkupContainer parent, String id,
470:                    final TreeNode node) {
471:                return new WebMarkupContainer(id) {
472:                    private static final long serialVersionUID = 1L;
473:
474:                    protected void onComponentTag(ComponentTag tag) {
475:                        super .onComponentTag(tag);
476:                        tag.put("style", "background-image: url('"
477:                                + RequestCycle.get().urlFor(getNodeIcon(node))
478:                                + "')");
479:                    }
480:                };
481:
482:            }
483:
484:            /**
485:             * Creates a link that can be used to select / unselect the specified node.
486:             * 
487:             * @param parent
488:             *            The parent component
489:             * @param id
490:             *            The component id
491:             * @param node
492:             *            The parent node
493:             * @return The component that represents the link
494:             */
495:            protected MarkupContainer newNodeLink(MarkupContainer parent,
496:                    String id, final TreeNode node) {
497:                return newLink(parent, id, new ILinkCallback() {
498:                    private static final long serialVersionUID = 1L;
499:
500:                    public void onClick(AjaxRequestTarget target) {
501:                        getTreeState().selectNode(node,
502:                                !getTreeState().isNodeSelected(node));
503:                        onNodeLinkClicked(target, node);
504:                        updateTree(target);
505:                    }
506:                });
507:            }
508:
509:            /**
510:             * Callback function called after user clicked on an junction link. The node
511:             * has already been expanded/collapsed (depending on previous status).
512:             * 
513:             * @param target
514:             *            Request target - may be null on non-ajax call
515:             * 
516:             * @param node
517:             *            Node for which this callback is relevant
518:             */
519:            protected void onJunctionLinkClicked(AjaxRequestTarget target,
520:                    TreeNode node) {
521:            }
522:
523:            /**
524:             * This callback method is called after user has selected / deselected the
525:             * given node.
526:             * 
527:             * @param target
528:             *            Request target - may be null on non-ajax call
529:             * 
530:             * @param node
531:             *            Node for which this this callback is fired.
532:             */
533:            protected void onNodeLinkClicked(AjaxRequestTarget target,
534:                    TreeNode node) {
535:            }
536:
537:            /**
538:             * Performs the tree initialization. Adds header contribution for the
539:             * stylesheet.
540:             */
541:            private void init() {
542:                PackageResourceReference css = getCSS();
543:                if (css != null) {
544:                    add(HeaderContributor.forCss(css.getScope(), css.getName()));
545:                }
546:            }
547:
548:            /**
549:             * Returns whether the provided node is last child of it's parent.
550:             * 
551:             * @param node
552:             *            The node
553:             * @return whether the provided node is the last child
554:             */
555:            private boolean isNodeLast(TreeNode node) {
556:                TreeNode parent = node.getParent();
557:                if (parent == null) {
558:                    return true;
559:                } else {
560:                    return parent.getChildAt(parent.getChildCount() - 1)
561:                            .equals(node);
562:                }
563:            }
564:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.