home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / DynamicTreeNode.java < prev    next >
Text File  |  1998-02-26  |  6KB  |  173 lines

  1. /*
  2.  * @(#)DynamicTreeNode.java    1.3 97/09/23
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  */
  20.  
  21. import com.sun.java.swing.tree.DefaultMutableTreeNode;
  22. import java.awt.Color;
  23. import java.awt.Font;
  24. import java.awt.Toolkit;
  25. import java.util.Random;
  26.  
  27. /**
  28.   * DynamicTreeNode illustrates one of the possible ways in which dynamic
  29.   * loading can be used in tree.  The basic premise behind this is that
  30.   * getChildCount() will be messaged from JTreeModel before any children
  31.   * are asked for.  So, the first time getChildCount() is issued the
  32.   * children are loaded.<p>
  33.   * It should be noted that isLeaf will also be messaged from the model.
  34.   * The default behavior of TreeNode is to message getChildCount to
  35.   * determine this. As such, isLeaf is subclassed to always return false.<p>
  36.   * There are others ways this could be accomplished as well.  Instead of
  37.   * subclassing TreeNode you could subclass JTreeModel and do the same
  38.   * thing in getChildCount().  Or, if you aren't using TreeNode you could
  39.   * write your own TreeModel implementation.
  40.   * Another solution would be to listen for TreeNodeExpansion events and
  41.   * the first time a node has been expanded post the appropriate insertion
  42.   * events.  I would not recommend this approach though, the other two
  43.   * are much simpler and cleaner (and are faster from the perspective of
  44.   * how tree deals with it).
  45.   *
  46.   * NOTE: getAllowsChildren() can be messaged before getChildCount().
  47.   *       For this example the nodes always allow children, so it isn't
  48.   *       a problem, but if you do support true leaf nodes you may want
  49.   *       to check for loading in getAllowsChildren too.
  50.   *
  51.   * @version 1.3 09/23/97
  52.   * @author Scott Violet
  53.   */
  54.  
  55. public class DynamicTreeNode extends DefaultMutableTreeNode
  56. {
  57.     // Class stuff.
  58.     /** Number of names. */
  59.     static protected float                    nameCount;
  60.  
  61.     /** Names to use for children. */
  62.     static protected String[]                 names;
  63.  
  64.     /** Potential fonts used to draw with. */
  65.     static protected Font[]                   fonts;
  66.  
  67.     /** Used to generate the names. */
  68.     static protected Random                   nameGen;
  69.  
  70.     /** Number of children to create for each node. */
  71.     static protected final int                DefaultChildrenCount = 7;
  72.  
  73.     static {
  74.     String[]            fontNames;
  75.  
  76.     try {
  77.         fontNames = Toolkit.getDefaultToolkit().getFontList();
  78.     } catch (Exception e) {
  79.         fontNames = null;
  80.     }
  81.     if(fontNames == null || fontNames.length == 0) {
  82.         names = new String[] {"Mark Andrews", "Tom Ball", "Alan Chung",
  83.                       "Rob Davis", "Jeff Dinkins",
  84.                       "Amy Fowler", "James Gosling",
  85.                       "David Karlton", "Dave Kloba", 
  86.                       "Dave Moore", "Hans Muller",
  87.                       "Rick Levenson", "Tim Prinzing",
  88.                       "Chester Rose", "Ray Ryan",
  89.                       "Georges Saab", "Scott Violet",
  90.                       "Kathy Walrath", "Arnaud Weber" };
  91.     }
  92.     else {
  93.         /* Create the Fonts, creating fonts is slow, much better to
  94.            do it once. */
  95.         int              fontSize = 12;
  96.  
  97.         names = fontNames;
  98.         fonts = new Font[names.length];
  99.         for(int counter = 0, maxCounter = names.length;
  100.         counter < maxCounter; counter++) {
  101.         try {
  102.             fonts[counter] = new Font(fontNames[counter], 0, fontSize);
  103.         }
  104.         catch (Exception e) {
  105.             fonts[counter] = null;
  106.         }
  107.         fontSize = ((fontSize + 2 - 12) % 12) + 12;
  108.         }
  109.     }
  110.     nameCount = (float)names.length;
  111.     nameGen = new Random(System.currentTimeMillis());
  112.     }
  113.  
  114.  
  115.     /** Have the children of this node been loaded yet? */
  116.     protected boolean           hasLoaded;
  117.  
  118.     /**
  119.       * Constructs a new DynamicTreeNode instance with o as the user
  120.       * object.
  121.       */
  122.     public DynamicTreeNode(Object o) {
  123.     super(o);
  124.     }
  125.  
  126.     public boolean isLeaf() {
  127.     return false;
  128.     }
  129.  
  130.     /**
  131.       * If hasLoaded is false, meaning the children have not yet been
  132.       * loaded, loadChildren is messaged and super is messaged for
  133.       * the return value.
  134.       */
  135.     public int getChildCount() {
  136.     if(!hasLoaded) {
  137.         loadChildren();
  138.     }
  139.     return super.getChildCount();
  140.     }
  141.  
  142.     /**
  143.       * Messaged the first time getChildCount is messaged.  Creates
  144.       * children with random names from names.
  145.       */
  146.     protected void loadChildren() {
  147.     DynamicTreeNode             newNode;
  148.     Font                        font;
  149.     int                         randomIndex;
  150.     SampleData                  data;
  151.  
  152.     for(int counter = 0; counter < DynamicTreeNode.DefaultChildrenCount;
  153.         counter++) {
  154.         randomIndex = (int)(nameGen.nextFloat() * nameCount);
  155.         if(fonts != null)
  156.         font = fonts[randomIndex];
  157.         else
  158.         font = null;
  159.         if(counter % 2 == 0)
  160.         data = new SampleData(font, Color.red, names[randomIndex]);
  161.         else
  162.         data = new SampleData(font, Color.blue, names[randomIndex]);
  163.         newNode = new DynamicTreeNode(data);
  164.         /* Don't use add() here, add calls insert(newNode, getChildCount())
  165.            so if you want to use add, just be sure to set hasLoaded = true
  166.            first. */
  167.         insert(newNode, counter);
  168.     }
  169.     /* This node has now been loaded, mark it so. */
  170.     hasLoaded = true;
  171.     }
  172. }
  173.