@Chris: I'm not sure how this is applicable. I'm calling setUnderline in the UI thread already.
@Greg: wow, I didn't even notice that object. It certainly seems like it would be cleaner, but much harder to make it participate in other Document text operations, e.g., can I select a range of text that includes it and then Copy the whole thing? I'm assuming you're suggesting that I make my Hyperlink object a subclass of ComponentNode that wraps a Label. I guess it wouldn't be hard to implement its getCharacterAt and getCharacterCount. Maybe I could get away without implementing the xxxRange methods if I'm never in an editable pane.
