001 /*
002 * $Id: EditorPaneLinkVisitor.java,v 1.1 2005/10/12 08:48:28 kleopatra Exp $
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;
022
023 import java.awt.event.ActionEvent;
024 import java.awt.event.ActionListener;
025 import java.io.IOException;
026 import java.net.URL;
027
028 import javax.swing.SwingUtilities;
029 import javax.swing.event.HyperlinkEvent;
030 import javax.swing.event.HyperlinkListener;
031 import javax.swing.text.Document;
032
033
034 /**
035 * A ActionListener using a JXEditorPane to "visit" a LinkModel.
036 *
037 * adds an internal HyperlinkListener to visit links contained
038 * in the document.
039 *
040 * @author Jeanette Winzenburg
041 */
042 public class EditorPaneLinkVisitor implements ActionListener {
043 private JXEditorPane editorPane;
044 private HyperlinkListener hyperlinkListener;
045 private LinkModel internalLink;
046
047 public EditorPaneLinkVisitor() {
048 this(null);
049 }
050
051 public EditorPaneLinkVisitor(JXEditorPane pane) {
052 if (editorPane != null) {
053 editorPane.removeHyperlinkListener(getHyperlinkListener());
054 }
055 if (pane == null) {
056 pane = createDefaultEditorPane();
057 }
058 this.editorPane = pane;
059 pane.addHyperlinkListener(getHyperlinkListener());
060 }
061
062
063 public JXEditorPane getOutputComponent() {
064 return editorPane;
065 }
066
067 public void actionPerformed(ActionEvent e) {
068 if (e.getSource() instanceof LinkModel) {
069 final LinkModel link = (LinkModel) e.getSource();
070 SwingUtilities.invokeLater(new Runnable() {
071 public void run() {
072 visit(link);
073
074 }
075 });
076 }
077
078 }
079
080 public void visit(LinkModel link) {
081 try {
082 // make sure to reload
083 editorPane.getDocument().putProperty(Document.StreamDescriptionProperty, null);
084 // JW: editorPane defaults to asynchronous loading
085 // no need to explicitly start a thread - really?
086 editorPane.setPage(link.getURL());
087 link.setVisited(true);
088 } catch (IOException e1) {
089 editorPane.setText("<html>Error 404: couldn't show " + link.getURL() + " </html>");
090 }
091 }
092
093 protected JXEditorPane createDefaultEditorPane() {
094 final JXEditorPane editorPane = new JXEditorPane();
095 editorPane.setEditable(false);
096 editorPane.setContentType("text/html");
097 return editorPane;
098 }
099
100 protected HyperlinkListener getHyperlinkListener() {
101 if (hyperlinkListener == null) {
102 hyperlinkListener = createHyperlinkListener();
103 }
104 return hyperlinkListener;
105 }
106
107 protected HyperlinkListener createHyperlinkListener() {
108 HyperlinkListener l = new HyperlinkListener() {
109
110 public void hyperlinkUpdate(HyperlinkEvent e) {
111 if (HyperlinkEvent.EventType.ACTIVATED == e.getEventType()) {
112 visitInternal(e.getURL());
113 }
114
115 }
116
117 };
118 return l;
119 }
120
121 protected LinkModel getInternalLink() {
122 if (internalLink == null) {
123 internalLink = new LinkModel("internal");
124 }
125 return internalLink;
126 }
127
128 protected void visitInternal(URL url) {
129 try {
130 getInternalLink().setURL(url);
131 visit(getInternalLink());
132 } catch (Exception e) {
133 // todo: error feedback
134 }
135 }
136
137
138 }