1 package org.wcb.common;
2 /***
3 * Copyright (C) 1999 Walter Bogaardt
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 *
19 */
20 import javax.swing.JButton;
21 import javax.swing.JTextField;
22 import javax.swing.JEditorPane;
23 import javax.swing.JFrame;
24 import javax.swing.JOptionPane;
25 import javax.swing.JPanel;
26 import javax.swing.JScrollPane;
27 import javax.swing.JLabel;
28 import javax.swing.ImageIcon;
29 import javax.swing.event.HyperlinkListener;
30 import javax.swing.event.HyperlinkEvent;
31 import javax.swing.text.html.HTMLFrameHyperlinkEvent;
32 import javax.swing.text.html.HTMLDocument;
33 import java.awt.Cursor;
34 import java.awt.BorderLayout;
35 import java.awt.Dimension;
36 import java.awt.Toolkit;
37 import java.awt.event.KeyEvent;
38 import java.awt.event.KeyAdapter;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ActionListener;
41 import java.awt.event.WindowAdapter;
42 import java.awt.event.WindowEvent;
43 import java.awt.event.WindowListener;
44 import java.io.IOException;
45 import java.net.URL;
46 import java.net.MalformedURLException;
47
48 /***
49 * This is a mini web browser which is a simple frame with a JEditorPane field that
50 * can render some html.
51 */
52 public class MiniBrowser extends JFrame {
53
54 private URL help, urlHome;
55 private JButton backButton, forwardButton, homeButton;
56 private JTextField urlField;
57 private JEditorPane viewComp;
58 private URL[] history;
59 private int historyPos;
60
61 /***
62 * Takes a url and opens a frame to display that url information
63 * in a JEditor html viewer pane. If a null value is submitted in the
64 * construction then by default the URL assumed will be the application
65 * current running directory having a file of index.html in it to view
66 * @param htmlUrl Url to start the browser on
67 * @param title the Title of the mini browser
68 */
69 public MiniBrowser(URL htmlUrl, String title) {
70 super(title);
71 history = new URL[25];
72 setupComponents();
73 listenToMePunk();
74 if (htmlUrl == null)
75 {
76 urlHome = setHomeURL("help/help.html");
77 gotoURL(urlHome, true);
78 }
79 else
80 {
81 gotoURL(htmlUrl, true);
82 }
83 }
84
85 private void setupComponents() {
86 getContentPane().setLayout(new BorderLayout());
87
88 JPanel panel = new JPanel(new BorderLayout());
89 panel.add(BorderLayout.WEST, new JLabel("Location:"));
90 urlField = new JTextField();
91 urlField.addKeyListener(new KeyHandler());
92 panel.add(urlField);
93 viewComp = createEditorPane();
94 JScrollPane helpScrollPane = new JScrollPane(viewComp);
95 helpScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
96 helpScrollPane.setPreferredSize(new Dimension(250, 250));
97 helpScrollPane.setMinimumSize(new Dimension(10, 10));
98
99 JPanel btnPanel = new JPanel();
100 backButton = new JButton("Back", new ImageIcon(Toolkit.getDefaultToolkit().createImage(MiniBrowser.class.getResource("/images/Left.gif"))));
101 forwardButton = new JButton("Forward", new ImageIcon(Toolkit.getDefaultToolkit().createImage(MiniBrowser.class.getResource("/images/Right.gif"))));
102 homeButton = new JButton("Content", new ImageIcon(Toolkit.getDefaultToolkit().createImage(MiniBrowser.class.getResource("/images/Help.gif"))));
103 btnPanel.add(backButton);
104 btnPanel.add(forwardButton);
105 btnPanel.add(homeButton);
106 getContentPane().add(panel, BorderLayout.NORTH);
107 getContentPane().add(helpScrollPane, BorderLayout.CENTER);
108 getContentPane().add(btnPanel, BorderLayout.SOUTH);
109 setSize(450, 350);
110 }
111
112 /***
113 * Standard listener group so that the buttons can either
114 * move forward or backwards through the history of the
115 * urls
116 */
117 public void listenToMePunk() {
118 ActionListener al = new ActionListener() {
119 public void actionPerformed(ActionEvent evt) {
120 Object src = evt.getSource();
121 if (src == backButton)
122 {
123 if (historyPos <= 1)
124 {
125 getToolkit().beep();
126 }
127 else
128 {
129 URL url = history[--historyPos - 1];
130 gotoURL(url, false);
131 }
132 }
133 if (src == forwardButton)
134 {
135 if (history.length - historyPos <= 1)
136 {
137 getToolkit().beep();
138 }
139 else
140 {
141 URL url = history[historyPos];
142 if (url == null)
143 {
144 getToolkit().beep();
145 }
146 else
147 {
148 historyPos++;
149 gotoURL(url, false);
150 }
151 }
152 }
153 if (src == homeButton)
154 {
155 gotoURL(urlHome, true);
156 }
157 }
158 };
159 WindowListener wl = new WindowAdapter() {
160 public void windowClosing(WindowEvent we) {
161 setVisible(false);
162 }
163 };
164 this.addWindowListener(wl);
165 backButton.addActionListener(al);
166 forwardButton.addActionListener(al);
167 homeButton.addActionListener(al);
168 }
169
170 /***
171 * sets the home button URL location file from the application
172 * current directory so that if the HTML file is located at currDir/filename.html
173 *@param homeURL URL to start from.
174 *@return default home url.
175 */
176 public URL setHomeURL(String homeURL) {
177 URL furby = null;
178 furby = MiniBrowser.class.getResource("/" + homeURL);
179 if (furby == null)
180 {
181 try
182 {
183 furby = new URL("http://jhome.sourceforge.net");
184 }
185 catch (MalformedURLException err)
186 {
187 err.printStackTrace();
188 }
189 }
190 return furby;
191 }
192
193 /***
194 * allow outsiders to modify the current url that
195 *this browser will display.
196 *
197 *@param urlToGo http url to display
198 */
199 public void displayURL(URL urlToGo)
200 {
201 gotoURL(urlToGo, false);
202 }
203
204 private JEditorPane createEditorPane() {
205 JEditorPane helpPane = new JEditorPane();
206 helpPane.setEditable(false);
207 helpPane.addHyperlinkListener(new LinkHandler());
208 return helpPane;
209 }
210
211 /***
212 * Go to a selecte URL and store it in a history map.
213 * @param url Url address to go to
214 * @param addToHistory true indicates store url in history.
215 */
216 private void gotoURL(URL url, boolean addToHistory)
217 {
218 viewComp.setCursor(Cursor.getDefaultCursor());
219 try
220 {
221 urlField.setText(url.toString());
222 viewComp.setPage(url);
223 if (addToHistory)
224 {
225 history[historyPos++] = url;
226 if (history.length == historyPos)
227 {
228 System.arraycopy(history, 1, history, 0, history.length);
229 }
230 history[historyPos] = null;
231 }
232 }
233 catch (IOException io)
234 {
235 JOptionPane.showMessageDialog(null, "Unable to open file at\n"
236 + io, "URL Error", JOptionPane.ERROR_MESSAGE);
237 }
238 }
239
240 /***
241 * Detect the enter key for the location text field that the user enters
242 * and test the url. If the URL was bad then tell the user he is an idiot.
243 */
244 class KeyHandler extends KeyAdapter {
245 /***
246 * Detect action of a key event being pressed.
247 * @param evt Key event to listen for which is the enter eky
248 */
249 public void keyPressed(KeyEvent evt) {
250 if (evt.getKeyCode() == KeyEvent.VK_ENTER)
251 {
252 try
253 {
254 gotoURL(new URL(urlField.getText()), true);
255 }
256 catch (MalformedURLException mfUrl)
257 {
258 JOptionPane.showMessageDialog(null, "Unable to open file at\n"
259 + mfUrl, "URL Error", JOptionPane.ERROR_MESSAGE);
260 }
261 }
262 }
263 }
264
265 /***
266 * Handles hypertext links within the document and display as cursors
267 * as they would appear in a normal web browser
268 */
269 class LinkHandler implements HyperlinkListener {
270 /***
271 * Allow hyper link event updates on the JEditPanel
272 * @param evt Hypertext document to validate link.
273 */
274 public void hyperlinkUpdate(HyperlinkEvent evt)
275 {
276 if (evt.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
277 {
278 if (evt instanceof HTMLFrameHyperlinkEvent)
279 {
280 ((HTMLDocument) viewComp.getDocument()).processHTMLFrameHyperlinkEvent((HTMLFrameHyperlinkEvent) evt);
281 }
282 else
283 {
284 URL url = evt.getURL();
285 if (url != null)
286 {
287 gotoURL(url, true);
288 }
289 }
290 }
291 else if (evt.getEventType() == HyperlinkEvent.EventType.ENTERED)
292 {
293 viewComp.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
294 }
295 else if (evt.getEventType() == HyperlinkEvent.EventType.EXITED)
296 {
297 viewComp.setCursor(Cursor.getDefaultCursor());
298 }
299 }
300 }
301 }