You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@pivot.apache.org by Bill van Melle <bi...@gmail.com> on 2011/07/13 23:39:21 UTC

Implementing a hyperlink element in Document

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.

Re: Implementing a hyperlink element in Document

Posted by Chris Bartlett <cb...@gmail.com>.
Bill,

I don't have any experience with TextPanes, but #2 sounds like it
might be addressed by this thread from yesterday.
http://apache-pivot-users.399431.n3.nabble.com/Task-countdown-and-Labels-td3160961.html

Chris

On 14 July 2011 04:39, Bill van Melle <bi...@gmail.com> wrote:
> 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.
>
>

Re: Implementing a hyperlink element in Document

Posted by Greg Brown <gk...@verizon.net>.
> @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?  

Yes, you should be able to. I'm not sure that it will properly copy as text at the moment, but that can probably be addressed fairly easily.

> I'm assuming you're suggesting that I make my Hyperlink object a subclass of ComponentNode that wraps a Label.  

I was thinking of wrapping a LinkButton, but a Label could work too.



Re: Implementing a hyperlink element in Document

Posted by Bill van Melle <bi...@gmail.com>.
@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.

Re: Implementing a hyperlink element in Document

Posted by Greg Brown <gk...@verizon.net>.
Did you try using a ComponentNode?

On Jul 13, 2011, at 5:39 PM, Bill van Melle wrote:

> 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.
>