1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| /*
* PatchedHTMLEditorKit.java
* A simple extension of the HTMLEditor kit that fires Enter/Exit
* hyperlink events.
*/
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
import java.io.Serializable;
import java.net.*;
public class HTMLPatchedHTMLEditorKit extends HTMLEditorKit
{
// Since we only have two mouse events to listen to, we'll use the same
// method to generate the appropriate hyperlinks and distinguish
// between them when we react to the mouse events.
public static final int JUMP = 0;
public static final int MOVE = 1;
LinkController myController = new LinkController();
public void install(JEditorPane c)
{
c.addMouseListener(myController);
c.addMouseMotionListener(myController);
}
public static class LinkController extends MouseInputAdapter
implements Serializable {
URL currentUrl = null;
// here's the mouseClicked event similar to the one in
// the regular HTMLEditorKit, updated to indicate this is
// a "jump" event
public void mouseClicked(MouseEvent e) {
JEditorPane editor = (JEditorPane) e.getSource();
if (! editor.isEditable()) {
Point pt = new Point(e.getX(), e.getY());
int pos = editor.viewToModel(pt);
if (pos >= 0) {
activateLink(pos, editor, JUMP);
}
}
}
// And here's our addition. Now the mouseMove events will
// also call activateLink, but with a "move" type
public void mouseMoved(MouseEvent e) {
JEditorPane editor = (JEditorPane) e.getSource();
if (! editor.isEditable()) {
Point pt = new Point(e.getX(), e.getY());
int pos = editor.viewToModel(pt);
if (pos >= 0) {
activateLink(pos, editor, MOVE);
}
}
}
// activateLink has now been updated to decide which hyperlink
// event to generate, based on the event type and status of the
// currentUrl field. Rather than have two handlers (one for
// enter/exit, one for active) we do all the work here. This
// saves us the effort of duplicating the href location code.
// But that's really minor point. You could certainly provide
// two handlers if that makes more sense to you.
protected void activateLink(int pos, JEditorPane html, int type) {
Document doc = html.getDocument();
if (doc instanceof HTMLDocument) {
HTMLDocument hdoc = (HTMLDocument) doc;
Element e = hdoc.getCharacterElement(pos);
AttributeSet a = e.getAttributes();
AttributeSet anchor = (AttributeSet) a.getAttribute(HTML.Tag.A);
String href = (anchor != null) ?
(String) anchor.getAttribute(HTML.Attribute.HREF) : null;
boolean shouldExit = false;
HyperlinkEvent linkEvent = null;
if (href != null) {
URL u;
try {
u = new URL(hdoc.getBase(), href);
} catch (MalformedURLException m) {
u = null;
}
if ((type == MOVE) && (!u.equals(currentUrl))) {
linkEvent = new HyperlinkEvent(html,
HyperlinkEvent.EventType.ENTERED, u, href);
currentUrl = u;
}
else if (type == JUMP) {
linkEvent = new HyperlinkEvent(html,
HyperlinkEvent.EventType.ACTIVATED, u, href);
shouldExit = true;
}
else {
return;
}
html.fireHyperlinkUpdate(linkEvent);
}
else if (currentUrl != null) {
shouldExit = true;
}
if (shouldExit) {
linkEvent = new HyperlinkEvent(html,
HyperlinkEvent.EventType.EXITED,
currentUrl, null);
html.fireHyperlinkUpdate(linkEvent);
currentUrl = null;
}
}
}
}
} |
Partager