I want to add a "hyperlink" element to a Document -- a stretch of text (or
possibly an image) that responds to a user click by doing something
(typically visiting a web page). At first blush, I thought, I'll subclass
TextNode and add a mouse listener to it. That's wrong on a bunch of fronts
-- TextNode is final, TextNode doesn't have appearance properties, and
Document elements do not support mouse listeners.

So after much consideration, I did the following, which mostly works (but
see question 2):

I subclassed Span to produce a new Element called Hyperlink. It sets its
style properties suitably for a link (for now, that just means setting color
blue). In its simplest form, it has a constructor that accepts a string of
text and a url, and adds a TextNode to itself containing the text.

I then subclassed TextPane and its Terra skin. In the skin, I override
mouseDown/Move/Up. In each of those, I locate the element under the mouse
and if it is of type Hyperlink take appropriate action. To determine the
element under the mouse, I call Document#getInsertionPoint to get an offset,
then Document#getNodeAt to get a Node. If the Node is a Paragraph p, I
further call p.getDescendantAt(offset - p.getOffset()) to get a simpler
Node. Then I fetch the parent of the node and test whether it is an instance
of Hyperlink.

(1) This approach mostly works, but seems kludgy. E.g., it implicitly
requires that Hyperlink only appear inside my new TextPane subclass. Is
there a better approach?

(2) When the mouse hovers over a Hyperlink, I'd like to underline the link
text. However, calling setUnderline does not have an immediate effect -- the
underline doesn't appear until I either click or take focus out of the
application (e.g., by Windows' Alt-Tab). Is this a bug, or is there some
method I need to call? I traced thru the code, and it looks like there is a
listener on the span that calls underlinedChanged and ultimately repaint,
but the Eclipse debugger gets confused about where it is, so I can't tell
for sure that repaint really gets called.

(3) Once in a while, Document#getInsertionPoint returns -1 for no apparent
reason. Unfortunately, I don't have a test case at this point.

Reply via email to