001 /*
002 * $Id: EditorPaneLinkVisitor.java 2951 2008-06-17 10:07:49Z kleopatra $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.hyperlink;
022
023 import javax.swing.*;
024 import javax.swing.event.HyperlinkEvent;
025 import javax.swing.event.HyperlinkListener;
026 import javax.swing.text.Document;
027
028 import org.jdesktop.swingx.JXEditorPane;
029
030 import java.awt.event.ActionEvent;
031 import java.awt.event.ActionListener;
032 import java.io.IOException;
033 import java.net.URL;
034
035
036 /**
037 * A ActionListener using a JXEditorPane to "visit" a LinkModel.
038 *
039 * adds an internal HyperlinkListener to visit links contained
040 * in the document.
041 *
042 * @author Jeanette Winzenburg
043 */
044 public class EditorPaneLinkVisitor implements ActionListener {
045 private JXEditorPane editorPane;
046 private HyperlinkListener hyperlinkListener;
047 private LinkModel internalLink;
048
049 public EditorPaneLinkVisitor() {
050 this(null);
051 }
052
053 public EditorPaneLinkVisitor(JXEditorPane pane) {
054 if (pane == null) {
055 pane = createDefaultEditorPane();
056 }
057 this.editorPane = pane;
058 pane.addHyperlinkListener(getHyperlinkListener());
059 }
060
061
062 public JXEditorPane getOutputComponent() {
063 return editorPane;
064 }
065
066 public void actionPerformed(ActionEvent e) {
067 if (e.getSource() instanceof LinkModel) {
068 final LinkModel link = (LinkModel) e.getSource();
069 SwingUtilities.invokeLater(new Runnable() {
070 public void run() {
071 visit(link);
072
073 }
074 });
075 }
076
077 }
078
079 public void visit(LinkModel link) {
080 try {
081 // make sure to reload
082 editorPane.getDocument().putProperty(Document.StreamDescriptionProperty, null);
083 // JW: editorPane defaults to asynchronous loading
084 // no need to explicitly start a thread - really?
085 editorPane.setPage(link.getURL());
086 link.setVisited(true);
087 } catch (IOException e1) {
088 editorPane.setText("<html>Error 404: couldn't show " + link.getURL() + " </html>");
089 }
090 }
091
092 protected JXEditorPane createDefaultEditorPane() {
093 final JXEditorPane editorPane = new JXEditorPane();
094 editorPane.setEditable(false);
095 editorPane.setContentType("text/html");
096 return editorPane;
097 }
098
099 protected HyperlinkListener getHyperlinkListener() {
100 if (hyperlinkListener == null) {
101 hyperlinkListener = createHyperlinkListener();
102 }
103 return hyperlinkListener;
104 }
105
106 protected HyperlinkListener createHyperlinkListener() {
107 return new HyperlinkListener() {
108 public void hyperlinkUpdate(HyperlinkEvent e) {
109 if (HyperlinkEvent.EventType.ACTIVATED == e.getEventType()) {
110 visitInternal(e.getURL());
111 }
112
113 }
114
115 };
116 }
117
118 protected LinkModel getInternalLink() {
119 if (internalLink == null) {
120 internalLink = new LinkModel("internal");
121 }
122 return internalLink;
123 }
124
125 protected void visitInternal(URL url) {
126 try {
127 getInternalLink().setURL(url);
128 visit(getInternalLink());
129 } catch (Exception e) {
130 // todo: error feedback
131 }
132 }
133
134
135 }