jdk/src/share/demo/jfc/SampleTree/DynamicTreeNode.java
author tbell
Fri, 27 Feb 2009 10:54:11 -0800
changeset 2091 7faffd237305
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1997-1998 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * Redistribution and use in source and binary forms, with or without
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * modification, are permitted provided that the following conditions
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * are met:
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *   - Redistributions of source code must retain the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *     notice, this list of conditions and the following disclaimer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 *   - Redistributions in binary form must reproduce the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 *     notice, this list of conditions and the following disclaimer in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 *     documentation and/or other materials provided with the distribution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *   - Neither the name of Sun Microsystems nor the names of its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *     contributors may be used to endorse or promote products derived
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 *     from this software without specific prior written permission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.swing.tree.DefaultMutableTreeNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.Random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
  * DynamicTreeNode illustrates one of the possible ways in which dynamic
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
  * loading can be used in tree.  The basic premise behind this is that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
  * getChildCount() will be messaged from JTreeModel before any children
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
  * are asked for.  So, the first time getChildCount() is issued the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
  * children are loaded.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
  * It should be noted that isLeaf will also be messaged from the model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
  * The default behavior of TreeNode is to message getChildCount to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
  * determine this. As such, isLeaf is subclassed to always return false.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
  * There are others ways this could be accomplished as well.  Instead of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
  * subclassing TreeNode you could subclass JTreeModel and do the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
  * thing in getChildCount().  Or, if you aren't using TreeNode you could
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
  * write your own TreeModel implementation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
  * Another solution would be to listen for TreeNodeExpansion events and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
  * the first time a node has been expanded post the appropriate insertion
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
  * events.  I would not recommend this approach though, the other two
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
  * are much simpler and cleaner (and are faster from the perspective of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
  * how tree deals with it).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
  * NOTE: getAllowsChildren() can be messaged before getChildCount().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
  *       For this example the nodes always allow children, so it isn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
  *       a problem, but if you do support true leaf nodes you may want
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
  *       to check for loading in getAllowsChildren too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
  * @author Scott Violet
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
public class DynamicTreeNode extends DefaultMutableTreeNode
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    // Class stuff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    /** Number of names. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    static protected float                    nameCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    /** Names to use for children. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    static protected String[]                 names;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /** Potential fonts used to draw with. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    static protected Font[]                   fonts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /** Used to generate the names. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    static protected Random                   nameGen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    /** Number of children to create for each node. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    static protected final int                DefaultChildrenCount = 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        String[]            fontNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            fontNames = Toolkit.getDefaultToolkit().getFontList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            fontNames = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        if(fontNames == null || fontNames.length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            names = new String[] {"Mark Andrews", "Tom Ball", "Alan Chung",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                                      "Rob Davis", "Jeff Dinkins",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
                                      "Amy Fowler", "James Gosling",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                                      "David Karlton", "Dave Kloba",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                                      "Dave Moore", "Hans Muller",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                                      "Rick Levenson", "Tim Prinzing",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                                      "Chester Rose", "Ray Ryan",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                                      "Georges Saab", "Scott Violet",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                                      "Kathy Walrath", "Arnaud Weber" };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            /* Create the Fonts, creating fonts is slow, much better to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
               do it once. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            int              fontSize = 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            names = fontNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            fonts = new Font[names.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            for(int counter = 0, maxCounter = names.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                counter < maxCounter; counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                    fonts[counter] = new Font(fontNames[counter], 0, fontSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                    fonts[counter] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                fontSize = ((fontSize + 2 - 12) % 12) + 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        nameCount = (float)names.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        nameGen = new Random(System.currentTimeMillis());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    /** Have the children of this node been loaded yet? */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    protected boolean           hasLoaded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
      * Constructs a new DynamicTreeNode instance with o as the user
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
      * object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    public DynamicTreeNode(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        super(o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    public boolean isLeaf() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
      * If hasLoaded is false, meaning the children have not yet been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
      * loaded, loadChildren is messaged and super is messaged for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
      * the return value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    public int getChildCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        if(!hasLoaded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            loadChildren();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        return super.getChildCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
      * Messaged the first time getChildCount is messaged.  Creates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
      * children with random names from names.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    protected void loadChildren() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        DynamicTreeNode             newNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        Font                        font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        int                         randomIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        SampleData                  data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        for(int counter = 0; counter < DynamicTreeNode.DefaultChildrenCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            randomIndex = (int)(nameGen.nextFloat() * nameCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            if(fonts != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                font = fonts[randomIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                font = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            if(counter % 2 == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                data = new SampleData(font, Color.red, names[randomIndex]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                data = new SampleData(font, Color.blue, names[randomIndex]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            newNode = new DynamicTreeNode(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            /* Don't use add() here, add calls insert(newNode, getChildCount())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
               so if you want to use add, just be sure to set hasLoaded = true
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
               first. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            insert(newNode, counter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        /* This node has now been loaded, mark it so. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        hasLoaded = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
}