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 }