View Javadoc

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 }