1310 lines
55 KiB
Text
1310 lines
55 KiB
Text
|
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
|
||
|
<BUTTON> tag (which the CalPane supports) and such buttons can hold
|
||
|
almost any type of HTML content, including images. It might look odd
|
||
|
however if an image which the programmer wants to display in one of these
|
||
|
buttons loads asynchronously. To avoid this the image can be pre-loaded,
|
||
|
added to CalHTMLManager, thus ensuring that it will display immediately
|
||
|
when shown in a document.
|
||
|
|
||
|
For a simple example, try adding this to a test HTML document:
|
||
|
|
||
|
<IMG jname="cal_warning">
|
||
|
|
||
|
The 'jname' attribute (which is not HTML) tells the CalPane's parser to
|
||
|
use an image that has been cached with CalHTMLManager. Note that there
|
||
|
is no need to use the 'src=..." attribute. The example IMG tag above
|
||
|
will display an exclamation mark image which is used in the CalPane's
|
||
|
error dialog.
|
||
|
|
||
|
For JComponents the <OBJECT> tag or the form <INPUT> tag should be
|
||
|
used. Here are examples of both:
|
||
|
|
||
|
<OBJECT type=jcomponent jname=mycolorchooser name=chooser>
|
||
|
<INPUT type=jcomponent jname=mainmenubar name=menubar>
|
||
|
|
||
|
If a JComponent has been added to CalHTMLManager with the corresponding
|
||
|
name it will be incorporated into the document much like an image or
|
||
|
form control (the name of the component is set by calling the AWT
|
||
|
Component method setName()).
|
||
|
|
||
|
Note that the 'name' attribute is included in the above tags. This is
|
||
|
so that they can be used within an HTML form. Normally when a form is
|
||
|
submitted the browser will gather values from each component and
|
||
|
submit these values as part of the form submission. But how do we find
|
||
|
the 'value' of a custom component? What CalPane does with these custom
|
||
|
objects is to call their toString() method and transmit this with the
|
||
|
form. So, by overriding the toString() method in your custom components
|
||
|
you can pass information out of that component and send it with the
|
||
|
form.
|
||
|
|
||
|
Rather than add JComponents one by one to CalHTMLManager, it is
|
||
|
possible to add an *array* of JComponents. A class name needs to
|
||
|
be specified for the array, and then this array can be referenced
|
||
|
within documents like so:
|
||
|
|
||
|
<OBJECT type=jcomponent jclass=mycomps jname=mycolorchooser>
|
||
|
|
||
|
Here is some code that will get a JColorChooser showing within an HTML
|
||
|
document, and it also demonstrates another aspect of the CalPane - the
|
||
|
ability to show HTML from a String argument rather than a URL:
|
||
|
|
||
|
----------------------------------------
|
||
|
import java.net.*;
|
||
|
import java.awt.*;
|
||
|
import javax.swing.*;
|
||
|
import calpa.html.*;
|
||
|
|
||
|
public class MyFifthCalPaneApplication {
|
||
|
|
||
|
public static void main(String args[]) {
|
||
|
|
||
|
String markup = "<H1>Hello World</H1><P align=center><OBJECT type=jcomponent jname=mycolorchooser>";
|
||
|
|
||
|
//create ColorChooser, name it, add it to CalHTMLManager
|
||
|
JColorChooser chooser = new JColorChooser();
|
||
|
chooser.setName("mycolorchooser");
|
||
|
CalHTMLManager.addUserComponent(chooser);
|
||
|
|
||
|
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);
|
||
|
pane.showHTMLDocument(markup);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
INTERCEPTING EVENTS FROM WITHIN A DOCUMENT
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
The 'jname' attribute used above in the <IMG>, <OBJECT> and <INPUT>
|
||
|
tags can also be used within the <A> tag. A CalPane will not try and
|
||
|
follow an activated hyperlink which has a jname, but it will pass the
|
||
|
information to its resident CalHTMLObserver. This means that the
|
||
|
programmer can put links within documents which, when activated, will
|
||
|
be sent externally to the CalPane. This is akin to having a hyperlink
|
||
|
with an ActionListener attached to it.
|
||
|
|
||
|
Note that unlike the <IMG> tag where no 'src' attribute is required,
|
||
|
the 'href' attribute must be specified within the <A> tag. This is to
|
||
|
avoid null URL errors being thrown inside the CalPane and also so that
|
||
|
the hyperlink can still be marked as visited. A real URL should not be
|
||
|
specified, but one that Java's URL class will accept as being
|
||
|
valid. So, an <A> tag might look like this:
|
||
|
|
||
|
<A href="http://www.dummy.com" jname="load_personnel_files">
|
||
|
Click here to load the personnel files
|
||
|
</A>
|
||
|
|
||
|
There is also one other way for the programmer to receive data from
|
||
|
within documents. Normally when the HTML <FORM> tag is used, the
|
||
|
'method' attribute will be given one of two arguments: 'post' or
|
||
|
'get'. Within the CalPane however the value 'jform' can also be used.
|
||
|
The Pane will not attempt to handle a 'jform' submission when a
|
||
|
'submit' control is activated. Like the <A> tag above it will simply
|
||
|
pass on all the form data to its CalHTMLObserver where it can be
|
||
|
handled directly by the programmer. For example, the following might
|
||
|
be put:
|
||
|
|
||
|
<FORM method=jform action="quit_application">
|
||
|
<INPUT type=submit value="Quit">
|
||
|
</FORM>
|
||
|
|
||
|
This will create a single 'Quit' button. There may of course be
|
||
|
situations where users need to be able to choose from a range of
|
||
|
buttons. Here is one of the ways of doing this:
|
||
|
|
||
|
<FORM method=jform action="user_choice">
|
||
|
<INPUT type=submit name=yes value=Yes>
|
||
|
<INPUT type=submit name=no value=No>
|
||
|
<INPUT type=submit name=cancel value=Cancel>
|
||
|
<INPUT type=submit name=help value=Help>
|
||
|
</FORM>
|
||
|
|
||
|
When a user activates a 'submit' control in an HTML form, the
|
||
|
activated control is treated as being successful, and so the form
|
||
|
data will include details of which control has been pressed. Thus
|
||
|
if a user pressed the Help button in the above example, the form
|
||
|
data would include the text: help=Help.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
SUPPORTED HTML TAGS AND ATTRIBUTES
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
The CalHTMLPane does not support any particular HTML standard. The aim
|
||
|
has simply been to provide a component for the Calpa package which will
|
||
|
display *most* HTML documents and display them at a speed which a
|
||
|
user of that document will find acceptable.
|
||
|
|
||
|
This speed aspect was considered to be of paramount importance, and it
|
||
|
is the reason why style sheet support has not yet been integrated into
|
||
|
the component. The overhead in parsing style data is simply too great
|
||
|
at the current time. However, the CalHTMLPane's structure has been
|
||
|
designed to support style sheets, and adding this at a later date will
|
||
|
only involve very minor code reauthoring.
|
||
|
|
||
|
The second most obvious omission in the CalPane is support for the
|
||
|
<APPLET> tag. There is a version of the CalPane which fully supports
|
||
|
applets, but this is not being released publicly under free license.
|
||
|
|
||
|
Apart from the above, you should find that the CalPane has fairly
|
||
|
wide tag and attribute support. More details and some examples of
|
||
|
tag/attribute usage can be found in the HTML documentation
|
||
|
included in the download. Generally the Pane supports most HTML3.2
|
||
|
tags and a fair number of HTML4.0 ones. In most cases tags have
|
||
|
been implemented according to HTML4.0 specification rather than
|
||
|
HTML3.2.
|
||
|
|
||
|
|
||
|
Here is a brief summary of a CalHTMLPane's tag support:
|
||
|
|
||
|
-Tables support the <COLGROUP>, <COL>, <THEAD>, <TBODY> and <TFOOT>
|
||
|
tags, and widths can be absolute, percentage or relative. The
|
||
|
bgcolor, bordercolor, bordercolorlight and bordercolordark
|
||
|
attributes allow almost any color rendering to be specified for
|
||
|
tables, groups, rows, columns and individual cells. The new <TABLE>
|
||
|
'frame' and 'rules' attributes are also supported.
|
||
|
|
||
|
-A CalPane can handle Frames including the HTML4.0 <IFRAME> tag,
|
||
|
allowing the simple inclusion of documents within documents. The
|
||
|
<IFRAME> tag has yet to be fully exploited by authors - it is
|
||
|
possible for example to run a timer which periodically updates an
|
||
|
<IFRAME> with adverts while the rest of the surrounding document
|
||
|
stays as normal. The effect is very powerful.
|
||
|
|
||
|
-The <FONT> tag will take a 'face=xxx' argument, but this is limited
|
||
|
at present. This is due to a major bug in Java 2 relating to system
|
||
|
fonts. The code for handling system fonts is already within CalPane
|
||
|
but is currently disabled because of this bug.
|
||
|
|
||
|
-Client-side image maps are supported, including the 'circle' and
|
||
|
'poly' shapes. Coordinates can also expressed in percentage rather
|
||
|
than absolute coordinates, and HTML4.0 recommendation that even
|
||
|
Internet Explorer 4 has yet to support. The HTML4.0 specification
|
||
|
states that image maps can be sourced from other documents, but
|
||
|
this is very difficult to implement. However this is supported to
|
||
|
a certain extent - the CalPane will cache any image maps it comes
|
||
|
across, and if the map is referenced in another document it will be
|
||
|
available from the cache.
|
||
|
|
||
|
-Images, tables and form components will 'float' (i.e. text and
|
||
|
other objects will wrap around them) if they are given either an
|
||
|
'align=left' or 'align=right' alignment argument. Multiple objects
|
||
|
can be floated on the same line (left and right).
|
||
|
|
||
|
-Lists should operate much as normal, though Netscape Navigator and
|
||
|
Internet Explorer treat the DD/DT tags slightly differently under
|
||
|
certain circumstances. The Pane acts much like Explorer.
|
||
|
|
||
|
-The <HR> tag will take a color argument
|
||
|
|
||
|
-<STRIKE> and <U> (underline) are both implemented, but the <BLINK>
|
||
|
tag is not as it has almost universally fallen out of use.
|
||
|
|
||
|
-Forms are supported and are the subject of the next section. Form
|
||
|
components support the HTML4.0 'accesskey' argument which allows
|
||
|
key accelerators to be given to controls . The 'tabindex' attribute
|
||
|
is in the CalHTMLPane code but is currently disabled as it creates
|
||
|
a very heavy parsing overhead (because it can be used not only with
|
||
|
form components, but with hyperlinks too).
|
||
|
|
||
|
-Finally, the CalPane supports a number of tag attributes (mainly
|
||
|
color-related) which are not officially supposed to exist. A
|
||
|
document using these attributes will show as normal in any other
|
||
|
HTML renderer.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
FORM COMPONENTS
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
As the CalHTMLPane was tested across different Look&Feels it
|
||
|
immediately became apparent that there were major problems in simply
|
||
|
instantiating form controls and adding them into documents without
|
||
|
modification.
|
||
|
|
||
|
|
||
|
The various Pluggable Look And Feel (PLAF) styles supported by Swing
|
||
|
are designed primarily for application-based programming rather than
|
||
|
what might be termed as 'document-based' or 'content-based' GUI
|
||
|
displays. These PLAFs assume the presence of a consistent background
|
||
|
('control') color against which components will be rendered, and
|
||
|
borders and other style features are incorporated into the components
|
||
|
with this control color in mind. It is possible to change the color of
|
||
|
certain basic controls with methods such as setBackground() and
|
||
|
setForeground(), but on more complex components such as comboboxes
|
||
|
these methods have limited effect.
|
||
|
|
||
|
In an HTML document however, the control color is essentially the
|
||
|
background color of the document itself - which can be any color at
|
||
|
all, including black and white. When standard Swing components are
|
||
|
rendered against such backgrounds there can be a clash (or over-
|
||
|
similarity) of colors which causes carefully programmed style features
|
||
|
to completely disappear, leaving a rather odd-looking GUI control
|
||
|
sitting on the reader's screen.
|
||
|
|
||
|
There are other problems too. Some PLAF controls (Motif buttons for
|
||
|
example) are given large borders *outside of the component itself*
|
||
|
and it becomes impossible to line such components up properly within an
|
||
|
HTML document. Opacity is also an issue, with some components
|
||
|
looking bizarre if they are made opaque, and others almost disappearing
|
||
|
if their opacity is set to false.
|
||
|
|
||
|
In order to try and overcome these difficulties a CalHTMLPane supports
|
||
|
two additional rendering styles - THREEDEE and FLUSH. Rendering form
|
||
|
controls in these styles ensures that the document will be displayed
|
||
|
in exactly the same way without regard for the currently installed
|
||
|
LAF.
|
||
|
|
||
|
There is an obvious downside to this - the form rendering style
|
||
|
incorporated into the document may be out of step with the installed
|
||
|
Look&Feel. However, testing has shown that this is not too much of an
|
||
|
issue. The document reader is not overly aware of any disparity,
|
||
|
particularly if the color of the form control is matched to the
|
||
|
document background. The two CalPane form rendering styles give the
|
||
|
document author considerable freedom in setting component colors by
|
||
|
using attributes within the relevant form tags.
|
||
|
|
||
|
The accompanying HTML documentation contains a number of examples
|
||
|
which demonstrate how to use the Pane's own form rendering styles. The
|
||
|
default rendering style is set through a method in CalHTMLPreferences,
|
||
|
but this does not prevent styles being mixed freely within documents.
|
||
|
It is possible to put a LOOKANDFEEL checkbox next to a THREEDEE button
|
||
|
which is next to a FLUSH textfield. The choice of from component
|
||
|
rendering has therefore been left entirely in the hands of the
|
||
|
programmer/author.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
THE PANE'S DIALOG
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
When an error is thrown within a CalPane (for example when an invalid
|
||
|
URL is specified in an activated hyperlink) notification of the failure
|
||
|
is sent to the resident CalHTMLObserver. Strictly speaking it is up to
|
||
|
the programmer to inform the user that such an error has occured, as
|
||
|
the CalPane may only be a small part of a much larger application.
|
||
|
|
||
|
However, the CalHTMLPane has a dialog of sorts which at times can be
|
||
|
extremely useful, not only for error messages, but for obtaining
|
||
|
user-input or displaying a menu on top of HTML documents. By default
|
||
|
this dialog will appear when an error occurs, or for example when a
|
||
|
form POST submission is made, when a warning is given to the user that
|
||
|
the transmission will be unsecure. The showing of these messages can
|
||
|
easily be disabled through a method in CalHTMLPreferences.
|
||
|
|
||
|
'Dialog' is perhaps a misnomer. The CalPane's dialog cannot be modal,
|
||
|
it is not resizable and there is no bar along its top with a close
|
||
|
button on it. It should really be thought of as a blank canvas
|
||
|
which is displayed in the JLayeredPane.MODAL_LAYER of the Pane.
|
||
|
|
||
|
To display the dialog the programmer calls one of the CalPane's
|
||
|
showDialog() methods and pass it a text string. This string is parsed
|
||
|
as HTML and the results are displayed in the dialog much as an HTML
|
||
|
document would be. (The only reason the display of a URL-based
|
||
|
dialog has not been allowed is because fetching the dialog data could
|
||
|
itself throw an error and we would have the problem of showing an error
|
||
|
dialog for an error dialog.)
|
||
|
|
||
|
The dialog can handle all supported HTML tags except for inline frames
|
||
|
and framesets. This means form components, images, hyperlinks, tables,
|
||
|
lists etc. can all be included within the dialog. With a bit of
|
||
|
practice the programmer will see that it is possible to simulate almost
|
||
|
any 'normal' dialog by using HTML, with the added bonus that complex
|
||
|
dialogs can be created which would be extremely difficult to produce
|
||
|
without the power of HTML.
|
||
|
|
||
|
The dialog can be shown anywhere within the Pane, at almost any size.
|
||
|
Events such as button presses can be picked up in the CalHTMLObserver,
|
||
|
and the programmer can add custom Swing components (with listeners
|
||
|
attached) to CalHTMLManager and have them displayed in the dialog using
|
||
|
the <OBJECT> tag.
|
||
|
|
||
|
The following simple program creates a CalHTMLPane with a JTextArea
|
||
|
below it and a 'Show Dialog' button. HTML can be enetred into the
|
||
|
textarea and when the button is pressed the dialog will appear showing
|
||
|
the rendered HTML. The HTML can be edited and another button press
|
||
|
will update the dialog display.
|
||
|
|
||
|
Here is some example HTML that you might want to try first:
|
||
|
|
||
|
<TABLE width=100% bgcolor=navy border=1 rules=none cellspacing=0>
|
||
|
<TR><TD>
|
||
|
<FONT face=helvetica color=white><B>User Log-on</B></FONT>
|
||
|
</TD></TR>
|
||
|
</TABLE>
|
||
|
<FORM method=jform action=user_logon>
|
||
|
<TABLE width=100% cellspacing=0>
|
||
|
<COLGROUP align=center></COLGROUP>
|
||
|
<TR><TD>
|
||
|
Please enter your username:
|
||
|
</TD></TR>
|
||
|
<TR><TD>
|
||
|
<INPUT type=password>
|
||
|
</TD></TR>
|
||
|
<TR><TD>
|
||
|
<BR>
|
||
|
<INPUT type=submit value=Log-On name=logon>
|
||
|
|
||
|
<INPUT type=submit value=Cancel name=cancel>
|
||
|
</TD></TR>
|
||
|
</TABLE>
|
||
|
</FORM>
|
||
|
|
||
|
Some points to note:
|
||
|
|
||
|
-The dialog has a marginwidth/marginheight of 0. If you want some
|
||
|
insets around your HTML content, wrap the content in a <TABLE>
|
||
|
tag with cellspacing or cellpadding set to the desired border.
|
||
|
|
||
|
-Because we send a width of -1 to the showDialog() method in the
|
||
|
example, the Pane shows the dialog with a default width. This
|
||
|
is why the dialog may be wider than the HTML content you enter.
|
||
|
|
||
|
-Setting the 'bgcolor' attribute in a <BODY> tag will change the
|
||
|
background color of the dialog, and its border colors as well.
|
||
|
|
||
|
-When the dialog is displayed it gets keyboard focus. Pressing the
|
||
|
ESC key will close the dialog.
|
||
|
|
||
|
-The dialog will not display scrollbars.
|
||
|
|
||
|
-The dialog's default font sizes are smaller than those used
|
||
|
within normal documents.
|
||
|
|
||
|
-Try this: <FORM method=jform action=close_dialog>
|
||
|
<INPUT type=submit value=Close>
|
||
|
</FORM>
|
||
|
|
||
|
|
||
|
----------------------------------------
|
||
|
import java.awt.*;
|
||
|
import java.awt.event.*;
|
||
|
import javax.swing.*;
|
||
|
import calpa.html.*;
|
||
|
|
||
|
public class MySixthCalPaneApplication {
|
||
|
|
||
|
public static void main(String args[]) {
|
||
|
|
||
|
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||
|
d.width = Math.min(d.width, 800);
|
||
|
d.height = Math.min(d.height, 600);
|
||
|
JFrame f = new JFrame();
|
||
|
CalHTMLPane pane = new CalHTMLPane();
|
||
|
JPanel p = new JPanel();
|
||
|
JTextArea ta = new JTextArea();
|
||
|
ta.setLineWrap(true);
|
||
|
JScrollPane sp = new JScrollPane(ta);
|
||
|
sp.setPreferredSize(new Dimension(d.width / 2, d.height / 4));
|
||
|
JButton b = new JButton("Show Dialog");
|
||
|
b.addActionListener(new MyListener(pane, ta));
|
||
|
p.add(sp);
|
||
|
p.add(b);
|
||
|
f.getContentPane().add(pane, "Center");
|
||
|
f.getContentPane().add(p, "South");
|
||
|
f.setSize(new Dimension(d.width - 10, d.height - 40));
|
||
|
f.setVisible(true);
|
||
|
}
|
||
|
|
||
|
private static class MyListener implements ActionListener {
|
||
|
|
||
|
CalHTMLPane pane;
|
||
|
JTextArea ta;
|
||
|
|
||
|
public MyListener(CalHTMLPane pane, JTextArea ta) {
|
||
|
|
||
|
this.pane = pane;
|
||
|
this.ta = ta;
|
||
|
}
|
||
|
|
||
|
public void actionPerformed(ActionEvent e) {
|
||
|
|
||
|
pane.showDialog(ta.getText(), null, -1, -1, -1, -1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
THE PANE'S FOCUS MANAGER
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
When a CalPane is instantiated, it immediately removes the existing
|
||
|
Focus Manager (usually Swing's DefaultFocusManager) and installs a
|
||
|
CalFocusManager to handle keyboard events. This action can be prevented
|
||
|
via a method in CalHTMLManager.
|
||
|
|
||
|
Swing's DefaultFocusManager uses a top-down, left-right tabbing order
|
||
|
which is not really suitable for HTML documents. The HTML4.0
|
||
|
specification states that the default tab order within documents should
|
||
|
be determined by the order in which entities appear in tags, but this
|
||
|
will not happen with Swing's Manager. If, for example, a button is put
|
||
|
in a document and then a textarea is placed to the right of it, the
|
||
|
textarea will most likely receive focus before the button because it is
|
||
|
taller and hence has a lower y-coordinate on the screen.
|
||
|
|
||
|
Even more importantly, the Swing Manager will only tab between
|
||
|
components, whereas in an HTML document we need to be able to tab
|
||
|
between hyperlinks as well.
|
||
|
|
||
|
Swing only allows a single Focus Manager per thread, so running the
|
||
|
CalFocusManager is an all-or-nothing affair. There is a method in
|
||
|
the JComponent class which looks as if it could solve the problem
|
||
|
of focus management without installing a new Manager: by overriding
|
||
|
isManagingFocus() and returning a value of true it is possible for
|
||
|
a component to handle its own keyboard events.
|
||
|
|
||
|
Unfortunately Swing's DefaultFocusManager will still manage focus for
|
||
|
components *within* the CalPane, even when the CalPane is handling its
|
||
|
own focus. Nevertheless, we could still solve this if there was a
|
||
|
method in JComponent such as:
|
||
|
|
||
|
setIsManagingFocus(boolean b)
|
||
|
|
||
|
We could then call this method with an argument of 'true' for all the
|
||
|
CalPane's children. This would cause the Swing Manager to ignore key
|
||
|
events from such components and we could pick these up from a
|
||
|
listener. As far as can be seen however, the only way to tell the
|
||
|
Swing Manager that we are handling focus is to *extend* the component
|
||
|
and override isManagingFocus(). This is totally impractical.
|
||
|
|
||
|
Most users need not worry about the above. The CalFocusManager should
|
||
|
operate in much the same way as Swing's Manager when keyboard events
|
||
|
occur outside the CalPane. Only *inside* the Pane will tabbing be
|
||
|
handled differently.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
OPTIMIZE DISPLAY
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
'Optimize display' is a feature of the CalHTMLPane which has yet to be
|
||
|
fully implemented. However, programmers may find it useful in certain
|
||
|
situations.
|
||
|
|
||
|
By default, optimizeDisplay is disabled within the pane. A method in
|
||
|
CalHTMLPreferences allows it to be set to one of two levels:
|
||
|
|
||
|
CalCons.OPTIMIZE_FONTS
|
||
|
CalCons.OPTIMIZE_ALL
|
||
|
|
||
|
When OPTIMIZE_FONTS is enabled, the default font size of a document
|
||
|
will change depending on the width of its display area. This can be
|
||
|
quite useful when displaying help documentation in a frameset.
|
||
|
The JDK API documents are a good example. When shown in frames, the
|
||
|
index part of the documentation is displayed in two narrow frames at
|
||
|
the side of the screen. If these are viewed in a CalPane with
|
||
|
OPTIMIZE_FONTS switched on, more of the index is visible because
|
||
|
the fonts used are smaller. The fonts used in the main display frame
|
||
|
will remain as normal.
|
||
|
|
||
|
If the frames are now resized by dragging the mouse it will be seen
|
||
|
that OPTIMIZE_FONTS is dynamic - as soon as a frame's width crosses
|
||
|
a certain threshold, the document will be reformatted with a new base
|
||
|
font size.
|
||
|
|
||
|
OPTIMIZE_ALL takes this a step further by trying to alter certain HTML
|
||
|
parameters in order to fit the current document into its display area.
|
||
|
With HTML tables for example, a table's border, cellspacing and
|
||
|
cellpadding will be progressively reduced until they reach their
|
||
|
absolute minimum levels. Table preferred widths will be overriden where
|
||
|
possible so that column sizes can be reduced. In short, the CalPane
|
||
|
will do whatever it can to avoid horizontal scrolling.
|
||
|
|
||
|
The optimizeDisplay feature is probably most useful when dealing with
|
||
|
technical and support documentation that could be running on any size
|
||
|
of display. It is not wise to use it when trying to show the sort of
|
||
|
graphically-rich HTML pages found on commercial Web sites. Such pages
|
||
|
tend to be formatted by their authors to absolute pixel widths, and
|
||
|
any attempt to scale these pages usually upsets the fine balance of
|
||
|
their design.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
VIEWING WEB PAGES
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
It must be stressed that if this component is used on the Web the user
|
||
|
will encounter a number of pages which render incompletely. Inline
|
||
|
scripting is becoming very common on the major sites, partcularly for
|
||
|
the dynamic creation of form controls (e.g. the checkboxes which give
|
||
|
suggested extra search parameters on Excite). The CalHTMLPane simply
|
||
|
ignores these scripts.
|
||
|
|
||
|
Programmers should also be aware of how the CalPane handles many of
|
||
|
today's commercial Web pages. These tend to be constructed in a similar
|
||
|
manner: a banner (which often includes an animated GIF) is placed
|
||
|
across the top of the page, and the rest of the document consists of
|
||
|
one or two large tables which format the content to a 640 or 800 pixel
|
||
|
display width.
|
||
|
|
||
|
Like the majority of browsers, the CalPane does not support incremental
|
||
|
table display, so most of the page will not be shown until all the
|
||
|
table data has been received. This is not normally a problem as the
|
||
|
CalPane can parse this data as fast as Java can deliver it over the
|
||
|
Web. However, a difficulty arises when the page contains images of
|
||
|
unspecified width and height.
|
||
|
|
||
|
If an author puts the widths and heights of images within <IMG> tags
|
||
|
then the document format can be determined before the image has even
|
||
|
begun loading. Without this size information however, an HTML renderer
|
||
|
can handle the page in two basic ways:
|
||
|
|
||
|
-a default size can be given to the image before its true size is
|
||
|
known. This means that the page can be displayed immediately, but
|
||
|
has the severe disadvantage that the whole document needs to be
|
||
|
completely reformatted once the actual image size is determined.
|
||
|
If there are many such images within the page, the constant
|
||
|
reformatting is extremely irritating to the user, and can
|
||
|
considerably lengthen the total time taken to display the page.
|
||
|
|
||
|
-we can wait until all image sizes are known and then display the
|
||
|
document in a single pass. The downside here is that the user's
|
||
|
screen is going to remain blank for some time as the images load.
|
||
|
|
||
|
The CalPane takes the latter approach, and the same effect can be
|
||
|
seen on many Web browsers. Apart from perhaps the page banner
|
||
|
appearing, nothing else is shown until the whole page suddenly
|
||
|
appears fully formatted with text and images. Some document authors
|
||
|
actually favor this display method because the user gets the full
|
||
|
impact of their page design rather than seeing it a piece at a time.
|
||
|
|
||
|
If you are monitoring events from within the Pane via the
|
||
|
statusUpdate() method in CalHTMLObserver you will receive a
|
||
|
WAITING_FOR_IMAGES update when this situation occurs. This message
|
||
|
indicates that the document has been fully parsed but the final
|
||
|
display format cannot be completed until all image sizes are known.
|
||
|
|
||
|
You may also encounter problems with Web pages that contain several
|
||
|
animated GIFs. See the 'known problems' section for details.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
BUG REPORTS
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
Please report any bugs you encounter with the component. It would
|
||
|
be extemely helpful if you could describe exactly the circumstances
|
||
|
under which the problem arose. In particular a sample HTML document
|
||
|
which trips the bug would be most welcome.
|
||
|
|
||
|
Not every apparently incorrect rendering is due to code deficiency.
|
||
|
When testing Web pages it immediately becomes apparent that many
|
||
|
authors do not check to see how their documents display on different
|
||
|
browsers. There are of course only two browsers that really matter,
|
||
|
but page designers may be surprised to see how differently the latest
|
||
|
versions of Explorer and Navigator handle identical HTML. It is
|
||
|
therefore possible that programmers will come across apparent
|
||
|
rendering bugs which are accounted for by a differing interpretation
|
||
|
of the underlying HTML tags.
|
||
|
|
||
|
Send bug reports to: offshore@netcomuk.co.uk
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
KNOWN PROBLEMS
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
Below are listed the known problems with the CalHTMLPane (in estimated
|
||
|
order of seriousness).
|
||
|
|
||
|
-There are occasional rendering problems on certain Web pages which
|
||
|
appear to be caused by incorrect character conversion within the
|
||
|
Java stream classes. Colors sometime display incorrectly and text
|
||
|
information disappears. If the Web page is displayed within a
|
||
|
browser such as Netscape Navigator and saved to a local file, when
|
||
|
that local file is loaded into the CalPane it displays perfectly.
|
||
|
If however the character stream sent from Java is saved to a
|
||
|
local file, the characters are slightly different to those in the
|
||
|
Navigator file.
|
||
|
|
||
|
This could be caused by incorrect byte-to-character conversion, or
|
||
|
it could be that Netscape's programmers have built in some error
|
||
|
correction into their byte converter which fixes what experience
|
||
|
has shown to be 'bad' byte sequences.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
-There can be problems with Web pages which contain 5+ animated
|
||
|
GIFs.
|
||
|
|
||
|
It does not seem to be documented anywhere, but there appears to
|
||
|
be a limit to the number of images Java will load asynchronously.
|
||
|
With an animated GIF however, the imageUpdate method never sets
|
||
|
the ALLBITS flag because image frames need to be constantly
|
||
|
streamed in. We get a FRAMEBITS flag instead. This means that to
|
||
|
keep showing the animated image we never return 'false' to
|
||
|
imageUpdate, and the image thread is permanently active while the
|
||
|
page is loaded.
|
||
|
|
||
|
Unfortunately this animated image counts towards the asynchronous
|
||
|
limit and once there are 5 (or whatever the limit is) such GIFs
|
||
|
running all other image loading becomes blocked.
|
||
|
|
||
|
One obvious way to deal with this would be to delay the loading of
|
||
|
animated GIFs until all other images had loaded. Unfortunately
|
||
|
there is no simple way to tell if an image is a GIF89 until
|
||
|
loading has begun. If we then halt the GIF once we have
|
||
|
determined its type to allow other images to load, subsequent
|
||
|
paint operations on that image later can lead to the throwing of
|
||
|
a java.lang.SecurityException from within the Sun classes. This
|
||
|
will not halt the program, but the animated GIF sometimes will not
|
||
|
display correctly.
|
||
|
|
||
|
As a consequence certain pages with a high number of GIF89s will
|
||
|
not load all images, and the DOC_LOADED call to CalHTMLObserver
|
||
|
will not be made.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- A wait cursor ought to be displayed in the period from when a
|
||
|
hyperlink is pressed to the opening of the URL connection.
|
||
|
This cannot currently be implemented due to a Java bug (which
|
||
|
is peculiar to Win32) which stops the cursor changing until the
|
||
|
mouse is moved. This can result in the wait cursor continuing
|
||
|
to display long after a method call to change it back to the
|
||
|
default cursor.
|
||
|
|
||
|
Surprisingly JavaSoft engineers refuse to accept the validity of
|
||
|
this bug, despite constant complaints from developers.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- JScrollPane will sometimes fail to display a horizontal scrollbar
|
||
|
when one is needed. This problem has been in Swing since its very
|
||
|
early release. Under certain circumstances the calculations which
|
||
|
determine whether or not a horizontal scrollbar is required seem
|
||
|
to fail to take account of the fact that a *vertical* scrollbar
|
||
|
is going to be displayed, narrowing the viewport width.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- There is a Java 2 bug which can cause incorrect style rendering
|
||
|
of system fonts. This can cause a whole page of text to be
|
||
|
rendered in italic for example instead of plain. Java's logical
|
||
|
fonts are not affected, so until this bug is fixed the support of
|
||
|
system fonts within CalPane has been disabled.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- Swing contains a bug which prevents the background of a component
|
||
|
being painted when the component dimensions are very large. This
|
||
|
can cause some temporarily strange behavior with a loading Web
|
||
|
page which has a wallpaper background image. The page should
|
||
|
display correctly when it has finished loading.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- If a document contains an inline frame (created with the
|
||
|
<IFRAME> tag) and a number of documents have been viewed
|
||
|
within it, tracking back through the Pane's history will take
|
||
|
the user back to those documents as normal.However, if the user
|
||
|
has scrolled up or down the document which contains the IFRAME
|
||
|
and the IFRAME is no longer in view within the viewport, the
|
||
|
history changes will not be visible. The user will be pressing
|
||
|
the BACK button and nothing will appear to be happening.
|
||
|
|
||
|
In theory the IFRAME should be scrolled into view when history
|
||
|
events like this take place, but this is very difficult to
|
||
|
implement because of the way frame histories work. Microsoft's
|
||
|
programmers have not been able to solve this in Internet
|
||
|
Explorer 4.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- The setting of percentage widths/heights for images within
|
||
|
nested entities (i.e. tables) has been disabled. It is clear
|
||
|
from seeing pages authored with such dimensions that there is
|
||
|
no consensus as to what the proper rendering should be. HTML4.0
|
||
|
specifies that the %width/height relates not to the image
|
||
|
size but to the amount of 'available width' - the space
|
||
|
between the current left and right margins. But does this
|
||
|
mean the document width or the TD/TH width? The latter seems
|
||
|
the obvious answer, but then we find authors using markup such
|
||
|
as:
|
||
|
|
||
|
<TABLE><TR><TD>
|
||
|
<IMG src="pic.jpg" width=20% height=10%>
|
||
|
</TD></TR></TABLE>
|
||
|
|
||
|
...which is chicken-and-egg HTML. There's no way the table size
|
||
|
can be computed.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- The <INPUT type=file> tag has not been implemented because
|
||
|
Swing's JFileChooser is still unstable.
|
||
|
|
||
|
* * *
|
||
|
|
||
|
- There's a minor problem with the Windows L&F. The scrollbar track
|
||
|
color in this L&F is gray, but it has no border. If a document is
|
||
|
displayed which has an identical background color to the
|
||
|
scrollbar track color, the two merge into one and this results in
|
||
|
a scrollbar thumb that appears to be floating in mid-air.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
ACKNOWLEDGEMENTS
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
Thanks to:
|
||
|
|
||
|
-Roedy Green, Elliotte Rusty Harold, and Peter van der Linden for
|
||
|
the wealth of Java information they freely supply.
|
||
|
|
||
|
-Steve Wilson, co-author of the MetalLookAndFeel, for his patient
|
||
|
explanations to Swing developers.
|
||
|
|
||
|
|
||
|
-----------------------------------------------------------------------
|
||
|
CONTACTING THE AUTHOR
|
||
|
-----------------------------------------------------------------------
|
||
|
|
||
|
Please contact:
|
||
|
|
||
|
Andrew Moulden
|
||
|
offshore@netcomuk.co.uk
|
||
|
|
||
|
Address:
|
||
|
|
||
|
82A Queens Road,
|
||
|
Leicester
|
||
|
LE2 1TU
|
||
|
United Kingdom
|
||
|
+44 116 270 5090
|
||
|
|