--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/demo/share/jfc/SampleTree/DynamicTreeNode.java Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This source code is provided to illustrate the usage of a given feature
+ * or technique and has been deliberately simplified. Additional steps
+ * required for a production-quality application, such as security checks,
+ * input validation and proper error handling, might not be present in
+ * this sample code.
+ */
+
+
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.util.Random;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+
+/**
+ * DynamicTreeNode illustrates one of the possible ways in which dynamic
+ * loading can be used in tree. The basic premise behind this is that
+ * getChildCount() will be messaged from JTreeModel before any children
+ * are asked for. So, the first time getChildCount() is issued the
+ * children are loaded.<p>
+ * It should be noted that isLeaf will also be messaged from the model.
+ * The default behavior of TreeNode is to message getChildCount to
+ * determine this. As such, isLeaf is subclassed to always return false.<p>
+ * There are others ways this could be accomplished as well. Instead of
+ * subclassing TreeNode you could subclass JTreeModel and do the same
+ * thing in getChildCount(). Or, if you aren't using TreeNode you could
+ * write your own TreeModel implementation.
+ * Another solution would be to listen for TreeNodeExpansion events and
+ * the first time a node has been expanded post the appropriate insertion
+ * events. I would not recommend this approach though, the other two
+ * are much simpler and cleaner (and are faster from the perspective of
+ * how tree deals with it).
+ *
+ * NOTE: getAllowsChildren() can be messaged before getChildCount().
+ * For this example the nodes always allow children, so it isn't
+ * a problem, but if you do support true leaf nodes you may want
+ * to check for loading in getAllowsChildren too.
+ *
+ * @author Scott Violet
+ */
+@SuppressWarnings("serial")
+public class DynamicTreeNode extends DefaultMutableTreeNode {
+ // Class stuff.
+
+ /** Number of names. */
+ protected static float nameCount;
+ /** Names to use for children. */
+ protected static final String[] NAMES;
+ /** Potential fonts used to draw with. */
+ protected static Font[] fonts;
+ /** Used to generate the names. */
+ protected static Random nameGen;
+ /** Number of children to create for each node. */
+ protected static final int DEFAULT_CHILDREN_COUNT = 7;
+
+ static {
+ String[] fontNames;
+
+ try {
+ fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getAvailableFontFamilyNames();
+
+ } catch (Exception e) {
+ fontNames = null;
+ }
+ if (fontNames == null || fontNames.length == 0) {
+ NAMES = new String[] { "Mark Andrews", "Tom Ball", "Alan Chung",
+ "Rob Davis", "Jeff Dinkins",
+ "Amy Fowler", "James Gosling",
+ "David Karlton", "Dave Kloba",
+ "Dave Moore", "Hans Muller",
+ "Rick Levenson", "Tim Prinzing",
+ "Chester Rose", "Ray Ryan",
+ "Georges Saab", "Scott Violet",
+ "Kathy Walrath", "Arnaud Weber" };
+ } else {
+ /* Create the Fonts, creating fonts is slow, much better to
+ do it once. */
+ int fontSize = 12;
+
+ NAMES = fontNames;
+ fonts = new Font[NAMES.length];
+ for (int counter = 0, maxCounter = NAMES.length;
+ counter < maxCounter; counter++) {
+ try {
+ fonts[counter] = new Font(fontNames[counter], 0, fontSize);
+ } catch (Exception e) {
+ fonts[counter] = null;
+ }
+ fontSize = ((fontSize + 2 - 12) % 12) + 12;
+ }
+ }
+ nameCount = (float) NAMES.length;
+ nameGen = new Random(System.currentTimeMillis());
+ }
+ /** Have the children of this node been loaded yet? */
+ protected boolean hasLoaded;
+
+ /**
+ * Constructs a new DynamicTreeNode instance with o as the user
+ * object.
+ */
+ public DynamicTreeNode(Object o) {
+ super(o);
+ }
+
+ @Override
+ public boolean isLeaf() {
+ return false;
+ }
+
+ /**
+ * If hasLoaded is false, meaning the children have not yet been
+ * loaded, loadChildren is messaged and super is messaged for
+ * the return value.
+ */
+ @Override
+ public int getChildCount() {
+ if (!hasLoaded) {
+ loadChildren();
+ }
+ return super.getChildCount();
+ }
+
+ /**
+ * Messaged the first time getChildCount is messaged. Creates
+ * children with random names from names.
+ */
+ protected void loadChildren() {
+ DynamicTreeNode newNode;
+ Font font;
+ int randomIndex;
+ SampleData data;
+
+ for (int counter = 0; counter < DynamicTreeNode.DEFAULT_CHILDREN_COUNT;
+ counter++) {
+ randomIndex = (int) (nameGen.nextFloat() * nameCount);
+ String displayString = NAMES[randomIndex];
+ if (fonts == null || fonts[randomIndex].canDisplayUpTo(displayString)
+ != -1) {
+ font = null;
+ } else {
+ font = fonts[randomIndex];
+ }
+
+ if (counter % 2 == 0) {
+ data = new SampleData(font, Color.red, displayString);
+ } else {
+ data = new SampleData(font, Color.blue, displayString);
+ }
+ newNode = new DynamicTreeNode(data);
+ /* Don't use add() here, add calls insert(newNode, getChildCount())
+ so if you want to use add, just be sure to set hasLoaded = true
+ first. */
+ insert(newNode, counter);
+ }
+ /* This node has now been loaded, mark it so. */
+ hasLoaded = true;
+ }
+}