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