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