Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/common/awt/tree/FlexTreeNode.java


1   /*
2    * FlexTreeNode.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:36 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.common.awt.tree;
12  
13  import java.awt.Color;
14  import java.awt.FontMetrics;
15  import java.awt.Graphics;
16  import java.awt.Image;
17  import java.util.ArrayList;
18  import java.util.Iterator;
19  
20  /**
21   * The FlexTreeNode is a support class for the Tree.
22   * It is used to represent a single line item in the Tree.
23   * This class is based on the Proto View TreeViewJ version 2.0
24   *
25   * @version 2.1
26   * @author Don Preuninger (Proto View)
27   * @author Viktor Snezhko (Proto View)
28   * @author Dan Schroeder (Rorke Data)
29   */
30  public class FlexTreeNode
31  {
32     public    static final int FIRST       = -100;                       // First child -- used in addChild()
33     public    static final int LAST        = -200;                       // Last child -- used in addChild()
34  
35     private   static Image     iDefExp     = null;                       // Default expanded image.
36     private   static Image     iDefCol     = null;                       // Default collapsed image.
37     private   Image            iExpanded   = null;                       // Expanded image.
38     private   Image            iCollapsed  = null;                       // Collapsed image.
39  
40     private   String           sLabel      = null;                       // Label
41     private   Color            cFg         = Color.black;                // Foreground color
42     private   Color            cBgSel      = new Color ( 0, 0, 119 );    // Selected background color
43     private   Color            cFgSel      = Color.white;                // Selected foreground color
44     private   Color            cLine       = Color.gray;                 // Line color
45     private   Color            cDotBorder  = Color.yellow;               // The dotted border color for the current node.
46  
47     private   boolean          bTrueRoot   = false;                      // True if this is a "true" root node.  This is a node that is
48                                                                          // not visible on the tree and is the parent of all other root nodes.
49     private   boolean          bSubRoot    = false;                      // True if this is a root node.
50     private   int              nTreeID     = -1;                         // ID of this node's tree (used by root only)
51     private   int              nLevel      = -1;                         // Node level - calculated by getLevel()
52     private   boolean          bRemoved    = false;                      // ???
53     private   boolean          bExpanded   = true;                      // True if this node is currently expanded.
54  
55     public    FlexTreeNode       nNext       = null;                       // The next sibling node.
56     protected FlexTreeNode       nPrev       = null;                       // The previous sibling node.
57     protected FlexTreeNode       nFirstChild = null;                       // First child of this node.
58     protected FlexTreeNode       nLastChild  = null;                       // Last child of this node.
59     protected FlexTreeNode       nParent     = null;                       // The parent of this node.
60  
61     private   boolean          bAlwaysShowPlusMinus = false;
62     private   boolean          bSelected   = false;
63  
64     public FlexTreeNode ( )
65     {
66        this ( "", null, null );
67     }
68  
69     public FlexTreeNode ( String sLabel )
70     {
71        this ( sLabel, null, null );
72     }
73  
74  
75     public FlexTreeNode ( String sLabel, Image expanded, Image collapsed )
76     {
77        this.sLabel = sLabel;
78        setDefaultImages();
79        setImages ( expanded, collapsed );
80     }
81  
82  
83     public int getTreeID ( )
84     {
85        FlexTreeNode n = this;
86  
87        // Find a root node.
88        while ( n != null && !n.isTrueRoot() )
89           n = n.getParent();
90  
91        return (n == null) ? -1 : n.nTreeID;
92     }
93  
94  
95     public void forceRepaint ( )
96     {
97        TreeNotifier.notify ( getTreeID(), TreeNotifier.REPAINT );
98     }
99  
100 
101    public void forceLayout ( )
102    {
103       TreeNotifier.notify ( getTreeID(), TreeNotifier.REPAINT );
104    }
105 
106 
107    public void setRedraw ( boolean bState )
108    {
109       if ( bState )
110          TreeNotifier.notify ( getTreeID(), TreeNotifier.REDRAW_ON );
111       else
112          TreeNotifier.notify ( getTreeID(), TreeNotifier.REDRAW_OFF );
113    }
114 
115    public void setAlwaysShowPlusMinus ( boolean  bAlwaysShowPlusMinus )
116    {
117       this.bAlwaysShowPlusMinus = bAlwaysShowPlusMinus;
118    }
119 
120    public boolean getAlwaysShowPlusMinus ( )
121    {
122       return bAlwaysShowPlusMinus;
123    }
124 
125    protected void setAsTrueRoot ( int id )
126    {
127       bTrueRoot = true;
128       nTreeID   = id;
129    }
130 
131    protected void setAsRoot ( )
132    {
133       bSubRoot = true;
134    }
135 
136    public boolean isTrueRoot ( )
137    {
138       return bTrueRoot;
139    }
140 
141    public boolean isRoot ( )
142    {
143       return bSubRoot;
144    }
145 
146    public void addChild ( FlexTreeNode n, int nPosition )
147    {
148       FlexTreeNode c1;  // Child that will be before the new node.
149       FlexTreeNode c2;  // Child that will be after the new node.
150 
151       // ...--> c1 <--> n <--> c2 <--...
152 
153       switch ( nPosition )
154       {
155          case FIRST:
156          case 0:
157          {
158             c1 = null;
159             c2 = nFirstChild;
160             break;
161          }
162 
163          case LAST:
164          {
165             c1 = getLastChild();
166             c2 = null;
167             break;
168          }
169 
170          default:
171          {
172             c1 = getChild ( nPosition-1 );
173             c2 = getChild ( nPosition );
174 
175             if ( c1 == c2 )
176                c2 = null;
177 
178             break;
179          }
180       }
181 
182       /*
183       System.out.println ( "" );
184 
185       if ( nPosition == FIRST )
186          System.out.println ( "FIRST" );
187       else if ( nPosition == LAST )
188          System.out.println ( "LAST" );
189       else
190          System.out.println ( nPosition );
191 
192       System.out.println ( "n  = " + n  + " - " + n.getLabel() );
193 
194       if ( c1 == null )
195          System.out.println ( "c1 = " + c1 );
196       else
197          System.out.println ( "c1 = " + c1 + " - " + c1.getLabel());
198 
199       if ( c2 == null )
200          System.out.println ( "c2 = " + c2 );
201       else
202          System.out.println ( "c2 = " + c2 + " - " + c2.getLabel());
203       */
204 
205       // Link n to this node (parent).
206       n.nParent = this;
207 
208       // Link nodes c1 and n
209       if ( c1 == null )
210       {
211          nFirstChild = n;
212          n.nPrev = null;
213       }
214       else
215       {
216          c1.nNext = n;
217          n.nPrev = c1;
218       }
219 
220       // Link nodes n and c2;
221       if ( c2 == null )
222       {
223          nLastChild = n;
224          n.nNext = null;
225       }
226       else
227       {
228          n.nNext = c2;
229          c2.nPrev = n;
230       }
231    }
232 
233 
234    public ArrayList getChildren ( )
235    {
236       ArrayList l = new ArrayList();
237       FlexTreeNode node = nFirstChild;
238 
239       while ( node != null )
240       {
241          l.add ( node );
242          node = node.nNext;
243       }
244 
245       return l;
246    }
247 
248 
249    public FlexTreeNode getFirstChild ( )
250    {
251       return nFirstChild;
252    }
253 
254 
255    public ArrayList getAllChildren ( )
256    {
257       FlexTreeNode node = nFirstChild;
258       ArrayList l = new ArrayList();
259 
260       while ( node != null )
261       {
262          l.add    ( node );
263          l.addAll ( node.getAllChildren() );
264          node = node.nNext;
265       }
266       
267       return l;
268    }
269 
270 
271    /**
272     * Returns the Nth child of this node.
273     * If there are less than N children, then the last child is returned.
274     * If there are no childen, then null is returned.
275     * @param n the child to return.
276     * @return the child node.
277     */
278    public FlexTreeNode getChild ( int n )
279    {
280       int nCount = 1;
281       FlexTreeNode node = nFirstChild;
282 
283       while ( node != null && node.nNext != null && nCount <= n )
284       {
285          node = node.nNext;
286          nCount++;
287       }
288 
289       return node;
290    }
291 
292 
293    private FlexTreeNode getLastChild ( )
294    {
295       FlexTreeNode n = nFirstChild;
296 
297       while ( n != null && n.nNext != null )
298       {
299          n = n.nNext;
300       }
301 
302       return n;
303    }
304 
305 
306    /**
307     * Set the foreground color for this node
308     * @param color the new background color
309     */
310    public void setForeground(Color color)
311    {
312       cFg = color;
313    }
314 
315 
316    /**
317     * Get the foreground color for this node.  If no foreground color has been set,
318     * then the return value is null.
319     */
320    public Color getForeground()
321    {
322       return cFg;
323    }
324 
325    /**
326     * Set the foreground color for this node when selected
327     * @param color the new selected background color
328     */
329    public void setSelectedForeground(Color color)
330    {
331       cFgSel = color;
332    }
333 
334 
335    /**
336     * Get the selected foreground color for this node.
337     */
338    public Color getSelectedForeground()
339    {
340       return cFgSel;
341    }
342 
343 
344    /**
345     * Check if the "node" is a child of this node.
346     * @param node node to test as a child.
347     * @return True - node is a child, false node is not a child
348     * @see #isDescendant
349     */
350    public boolean isChild(FlexTreeNode node)
351    {
352       FlexTreeNode n = nFirstChild;
353       if(node == null || n == null) return false;
354       if(n == node) return true;
355       while(n != null)
356       {
357          n = n.nNext;
358          if(n == node)
359             return true;
360       }
361       return false;
362    }
363 
364 
365    /**
366     * Check if the "node" is a descendant of this node.
367     * @param node node to test as a descendant.
368     * @return True - node is a descendant, false - node is not a descendant
369     * @see #isChild
370     */
371    public boolean isDescendant(FlexTreeNode node)
372    {
373       FlexTreeNode n = nFirstChild;
374       if(node == null || n == null) return false;
375       if(isChild(node))
376          return true;
377       while(!n.isDescendant(node))
378       {
379          n = n.nNext;
380          if(n == null)
381             return false;
382       }
383       return true;
384    }
385 
386 
387    public void remove()
388    {
389       int nID = getTreeID();
390 
391       // Remove children
392       FlexTreeNode c = nFirstChild;
393       nLastChild = null;
394       nFirstChild = null;
395       while ( c != null )
396       {
397          c.remove();
398          c = c.nNext;
399       }
400 
401       // Node is in the middle of other nodes
402       if ( nNext != null && nPrev != null )
403       {
404          nNext.nPrev = nPrev;
405          nPrev.nNext = nNext;
406       }
407 
408       // Node is the first child of several
409       else if ( nNext != null )
410       {
411          nNext.nPrev = null;
412          if ( nParent != null && nParent.nFirstChild == this )
413             nParent.nFirstChild = nNext;
414       }
415 
416       // Node is the last child of several
417       else if(nPrev != null)
418       {
419          nPrev.nNext = null;
420          if ( nParent != null && nParent.nLastChild == this )
421             nParent.nLastChild = nPrev;
422       }
423       // The only child
424       else if(nParent != null)
425       {
426          if(nParent.nFirstChild == this)
427             nParent.nFirstChild = null;
428 
429          if(nParent.nLastChild == this)
430             nParent.nLastChild = null;
431       }
432 
433       nPrev = null;
434       nParent = null;
435       bRemoved = true;
436 
437       // Need to test if this deleted item is the first visible item in the tree (bug #6565)
438       TreeNotifier.notify ( nID, TreeNotifier.CHECK_FIRST_VISIBLE_NODE );
439    }
440 
441    public void removeChildren()
442    {
443       for ( Iterator i = getChildren().iterator(); i.hasNext(); )
444          ((FlexTreeNode)i.next()).remove();
445    }
446 
447    protected int _paint ( Tree Tree, Graphics g, int count )
448    {
449       if ( bRemoved )
450          return 0;
451 
452       int nHOffset = 3 + ( getLevel() * Tree.m_iIndent ) - Tree.m_iHScroll;
453       int nVOffset = ( count - 1 ) * Tree.m_iLineHeight;
454       int nHStart  = -( 2 + Tree.m_iHScroll ) + Tree.m_imMinus.getHeight( Tree );
455 
456       if ( Tree.getLines() )
457       {
458          int nHalfLineHeight = Tree.m_iLineHeight / 2;
459 
460          // set lines color
461          g.setColor( cLine );
462 
463          int nHLineOffset = 0;
464          
465          // draw vertical lines
466          for ( int nCurrentLevel = 0; nCurrentLevel <= getLevel(); nCurrentLevel++ )
467          {
468             FlexTreeNode parent = this;
469 
470             int nL = getLevel();
471             while ( nL > nCurrentLevel )
472             {
473                parent = parent.nParent;
474                
475                nL--;
476             }
477             
478             nHLineOffset = ( nCurrentLevel * Tree.m_iIndent ) + nHStart;
479 
480             // line down from "+"
481             if ( ( getLevel() == 0 ) && ( nPrev == null ) )
482             {
483                if ( nNext != null )
484                {
485                   g.drawLine( nHStart, nVOffset + nHalfLineHeight, nHStart, nVOffset + Tree.m_iLineHeight );
486                }
487             }
488             // line up from last sibling node
489             else if ( ( parent.nNext == null ) && ( nCurrentLevel == getLevel() ) )
490             {
491                // "vOffset - 1" - connect to node image on the top
492                g.drawLine( nHLineOffset, nVOffset - 1, nHLineOffset, nVOffset + nHalfLineHeight );
493             }
494             // line up/down from previous to next sibling
495             else if ( parent.nNext != null )
496             {
497                g.drawLine( nHLineOffset, nVOffset - 1, nHLineOffset, nVOffset + Tree.m_iLineHeight );
498             }
499          }
500 
501          // draw horizontal line ( 7 pixels )
502          g.drawLine( nHLineOffset, nVOffset + nHalfLineHeight, nHLineOffset + 7, nVOffset + nHalfLineHeight );
503       }
504 
505       // paint the plus and minus buttons
506       if ( bAlwaysShowPlusMinus || nFirstChild != null )
507       {
508          g.drawImage( bExpanded ? Tree.m_imMinus : Tree.m_imPlus,
509                       nHOffset, nVOffset + ( Tree.m_iLineHeight - Tree.m_imMinus.getHeight( Tree ) ) / 2, Tree );
510       }
511       nHOffset += Tree.m_imMinus.getWidth( Tree ) + 5;
512 
513       // paint the image
514       Image image = bExpanded ? getExpandedImage() : getCollapsedImage();
515       if( image != null )
516       {
517          g.drawImage( image, nHOffset, nVOffset + ( Tree.m_iLineHeight - image.getHeight( Tree ) ) / 2, Tree );
518 
519          nHOffset += image.getWidth( Tree );
520       }
521       else if ( Tree.getLines() )
522       {
523          nHOffset += 4;
524       }
525       
526       // gap between image and text
527       nHOffset += 5;
528 
529       FontMetrics fm = g.getFontMetrics();
530       
531       // text vertical offset
532       int vTextVOffset = nVOffset + fm.getAscent() + ( Tree.m_iLineHeight - ( fm.getAscent() + fm.getDescent() ) ) / 2;
533 
534       // focus rectangle
535       if ( Tree.selection.isSelected( this ) )
536       {
537          int nTextWidth = fm.stringWidth( getLabel() ) + 5;
538 
539          // set selection rectangle
540          g.setColor( cBgSel );
541          g.fillRect( nHOffset - 2, nVOffset, nTextWidth, Tree.m_iLineHeight );
542          
543          // draw text string
544          g.setColor( getSelectedForeground() );
545          g.drawString( getLabel(), nHOffset, vTextVOffset );
546 
547          // if focus is in current node, draw focus border around selection rectangle
548          if ( Tree.getCurrentNode() == this )
549             drawSelectedBorder( g, nHOffset - 2, nVOffset, nTextWidth - 1, Tree.m_iLineHeight - 1 );
550       }
551       else
552       {
553          // draw text string
554          g.setColor( getForeground() );
555          g.drawString( getLabel(), nHOffset, vTextVOffset );
556       }
557 
558       return count;
559    }
560 
561    public void drawSelectedBorder ( Graphics g, int l, int t, int w, int h )
562    {
563       int d = w & 1;
564       w += l;
565       int i = t - 1;
566 
567       g.setColor ( cDotBorder );
568 
569       // left/right lines
570       while((i += 2) <= h + t)
571       {
572          g.drawLine(l, i, l, i);
573          g.drawLine(w, i + d, w, i + d);
574       }
575 
576       // top/bottom lines
577       d = h & 1;
578       h += t;
579       i = l - 1;
580       while((i += 2) <= w)
581       {
582          g.drawLine(i, t, i, t);
583          g.drawLine(i + d, h, i + d, h);
584       }
585    }
586 
587 
588    protected FlexTreeNode nodeAtLine(int Line)
589    {
590       FlexTreeNode oldNode = null;
591       FlexTreeNode next = this;
592       int x = 1;
593       while((next != null) && x < Line)
594       {
595          oldNode = next;
596          next = next.getNextVisible();
597          x++;
598       }
599       return (next == null) ? oldNode : next;
600    }
601 
602 
603    protected int lineFromNode(Tree tree)
604    {
605       int x = 1;
606       FlexTreeNode next = tree.firstVisNode;
607       while((next != null) && x <= tree.m_iLinesPerPage + 1)
608       {
609          if(next == this)
610             return x;
611          next = next.getNextVisible();
612          x++;
613       }
614       return -1;
615    }
616 
617 
618    /**
619     * Return the parent node of this node
620     */
621    public FlexTreeNode getParent()
622    {
623       return nParent;
624    }
625 
626 
627    /**
628     * Return the next node that is visible.  The visible nodes are the nodes
629     * whose ancestors are all expanded.  Even if a node is scrolled out of view,
630     * it can still be considered visible.
631     */
632    public FlexTreeNode getNextVisible()
633    {
634       if((nFirstChild != null) && bExpanded)
635          return nFirstChild;
636       else if(nNext != null)
637          return nNext;
638       return (nParent == null) ? null : nParent.getNextParent();
639    }
640 
641 
642    /**
643     * Return the next node following this node.  The next node may not be visible
644     * and it may not be either a child nor a sibling of this node.  This method is used for
645     * enumerating all nodes
646     */
647    public FlexTreeNode getNext()
648    {
649       if(nFirstChild != null)
650          return nFirstChild;
651       else if(nNext != null)
652          return nNext;
653       return (nParent == null) ? null : nParent.getNextParent();
654    }
655 
656 
657    /**
658     * Return the previous node following this node.  The previous node may not
659     * be visible and it may not be either a child nor a sibling of this node.
660     * This method is used for enumerating all nodes in reverse
661     */
662    public FlexTreeNode getPrev()
663    {
664       return (nPrev == null) ? (nParent.isTrueRoot() ? null : nParent) :
665          nPrev.getPrevLast(this);
666    }
667 
668 
669    protected FlexTreeNode getPrevLast(FlexTreeNode node)
670    {
671       if(nLastChild == null)
672          return this;
673       else
674          return (nLastChild == node) ? null : nLastChild.getPrevLast(node);
675    }
676 
677 
678    protected FlexTreeNode getNextParent()
679    {
680       if(nNext != null)
681          return nNext;
682       return (nParent == null) ? null : nParent.getNextParent();
683    }
684 
685 
686    /**
687     * Return the previous node that is visible.  The visible nodes are the nodes
688     * whose ancestors are all expanded.  Even if a node is scrolled out of view,
689     * it can still be considered visible.
690     */
691    public FlexTreeNode getPrevVisible()
692    {
693       if ( nPrev != null )
694          return nPrev.lastVisible(this);
695       else if ( nParent == null )
696          return null;
697       else
698          return nParent.isTrueRoot() ? null : nParent;
699    }
700 
701 
702    protected FlexTreeNode lastVisible(FlexTreeNode node)
703    {
704       if(!bExpanded || nLastChild == null)
705          return this;
706       return (nLastChild == node) ? null : nLastChild.lastVisible(node);
707    }
708 
709    public FlexTreeNode getLastVisible()
710    {
711       if ( !bExpanded || nLastChild == null )
712          return this;
713       return nLastChild.getLastVisible();
714    }
715 
716 
717    /**
718     * Return a boolean value indicating whether or not the node has
719     * any child nodes associated with it.
720     */
721    public boolean hasChildren()
722    {
723       return nFirstChild != null;
724    }
725 
726 
727    /**
728     * Get the level of this node within the tree hierarchy.
729     */
730    public int getLevel()
731    {
732       // If nLevel is -1, then need to calculate it.
733       if ( nLevel == -1 )
734       {
735          FlexTreeNode currentNode = this;
736 
737          while ( !currentNode.isTrueRoot() )
738          {
739             nLevel++;
740 
741             currentNode = currentNode.getParent();
742 
743             // If this occurs, then this node (or one of it's parents) is not properly
744             // attached to the "true" root node of this tree.
745             if ( currentNode == null )
746                break;
747          }
748       }
749 
750       return nLevel;
751    }
752 
753 
754    /**
755     * Return the next sibling node for this node. The
756     * value will be null if there is no next sibling.
757     */
758    public FlexTreeNode getNextSibling()
759    {
760       return nNext;
761    }
762 
763 
764    /**
765     * Return the previous sibling node for this node. The
766     * value will be null if there is no previous sibling.
767     */
768    public FlexTreeNode getPrevSibling()
769    {
770       return nPrev;
771    }
772 
773 
774    /**
775     * Return the text label of the this node.
776     */
777    public String getLabel()
778    {
779       return sLabel;
780    }
781 
782 
783    /**
784     * Set the text label of the this node.
785     * Note: this method does not update tree painting.
786     */
787    public void setLabel ( String sLabel )
788    {
789       this.sLabel = sLabel;
790    }
791 
792 
793    public void setExpanded ( boolean expanded, boolean bChild )
794    {
795       bExpanded = expanded;
796 
797       if ( bChild )
798       {
799          FlexTreeNode next = nFirstChild;
800          while(next != null)
801          {
802             next.setExpanded ( expanded, bChild );
803             next = next.nNext;
804          }
805       }
806    }
807 
808 
809    /**
810     * Return the expanded state of the node.  If true, the node is expanded.
811     * If false the node is not expanded.
812     */
813    public boolean isExpanded()
814    {
815       return bExpanded;
816    }
817 
818 
819    boolean sortChildren( boolean bRecursive, boolean bCase)
820    {
821        FlexTreeNode oldFirst;
822        FlexTreeNode oldLast;
823        FlexTreeNode current;
824        FlexTreeNode next;
825         boolean didSwitch = true;
826         int result;
827 
828         if(nFirstChild == null)
829            return false;
830 
831        if(nFirstChild.nPrev != null)
832            return false;
833 
834         oldLast = nLastChild;
835 
836         while(didSwitch) {
837           while(nFirstChild.nPrev != null)
838               nFirstChild = nFirstChild.nPrev;
839           current = nFirstChild;
840 
841            next = current.nNext;
842             didSwitch = false;
843             while(next != null) {
844                if(bCase)
845                  result = current.getLabel().compareTo(next.getLabel());
846              else {
847                   String one = current.getLabel().toUpperCase();
848                   String two = next.getLabel().toUpperCase();
849                   result = one.compareTo(two);
850              }
851               if(result > 0) {
852                    // switch the nodes
853                    switchNodes(current, next);
854                    next = current;
855                    didSwitch = true;
856                }
857                current = next;
858                next = next.nNext;
859             }
860         }
861 
862         // recursively sort the children of this node
863         if(bRecursive) {
864             current = nFirstChild;
865             while(current != null) {
866                 current.sortChildren(bRecursive, bCase);
867                 current = current.nNext;
868             }
869         }
870 
871         // reset the first and last child nodes of this node correctly
872         while(oldLast != null) {
873             nLastChild = oldLast;
874             oldLast = oldLast.nNext;
875         }
876 
877         return true;
878    }
879 
880 
881    void switchNodes(FlexTreeNode one, FlexTreeNode two)
882    {
883         FlexTreeNode tmpNext;
884         FlexTreeNode tmpPrev;
885 
886         tmpNext = two.nNext;
887         tmpPrev = one.nPrev;
888 
889         two.nNext = one;
890         two.nPrev = tmpPrev;
891         one.nPrev = two;
892         one.nNext = tmpNext;
893 
894         // switch the neighbor links
895         if(tmpNext != null)
896             tmpNext.nPrev = one;
897         if(tmpPrev != null)
898             tmpPrev.nNext = two;
899    }
900 
901 
902    public boolean getRemoved ( )
903    {
904       return bRemoved;
905    }
906 
907 
908    public void setImages ( Image expanded, Image collapsed )
909    {
910       iExpanded  = (expanded  == null) ? iDefExp : expanded;
911       iCollapsed = (collapsed == null) ? iDefCol : collapsed;
912    }
913 
914 
915    public Image getExpandedImage ( )
916    {
917       return iExpanded;
918    }
919 
920 
921    public Image getCollapsedImage ( )
922    {
923       return iCollapsed;
924    }
925 
926 
927    public void setDefaultImages ( )
928    {
929       if ( iDefExp == null )
930          iDefExp = (new DefaultTreeImages()).getExpandedImage();
931 
932       if ( iDefCol == null )
933          iDefCol = (new DefaultTreeImages()).getCollapsedImage();
934    }
935 
936 
937    /**
938     * Gets the position of this node in its parent container.
939     */
940    public int getPosition ( )
941    {
942       if ( getParent() == null )
943          return -1;
944 
945       int        nPos = 0;
946       FlexTreeNode node = getParent().nFirstChild;
947 
948       while ( node != this )
949       {
950          node = node.nNext;
951          nPos++;
952       }
953 
954       return nPos;
955    }
956 
957    /**
958     * Returns all the leaf nodes of this node and all sub nodes.
959     * @return list of the leaf nodes.
960     */
961    public ArrayList getLeafNodes ( )
962    {
963       ArrayList l = new ArrayList();
964       ArrayList c = getChildren();
965 
966       // If this is a leaf node, add it...
967       if ( !hasChildren() )
968          l.add ( this );
969 
970       for ( int i = 0; i < c.size(); i++ )
971          l.addAll ( ((FlexTreeNode)c.get(i)).getLeafNodes() );
972 
973       return l;
974    }
975 
976    protected boolean isSelected ( )
977    {
978       return bSelected;
979    }
980 
981    protected void setSelected ( boolean b )
982    {
983       bSelected = b;
984    }
985 }