README CalHTMLPane 2.021 ----------------------------------------------------------------------- CONTENTS - Overview - License for use - Requirements - Using a CalPane - Adding your own components and images - Intercepting events from within a document - Supported tags and attributes - Form components - The Pane's Dialog - The Pane's Focus Manager - Optimize Display - Viewing Web pages - Bug reports - Known problems - Contacting the author ----------------------------------------------------------------------- OVERVIEW ----------------------------------------------------------------------- This is version 2.021 of the CalHTMLPane ('CalPane' or 'Pane'). The CalHTMLPane is a sub-component of a Java development package named Calpa, and was built to provide two main services to the package: -Instantly accessible HTML Help documentation without the need to start up a native Web browser. -The display of HTML documents dynamically authored from online databases. A CalHTMLPane allows Java application builders to incorporate HTML documents into a GUI display. It supports a wide range of HTML3.2 and HTML4.0 tags so that documents can be authored with popular HTML editors and immediately displayed within a Java application. HTML form components can be included in these documents in the normal way, and a programming API is provided to enable the controlling Java application to interact with those components, and to enable programmers to customize the component within their own applications. The Pane also contains caching and history features which remove much of the burden of document management. Keyboard support is provided, including tabbing between and activating hyperlinks via the keyboard. The Pane can be used to display Web pages from within an application, and Web browsing capabilities can be built around it. It can automatically handle basic form submissions, with more complex server interaction being dealt with by the programmer if so desired. However the Pane cannot be expected to handle documents which incorporate inline scripts. That is not the purpose of its design. This document gives the class user a general introduction to the CalHTMLPane's API and discusses certain aspects of its implementation. It is not necessary to read all of the sections below to begin using a CalPane, but following the first five examples will give the reader a good insight into how the calpa.html public classes relate to one another. Additional documentation is also provided: JavaDoc for the CalPane's public classes, and HTML documentation giving examples of tag and attribute usage. The HTML documents need to be viewed within a running CalPane, not a normal Web browser, as they demonstrate aspects of the component's form rendering styles as well as other features specific to a CalPane. 'CalGuide.html' is the main index of this documentation. The rest of these notes presume a certain level of Java programming experience on the part of the reader, and strong familiarity with the Swing package. ----------------------------------------------------------------------- LICENSE FOR USE ----------------------------------------------------------------------- You must read the license that accompanies the calp.html package class files before you may use them. Briefly, however, and without prejudice to the terms of the license, you are permitted to use the class files: -for non-commercial use. -for commercial use, provided that you are only using the class files to show either : (a) Help, Support or Tutorial documentation within your application, and provided that the use of the classes is incidental to the main function of that application. or: (b) Advertising or Promotional material relating to your application or business. For other commercial uses you should email the copyright holder at the following address stating the desired use of the classes, and consideration will be given to the grant of a commercial license. Contact: Andrew J. Moulden offshore@netcomuk.co.uk ----------------------------------------------------------------------- REQUIREMENTS ----------------------------------------------------------------------- Version 2.0 of the CalHTMLPane requires a Java 2 Virtual Machine, and the classes have not been tested against any version of the Java Development Kit before 1.2 Final. This component was built and tested on a Win32 machine running Windows95. It is believed to be written in 100% Java using Sun's JDK tools and should perform identically elsewhere. It is best to give an increased amount of memory to the JVM running a CalPane. The first instantiation of the Pane (including its static support classes) uses 300K - 400K of memory, but it is the HTML documents which take up space. As a general guide (assuming you are caching documents) : -For showing fairly simple Help documentation 2MB of system memory should be sufficient. -For more complex documentation such as the JDK API, 4MB min is recommended if 50+ documents will be viewed and cached. -For viewing the sort of documents found on commercial Web sites consider 8MB+. The images within such pages can consume a great deal of memory. The amount of memory given to the JVM can be set by using the -ms switch when a program is run. To give an application 8MB of RAM the command would be: java -ms8m MyApplication Memory specification is not mandatory however. The VM will allocate memory on an as-needed basis, though this may slow document loading. The caching of documents is programmable, and the CalPane's Manager will start removing the oldest documents from the cache when it gets full. Caching of images is left to the JVM. If the CalHTMLPane is run in conjunction with a Just-In-Time (JIT) compiler, the first two or three documents will load quite slowly and the mouse cursor may not focus hyperlinks for a brief moment. However there should be a significant performance boost thereafter. On many machines parsing matches or even surpasses that of a native Web browser, allowing the disabling of caching if documents are being loaded from a local file system. ----------------------------------------------------------------------- USING A CALPANE ----------------------------------------------------------------------- The CalHTMLPane is a Swing JComponent. Specifically it extends the JLayeredPane class. It is therefore recommended that the component be used in a 'lightweight' Swing environment rather than mixing it with 'heavyweight' AWT components. The JAR file containing the CalPane classes (calpahtml.jar) needs to be in your classpath. The following code should then load and display an HTML document of your choosing: ---------------------------------------- import java.net.*; import java.awt.*; import javax.swing.*; import calpa.html.*; public class MyFirstCalPaneApplication { public static void main(String args[]) { URL url = null; try { //This is an example URL. You need to format your own. //If you use an http URL you'll need an open http connection url = new URL("file:///c:/jdk1.2/docs/api/overview-summary.html"); } catch (MalformedURLException e) { System.err.println("Malformed URL"); System.exit(1); } JFrame f = new JFrame(); CalHTMLPane pane = new CalHTMLPane(); f.getContentPane().add(pane, "Center"); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(new Dimension(Math.min(d.width - 10, 800), Math.min(d.height - 40, 600))); f.setVisible(true); if (url != null) { pane.showHTMLDocument(url); pane.requestFocus(); } } } ---------------------------------------- Assuming the document has displayed correctly you should find that you can navigate any hyperlinks. Any links which can't be followed will result in an error dialog appearing. This dialog will be discussed later. Keyboard navigation should be avaialable within the document. We called requestFocus() for the Pane, and pressing the TAB key should move focus to the next hyperlink or form control if either exist. -SHIFT-TAB will move backwards through the focus cycle. -ENTER will activate a hyperlink if one has focus. -CURSOR-DOWN or SPACE will scroll the Pane downward if the document is long enough. -CURSOR-UP or SHIFT_SPACE will scroll upward. -CURSOR_LEFT, CURSOR_RIGHT scroll left and right. -PAGE_UP and PAGE_DOWN scroll up and down a page at at time If there is a Frameset document on screen it is possible to tab between frames by pressing CTRL-TAB (which also gets the user out of the Pane completely if there are other controls in the application which can accept keyboard focus). * * * The CalPane is a component, not an application, and so it is left to the class user to create customized navigation buttons such as 'back' and 'forward'. However, the Pane has an internal navigation bar which is useful for testing purposes, and in the next example we will make this visible. This introduces another of the calpa.html public classes - CalHTMLPreferences. A CalHTMLPreferences ('CalPref') object controls aspects of a CalPane's behaviour and rendering policy - whether to underline hyperlinks, handle form submission etc. Every Pane has a controlling CalHTMLPreferences object, and when the first example above was run, a default CalPref was used. The programmer can create an instance of CalHTMLPreferences, modify selected values by using its access methods, and then pass it to a CalPane constructor. It is possible to change certain preferences after the Pane has been constructed, but only before construction can *all* preferences be set. Note also that a single CalPref can control any number of CalPanes. So, in the following slightly modified version of the first example we will create a CalHTMLPreferences object and use one of its public methods to get the CalPane's test navigation bar showing: ---------------------------------------- import java.net.*; import java.awt.*; import javax.swing.*; import calpa.html.*; public class MySecondCalPaneApplication { public static void main(String args[]) { URL url = null; try { url = new URL("file:///c:/jdk1.2/docs/api/overview-summary.html"); } catch (MalformedURLException e) { System.err.println("Malformed URL"); System.exit(1); } JFrame f = new JFrame(); //create a Preferences object CalHTMLPreferences pref = new CalHTMLPreferences(); //use one of its methods to enable the test navbar pref.setShowTestNavBar(true); //now pass the pref object to the Pane's constructor CalHTMLPane pane = new CalHTMLPane(pref, null, null); f.getContentPane().add(pane, "Center"); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(new Dimension(Math.min(d.width - 10, 800), Math.min(d.height - 40, 600))); f.setVisible(true); if (url != null) { pane.showHTMLDocument(url); } } } ---------------------------------------- You should see a rather unexciting navigation bar when you run the program, but at least it is now possible to traverse the CalPane's history, reload a document, stop any processes if necessary, navigate by entering a URL in the textfield, and get some status information on document loading. Note that this navbar is actually *within* the Pane and is ignored by the Pane's focus manager. You cannot tab to the controls because they do not exist as far as the Pane is concerned. (The textfield will accept a single name as an argument. If you type 'amazon' for example it will treat this as 'http://www.amazon.com') * * * Designing your own custom controls for a CalHTMLPane is very straightforward, as demonstrated in Example 3. We will create some external buttons ('Back', 'Forward', 'Reload' and 'Stop') to demonstrate how controls can easily be added. [ Dean Jones' icon collection at: http://webart.javalobby.org/jlicons/ contains a number of icons which are well-suited for buttons to control a CalHTMLPane. Dean has generously made these free for use within Java applications. ] ---------------------------------------- import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import calpa.html.*; public class MyThirdCalPaneApplication { public static void main(String args[]) { URL url = null; try { url = new URL("file:///c:/jdk1.2/docs/api/overview-summary.html"); } catch (MalformedURLException e) { System.err.println("Malformed URL"); System.exit(1); } JFrame f = new JFrame(); CalHTMLPane pane = new CalHTMLPane(); f.getContentPane().add(pane, "Center"); //create a panel, add buttons, and add a listener to the buttons JPanel p = new JPanel(); MyListener ml = new MyListener(pane); String[] s = {"Reload", "Back", "Forward", "Stop"}; JButton b; for (int i=0; i<4; i++) { b = new JButton(s[i]); b.addActionListener(ml); p.add(b); } f.getContentPane().add(p, "South"); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(new Dimension(Math.min(d.width - 10, 800), Math.min(d.height - 40, 600))); f.setVisible(true); if (url != null) { pane.showHTMLDocument(url); } } private static class MyListener implements ActionListener { CalHTMLPane pane; public MyListener(CalHTMLPane pane) { this.pane = pane; } public void actionPerformed(ActionEvent e) { String s = e.getActionCommand(); if (("Reload").equals(s)) { pane.reloadDocument(); } else if (("Back").equals(s)) { pane.goBack(); } else if (("Forward").equals(s)) { pane.goForward(); } else if (("Stop").equals(s)) { pane.stopAll(); } } } } ---------------------------------------- The JavaDoc included in the download gives details regarding the methods which can be used to directly control a CalHTMLPane. The reader may be wondering however how the buttons on the test navbar in example 2 'knew' when to turn on and off. This introduces a third calpa.html public class - CalHTMLObserver ('CalObs' or 'Observer'). In the same way a Pane always has a resident Preferences object, it also always has an Observer. Once again a default CalHTMLObserver is used if one is not passed to the Pane's constructor. CalHTMLObserver is an interface, and an Observer can be created for a CalHTMLPane in one of two ways: -by implementing CalHTMLObserver in a class. This means implementing all methods of the interface. -by extending the public DefaultCalHTMLObserver class. This class implements all the methods of CalHTMLObserver as null-ops, so only those methods of interest need be overridden. The methods of CalHTMLObserver are basically all update methods. When certain events occur within a CalHTMLPane (e.g. a form submit button is pressed, a hyperlink gets focus, a document has finished loading) the Pane will pass information about the event to its resident CalObs, and from these updates the programmer can determine whether buttons should be on or off, what the title of the current document is, and so on. A single CalObs can listen to any number of CalPanes, and centralising events into this single interface is far more efficient than using normal AWT event firing, additionally avoiding potentially dangerous synchronization problems. Event multicasting is not normally required in a component of this type, but if this is necessary the programmer can maintain listener lists within the CalHTMLObserver implementation. In the next example we instantiate a CalHTMLPane as before, and this time add a single label at the bottom in place of the buttons in the previous example. We create our own CalHTMLObserver by extending DefaultCalHTMLObserver, and override a single method which allows us to get updates on focused hyperlinks. We then show the URL of the link in the label. ---------------------------------------- import java.net.*; import java.awt.*; import javax.swing.*; import calpa.html.*; public class MyFourthCalPaneApplication { public static void main(String args[]) { URL url = null; try { url = new URL("file:///c:/jdk1.2/docs/api/overview-summary.html"); } catch (MalformedURLException e) { System.err.println("Malformed URL"); System.exit(1); } JFrame f = new JFrame(); JLabel label = new JLabel("0"); label.setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 8)); label.setPreferredSize(label.getPreferredSize()); label.setText(""); CalHTMLPane pane = new CalHTMLPane(null, new MyCalHTMLObserver(label), null); f.getContentPane().add(pane, "Center"); f.getContentPane().add(label, "South"); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(new Dimension(Math.min(d.width - 10, 800), Math.min(d.height - 40, 600))); f.setVisible(true); if (url != null) { pane.showHTMLDocument(url); } } private static class MyCalHTMLObserver extends DefaultCalHTMLObserver { JLabel label; public MyCalHTMLObserver(JLabel label) { super(); this.label = label; } public void linkFocusedUpdate(CalHTMLPane p, URL url) { label.setText((url == null) ? "" : url.toExternalForm()); } } } ---------------------------------------- When the above example is run, links which get either mouse or keyboard focus should be shown at the bottom of the frame. When no link has focus the label's text will be blank (actually, the label does not clear itself when you go from one document to another, but that would mean using another update method which would complicate the example). The example is in fact a little flawed. In the linkFocusedUpdate() method there is no check made to ensure that the CalHTMLPane sending the update is the one we originally instantiated. Although it seems obvious that the CalHTMLPane sending the updates to the CalObserver *must* be the Pane we created earlier, this is not necessarily so. HTML allows the author to specify a target frame in hyperlinks, and if the target is called '_blank' or is not the name of a currently visible frame, then a new frame should be created to show the linked document. By default a CalHTMLPane will create a new CalPane if it comes across a link like this, and this could have happened when the above example was run. In most cases the programmer will want a customized version of the CalHTMLPane to appear in circumstances such as this, and the automatic opening of new frames can be disabled through a method in CalHTMLPreferences. When so disabled, the CalPane will call an update method in CalHTMLObserver requesting the programmer to create a new CalHTMLPane. ----------------------------------------------------------------------- ADDING YOUR OWN COMPONENTS AND IMAGES TO A CALPANE ----------------------------------------------------------------------- There is just one more public calpa.html class that needs to be discussed - CalHTMLManager ('Manager'). This class consists of a number of static fields and methods and basically acts as a storage point for all the CalPanes running in an application. The Manager caches documents and imagemaps, and performs some other behind-the-scenes housekeeping functions. There are also some public methods in CalHTMLManager which allow the programmer to store JComponents and Images (i.e. instances of java.awt.Image) with the Manager. Once these are cached with the Manager they can be incorporated into HTML documents simply by naming them within a relevant tag. A component or image can be referenced and reused in any number of documents, and shown in any running CalPane (though of course, a component can only be in one place at a time). The ability to add images in this manner was put into the Calpa package because there are times when it is desirable to display an image which the class user can be *sure* is available and fully loaded. A document may for example contain form controls created with the new HTML4.0