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