001: package net.suberic.util.swing;
002:
003: import javax.swing.JEditorPane;
004: import javax.swing.event.HyperlinkEvent;
005: import javax.swing.event.MouseInputAdapter;
006: import java.awt.event.MouseEvent;
007: import java.awt.Point;
008: import java.net.URL;
009: import java.net.MalformedURLException;
010: import javax.swing.text.Document;
011:
012: /**
013: * This is a class which tracks hyperlink action for a JEditorPane.
014: */
015: public class HyperlinkMouseHandler extends MouseInputAdapter {
016:
017: public class URLSelection {
018: public URL url;
019: public int start;
020: public int end;
021: public JEditorPane editor;
022:
023: public URLSelection(JEditorPane newEditor, URL newUrl,
024: int newStart, int newEnd) {
025: url = newUrl;
026: start = newStart;
027: end = newEnd;
028: editor = newEditor;
029: }
030: }
031:
032: private int lineLength;
033: private URLSelection currentSelection = null;
034:
035: public HyperlinkMouseHandler(int newLineLength) {
036: lineLength = newLineLength;
037: }
038:
039: // track the moving of the mouse.
040: public void mouseMoved(MouseEvent e) {
041: JEditorPane editor = (JEditorPane) e.getSource();
042: if (!editor.isEditable()) {
043: Point pt = new Point(e.getX(), e.getY());
044: URLSelection newSelection = getIndicatedURL(pt, editor);
045: if (newSelection != currentSelection) {
046: if (currentSelection != null) {
047: editor.fireHyperlinkUpdate(new HyperlinkEvent(
048: currentSelection,
049: HyperlinkEvent.EventType.EXITED,
050: currentSelection.url));
051: }
052:
053: if (newSelection != null) {
054: editor.fireHyperlinkUpdate(new HyperlinkEvent(
055: newSelection,
056: HyperlinkEvent.EventType.ENTERED,
057: newSelection.url));
058: }
059: currentSelection = newSelection;
060: }
061: }
062: }
063:
064: URLSelection getIndicatedURL(Point pt, JEditorPane editor) {
065: int pos = editor.viewToModel(pt);
066: if (pos >= 0) {
067: try {
068: Document doc = editor.getDocument();
069: int docLength = doc.getLength();
070:
071: int wordStart = 0;
072:
073: int startOffset = pos;
074: int relativePosition;
075: boolean startFound = false;
076:
077: while (!startFound) {
078: startOffset = startOffset - lineLength;
079: relativePosition = lineLength;
080:
081: if (startOffset < 0) {
082: relativePosition = relativePosition
083: + startOffset;
084: startOffset = 0;
085: }
086:
087: String possibleText = doc.getText(startOffset,
088: relativePosition);
089: char[] charArray = possibleText.toCharArray();
090: for (int i = relativePosition - 1; (!startFound && i >= 0); i--) {
091: if (Character.isWhitespace(charArray[i])
092: || charArray[i] == '('
093: || charArray[i] == ')'
094: || charArray[i] == '<'
095: || charArray[i] == '>') {
096: startFound = true;
097: wordStart = startOffset + i + 1;
098: }
099: }
100:
101: if (startOffset == 0)
102: startFound = true;
103: }
104:
105: int wordEnd = docLength - 1;
106: startOffset = pos - 1 - lineLength;
107: int length = lineLength;
108: boolean endFound = false;
109:
110: while (!endFound) {
111: startOffset = startOffset + lineLength;
112:
113: if (startOffset + lineLength > docLength) {
114: length = docLength - startOffset;
115: }
116:
117: String possibleText = doc.getText(startOffset,
118: length);
119: char[] charArray = possibleText.toCharArray();
120: for (int i = 0; (!endFound && i < length); i++) {
121: if (Character.isWhitespace(charArray[i])
122: || charArray[i] == '('
123: || charArray[i] == ')'
124: || charArray[i] == '<'
125: || charArray[i] == '>') {
126: endFound = true;
127: wordEnd = startOffset + i - 1;
128: }
129: }
130:
131: if (startOffset + length >= docLength)
132: endFound = true;
133: }
134:
135: int wordLength = wordEnd - wordStart + 1;
136: if (wordLength > 3) {
137: String word = doc.getText(wordStart, wordLength);
138: if (word.indexOf("://") != -1) {
139: try {
140: URL urlSelected = new URL(word);
141:
142: return new URLSelection(editor,
143: urlSelected, wordStart, wordEnd);
144: } catch (MalformedURLException mue) {
145: }
146: }
147: }
148: } catch (javax.swing.text.BadLocationException ble) {
149:
150: }
151: }
152:
153: return null;
154: }
155:
156: public void mouseClicked(MouseEvent e) {
157: JEditorPane editor = (JEditorPane) e.getSource();
158: if (!editor.isEditable()) {
159: Point pt = new Point(e.getX(), e.getY());
160: URLSelection selection = getIndicatedURL(pt, editor);
161: if (selection != null) {
162: editor.fireHyperlinkUpdate(new HyperlinkEvent(
163: selection, HyperlinkEvent.EventType.ACTIVATED,
164: selection.url));
165: }
166: }
167: }
168:
169: }
|