gvsig-scripting / trunk / org.gvsig.scripting.thing / src / main / java / thing / ThinletWorkarounds.java @ 4
History | View | Annotate | Download (9.61 KB)
1 |
// jEdit settings:
|
---|---|
2 |
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
|
3 |
|
4 |
package thing; |
5 |
|
6 |
|
7 |
import java.awt.AWTKeyStroke; |
8 |
import java.awt.Color; |
9 |
import java.awt.Font; |
10 |
import java.util.Arrays; |
11 |
import java.util.Enumeration; |
12 |
import java.util.Hashtable; |
13 |
import java.util.HashSet; |
14 |
import java.util.NoSuchElementException; |
15 |
import java.util.Set; |
16 |
import java.util.StringTokenizer; |
17 |
|
18 |
import thinlet.Thinlet; |
19 |
|
20 |
|
21 |
/**
|
22 |
* This class encapsulates workarounds for missing functionality in
|
23 |
* Thinlet.java.
|
24 |
* <p>
|
25 |
* Some of Thinlet's private methods needed by ThinG are copied here and have
|
26 |
* at times been sligtly modified. This methods need to be adapted when
|
27 |
* their counterparts in Thinlet.java changes.
|
28 |
* <p>
|
29 |
* Some other helper methods are here, that should better be put into
|
30 |
* Thinlet.java.
|
31 |
*
|
32 |
* @author Dirk Moebius
|
33 |
*/
|
34 |
public class ThinletWorkarounds |
35 |
{ |
36 |
//{{{ private methods copied from Thinlet.java
|
37 |
/**
|
38 |
* Copied from <code>Thinlet.java</code>:
|
39 |
* Get a specified sub-component or component part. Key is e.g. "header" (table header),
|
40 |
* ":parent" (parent component), ":comp" (head of a component list),
|
41 |
* ":next" (next component in a list), "popupmenu" is a popupmenu, etc ...
|
42 |
*/
|
43 |
static Object get(Object component, String key) { |
44 |
for (Object[] entry = (Object[]) component; entry != null; |
45 |
entry = (Object[]) entry[2]) { |
46 |
if (key.equals((String)entry[0])) { |
47 |
return entry[1]; |
48 |
} |
49 |
} |
50 |
return null; |
51 |
} |
52 |
//}}}
|
53 |
|
54 |
|
55 |
//{{{ methods missing in Thinlet.java
|
56 |
/**
|
57 |
* Gets the property value of the given component by the property key.
|
58 |
* This method should really be in Thinlet.java.
|
59 |
*/
|
60 |
public static Color getColor(Object component, String key) |
61 |
{ |
62 |
return (Color) get(component, key); |
63 |
} |
64 |
|
65 |
|
66 |
/**
|
67 |
* Gets the font of the given component, or the font of the thinlet, if
|
68 |
* the font of the component has not been set explicitely.
|
69 |
* This method should really be in Thinlet.java.
|
70 |
*/
|
71 |
public static Font getFont(Thinlet thinlet, Object component, String key) |
72 |
{ |
73 |
Font font = getFont(component, key);
|
74 |
return font == null ? thinlet.getFont() : font; |
75 |
} |
76 |
|
77 |
|
78 |
/**
|
79 |
* Gets the property value of the given component by the property key,
|
80 |
* in this case, a font. In most cases, the property key is "font".
|
81 |
* This method should really be in Thinlet.java.
|
82 |
*/
|
83 |
public static Font getFont(Object component, String key) |
84 |
{ |
85 |
return (Font) get(component, key); |
86 |
} |
87 |
|
88 |
|
89 |
/**
|
90 |
*
|
91 |
*/
|
92 |
public static AWTKeyStroke getKeystroke(Object component, String key) |
93 |
{ |
94 |
Object value = get(component, key);
|
95 |
if (value != null) { |
96 |
long keystroke = ((Long) value).longValue(); |
97 |
int modifiers = (int) (keystroke >> 32); |
98 |
int keycode = (int) (keystroke & 0xffff); |
99 |
return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers); |
100 |
} |
101 |
return null; |
102 |
} |
103 |
|
104 |
|
105 |
/**
|
106 |
* Ripped off <code>Thinlet.addAttribute()</code>: returns a <code>Color</code>
|
107 |
* object for a color description such as "#A0A0A0" or "0xA0A0A0" or
|
108 |
* "240,240,240".
|
109 |
*/
|
110 |
public static Color string2color(String value) |
111 |
{ |
112 |
if(value == null) return null; |
113 |
if(value.length() == 0) return null; |
114 |
int color = 0; |
115 |
if (value.startsWith("#")) { color = Integer.parseInt(value.substring(1), 16); } |
116 |
else if (value.startsWith("0x")) { color = Integer.parseInt(value.substring(2), 16); } |
117 |
else { // three separated integer including red, green, and blue |
118 |
StringTokenizer st = new StringTokenizer(value, " \r\n\t,"); |
119 |
color = 0xff000000 | ((Integer.parseInt(st.nextToken()) & 0xff) << 16) | |
120 |
((Integer.parseInt(st.nextToken()) & 0xff) << 8) | |
121 |
(Integer.parseInt(st.nextToken()) & 0xff); |
122 |
} |
123 |
return new Color(color); |
124 |
} |
125 |
|
126 |
|
127 |
/**
|
128 |
* Ripped off <code>Thinlet.addAttribute()</code>: returns a <code>Font</code>
|
129 |
* object for a thinlet font description such as "Serif 10 bold italic".
|
130 |
*/
|
131 |
public static Font string2font(Thinlet thinlet, String value) |
132 |
{ |
133 |
Font font = thinlet.getFont(); // default thinlet font |
134 |
String name = null; |
135 |
boolean bold = false; boolean italic = false; |
136 |
int size = 0; |
137 |
StringTokenizer st = new StringTokenizer(value); |
138 |
while (st.hasMoreTokens()) {
|
139 |
String token = st.nextToken();
|
140 |
if ("bold".equalsIgnoreCase(token)) { bold = true; } |
141 |
else if ("italic".equalsIgnoreCase(token)) { italic = true; } |
142 |
else {
|
143 |
try {
|
144 |
size = Integer.parseInt(token);
|
145 |
} catch (NumberFormatException nfe) { |
146 |
name = (name == null) ? token : (name + " " + token); |
147 |
} |
148 |
} |
149 |
} |
150 |
if (name == null) { name = font.getName(); } |
151 |
if (size == 0) { size = font.getSize(); } |
152 |
return new Font(name, |
153 |
(bold ? Font.BOLD : 0) | (italic ? Font.ITALIC : 0), size); |
154 |
} |
155 |
|
156 |
|
157 |
/**
|
158 |
* Returns an enumeration of all client property keys defined in the
|
159 |
* specified component.
|
160 |
* This method should really be in Thinlet.java.
|
161 |
*/
|
162 |
public static Enumeration getPropertyKeys(Object component) |
163 |
{ |
164 |
Object table = get(component, ":bind"); |
165 |
if(table != null) |
166 |
return ((Hashtable) table).keys(); |
167 |
else
|
168 |
{ |
169 |
return new Enumeration() |
170 |
{ |
171 |
public boolean hasMoreElements() { return false; } |
172 |
public Object nextElement() { throw new NoSuchElementException("empty enumeration"); } |
173 |
}; |
174 |
} |
175 |
} |
176 |
|
177 |
|
178 |
/**
|
179 |
* Gets all the components in this container.
|
180 |
* <p>
|
181 |
* The difference between <code>Thinlet.getItems(Object component)</code>
|
182 |
* is the following: If the container is a tree, then recursively get
|
183 |
* <i>all</i> nodes of the tree. (The Thinlet method only returns the
|
184 |
* nodes of the top level).
|
185 |
*/
|
186 |
public static Object[] getItems(Thinlet thinlet, Object component) |
187 |
{ |
188 |
String classname = Thinlet.getClass(component);
|
189 |
if(classname.equals("tree")) |
190 |
{ |
191 |
Set result = new HashSet(); |
192 |
getAllTreeItems(thinlet, component, result); |
193 |
return (Object[]) result.toArray(new Object[result.size()]); |
194 |
} |
195 |
else
|
196 |
return thinlet.getItems(component);
|
197 |
} |
198 |
|
199 |
|
200 |
/**
|
201 |
* Returns the index of the specified item in the item list of the
|
202 |
* specified component.
|
203 |
* Note that trees are <i>not</i> searched recursively.
|
204 |
* This method should really be in Thinlet.java.
|
205 |
*
|
206 |
* @param thinlet the Thinlet
|
207 |
* @param component the component; this should be a component that
|
208 |
* has sub-items such as tree, table, node etc.
|
209 |
* @param item the item to search for.
|
210 |
* @return the index of the item, or -1 if the item cannot be found.
|
211 |
*/
|
212 |
public static int getIndexOfItem(Thinlet thinlet, Object component, Object item) |
213 |
{ |
214 |
Object[] items = thinlet.getItems(component); |
215 |
for(int i = 0; i < items.length; ++i) |
216 |
if(item == items[i])
|
217 |
return i;
|
218 |
return -1; |
219 |
} |
220 |
|
221 |
|
222 |
/**
|
223 |
* Sets the selected item of the specified component, deselects all others.
|
224 |
* This method should really be in Thinlet.java.
|
225 |
*/
|
226 |
public static void setSelectedItem(Thinlet thinlet, Object component, Object item) |
227 |
{ |
228 |
Object[] items = getItems(thinlet, component); |
229 |
if(items != null) |
230 |
{ |
231 |
for(int i = 0; i < items.length; ++i) |
232 |
thinlet.setBoolean(items[i], "selected", items[i] == item);
|
233 |
} |
234 |
} |
235 |
|
236 |
|
237 |
/**
|
238 |
* Returns the total count of all sub-components of the specified
|
239 |
* components, including the children's children, recursively.
|
240 |
*/
|
241 |
public static int getTotalCount(Thinlet thinlet, Object component) |
242 |
{ |
243 |
class CountVisitor implements ComponentWalker.Visitor |
244 |
{ |
245 |
int count = 0; |
246 |
public boolean visit(Object component, int depth) { count++; return true; } |
247 |
public void leave(Object component, int depth) {} |
248 |
} |
249 |
|
250 |
CountVisitor visitor = new CountVisitor();
|
251 |
new ComponentWalker().walk(thinlet, component, visitor);
|
252 |
return visitor.count;
|
253 |
} |
254 |
|
255 |
|
256 |
/**
|
257 |
* Returns a short string representation of the specified component,
|
258 |
* for example "button:btnOk". Useful for debugging output.
|
259 |
*
|
260 |
* @param component the component. If it is null, the string "null" is
|
261 |
* returned.
|
262 |
* @return a string representation of the component.
|
263 |
*/
|
264 |
public static String toString(Object component) |
265 |
{ |
266 |
if(component == null) |
267 |
return "null"; |
268 |
StringBuffer buf = new StringBuffer("["); |
269 |
String classname = Thinlet.getClass(component);
|
270 |
if(classname == null) |
271 |
buf.append("not a component: ").append(component.toString());
|
272 |
else
|
273 |
{ |
274 |
buf.append(classname); |
275 |
String name = (String) get(component, "name"); |
276 |
if(name != null) |
277 |
buf.append(':').append(name);
|
278 |
} |
279 |
buf.append(']');
|
280 |
return buf.toString();
|
281 |
} |
282 |
//}}}
|
283 |
|
284 |
|
285 |
//{{{ private helper methods
|
286 |
private static void getAllTreeItems(Thinlet thinlet, Object component, Set result) |
287 |
{ |
288 |
Object[] items = thinlet.getItems(component); |
289 |
result.addAll(Arrays.asList(items));
|
290 |
for(int i = 0; i < items.length; ++i) |
291 |
{ |
292 |
String classname = Thinlet.getClass(items[i]);
|
293 |
if(classname.equals("node")) |
294 |
getAllTreeItems(thinlet, items[i], result); |
295 |
} |
296 |
} |
297 |
//}}}
|
298 |
|
299 |
} |
300 |
|