JavaSwingText components and Document: StyledDocument


StyledDocument is very strange. The only extensions of Document that are worth anything are a) the (albeit limited) ability to change attributes and b) the paragraph structure, and both has nothing directly to do with style.

Features of StyledDocument not present in Document

Style extraction: getFont, getForeground, getBackground

These three methods extract a property value from an AttributeSet. These may allow to return something different than actually is stored there (as understood by StyleConstants). For all other attributes, you have use the StyleConstants helper methods (or direct lookup) anyway, so there is almost no advantage (like independence from a certain set of attributes) in these method; rather the opposite: if you want to honor colors and font for a non-StyledDocument as well (there is nothing against that), you have to use different code for those and for StyledDocument.

A possible optimization could be that getFont() always returns the same Font instead of creating it each time. But that could also be handled somewhere else (root View, for example).

Style set management: addStyle, getStyle, removeStyle

Apparently the Styles usable for setLogicalStyle() should be created by the Document (in order to be easily observable - otherwise care must be used to react to each Style change only once (even if attached to many paragraphs) and to disattach the listener when the last paragraph with that Style has been removed), otherwise the existance of these methods is pointless.

The notion of referring to a Style by name is weak, since the Style's name is usually easily modifiable: addAttribute(NameAttribute, ...).

But for StyleContext's Styles, the internal name remains the same no matter how you modify the Style's.

There is no method to get all registered styles (which may be useful to present to the user). There is in DefaultStyledDocument.

Paragraph structure: getParagraphElement, getCharacterElement

PlainDocument has getParagraphElement as well, although not a StyledDocument.

What's the difference between getCharacterElement and searching until a leaf element is found?

At least getCharacterElement lacks a bias. If the index in question is "between" two elements, the second element are taken, so the index is implicitly associated forwards, except at the end of the document, where it suddenly is biased backwards (since there is no forward direction). If really consistent, it should return null then.

Attribute modifications: setParagraphAttributes, setCharacterAttributes

These can also be used to add attributes, but to remove some, one has to copy the attribute set, modify the copy, and then set it again, and this has to be done for each existing element separately.

One can only modify the attributes of paragraph and character elements, not any higher level elements, although there is no reason at all (and there would be no difference in implementation). One has to refer to elements by position (including the ugly Math.max() for the off-by-one workaround), instead of the Elements themselves. This makes most sense only for character elements, whose structure is implicit (dependent on which attributes have been set on which ranges).

Style modifications: setLogicalStyle, getLogicalStyle

With DefaultStyledDocument, these are set as resolve parent again, so that attributes set on higher level elements (which would otherwise be resolved from there) are lost. This wouldn't have been a problem if there had been a list (and not only a single) resolving style.

Use of StyledDocument


ComposedCaret looks up background by looking up getCharacterElement() and then getBackground(attr). If no StyledDocument, or no background (that never happens with DefaultStyledDocument and StyleContext, since StyleConstants provide the default black), it takes the component background. Some strange caching behaviour will create wrong background colors (will it?).



Component property changes are copied into the StyledDocument's DEFAULT_STYLE (unclean)

LabelView / GlyphView

These use StyledDocument's getFont(), getForeground(), getBackground() instead of StyleConstants'. For unknown reasons, LabelView refuses to work without it at all.


getParagraphElement() makes use of getParagraphElement() for StyledDocument, otherwise uses a (possibly wrong) heuristic.



requires StyledDocument


read/write require it


Uses of HTMLDocument

(C) 2001-2009 Christian Kaufhold (