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 attr != null
366: && attr.containsAttributes(this)
367: && this.containsAttributes(attr);
368: }
369:
370: public String toString()
371: {
372: StringBuffer sb = new StringBuffer();
373: sb.append("[StyleContext.SmallattributeSet:");
374: for (int i = 0; i < attrs.length; ++i)
375: {
376: sb.append(" (");
377: sb.append(attrs[i].toString());
378: sb.append("=");
379: sb.append(attrs[i+1].toString());
380: sb.append(")");
381: }
382: sb.append("]");
383: return sb.toString();
384: }
385: }
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
398: public static final String DEFAULT_STYLE = "default";
399:
400:
403: NamedStyle defaultStyle = new NamedStyle(DEFAULT_STYLE, null);
404:
405: static Hashtable sharedAttributeSets = new Hashtable();
406: static Hashtable sharedFonts = new Hashtable();
407:
408: static StyleContext defaultStyleContext = new StyleContext();
409: static final int compressionThreshold = 9;
410:
411: EventListenerList listenerList;
412: Hashtable styleTable;
413:
414:
418: public StyleContext()
419: {
420: listenerList = new EventListenerList();
421: styleTable = new Hashtable();
422: styleTable.put(DEFAULT_STYLE, defaultStyle);
423: }
424:
425: protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
426: {
427: return new SmallAttributeSet(a);
428: }
429:
430: protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
431: {
432: return new SimpleAttributeSet(a);
433: }
434:
435: public void addChangeListener(ChangeListener listener)
436: {
437: listenerList.add(ChangeListener.class, listener);
438: }
439:
440: public void removeChangeListener(ChangeListener listener)
441: {
442: listenerList.remove(ChangeListener.class, listener);
443: }
444:
445: public ChangeListener[] getChangeListeners()
446: {
447: return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
448: }
449:
450: public Style addStyle(String name, Style parent)
451: {
452: Style newStyle = new NamedStyle(name, parent);
453: if (name != null)
454: styleTable.put(name, newStyle);
455: return newStyle;
456: }
457:
458: public void removeStyle(String name)
459: {
460: styleTable.remove(name);
461: }
462:
463:
473: public Style getStyle(String name)
474: {
475: return (Style) styleTable.get(name);
476: }
477:
478:
482: public Enumeration getStyleNames()
483: {
484: return styleTable.keys();
485: }
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502: private static class SimpleFontSpec
503: {
504: String family;
505: int style;
506: int size;
507: public SimpleFontSpec(String family,
508: int style,
509: int size)
510: {
511: this.family = family;
512: this.style = style;
513: this.size = size;
514: }
515: public boolean equals(Object obj)
516: {
517: return (obj != null)
518: && (obj instanceof SimpleFontSpec)
519: && (((SimpleFontSpec)obj).family.equals(this.family))
520: && (((SimpleFontSpec)obj).style == this.style)
521: && (((SimpleFontSpec)obj).size == this.size);
522: }
523: public int hashCode()
524: {
525: return family.hashCode() + style + size;
526: }
527: }
528:
529: public Font getFont(AttributeSet attr)
530: {
531: String family = StyleConstants.getFontFamily(attr);
532: int style = Font.PLAIN;
533: if (StyleConstants.isBold(attr))
534: style += Font.BOLD;
535: if (StyleConstants.isItalic(attr))
536: style += Font.ITALIC;
537: int size = StyleConstants.getFontSize(attr);
538: return getFont(family, style, size);
539: }
540:
541: public Font getFont(String family, int style, int size)
542: {
543: SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
544: if (sharedFonts.containsKey(spec))
545: return (Font) sharedFonts.get(spec);
546: else
547: {
548: Font tmp = new Font(family, style, size);
549: sharedFonts.put(spec, tmp);
550: return tmp;
551: }
552: }
553:
554: public FontMetrics getFontMetrics(Font f)
555: {
556: return Toolkit.getDefaultToolkit().getFontMetrics(f);
557: }
558:
559: public Color getForeground(AttributeSet a)
560: {
561: return StyleConstants.getForeground(a);
562: }
563:
564: public Color getBackground(AttributeSet a)
565: {
566: return StyleConstants.getBackground(a);
567: }
568:
569: protected int getCompressionThreshold()
570: {
571: return compressionThreshold;
572: }
573:
574: public static StyleContext getDefaultStyleContext()
575: {
576: return defaultStyleContext;
577: }
578:
579: public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
580: {
581: if (old instanceof MutableAttributeSet)
582: {
583: ((MutableAttributeSet)old).addAttribute(name, value);
584: return old;
585: }
586: else
587: {
588: MutableAttributeSet mutable = createLargeAttributeSet(old);
589: mutable.addAttribute(name, value);
590: if (mutable.getAttributeCount() >= getCompressionThreshold())
591: return mutable;
592: else
593: {
594: SmallAttributeSet small = createSmallAttributeSet(mutable);
595: if (sharedAttributeSets.containsKey(small))
596: small = (SmallAttributeSet) sharedAttributeSets.get(small);
597: else
598: sharedAttributeSets.put(small,small);
599: return small;
600: }
601: }
602: }
603:
604: public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
605: {
606: if (old instanceof MutableAttributeSet)
607: {
608: ((MutableAttributeSet)old).addAttributes(attributes);
609: return old;
610: }
611: else
612: {
613: MutableAttributeSet mutable = createLargeAttributeSet(old);
614: mutable.addAttributes(attributes);
615: if (mutable.getAttributeCount() >= getCompressionThreshold())
616: return mutable;
617: else
618: {
619: SmallAttributeSet small = createSmallAttributeSet(mutable);
620: if (sharedAttributeSets.containsKey(small))
621: small = (SmallAttributeSet) sharedAttributeSets.get(small);
622: else
623: sharedAttributeSets.put(small,small);
624: return small;
625: }
626: }
627: }
628:
629: public AttributeSet getEmptySet()
630: {
631: AttributeSet e = createSmallAttributeSet(null);
632: if (sharedAttributeSets.containsKey(e))
633: e = (AttributeSet) sharedAttributeSets.get(e);
634: else
635: sharedAttributeSets.put(e, e);
636: return e;
637: }
638:
639: public void reclaim(AttributeSet attributes)
640: {
641: if (sharedAttributeSets.containsKey(attributes))
642: sharedAttributeSets.remove(attributes);
643: }
644:
645: public AttributeSet removeAttribute(AttributeSet old, Object name)
646: {
647: if (old instanceof MutableAttributeSet)
648: {
649: ((MutableAttributeSet)old).removeAttribute(name);
650: if (old.getAttributeCount() < getCompressionThreshold())
651: {
652: SmallAttributeSet small = createSmallAttributeSet(old);
653: if (!sharedAttributeSets.containsKey(small))
654: sharedAttributeSets.put(small,small);
655: old = (AttributeSet) sharedAttributeSets.get(small);
656: }
657: return old;
658: }
659: else
660: {
661: MutableAttributeSet mutable = createLargeAttributeSet(old);
662: mutable.removeAttribute(name);
663: SmallAttributeSet small = createSmallAttributeSet(mutable);
664: if (sharedAttributeSets.containsKey(small))
665: small = (SmallAttributeSet) sharedAttributeSets.get(small);
666: else
667: sharedAttributeSets.put(small,small);
668: return small;
669: }
670: }
671:
672: public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
673: {
674: return removeAttributes(old, attributes.getAttributeNames());
675: }
676:
677: public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
678: {
679: if (old instanceof MutableAttributeSet)
680: {
681: ((MutableAttributeSet)old).removeAttributes(names);
682: if (old.getAttributeCount() < getCompressionThreshold())
683: {
684: SmallAttributeSet small = createSmallAttributeSet(old);
685: if (!sharedAttributeSets.containsKey(small))
686: sharedAttributeSets.put(small,small);
687: old = (AttributeSet) sharedAttributeSets.get(small);
688: }
689: return old;
690: }
691: else
692: {
693: MutableAttributeSet mutable = createLargeAttributeSet(old);
694: mutable.removeAttributes(names);
695: SmallAttributeSet small = createSmallAttributeSet(mutable);
696: if (sharedAttributeSets.containsKey(small))
697: small = (SmallAttributeSet) sharedAttributeSets.get(small);
698: else
699: sharedAttributeSets.put(small,small);
700: return small;
701: }
702: }
703:
704:
705:
706:
707:
708: public static Object getStaticAttribute(Object key)
709: {
710: throw new InternalError("not implemented");
711: }
712:
713: public static Object getStaticAttributeKey(Object key)
714: {
715: throw new InternalError("not implemented");
716: }
717:
718: public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
719: throws ClassNotFoundException, IOException
720: {
721: throw new InternalError("not implemented");
722: }
723:
724: public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
725: throws IOException
726: {
727: throw new InternalError("not implemented");
728: }
729:
730: public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
731: throws ClassNotFoundException, IOException
732: {
733: throw new InternalError("not implemented");
734: }
735:
736: public void writeAttributes(ObjectOutputStream out, AttributeSet a)
737: throws IOException
738: {
739: throw new InternalError("not implemented");
740: }
741: }