1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59:
60: public class StyleContext
61: implements Serializable, AbstractDocument.AttributeContext
62: {
63:
64: private static final long serialVersionUID = 8042858831190784241L;
65:
66: public class NamedStyle
67: implements Serializable, Style
68: {
69:
70: private static final long serialVersionUID = -6690628971806226374L;
71:
72: protected ChangeEvent changeEvent;
73: protected EventListenerList listenerList;
74:
75: AttributeSet attributes;
76: String name;
77:
78: public NamedStyle()
79: {
80: this(null, null);
81: }
82:
83: public NamedStyle(Style parent)
84: {
85: this(null, parent);
86: }
87:
88: public NamedStyle(String name, Style parent)
89: {
90: this.name = name;
91: this.attributes = getEmptySet();
92: this.changeEvent = new ChangeEvent(this);
93: this.listenerList = new EventListenerList();
94: setResolveParent(parent);
95: }
96:
97: public String getName()
98: {
99: return name;
100: }
101:
102: public void setName(String n)
103: {
104: name = n;
105: fireStateChanged();
106: }
107:
108: public void addChangeListener(ChangeListener l)
109: {
110: listenerList.add(ChangeListener.class, l);
111: }
112:
113: public void removeChangeListener(ChangeListener l)
114: {
115: listenerList.remove(ChangeListener.class, l);
116: }
117:
118: public EventListener[] getListeners(Class listenerType)
119: {
120: return listenerList.getListeners(listenerType);
121: }
122:
123: public ChangeListener[] getChangeListeners()
124: {
125: return (ChangeListener[]) getListeners(ChangeListener.class);
126: }
127:
128: protected void fireStateChanged()
129: {
130: ChangeListener[] listeners = getChangeListeners();
131: for (int i = 0; i < listeners.length; ++i)
132: {
133: listeners[i].stateChanged(changeEvent);
134: }
135: }
136:
137: public void addAttribute(Object name, Object value)
138: {
139: attributes = StyleContext.this.addAttribute(attributes, name, value);
140: fireStateChanged();
141: }
142:
143: public void addAttributes(AttributeSet attr)
144: {
145: attributes = StyleContext.this.addAttributes(attributes, attr);
146: fireStateChanged();
147: }
148:
149: public boolean containsAttribute(Object name, Object value)
150: {
151: return attributes.containsAttribute(name, value);
152: }
153:
154: public boolean containsAttributes(AttributeSet attrs)
155: {
156: return attributes.containsAttributes(attrs);
157: }
158:
159: public AttributeSet copyAttributes()
160: {
161: return attributes.copyAttributes();
162: }
163:
164: public Object getAttribute(Object attrName)
165: {
166: return attributes.getAttribute(attrName);
167: }
168:
169: public int getAttributeCount()
170: {
171: return attributes.getAttributeCount();
172: }
173:
174: public Enumeration getAttributeNames()
175: {
176: return attributes.getAttributeNames();
177: }
178:
179: public boolean isDefined(Object attrName)
180: {
181: return attributes.isDefined(attrName);
182: }
183:
184: public boolean isEqual(AttributeSet attr)
185: {
186: return attributes.isEqual(attr);
187: }
188:
189: public void removeAttribute(Object name)
190: {
191: attributes = StyleContext.this.removeAttribute(attributes, name);
192: fireStateChanged();
193: }
194:
195: public void removeAttributes(AttributeSet attrs)
196: {
197: attributes = StyleContext.this.removeAttributes(attributes, attrs);
198: fireStateChanged();
199: }
200:
201: public void removeAttributes(Enumeration names)
202: {
203: attributes = StyleContext.this.removeAttributes(attributes, names);
204: fireStateChanged();
205: }
206:
207:
208: public AttributeSet getResolveParent()
209: {
210: return attributes.getResolveParent();
211: }
212:
213: public void setResolveParent(AttributeSet parent)
214: {
215: if (parent != null)
216: {
217: attributes = StyleContext.this.addAttribute
218: (attributes, ResolveAttribute, parent);
219: }
220: fireStateChanged();
221: }
222:
223: public String toString()
224: {
225: return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
226: }
227: }
228:
229: public class SmallAttributeSet
230: implements AttributeSet
231: {
232: final Object [] attrs;
233: public SmallAttributeSet(AttributeSet a)
234: {
235: if (a == null)
236: attrs = new Object[0];
237: else
238: {
239: int n = a.getAttributeCount();
240: int i = 0;
241: attrs = new Object[n * 2];
242: Enumeration e = a.getAttributeNames();
243: while (e.hasMoreElements())
244: {
245: Object name = e.nextElement();
246: attrs[i++] = name;
247: attrs[i++] = a.getAttribute(name);
248: }
249: }
250: }
251:
252: public SmallAttributeSet(Object [] a)
253: {
254: if (a == null)
255: attrs = new Object[0];
256: else
257: {
258: attrs = new Object[a.length];
259: System.arraycopy(a, 0, attrs, 0, a.length);
260: }
261: }
262:
263: public Object clone()
264: {
265: return new SmallAttributeSet(this.attrs);
266: }
267:
268: public boolean containsAttribute(Object name, Object value)
269: {
270: for (int i = 0; i < attrs.length; i += 2)
271: {
272: if (attrs[i].equals(name) &&
273: attrs[i+1].equals(value))
274: return true;
275: }
276: return false;
277: }
278:
279: public boolean containsAttributes(AttributeSet a)
280: {
281: Enumeration e = a.getAttributeNames();
282: while (e.hasMoreElements())
283: {
284: Object name = e.nextElement();
285: Object val = a.getAttribute(name);
286: if (!containsAttribute(name, val))
287: return false;
288: }
289: return true;
290: }
291:
292: public AttributeSet copyAttributes()
293: {
294: return (AttributeSet) clone();
295: }
296:
297: public boolean equals(Object obj)
298: {
299: return
300: (obj instanceof AttributeSet)
301: && this.isEqual((AttributeSet)obj);
302: }
303:
304: public Object getAttribute(Object key)
305: {
306: for (int i = 0; i < attrs.length; i += 2)
307: {
308: if (attrs[i].equals(key))
309: return attrs[i+1];
310: }
311:
312:
313:
314: if (!(key.equals(ResolveAttribute)))
315: {
316: Object p = getResolveParent();
317: if (p != null && p instanceof AttributeSet)
318: return (((AttributeSet)p).getAttribute(key));
319: }
320:
321: return null;
322: }
323:
324: public int getAttributeCount()
325: {
326: return attrs.length / 2;
327: }
328:
329: public Enumeration getAttributeNames()
330: {
331: return new Enumeration()
332: {
333: int i = 0;
334: public boolean hasMoreElements()
335: {
336: return i < attrs.length;
337: }
338: public Object nextElement()
339: {
340: i += 2;
341: return attrs[i-2];
342: }
343: };
344: }
345:
346: public AttributeSet getResolveParent()
347: {
348: return (AttributeSet) getAttribute(ResolveAttribute);
349: }
350:
351: public int hashCode()
352: {
353: return java.util.Arrays.asList(attrs).hashCode();
354: }
355:
356: public boolean isDefined(Object key)
357: {
358: for (int i = 0; i < attrs.length; i += 2)
359: {
360: if (attrs[i].equals(key))
361: return true;
362: }
363: return false;
364: }
365:
366: public boolean isEqual(AttributeSet attr)
367: {
368: return getAttributeCount() == attr.getAttributeCount()
369: && this.containsAttributes(attr);
370: }
371:
372: public String toString()
373: {
374: StringBuffer sb = new StringBuffer();
375: sb.append("[StyleContext.SmallattributeSet:");
376: for (int i = 0; i < attrs.length - 1; ++i)
377: {
378: sb.append(" (");
379: sb.append(attrs[i].toString());
380: sb.append("=");
381: sb.append(attrs[i+1].toString());
382: sb.append(")");
383: }
384: sb.append("]");
385: return sb.toString();
386: }
387: }
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
400: public static final String DEFAULT_STYLE = "default";
401:
402:
405: NamedStyle defaultStyle = new NamedStyle(DEFAULT_STYLE, null);
406:
407: static Hashtable sharedAttributeSets = new Hashtable();
408: static Hashtable sharedFonts = new Hashtable();
409:
410: static StyleContext defaultStyleContext = new StyleContext();
411: static final int compressionThreshold = 9;
412:
413:
416: private static HashSet staticAttributeKeys = new HashSet();
417:
418: EventListenerList listenerList;
419: Hashtable styleTable;
420:
421:
425: public StyleContext()
426: {
427: listenerList = new EventListenerList();
428: styleTable = new Hashtable();
429: styleTable.put(DEFAULT_STYLE, defaultStyle);
430: }
431:
432: protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
433: {
434: return new SmallAttributeSet(a);
435: }
436:
437: protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
438: {
439: return new SimpleAttributeSet(a);
440: }
441:
442: public void addChangeListener(ChangeListener listener)
443: {
444: listenerList.add(ChangeListener.class, listener);
445: }
446:
447: public void removeChangeListener(ChangeListener listener)
448: {
449: listenerList.remove(ChangeListener.class, listener);
450: }
451:
452: public ChangeListener[] getChangeListeners()
453: {
454: return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
455: }
456:
457: public Style addStyle(String name, Style parent)
458: {
459: Style newStyle = new NamedStyle(name, parent);
460: if (name != null)
461: styleTable.put(name, newStyle);
462: return newStyle;
463: }
464:
465: public void removeStyle(String name)
466: {
467: styleTable.remove(name);
468: }
469:
470:
480: public Style getStyle(String name)
481: {
482: return (Style) styleTable.get(name);
483: }
484:
485:
489: public Enumeration getStyleNames()
490: {
491: return styleTable.keys();
492: }
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509: private static class SimpleFontSpec
510: {
511: String family;
512: int style;
513: int size;
514: public SimpleFontSpec(String family,
515: int style,
516: int size)
517: {
518: this.family = family;
519: this.style = style;
520: this.size = size;
521: }
522: public boolean equals(Object obj)
523: {
524: return (obj != null)
525: && (obj instanceof SimpleFontSpec)
526: && (((SimpleFontSpec)obj).family.equals(this.family))
527: && (((SimpleFontSpec)obj).style == this.style)
528: && (((SimpleFontSpec)obj).size == this.size);
529: }
530: public int hashCode()
531: {
532: return family.hashCode() + style + size;
533: }
534: }
535:
536: public Font getFont(AttributeSet attr)
537: {
538: String family = StyleConstants.getFontFamily(attr);
539: int style = Font.PLAIN;
540: if (StyleConstants.isBold(attr))
541: style += Font.BOLD;
542: if (StyleConstants.isItalic(attr))
543: style += Font.ITALIC;
544: int size = StyleConstants.getFontSize(attr);
545: return getFont(family, style, size);
546: }
547:
548: public Font getFont(String family, int style, int size)
549: {
550: SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
551: if (sharedFonts.containsKey(spec))
552: return (Font) sharedFonts.get(spec);
553: else
554: {
555: Font tmp = new Font(family, style, size);
556: sharedFonts.put(spec, tmp);
557: return tmp;
558: }
559: }
560:
561: public FontMetrics getFontMetrics(Font f)
562: {
563: return Toolkit.getDefaultToolkit().getFontMetrics(f);
564: }
565:
566: public Color getForeground(AttributeSet a)
567: {
568: return StyleConstants.getForeground(a);
569: }
570:
571: public Color getBackground(AttributeSet a)
572: {
573: return StyleConstants.getBackground(a);
574: }
575:
576: protected int getCompressionThreshold()
577: {
578: return compressionThreshold;
579: }
580:
581: public static StyleContext getDefaultStyleContext()
582: {
583: return defaultStyleContext;
584: }
585:
586: public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
587: {
588: if (old instanceof MutableAttributeSet)
589: {
590: ((MutableAttributeSet)old).addAttribute(name, value);
591: return old;
592: }
593: else
594: {
595: MutableAttributeSet mutable = createLargeAttributeSet(old);
596: mutable.addAttribute(name, value);
597: if (mutable.getAttributeCount() >= getCompressionThreshold())
598: return mutable;
599: else
600: {
601: SmallAttributeSet small = createSmallAttributeSet(mutable);
602: if (sharedAttributeSets.containsKey(small))
603: small = (SmallAttributeSet) sharedAttributeSets.get(small);
604: else
605: sharedAttributeSets.put(small,small);
606: return small;
607: }
608: }
609: }
610:
611: public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
612: {
613: if (old instanceof MutableAttributeSet)
614: {
615: ((MutableAttributeSet)old).addAttributes(attributes);
616: return old;
617: }
618: else
619: {
620: MutableAttributeSet mutable = createLargeAttributeSet(old);
621: mutable.addAttributes(attributes);
622: if (mutable.getAttributeCount() >= getCompressionThreshold())
623: return mutable;
624: else
625: {
626: SmallAttributeSet small = createSmallAttributeSet(mutable);
627: if (sharedAttributeSets.containsKey(small))
628: small = (SmallAttributeSet) sharedAttributeSets.get(small);
629: else
630: sharedAttributeSets.put(small,small);
631: return small;
632: }
633: }
634: }
635:
636: public AttributeSet getEmptySet()
637: {
638: AttributeSet e = createSmallAttributeSet(null);
639: if (sharedAttributeSets.containsKey(e))
640: e = (AttributeSet) sharedAttributeSets.get(e);
641: else
642: sharedAttributeSets.put(e, e);
643: return e;
644: }
645:
646: public void reclaim(AttributeSet attributes)
647: {
648: if (sharedAttributeSets.containsKey(attributes))
649: sharedAttributeSets.remove(attributes);
650: }
651:
652: public AttributeSet removeAttribute(AttributeSet old, Object name)
653: {
654: if (old instanceof MutableAttributeSet)
655: {
656: ((MutableAttributeSet)old).removeAttribute(name);
657: if (old.getAttributeCount() < getCompressionThreshold())
658: {
659: SmallAttributeSet small = createSmallAttributeSet(old);
660: if (!sharedAttributeSets.containsKey(small))
661: sharedAttributeSets.put(small,small);
662: old = (AttributeSet) sharedAttributeSets.get(small);
663: }
664: return old;
665: }
666: else
667: {
668: MutableAttributeSet mutable = createLargeAttributeSet(old);
669: mutable.removeAttribute(name);
670: SmallAttributeSet small = createSmallAttributeSet(mutable);
671: if (sharedAttributeSets.containsKey(small))
672: small = (SmallAttributeSet) sharedAttributeSets.get(small);
673: else
674: sharedAttributeSets.put(small,small);
675: return small;
676: }
677: }
678:
679: public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
680: {
681: return removeAttributes(old, attributes.getAttributeNames());
682: }
683:
684: public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
685: {
686: if (old instanceof MutableAttributeSet)
687: {
688: ((MutableAttributeSet)old).removeAttributes(names);
689: if (old.getAttributeCount() < getCompressionThreshold())
690: {
691: SmallAttributeSet small = createSmallAttributeSet(old);
692: if (!sharedAttributeSets.containsKey(small))
693: sharedAttributeSets.put(small,small);
694: old = (AttributeSet) sharedAttributeSets.get(small);
695: }
696: return old;
697: }
698: else
699: {
700: MutableAttributeSet mutable = createLargeAttributeSet(old);
701: mutable.removeAttributes(names);
702: SmallAttributeSet small = createSmallAttributeSet(mutable);
703: if (sharedAttributeSets.containsKey(small))
704: small = (SmallAttributeSet) sharedAttributeSets.get(small);
705: else
706: sharedAttributeSets.put(small,small);
707: return small;
708: }
709: }
710:
711:
712:
713:
714:
715: public static Object getStaticAttribute(Object key)
716: throws NotImplementedException
717: {
718: throw new InternalError("not implemented");
719: }
720:
721: public static Object getStaticAttributeKey(Object key)
722: throws NotImplementedException
723: {
724: throw new InternalError("not implemented");
725: }
726:
727: public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
728: throws ClassNotFoundException, IOException, NotImplementedException
729: {
730: throw new InternalError("not implemented");
731: }
732:
733: public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
734: throws IOException, NotImplementedException
735: {
736: throw new InternalError("not implemented");
737: }
738:
739: public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
740: throws ClassNotFoundException, IOException, NotImplementedException
741: {
742: throw new InternalError("not implemented");
743: }
744:
745: public void writeAttributes(ObjectOutputStream out, AttributeSet a)
746: throws IOException, NotImplementedException
747: {
748: throw new InternalError("not implemented");
749: }
750:
751:
761: public static void registerStaticAttributeKey(Object key)
762: {
763: staticAttributeKeys.add(key);
764: }
765: }