Source Code Cross Referenced for Tree.java in  » Web-Framework » Millstone » org » millstone » base » ui » 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 » Web Framework » Millstone » org.millstone.base.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *************************************************************************
002:         
003:                                        Millstone(TM) 
004:                           Open Sourced User Interface Library for
005:                               Internet Development with Java
006:
007:                     Millstone is a registered trademark of IT Mill Ltd
008:                          Copyright (C) 2000-2005 IT Mill Ltd
009:                             
010:         *************************************************************************
011:
012:           This library is free software; you can redistribute it and/or
013:           modify it under the terms of the GNU Lesser General Public
014:           license version 2.1 as published by the Free Software Foundation.
015:
016:           This library is distributed in the hope that it will be useful,
017:           but WITHOUT ANY WARRANTY; without even the implied warranty of
018:           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:           Lesser General Public License for more details.
020:
021:           You should have received a copy of the GNU Lesser General Public
022:           License along with this library; if not, write to the Free Software
023:           Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         *************************************************************************
026:           
027:           For more information, contact:
028:           
029:           IT Mill Ltd                           phone: +358 2 4802 7180
030:           Ruukinkatu 2-4                        fax:  +358 2 4802 7181
031:           20540, Turku                          email: info@itmill.com
032:           Finland                               company www: www.itmill.com
033:           
034:           Primary source for MillStone information and releases: www.millstone.org
035:
036:         ********************************************************************** */
037:
038:        package org.millstone.base.ui;
039:
040:        import java.lang.reflect.Method;
041:        import java.util.Collection;
042:        import java.util.HashSet;
043:        import java.util.Iterator;
044:        import java.util.LinkedHashSet;
045:        import java.util.LinkedList;
046:        import java.util.Map;
047:        import java.util.Set;
048:        import java.util.Stack;
049:        import java.util.StringTokenizer;
050:
051:        import org.millstone.base.data.Container;
052:        import org.millstone.base.data.util.ContainerHierarchicalWrapper;
053:        import org.millstone.base.event.Action;
054:        import org.millstone.base.terminal.KeyMapper;
055:        import org.millstone.base.terminal.PaintException;
056:        import org.millstone.base.terminal.PaintTarget;
057:        import org.millstone.base.terminal.Resource;
058:
059:        /** MenuTree component.
060:         *  MenuTree can be used to select an item (or multiple items)
061:         *  from a hierarchical set of items.
062:         *
063:         * @author IT Mill Ltd.
064:         * @version 3.1.1
065:         * @since 3.0
066:         */
067:        public class Tree extends Select implements  Container.Hierarchical,
068:                Action.Container {
069:
070:            /* Static members ***************************************************** */
071:
072:            private static final Method EXPAND_METHOD;
073:            private static final Method COLLAPSE_METHOD;
074:
075:            static {
076:                try {
077:                    EXPAND_METHOD = ExpandListener.class.getDeclaredMethod(
078:                            "nodeExpand", new Class[] { ExpandEvent.class });
079:                    COLLAPSE_METHOD = CollapseListener.class
080:                            .getDeclaredMethod("nodeCollapse",
081:                                    new Class[] { CollapseEvent.class });
082:                } catch (java.lang.NoSuchMethodException e) {
083:                    // This should never happen
084:                    e.printStackTrace();
085:                    throw new java.lang.RuntimeException(
086:                            "Internal error, please report");
087:                }
088:            }
089:
090:            /* Private members **************************************************** */
091:
092:            /** Set of expanded nodes */
093:            private HashSet expanded = new HashSet();
094:
095:            /** List of action handlers */
096:            private LinkedList actionHandlers = null;
097:
098:            /** Action mapper */
099:            private KeyMapper actionMapper = null;
100:
101:            /** Is the tree selectable */
102:            private boolean selectable = true;
103:
104:            /* Tree constructors ************************************************** */
105:
106:            /** Create new empty tree */
107:            public Tree() {
108:            }
109:
110:            /** Create new empty tree with caption. */
111:            public Tree(String caption) {
112:                setCaption(caption);
113:            }
114:
115:            /** Create new tree with caption and connect it to a Container. */
116:            public Tree(String caption, Container dataSource) {
117:                setCaption(caption);
118:                setContainerDataSource(dataSource);
119:            }
120:
121:            /* Expanding and collapsing ******************************************* */
122:
123:            /** Check is an item is expanded
124:             * @return true iff the item is expanded
125:             */
126:            public boolean isExpanded(Object itemId) {
127:                return expanded.contains(itemId);
128:            }
129:
130:            /** Expand an item.
131:             * 
132:             * @return True iff the expand operation succeeded
133:             */
134:            public boolean expandItem(Object itemId) {
135:
136:                // Succeeds if the node is already expanded
137:                if (isExpanded(itemId))
138:                    return true;
139:
140:                // Nodes that can not have children are not expandable
141:                if (!areChildrenAllowed(itemId))
142:                    return false;
143:
144:                // Expand
145:                expanded.add(itemId);
146:                requestRepaint();
147:                fireExpandEvent(itemId);
148:
149:                return true;
150:            }
151:
152:            /** Expand items recursively
153:             * 
154:             * Expands all the children recursively starting from an item.
155:             * Operation succeeds only if all expandable items are expanded.
156:             * @return True iff the expand operation succeeded
157:             */
158:            public boolean expandItemsRecursively(Object startItemId) {
159:
160:                boolean result = true;
161:
162:                // Initial stack
163:                Stack todo = new Stack();
164:                todo.add(startItemId);
165:
166:                // Expand recursively
167:                while (!todo.isEmpty()) {
168:                    Object id = todo.pop();
169:                    if (areChildrenAllowed(id) && !expandItem(id)) {
170:                        result = false;
171:                    }
172:                    if (hasChildren(id)) {
173:                        todo.addAll(getChildren(id));
174:                    }
175:                }
176:
177:                return result;
178:            }
179:
180:            /** Collapse an item.
181:             * 
182:             * @return True iff the collapse operation succeeded
183:             */
184:            public boolean collapseItem(Object itemId) {
185:
186:                // Succeeds if the node is already collapsed
187:                if (!isExpanded(itemId))
188:                    return true;
189:
190:                // Collapse
191:                expanded.remove(itemId);
192:                requestRepaint();
193:                fireCollapseEvent(itemId);
194:
195:                return true;
196:            }
197:
198:            /** Collapse items recursively
199:             * 
200:             * Collapse all the children recursively starting from an item.
201:             * Operation succeeds only if all expandable items are collapsed.
202:             * @return True iff the collapse operation succeeded
203:             */
204:            public boolean collapseItemsRecursively(Object startItemId) {
205:
206:                boolean result = true;
207:
208:                // Initial stack
209:                Stack todo = new Stack();
210:                todo.add(startItemId);
211:
212:                // Collapse recursively
213:                while (!todo.isEmpty()) {
214:                    Object id = todo.pop();
215:                    if (areChildrenAllowed(id) && !collapseItem(id)) {
216:                        result = false;
217:                    }
218:                    if (hasChildren(id)) {
219:                        todo.addAll(getChildren(id));
220:                    }
221:                }
222:
223:                return result;
224:            }
225:
226:            /** Getter for property selectable.
227:             * 
228:             * <p>The tree is selectable by default.</p>
229:             * 
230:             * @return Value of property selectable.
231:             */
232:            public boolean isSelectable() {
233:                return this .selectable;
234:            }
235:
236:            /** Setter for property selectable.
237:             * 
238:             * <p>The tree is selectable by default.</p>
239:             * 
240:             * @param selectable New value of property selectable.
241:             */
242:            public void setSelectable(boolean selectable) {
243:                if (this .selectable != selectable) {
244:                    this .selectable = selectable;
245:                    requestRepaint();
246:                }
247:            }
248:
249:            /* Component API ****************************************************** */
250:
251:            /**
252:             * @see org.millstone.base.ui.AbstractComponent#getTag()
253:             */
254:            public String getTag() {
255:                return "tree";
256:            }
257:
258:            /**
259:             * @see org.millstone.base.terminal.VariableOwner#changeVariables(Object source, Map variables)
260:             */
261:            public void changeVariables(Object source, Map variables) {
262:
263:                // Collapse nodes
264:                if (variables.containsKey("collapse")) {
265:                    String[] keys = (String[]) variables.get("collapse");
266:                    for (int i = 0; i < keys.length; i++) {
267:                        Object id = itemIdMapper.get(keys[i]);
268:                        if (id != null)
269:                            collapseItem(id);
270:                    }
271:                }
272:
273:                // Expand nodes
274:                if (variables.containsKey("expand")) {
275:                    String[] keys = (String[]) variables.get("expand");
276:                    for (int i = 0; i < keys.length; i++) {
277:                        Object id = itemIdMapper.get(keys[i]);
278:                        if (id != null)
279:                            expandItem(id);
280:                    }
281:                }
282:
283:                // Selections are handled by the select component
284:                super .changeVariables(source, variables);
285:
286:                // Actions
287:                if (variables.containsKey("action")) {
288:
289:                    StringTokenizer st = new StringTokenizer((String) variables
290:                            .get("action"), ",");
291:                    if (st.countTokens() == 2) {
292:                        Object itemId = itemIdMapper.get(st.nextToken());
293:                        Action action = (Action) actionMapper.get(st
294:                                .nextToken());
295:                        if (action != null && containsId(itemId)
296:                                && actionHandlers != null)
297:                            for (Iterator i = actionHandlers.iterator(); i
298:                                    .hasNext();)
299:                                ((Action.Handler) i.next()).handleAction(
300:                                        action, this , itemId);
301:                    }
302:                }
303:            }
304:
305:            /**
306:             * @see org.millstone.base.ui.AbstractComponent#paintContent(PaintTarget)
307:             */
308:            public void paintContent(PaintTarget target) throws PaintException {
309:
310:                // Focus control id
311:                if (this .getFocusableId() > 0) {
312:                    target.addAttribute("focusid", this .getFocusableId());
313:                }
314:
315:                // The tab ordering number
316:                if (this .getTabIndex() > 0)
317:                    target.addAttribute("tabindex", this .getTabIndex());
318:
319:                // Paint tree attributes
320:                if (isSelectable())
321:                    target.addAttribute("selectmode",
322:                            (isMultiSelect() ? "multi" : "single"));
323:                else
324:                    target.addAttribute("selectmode", "none");
325:                if (isNewItemsAllowed())
326:                    target.addAttribute("allownewitem", true);
327:
328:                // Initialize variables
329:                Set actionSet = new LinkedHashSet();
330:                String[] selectedKeys;
331:                if (isMultiSelect())
332:                    selectedKeys = new String[((Set) getValue()).size()];
333:                else
334:                    selectedKeys = new String[(getValue() == null ? 0 : 1)];
335:                int keyIndex = 0;
336:                LinkedList expandedKeys = new LinkedList();
337:
338:                // Iterate trough hierarchical tree using a stack of iterators
339:                Stack iteratorStack = new Stack();
340:                Collection ids = rootItemIds();
341:                if (ids != null)
342:                    iteratorStack.push(ids.iterator());
343:                while (!iteratorStack.isEmpty()) {
344:
345:                    // Get the iterator for current tree level
346:                    Iterator i = (Iterator) iteratorStack.peek();
347:
348:                    // If the level is finished, back to previous tree level
349:                    if (!i.hasNext()) {
350:
351:                        // Remove used iterator from the stack
352:                        iteratorStack.pop();
353:
354:                        // Close node
355:                        if (!iteratorStack.isEmpty())
356:                            target.endTag("node");
357:                    }
358:
359:                    // Add the item on current level
360:                    else {
361:                        Object itemId = i.next();
362:
363:                        // Start the item / node
364:                        boolean isNode = areChildrenAllowed(itemId);
365:                        if (isNode)
366:                            target.startTag("node");
367:                        else
368:                            target.startTag("leaf");
369:
370:                        // Add attributes
371:                        target.addAttribute("caption", getItemCaption(itemId));
372:                        Resource icon = getItemIcon(itemId);
373:                        if (icon != null)
374:                            target.addAttribute("icon", getItemIcon(itemId));
375:                        String key = itemIdMapper.key(itemId);
376:                        target.addAttribute("key", key);
377:                        if (isSelected(itemId)) {
378:                            target.addAttribute("selected", true);
379:                            selectedKeys[keyIndex++] = key;
380:                        }
381:                        if (areChildrenAllowed(itemId) && isExpanded(itemId)) {
382:                            target.addAttribute("expanded", true);
383:                            expandedKeys.add(key);
384:                        }
385:
386:                        // Actions
387:                        if (actionHandlers != null) {
388:                            target.startTag("al");
389:                            for (Iterator ahi = actionHandlers.iterator(); ahi
390:                                    .hasNext();) {
391:                                Action[] aa = ((Action.Handler) ahi.next())
392:                                        .getActions(itemId, this );
393:                                if (aa != null)
394:                                    for (int ai = 0; ai < aa.length; ai++) {
395:                                        String akey = actionMapper.key(aa[ai]);
396:                                        actionSet.add(aa[ai]);
397:                                        target.addSection("ak", akey);
398:                                    }
399:                            }
400:                            target.endTag("al");
401:                        }
402:
403:                        // Add children if expanded, or close the tag
404:                        if (isExpanded(itemId) && hasChildren(itemId)
405:                                && areChildrenAllowed(itemId)) {
406:                            iteratorStack.push(getChildren(itemId).iterator());
407:                        } else {
408:                            if (isNode)
409:                                target.endTag("node");
410:                            else
411:                                target.endTag("leaf");
412:                        }
413:                    }
414:                }
415:
416:                // Actions
417:                if (!actionSet.isEmpty()) {
418:                    target.startTag("actions");
419:                    target.addVariable(this , "action", "");
420:                    for (Iterator i = actionSet.iterator(); i.hasNext();) {
421:                        Action a = (Action) i.next();
422:                        target.startTag("action");
423:                        if (a.getCaption() != null)
424:                            target.addAttribute("caption", a.getCaption());
425:                        if (a.getIcon() != null)
426:                            target.addAttribute("icon", a.getIcon());
427:                        target.addAttribute("key", actionMapper.key(a));
428:                        target.endTag("action");
429:                    }
430:                    target.endTag("actions");
431:                }
432:
433:                // Selected
434:                target.addVariable(this , "selected", selectedKeys);
435:
436:                // Expand and collapse
437:                target.addVariable(this , "expand", new String[] {});
438:                target.addVariable(this , "collapse", new String[] {});
439:
440:                // New items
441:                target.addVariable(this , "newitem", new String[] {});
442:            }
443:
444:            /* Container.Hierarchical API ***************************************** */
445:
446:            /**
447:             * @see org.millstone.base.data.Container.Hierarchical#areChildrenAllowed(Object)
448:             */
449:            public boolean areChildrenAllowed(Object itemId) {
450:                return ((Container.Hierarchical) items)
451:                        .areChildrenAllowed(itemId);
452:            }
453:
454:            /**
455:             * @see org.millstone.base.data.Container.Hierarchical#getChildren(Object)
456:             */
457:            public Collection getChildren(Object itemId) {
458:                return ((Container.Hierarchical) items).getChildren(itemId);
459:            }
460:
461:            /**
462:             * @see org.millstone.base.data.Container.Hierarchical#getParent(Object)
463:             */
464:            public Object getParent(Object itemId) {
465:                return ((Container.Hierarchical) items).getParent(itemId);
466:            }
467:
468:            /**
469:             * @see org.millstone.base.data.Container.Hierarchical#hasChildren(Object)
470:             */
471:            public boolean hasChildren(Object itemId) {
472:                return ((Container.Hierarchical) items).hasChildren(itemId);
473:            }
474:
475:            /**
476:             * @see org.millstone.base.data.Container.Hierarchical#isRoot(Object)
477:             */
478:            public boolean isRoot(Object itemId) {
479:                return ((Container.Hierarchical) items).isRoot(itemId);
480:            }
481:
482:            /**
483:             * @see org.millstone.base.data.Container.Hierarchical#rootItemIds()
484:             */
485:            public Collection rootItemIds() {
486:                return ((Container.Hierarchical) items).rootItemIds();
487:            }
488:
489:            /**
490:             * @see org.millstone.base.data.Container.Hierarchical#setChildrenAllowed(Object, boolean)
491:             */
492:            public boolean setChildrenAllowed(Object itemId,
493:                    boolean areChildrenAllowed) {
494:                boolean success = ((Container.Hierarchical) items)
495:                        .setChildrenAllowed(itemId, areChildrenAllowed);
496:                if (success)
497:                    fireValueChange();
498:                return success;
499:            }
500:
501:            /**
502:             * @see org.millstone.base.data.Container.Hierarchical#setParent(Object, Object)
503:             */
504:            public boolean setParent(Object itemId, Object newParentId) {
505:                boolean success = ((Container.Hierarchical) items).setParent(
506:                        itemId, newParentId);
507:                if (success)
508:                    requestRepaint();
509:                return success;
510:            }
511:
512:            /* Overriding select behavior******************************************** */
513:
514:            /**
515:             * @see org.millstone.base.data.Container.Viewer#setContainerDataSource(Container)
516:             */
517:            public void setContainerDataSource(Container newDataSource) {
518:
519:                // Assure that the data source is ordered by making unordered 
520:                // containers ordered by wrapping them
521:                if (Container.Hierarchical.class.isAssignableFrom(newDataSource
522:                        .getClass()))
523:                    super .setContainerDataSource(newDataSource);
524:                else
525:                    super 
526:                            .setContainerDataSource(new ContainerHierarchicalWrapper(
527:                                    newDataSource));
528:            }
529:
530:            /* Expand event and listener ****************************************** */
531:
532:            /** Event to fired when a node is expanded.
533:             *  ExapandEvent is fired when a node is to be expanded.
534:             *  it can me used to dynamically fill the sub-nodes of the
535:             *  node.
536:             * @author IT Mill Ltd.
537:             * @version 3.1.1
538:             * @since 3.0
539:             */
540:            public class ExpandEvent extends Component.Event {
541:
542:                /**
543:                 * Serial generated by eclipse.
544:                 */
545:                private static final long serialVersionUID = 3832624001804481075L;
546:                private Object expandedItemId;
547:
548:                /** New instance of options change event
549:                 * @param source Source of the event.
550:                 */
551:                public ExpandEvent(Component source, Object expandedItemId) {
552:                    super (source);
553:                    this .expandedItemId = expandedItemId;
554:                }
555:
556:                /** Node where the event occurred
557:                 * @return Source of the event.
558:                 */
559:                public Object getItemId() {
560:                    return this .expandedItemId;
561:                }
562:            }
563:
564:            /** Expand event listener
565:             * @author IT Mill Ltd.
566:             * @version 3.1.1
567:             * @since 3.0 
568:             */
569:            public interface ExpandListener {
570:
571:                /** A node has been expanded.
572:                 * @param event Expand event.
573:                 */
574:                public void nodeExpand(ExpandEvent event);
575:            }
576:
577:            /** Add expand listener
578:             * @param listener Listener to be added.
579:             */
580:            public void addListener(ExpandListener listener) {
581:                addListener(ExpandEvent.class, listener, EXPAND_METHOD);
582:            }
583:
584:            /** Remove expand listener
585:             * @param listener Listener to be removed.
586:             */
587:            public void removeListener(ExpandListener listener) {
588:                removeListener(ExpandEvent.class, listener, EXPAND_METHOD);
589:            }
590:
591:            /** Emit expand  event. */
592:            protected void fireExpandEvent(Object itemId) {
593:                fireEvent(new ExpandEvent(this , itemId));
594:            }
595:
596:            /* Collapse  event ****************************************** */
597:
598:            /** Collapse event 
599:             * @author IT Mill Ltd.
600:             * @version 3.1.1
601:             * @since 3.0
602:             */
603:            public class CollapseEvent extends Component.Event {
604:
605:                /**
606:                 * Serial generated by eclipse.
607:                 */
608:                private static final long serialVersionUID = 3257009834783290160L;
609:
610:                private Object collapsedItemId;
611:
612:                /** New instance of options change event
613:                 * @param source Source of the event.
614:                 */
615:                public CollapseEvent(Component source, Object collapsedItemId) {
616:                    super (source);
617:                    this .collapsedItemId = collapsedItemId;
618:                }
619:
620:                /** Node where the event occurred
621:                 * @return Source of the event.
622:                 */
623:                public Object getItemId() {
624:                    return collapsedItemId;
625:                }
626:            }
627:
628:            /** Collapse event listener 
629:             * @author IT Mill Ltd.
630:             * @version 3.1.1
631:             * @since 3.0
632:             */
633:            public interface CollapseListener {
634:
635:                /** A node has been collapsed.
636:                 * @param event Collapse event.
637:                 */
638:                public void nodeCollapse(CollapseEvent event);
639:            }
640:
641:            /** Add collapse listener
642:             * @param listener Listener to be added.
643:             */
644:            public void addListener(CollapseListener listener) {
645:                addListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
646:            }
647:
648:            /** Remove collapse listener
649:             * @param listener Listener to be removed.
650:             */
651:            public void removeListener(CollapseListener listener) {
652:                removeListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
653:            }
654:
655:            /** Emit collapse  event. */
656:            protected void fireCollapseEvent(Object itemId) {
657:                fireEvent(new CollapseEvent(this , itemId));
658:            }
659:
660:            /* Action container *************************************************** */
661:
662:            /** Adds an action handler.
663:             * @see org.millstone.base.event.Action.Container#addActionHandler(Action.Handler)
664:             */
665:            public void addActionHandler(Action.Handler actionHandler) {
666:
667:                if (actionHandler != null) {
668:
669:                    if (actionHandlers == null) {
670:                        actionHandlers = new LinkedList();
671:                        actionMapper = new KeyMapper();
672:                    }
673:
674:                    if (!actionHandlers.contains(actionHandler)) {
675:                        actionHandlers.add(actionHandler);
676:                        requestRepaint();
677:                    }
678:                }
679:            }
680:
681:            /** Removes an action handler.
682:             * @see org.millstone.base.event.Action.Container#removeActionHandler(Action.Handler)
683:             */
684:            public void removeActionHandler(Action.Handler actionHandler) {
685:
686:                if (actionHandlers != null
687:                        && actionHandlers.contains(actionHandler)) {
688:
689:                    actionHandlers.remove(actionHandler);
690:
691:                    if (actionHandlers.isEmpty()) {
692:                        actionHandlers = null;
693:                        actionMapper = null;
694:                    }
695:
696:                    requestRepaint();
697:                }
698:            }
699:
700:            /**
701:             * @see org.millstone.base.ui.Select#getVisibleItemIds()
702:             */
703:            public Collection getVisibleItemIds() {
704:
705:                LinkedList visible = new LinkedList();
706:
707:                // Iterate trough hierarchical tree using a stack of iterators
708:                Stack iteratorStack = new Stack();
709:                Collection ids = rootItemIds();
710:                if (ids != null)
711:                    iteratorStack.push(ids.iterator());
712:                while (!iteratorStack.isEmpty()) {
713:
714:                    // Get the iterator for current tree level
715:                    Iterator i = (Iterator) iteratorStack.peek();
716:
717:                    // If the level is finished, back to previous tree level
718:                    if (!i.hasNext()) {
719:
720:                        // Remove used iterator from the stack
721:                        iteratorStack.pop();
722:                    }
723:
724:                    // Add the item on current level
725:                    else {
726:                        Object itemId = i.next();
727:
728:                        visible.add(itemId);
729:
730:                        // Add children if expanded, or close the tag
731:                        if (isExpanded(itemId) && hasChildren(itemId)) {
732:                            iteratorStack.push(getChildren(itemId).iterator());
733:                        }
734:                    }
735:                }
736:
737:                return visible;
738:            }
739:
740:            /** Adding new items is not supported. 
741:             * @see org.millstone.base.ui.Select#setNewItemsAllowed(boolean)
742:             * @throws UnsupportedOperationException if set to true.
743:             */
744:            public void setNewItemsAllowed(boolean allowNewOptions)
745:                    throws UnsupportedOperationException {
746:                if (allowNewOptions)
747:                    throw new UnsupportedOperationException();
748:            }
749:
750:            /** Focusing to this component is not supported.
751:             * @see org.millstone.base.ui.AbstractField#focus()
752:             * @throws UnsupportedOperationException if invoked.
753:             */
754:            public void focus() throws UnsupportedOperationException {
755:                throw new UnsupportedOperationException();
756:            }
757:
758:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.