1 17 package swingwtx.swing; 18 19 import java.beans.PropertyChangeListener; 20 import java.io.IOException; 21 import java.io.ObjectInputStream; 22 import java.io.ObjectOutputStream; 23 import java.io.Serializable; 24 import java.util.Enumeration; 25 import java.util.Hashtable; 26 27 import swingwtx.swing.event.SwingPropertyChangeSupport; 28 29 32 public abstract class AbstractAction implements Action, Cloneable, Serializable { 33 34 protected boolean enabled = true; 35 36 private transient ArrayTable arrayTable; 37 38 public AbstractAction() { 39 } 40 41 public AbstractAction(String name) { 42 putValue(Action.NAME, name); 43 } 44 45 public AbstractAction(String name, Icon icon) { 46 this(name); 47 putValue(Action.SMALL_ICON, icon); 48 } 49 50 public Object getValue(String key) { 51 if (arrayTable == null) { 52 return null; 53 } 54 return arrayTable.get(key); 55 } 56 57 public void putValue(String key, Object newValue) { 58 Object oldValue = null; 59 if (arrayTable == null) { 60 arrayTable = new ArrayTable(); 61 } 62 if (arrayTable.containsKey(key)) 63 oldValue = arrayTable.get(key); 64 if (newValue == null) { 65 arrayTable.remove(key); 66 } else { 67 arrayTable.put(key, newValue); 68 } 69 firePropertyChange(key, oldValue, newValue); 70 } 71 72 public boolean isEnabled() { 73 return enabled; 74 } 75 76 public void setEnabled(boolean newValue) { 77 boolean oldValue = this.enabled; 78 79 if (oldValue != newValue) { 80 this.enabled = newValue; 81 firePropertyChange( 82 "enabled", 83 new Boolean(oldValue), 84 new Boolean(newValue)); 85 } 86 } 87 88 public Object[] getKeys() { 89 if (arrayTable == null) { 90 return null; 91 } 92 Object[] keys = new Object[arrayTable.size()]; 93 arrayTable.getKeys(keys); 94 return keys; 95 } 96 97 protected SwingPropertyChangeSupport changeSupport; 98 99 protected void firePropertyChange( 100 String propertyName, 101 Object oldValue, 102 Object newValue) { 103 if (changeSupport == null 104 || (oldValue != null 105 && newValue != null 106 && oldValue.equals(newValue))) { 107 return; 108 } 109 changeSupport.firePropertyChange(propertyName, oldValue, newValue); 110 } 111 112 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { 113 if (changeSupport == null) { 114 changeSupport = new SwingPropertyChangeSupport(this); 115 } 116 changeSupport.addPropertyChangeListener(listener); 117 } 118 119 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { 120 if (changeSupport == null) { 121 return; 122 } 123 changeSupport.removePropertyChangeListener(listener); 124 } 125 126 public synchronized PropertyChangeListener[] getPropertyChangeListeners() { 127 if (changeSupport == null) { 128 return new PropertyChangeListener[0]; 129 } 130 return changeSupport.getPropertyChangeListeners(); 131 } 132 133 protected Object clone() throws CloneNotSupportedException { 134 AbstractAction newAction = (AbstractAction) super.clone(); 135 synchronized (this) { 136 if (arrayTable != null) { 137 newAction.arrayTable = (ArrayTable) arrayTable.clone(); 138 } 139 } 140 return newAction; 141 } 142 143 private void writeObject(ObjectOutputStream s) throws IOException { 144 s.defaultWriteObject(); 145 146 ArrayTable.writeArrayTable(s, arrayTable); 147 } 148 149 private void readObject(ObjectInputStream s) 150 throws ClassNotFoundException, IOException { 151 s.defaultReadObject(); 152 for (int counter = s.readInt() - 1; counter >= 0; counter--) { 153 putValue((String) s.readObject(), s.readObject()); 154 } 155 } 156 157 static class ArrayTable implements Cloneable { 158 private Object table = null; 159 private static final int ARRAY_BOUNDARY = 8; 160 161 public void put(Object key, Object value) { 162 if (table == null) { 163 table = new Object[] { key, value }; 164 } else { 165 int size = size(); 166 if (size < ARRAY_BOUNDARY) { 167 if (containsKey(key)) { 168 Object[] tmp = (Object[]) table; 169 for (int i = 0; i < tmp.length - 1; i += 2) { 170 if (tmp[i].equals(key)) { 171 tmp[i + 1] = value; 172 break; 173 } 174 } 175 } else { 176 Object[] array = (Object[]) table; 177 int i = array.length; 178 Object[] tmp = new Object[i + 2]; 179 System.arraycopy(array, 0, tmp, 0, i); 180 181 tmp[i] = key; 182 tmp[i + 1] = value; 183 table = tmp; 184 } 185 } else { 186 if ((size == ARRAY_BOUNDARY) && isArray()) { 187 grow(); 188 } 189 ((Hashtable) table).put(key, value); 190 } 191 } 192 } 193 194 public Object get(Object key) { 195 Object value = null; 196 if (table != null) { 197 if (isArray()) { 198 Object[] array = (Object[]) table; 199 for (int i = 0; i < array.length - 1; i += 2) { 200 if (array[i].equals(key)) { 201 value = array[i + 1]; 202 break; 203 } 204 } 205 } else { 206 value = ((Hashtable) table).get(key); 207 } 208 } 209 return value; 210 } 211 212 public int size() { 213 int size; 214 if (table == null) 215 return 0; 216 if (isArray()) { 217 size = ((Object[]) table).length / 2; 218 } else { 219 size = ((Hashtable) table).size(); 220 } 221 return size; 222 } 223 224 public boolean containsKey(Object key) { 225 boolean contains = false; 226 if (table != null) { 227 if (isArray()) { 228 Object[] array = (Object[]) table; 229 for (int i = 0; i < array.length - 1; i += 2) { 230 if (array[i].equals(key)) { 231 contains = true; 232 break; 233 } 234 } 235 } else { 236 contains = ((Hashtable) table).containsKey(key); 237 } 238 } 239 return contains; 240 } 241 242 public Object remove(Object key) { 243 Object value = null; 244 if (key == null) { 245 return null; 246 } 247 if (table != null) { 248 if (isArray()) { 249 int index = -1; 250 Object[] array = (Object[]) table; 251 for (int i = array.length - 2; i >= 0; i -= 2) { 252 if (array[i].equals(key)) { 253 index = i; 254 value = array[i + 1]; 255 break; 256 } 257 } 258 259 if (index != -1) { 260 Object[] tmp = new Object[array.length - 2]; 261 System.arraycopy(array, 0, tmp, 0, index); 262 if (index < tmp.length) 263 System.arraycopy( 264 array, 265 index + 2, 266 tmp, 267 index, 268 tmp.length - index); 269 table = (tmp.length == 0) ? null : tmp; 270 } 271 } else { 272 value = ((Hashtable) table).remove(key); 273 } 274 if (size() == 7 && !isArray()) { 275 shrink(); 276 } 277 } 278 return value; 279 } 280 281 public void clear() { 282 table = null; 283 } 284 285 public Object clone() { 286 ArrayTable newArrayTable = new ArrayTable(); 287 if (isArray()) { 288 Object[] array = (Object[]) table; 289 for (int i = 0; i < array.length - 1; i += 2) { 290 newArrayTable.put(array[i], array[i + 1]); 291 } 292 } else { 293 Hashtable tmp = (Hashtable) table; 294 Enumeration keys = tmp.keys(); 295 while (keys.hasMoreElements()) { 296 Object o = keys.nextElement(); 297 newArrayTable.put(o, tmp.get(o)); 298 } 299 } 300 return newArrayTable; 301 } 302 303 public Object[] getKeys(Object[] keys) { 304 if (table == null) { 305 return null; 306 } 307 if (isArray()) { 308 Object[] array = (Object[]) table; 309 if (keys == null) { 310 keys = new Object[array.length / 2]; 311 } 312 for (int i = 0, index = 0; 313 i < array.length - 1; 314 i += 2, index++) { 315 keys[index] = array[i]; 316 } 317 } else { 318 Hashtable tmp = (Hashtable) table; 319 Enumeration enum = tmp.keys(); 320 int counter = tmp.size(); 321 if (keys == null) { 322 keys = new Object[counter]; 323 } 324 while (counter > 0) { 325 keys[--counter] = enum.nextElement(); 326 } 327 } 328 return keys; 329 } 330 331 private boolean isArray() { 332 return (table instanceof Object[]); 333 } 334 335 private void grow() { 336 Object[] array = (Object[]) table; 337 Hashtable tmp = new Hashtable(array.length / 2); 338 for (int i = 0; i < array.length; i += 2) { 339 tmp.put(array[i], array[i + 1]); 340 } 341 table = tmp; 342 } 343 344 private void shrink() { 345 Hashtable tmp = (Hashtable) table; 346 Object[] array = new Object[tmp.size() * 2]; 347 Enumeration keys = tmp.keys(); 348 int j = 0; 349 350 while (keys.hasMoreElements()) { 351 Object o = keys.nextElement(); 352 array[j] = o; 353 array[j + 1] = tmp.get(o); 354 j += 2; 355 } 356 table = array; 357 } 358 359 static void writeArrayTable(ObjectOutputStream s, ArrayTable table) 360 throws IOException { 361 Object keys[]; 362 363 if (table == null || (keys = table.getKeys(null)) == null) { 364 s.writeInt(0); 365 } else { 366 int validCount = 0; 367 368 for (int counter = 0; counter < keys.length; counter++) { 369 if ((keys[counter] instanceof Serializable) 370 && (table.get(keys[counter]) instanceof Serializable)) { 371 validCount++; 372 } else { 373 keys[counter] = null; 374 } 375 } 376 s.writeInt(validCount); 377 if (validCount > 0) { 378 for (int counter = 0; counter < keys.length; counter++) { 379 if (keys[counter] != null) { 380 s.writeObject(keys[counter]); 381 s.writeObject(table.get(keys[counter])); 382 if (--validCount == 0) { 383 break; 384 } 385 } 386 } 387 } 388 } 389 } 390 } 391 } 392 393 410 | Popular Tags |