source: trunk/gli/src/org/greenstone/gatherer/gui/browser/GHTMLPane.java@ 4595

Last change on this file since 4595 was 4595, checked in by kjdon, 21 years ago

tidied up gatherer.debug - > gatherer.println

  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37
38
39
40
41
42
43package org.greenstone.gatherer.gui.browser;
44
45import java.awt.BorderLayout;
46import java.awt.Component;
47import java.awt.Dimension;
48import java.awt.Graphics;
49import java.awt.Graphics2D;
50import java.awt.image.BufferedImage;
51import java.beans.PropertyChangeEvent;
52import java.beans.PropertyChangeListener;
53import java.io.IOException;
54import java.net.URL;
55import java.util.Vector;
56import javax.swing.JEditorPane;
57import javax.swing.JPanel;
58import javax.swing.JProgressBar;
59import javax.swing.JScrollPane;
60import javax.swing.event.EventListenerList;
61import javax.swing.event.HyperlinkEvent;
62import javax.swing.event.HyperlinkListener;
63import org.greenstone.gatherer.Gatherer;
64import org.greenstone.gatherer.util.GURL;
65import org.greenstone.gatherer.util.Utility;
66/**
67 * Class Name: GHTMLPane
68 * Description: To provide a most basic implementation of the HTMLViewPane. Its
69 * rendering performance may be poor, but it will fully support all
70 * methods defined in the interface.
71 */
72public class GHTMLPane
73 extends JPanel
74 implements HTMLViewPane, HyperlinkListener, PropertyChangeListener {
75
76 /** follow_links - does the class automatically follow hyperlinks. */
77 boolean follow_links = true;
78 /** ready - has the view finished rendering the current URL. */
79 boolean ready = true;
80 /** the list of listeners associated with this class. */
81 EventListenerList listeners = null;
82 /** gatherer - a reference to the main class of Gatherer for messaging. */
83 Gatherer gatherer = null;
84 /** view - the JEditorPane the page content will be rendered on to. */
85 JEditorPane view = null;
86 Object control = null;
87 /** current_page - the URL of the currently shown page. */
88 GURL current_url = null;
89 /** back_pages - Vector of pages that have been visited. */
90 Vector back_pages = null;
91 /** Vector of pages that have been backed up from.
92 * Reset whenever a new url 'path' is entered.
93 */
94 Vector forward_pages = null;
95
96
97 /** Constructor - collects initial settings, lays out view, renders initial
98 * URL.
99 * @param gatherer - the main class of Gatherer
100 */
101 public GHTMLPane(Gatherer gatherer, Object control) {
102 this.gatherer = gatherer;
103 this.control = control;
104 this.setLayout(new BorderLayout());
105
106 listeners = new EventListenerList();
107
108 back_pages = new Vector();
109 forward_pages = new Vector();
110
111 Gatherer.println("\t\tCreating GHTMLPane");
112 view = new JEditorPane();
113 view.setEditable(false);
114 view.addHyperlinkListener(this);
115 view.addPropertyChangeListener(this);
116 this.add(new JScrollPane(view), BorderLayout.CENTER);
117 }
118
119 public void addGBrowserListener(GBrowserListener listener) {
120 listeners.add(GBrowserListener.class, listener);
121 }
122
123 public void afterDisplay() {
124 // Nothing to do. Only realy for embedded apps.
125 }
126
127 public boolean back() {
128 // Add current page to forward
129 forward_pages.add(0,current_url);
130 // Back up one page.
131 current_url = (GURL) back_pages.lastElement();
132 back_pages.remove(back_pages.size() - 1);
133 this.setPage(current_url);
134 return true;
135 }
136
137 public boolean canBack() {
138 if(back_pages.size() > 0 && ready) {
139 return true;
140 }
141 return false;
142 }
143
144 public boolean canForward() {
145 if(forward_pages.size() > 0 && ready) {
146 return true;
147 }
148 return false;
149 }
150
151 public boolean canStop() {
152 if(!ready) {
153 return true;
154 }
155 return false;
156 }
157
158 // This code courtesy of Horst ([email protected]) who provides this solution
159 // to the crap null exception I keep getting when I try to grab the image
160 // of a rendered HTML.
161 public BufferedImage capture() {
162 if(ready) {
163 // Paint to an off screen buffer
164 Dimension size = view.getSize();
165 //Graphics offgraphics = offscreen.getGraphics();
166 BufferedImage offscreen =
167 new BufferedImage(size.width, size.height,
168 BufferedImage.TYPE_INT_RGB);
169 Graphics2D offgraphics = (Graphics2D) offscreen.getGraphics();
170 // For some reason the clip rect is null for the created image
171 // (usually it is set to the size of the image) so set it.
172 offgraphics.setClip(0, 0, size.width, size.height);
173 offgraphics.setColor(getBackground());
174 offgraphics.fillRect(0, 0, size.width, size.height);
175 // This will display components in the HTML Page
176 view.paint(offgraphics);
177 return offscreen;
178 }
179 return null;
180 }
181
182 public GURL current() {
183 return current_url;
184 }
185
186 public void followHyperlinks(boolean value) {
187 follow_links = value;
188 }
189
190 public boolean forward() {
191 // Add current page to back
192 back_pages.add(current_url);
193 // Show forward page.
194 current_url = (GURL) forward_pages.firstElement();
195 forward_pages.remove(0);
196 setPage(current_url);
197 return true;
198 }
199
200 /** Since you can't add an interface to a component hierarchy this method is required to get a reference of the actual rendering component.
201 * @return This HTMLViewPane implementation as a component.
202 */
203 public Component getContent() {
204 return this;
205 }
206
207 public JProgressBar getProgress() {
208 // Currently not available. Will have to do some magic using the
209 // view.getStream() function.
210 return null;
211 }
212
213 /** When a hyperlink event is fired we handle it in one of several ways,
214 * based on the event type. Enters and exits get fired off as messages to
215 * the listeners so they can update their status bars. Clicks also fire
216 * status changes, but their event messages include the GURLs incase we
217 * to do something special to them. Furthermore if follow hyperlinks is
218 * set the browser is responsible for loading up the newly designated url.
219 * @param event A HyperlinkEvent containing useful data about the event,
220 * such as the url in question and the position of the mouse. It also is
221 * marked as one of several types of events including ENTERED and EXITED
222 * (for mouseovers) and ACTIVATED (clicked).
223 */
224 public void hyperlinkUpdate(HyperlinkEvent event) {
225 Object event_type = event.getEventType();
226 GURL new_url = new GURL(event.getURL());
227 // The mouse has been moved over a hyperlink.
228 if (event_type == HyperlinkEvent.EventType.ENTERED) {
229 fireStatusChange(new GURL(event.getURL()));
230 }
231 else if (event_type == HyperlinkEvent.EventType.EXITED) {
232 fireStatusChange(null);
233 }
234 else if (event_type == HyperlinkEvent.EventType.ACTIVATED) {
235 fireHyperlinkClick(new_url);
236 if(follow_links) {
237 show(new_url);
238 }
239 }
240 }
241
242 public boolean isReady() {
243 return ready;
244 }
245
246 public void propertyChange(PropertyChangeEvent evt) {
247 if(evt.getPropertyName() == "page") {
248 ready = true;
249 fireRenderComplete(current_url);
250 }
251 }
252
253 public void removeGBrowserListener(GBrowserListener listener) {
254 listeners.remove(GBrowserListener.class, listener);
255 }
256
257 public void setEnabled(boolean value) {
258 ready = value;
259 }
260
261 public boolean show(String filename) {
262 return show(new GURL("file:"+filename));
263 }
264
265 /**
266 *
267 * Precondition: ready = true <BR>
268 */
269 public boolean show(GURL url) {
270 if(current_url == null) {
271 fireRenderBegun(url);
272 current_url = url;
273 setPage(current_url);
274 return true;
275 }
276 else {
277 // If we are not already showing this url
278 if(!current_url.toString().equals(url.toString())) {
279 fireRenderBegun(url);
280 // Save a copy of the current page
281 back_pages.add(current_url);
282 current_url = url;
283 setPage(current_url);
284 return true;
285 }
286 }
287 return false;
288 }
289
290 public boolean stop() {
291 // Unfortunately a JEditorPane is not sophisticated enough to support
292 // this. Pretty much once you send the page to be rendered only killing
293 // the thread will stop it, and I'm not sure you can restart the thread
294 // later.
295 return false;
296 }
297
298 protected void fireActionFailed(GURL url) {
299 GBrowserEvent event = new GBrowserEvent(this,0,url);
300 Object[] concerned = listeners.getListenerList();
301 for(int i = 0; i < concerned.length ; i++) {
302 if(concerned[i] == GBrowserListener.class) {
303 ((GBrowserListener)concerned[i+1]).actionFailed(event);
304 }
305 }
306 }
307
308 protected void fireControlsChanged() {
309 Object[] concerned = listeners.getListenerList();
310 for(int i = 0; i < concerned.length ; i++) {
311 if(concerned[i] == GBrowserListener.class) {
312 ((GBrowserListener)concerned[i+1]).controlsChanged();
313 }
314 }
315 }
316
317 protected void fireHyperlinkClick(GURL url) {
318 GBrowserEvent event = new GBrowserEvent(this,0,url);
319 Object[] concerned = listeners.getListenerList();
320 for(int i = 0; i < concerned.length ; i++) {
321 if(concerned[i] == GBrowserListener.class) {
322 ((GBrowserListener)concerned[i+1]).hyperlinkClick(event);
323 }
324 }
325 }
326
327 protected void fireRenderBegun(GURL url) {
328 GBrowserEvent event = new GBrowserEvent(this,0,url);
329 Object[] concerned = listeners.getListenerList();
330 for(int i = 0; i < concerned.length ; i++) {
331 if(concerned[i] == GBrowserListener.class) {
332 ((GBrowserListener)concerned[i+1]).renderBegun(event);
333 }
334 }
335 }
336
337 protected void fireRenderComplete(GURL url) {
338 GBrowserEvent event = new GBrowserEvent(this,0,url);
339 Object[] concerned = listeners.getListenerList();
340 for(int i = 0; i < concerned.length ; i++) {
341 if(concerned[i] == GBrowserListener.class) {
342 ((GBrowserListener)concerned[i+1]).renderComplete(event);
343 }
344 }
345 }
346
347 protected void fireStatusChange(GURL url) {
348 GBrowserEvent event = new GBrowserEvent(this,0,url);
349 Object[] concerned = listeners.getListenerList();
350 for(int i = 0; i < concerned.length ; i++) {
351 if(concerned[i] == GBrowserListener.class) {
352 ((GBrowserListener)concerned[i+1]).statusChanged(event);
353 }
354 }
355 }
356
357 private void setPage(GURL url) {
358 try {
359 view.setPage(url.getURL());
360 }
361 catch (IOException e) {
362 Utility.showError(gatherer, "GHTMLPane.setPage()", e);
363 }
364 catch (Exception e) {
365 Utility.showError(gatherer, "Arrggg...", e);
366 }
367 }
368}
369
370
371
372
373
374
Note: See TracBrowser for help on using the repository browser.