Source code: com/virtuosotechnologies/lib/basiccommand/builder/AbstractBuilderNode.java
1 /*
2 ================================================================================
3
4 FILE: AbstractBuilderNode.java
5
6 PROJECT:
7
8 Virtuoso Utilities
9
10 CONTENTS:
11
12 A skeletal implementation for builder nodes.
13
14 PROGRAMMERS:
15
16 Daniel Azuma (DA) <dazuma@kagi.com>
17
18 COPYRIGHT:
19
20 Copyright (C) 2003 Daniel Azuma (dazuma@kagi.com)
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public
33 License along with this program; if not, write to
34 Free Software Foundation, Inc.
35 59 Temple Place, Suite 330
36 Boston, MA 02111-1307 USA
37
38 ================================================================================
39 */
40
41
42 package com.virtuosotechnologies.lib.basiccommand.builder;
43
44
45 import java.util.Iterator;
46
47 import com.virtuosotechnologies.lib.propertyset.PropertySetListener;
48 import com.virtuosotechnologies.lib.propertyset.PropertySetEvent;
49 import com.virtuosotechnologies.lib.command.CommandNode;
50 import com.virtuosotechnologies.lib.basiccommand.BasicCommandNode;
51 import com.virtuosotechnologies.lib.util.ObjectUtils;
52
53
54 /**
55 * A skeletal implementation for builder nodes. Note that this builder
56 * registers itself as a PropertySetListener on the CommandNode, so
57 * subclasses do not need to do so again.
58 */
59 public abstract class AbstractBuilderNode
60 implements
61 PropertySetListener
62 {
63 protected static final int END_POSITION = -1;
64
65
66 private CommandNode commandNode_;
67 private AbstractBranchBuilderNode parent_;
68 private boolean hidden_;
69 private boolean disabled_;
70 private int maskLevel_;
71 private int grayLevel_;
72
73
74 /**
75 * Constructor
76 */
77 protected AbstractBuilderNode(
78 CommandNode commandNode,
79 AbstractBranchBuilderNode parent,
80 int index)
81 {
82 parent_ = parent;
83 if (parent_ != null)
84 {
85 if (index == END_POSITION)
86 {
87 parent_.internalAddChild(this);
88 }
89 else
90 {
91 parent_.internalAddChild(index, this);
92 }
93 }
94 maskLevel_ = 0;
95 grayLevel_ = 0;
96 hidden_ = Boolean.TRUE.equals(commandNode.getValue(BasicCommandNode.HIDDEN_PROPERTY));
97 disabled_ = Boolean.TRUE.equals(commandNode.getValue(BasicCommandNode.DISABLED_PROPERTY));
98 commandNode_ = commandNode;
99 commandNode_.addPropertySetListener(this);
100 }
101
102
103 /**
104 * Return the parent
105 */
106 protected final AbstractBranchBuilderNode getParent()
107 {
108 return parent_;
109 }
110
111
112 /**
113 * Return the action node
114 */
115 protected final CommandNode getCommandNode()
116 {
117 return commandNode_;
118 }
119
120
121 /**
122 * Get the hidden state
123 */
124 protected final boolean isHidden()
125 {
126 return hidden_;
127 }
128
129
130 /**
131 * Get the grayed state
132 */
133 protected final boolean isDisabled()
134 {
135 return disabled_;
136 }
137
138
139 /**
140 * Increment the mask level
141 */
142 protected final void incMaskLevel()
143 {
144 ++maskLevel_;
145 if (maskLevel_ == 1)
146 {
147 updateHidden();
148 }
149 }
150
151
152 /**
153 * Decrement the mask level
154 */
155 protected final void decMaskLevel()
156 {
157 --maskLevel_;
158 if (maskLevel_ == 0)
159 {
160 updateHidden();
161 }
162 }
163
164
165 /**
166 * Increment the gray level
167 */
168 protected final void incGrayLevel()
169 {
170 ++grayLevel_;
171 if (grayLevel_ == 1)
172 {
173 updateDisabled();
174 }
175 }
176
177
178 /**
179 * Decrement the gray level
180 */
181 protected final void decGrayLevel()
182 {
183 --grayLevel_;
184 if (grayLevel_ == 0)
185 {
186 updateDisabled();
187 }
188 }
189
190
191 /**
192 * Model changed. If this is overridden, be sure to call the superclass.
193 */
194 public void propertySetChanged(
195 PropertySetEvent ev)
196 {
197 if (ev.getKey().equals(BasicCommandNode.HIDDEN_PROPERTY))
198 {
199 updateHidden();
200 }
201 else if (ev.getKey().equals(BasicCommandNode.DISABLED_PROPERTY))
202 {
203 updateDisabled();
204 }
205 }
206
207
208 private final void updateHidden()
209 {
210 boolean nHidden =
211 Boolean.TRUE.equals(commandNode_.getValue(BasicCommandNode.HIDDEN_PROPERTY)) ||
212 maskLevel_ > 0;
213 if (nHidden != hidden_)
214 {
215 hidden_ = nHidden;
216 hiddenStateChanged(hidden_);
217 }
218 }
219
220
221 private final void updateDisabled()
222 {
223 boolean nDisabled =
224 Boolean.TRUE.equals(commandNode_.getValue(BasicCommandNode.DISABLED_PROPERTY)) ||
225 grayLevel_ > 0;
226 if (nDisabled != disabled_)
227 {
228 disabled_ = nDisabled;
229 disabledStateChanged(disabled_);
230 }
231 }
232
233
234 /**
235 * The hidden state has changed.
236 */
237 protected abstract void hiddenStateChanged(
238 boolean nowHidden);
239
240
241 /**
242 * The gray state has changed.
243 */
244 protected abstract void disabledStateChanged(
245 boolean nowDisabled);
246
247
248 /**
249 * Get the cardinality (number of swing objects this node represents).
250 * Most things have a cardinality of 1. Groups have variable cardinality.
251 */
252 protected abstract int getCardinality();
253
254
255 /**
256 * Dump subgraph to standard error
257 */
258 public static void dump(
259 AbstractBuilderNode node)
260 {
261 dump(node, "");
262 }
263
264
265 /**
266 * Dump subgraph to standard error
267 */
268 private static void dump(
269 AbstractBuilderNode node,
270 String indent)
271 {
272 CommandNode commandNode = node.getCommandNode();
273 System.err.println(indent+ObjectUtils.shortClassName(node)+" from "+
274 ObjectUtils.shortClassName(commandNode)+' '+
275 commandNode.getValue(BasicCommandNode.NAME_PROPERTY));
276 indent += " ";
277 if (node instanceof AbstractBranchBuilderNode)
278 {
279 AbstractBranchBuilderNode bnode = (AbstractBranchBuilderNode)node;
280 for (Iterator iter = bnode.getChildren().iterator(); iter.hasNext(); )
281 {
282 dump((AbstractBuilderNode)iter.next(), indent);
283 }
284 }
285 }
286 }