/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.com/javaexamples2.
*/
package com.davidflanagan.examples.gui;
import java.awt.*; // LayoutManager stuff
import javax.swing.*; // Swing components
import java.awt.event.*; // AWT event handlers
import javax.swing.event.*; // Swing event handlers
import java.beans.*; // JavaBeans event handlers
import java.awt.print.*; // Printing functionality
import java.io.*; // Input/output
import java.net.*; // Networking with URLs
import java.util.*; // Hashtables and other utilities
// Import this class by name. JFileChooser uses it, and its name conflicts
// with java.io.FileFilter
import javax.swing.filechooser.FileFilter;
// Import a class for printing Swing documents. See printing chapter.
import com.davidflanagan.examples.print.PrintableDocument;
/**
* This class implements a simple web browser using the HTML
* display capabilities of the JEditorPane component.
**/
public class WebBrowser extends JFrame
implements HyperlinkListener, PropertyChangeListener
{
/**
* A simple main() method that allows the WebBrowser class to be used
* as a stand-alone application.
**/
public static void main(String[] args) throws IOException {
// End the program when there are no more open browser windows
WebBrowser.setExitWhenLastWindowClosed(true);
WebBrowser browser = new WebBrowser(); // Create a browser window
browser.setSize(800, 600); // Set its size
browser.setVisible(true); // Make it visible.
// Tell the browser what to display. This method is defined below.
browser.displayPage((args.length > 0) ? args[0] : browser.getHome());
}
// This class uses GUIResourceBundle to create its menubar and toolbar
// This static initializer performs one-time registration of the
// required ResourceParser classes.
static {
GUIResourceBundle.registerResourceParser(new MenuBarParser());
GUIResourceBundle.registerResourceParser(new MenuParser());
GUIResourceBundle.registerResourceParser(new ActionParser());
GUIResourceBundle.registerResourceParser(new CommandParser());
GUIResourceBundle.registerResourceParser(new ToolBarParser());
}
// These are the Swing components that the browser uses
JEditorPane textPane; // Where the HTML is displayed
JLabel messageLine; // Displays one-line messages
JTextField urlField; // Displays and edits the current URL
JFileChooser fileChooser; // Allows the user to select a local file
// These are Actions that are used in the menubar and toolbar.
// We obtain explicit references to them from the GUIResourceBundle
// so we can enable and disable them.
Action backAction, forwardAction;
// These fields are used to maintain the browsing history of the window
java.util.List history = new ArrayList(); // The history list
int currentHistoryPage = -1; // Current location in it
public static final int MAX_HISTORY = 50; // Trim list when over this size
// These static fields control the behavior of the close() action
static int numBrowserWindows = 0;
static boolean exitWhenLastWindowClosed = false;
// This is where the "home()" method takes us. See also setHome()
String home = "http://www.davidflanagan.com"; // A default value
/** Create and initialize a new WebBrowser window */
public WebBrowser() {
super(); // Chain to JFrame constructor
textPane = new JEditorPane(); // Create HTML window
textPane.setEditable(false); // Don't allow the user to edit it
// Register action listeners. The first is to handle hyperlinks.
// The second is to receive property change notifications, which tell
// us when a document is done loading. This class implements these
// EventListener interfaces, and the methods are defined below
textPane.addHyperlinkListener(this);
textPane.addPropertyChangeListener(this);
// Put the text pane in a JScrollPane in the center of the window
this.getContentPane().add(new JScrollPane(textPane),
BorderLayout.CENTER);
// Now create a message line and place it at the bottom of the window
messageLine = new JLabel(" ");
this.getContentPane().add(messageLine, BorderLayout.SOUTH);
// Read the file WebBrowserResources.properties (and any localized
// variants appropriate for the current Locale) to create a
// GUIResourceBundle from which we'll get our menubar and toolbar.
GUIResourceBundle resources =
new GUIResourceBundle(this,"com.davidflanagan.examples.gui." +
"WebBrowserResources");
// Read a menubar from the resource bundle and display it
JMenuBar menubar = (JMenuBar) resources.getResource("menubar",
JMenuBar.class);
this.setJMenuBar(menubar);
// Read a toolbar from the resource bundle. Don't display it yet.
JToolBar toolbar =
(JToolBar) resources.getResource("toolbar", JToolBar.class);
// Create a text field that the user can enter a URL in.
// Set up an action listener to respond to the ENTER key in that field
urlField = new JTextField();
urlField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayPage(urlField.getText());
}
});
// Add the URL field and a label for it to the end of the toolbar
toolbar.add(new JLabel(" URL:"));
toolbar.add(urlField);
// And add the toolbar to the top of the window
this.getContentPane().add(toolbar, BorderLayout.NORTH);
// Read cached copies of two Action objects from the resource bundle
// These actions are used by the menubar and toolbar, and enabling and
// disabling them enables and disables the menu and toolbar items.
backAction = (Action)resources.getResource("action.back",Action.class);
forwardAction =
(Action)resources.getResource("action.forward", Action.class);
// Start off with both actions disabled
backAction.setEnabled(false);
forwardAction.setEnabled(false);
// Create a ThemeManager for this frame,
// and add a Theme menu to the menubar
ThemeManager themes = new ThemeManager(this, resources);
menubar.add(themes.getThemeMenu());
// Keep track of how many web browser windows are open
WebBrowser.numBrowserWindows++;
}
/** Set the static property that controls the behavior of close() */
public static void setExitWhenLastWindowClosed(boolean b) {
exitWhenLastWindowClosed = b;
}
/** These are accessor methods for the home property. */
public void setHome(String home) { this.home = home; }
public String getHome() { return home; }
/**
* This internal method attempts to load and display the specified URL.
* It is called from various places throughout the class.
**/
boolean visit(URL url) {
try {
String href = url.toString();
// Start animating. Animation is stopped in propertyChanged()
startAnimation("Loading " + href + "...");
textPane.setPage(url); // Load and display the URL
this.setTitle(href); // Display URL in window titlebar
urlField.setText(href); // Display URL in text input field
return true; // Return success
}
catch (IOException ex) { // If page loading fails
stopAnimation();
messageLine.setText("Can't load page: " + ex.getMessage());
return false; // Return failure
}
}
/**
* Ask the browser to display the specified URL, and put it in the
* history li