Displaying HTML from an Applet

Many people have been frustrated by the fact that there seems to be no way to let the browser display arbitrary html generated by an Applet. Ideally what would be needed is something akin to the java.applet.AppletContext.showDocument() method, but which takes e.g. an InputStream instead of a URL. Since this does not exist here are some ways of getting the desired results that I'm aware of. The first one requires swing, which may mean a large download; the second one is more work but is probably smaller; the third requires help from a server; and finally the fourth one only works under Netscape (version 3.0b7 and later) and uses Javascript.

Use javax.swing.JEditorPane

Swing's JEditoryPane is capable of displaying html 3.0. If you are willing to require the users to already have or to download swing (it's a couple MB) then this is the easiest option:

    JEditorPane disp = new JEditorPane("text/html", html_text);
    disp.setEditable(false);

Rolling your own HTML formatter

Actually some are starting to come out. One you can try and use is the JavaBrowser - this is really a mini web browser written in Java and therefore contains a simple (but usable) display engine. You should be able to extract the necessary parts from there. Another option is the ICE Browser which offers better html support, but is not free for commercial use. A third possiblity is to use Netscape's IFCs - this also contains an html displayer, but the whole thing is rather large. Note that the JavaBrowser and Netscape's IFCs only display simple HTML (something like HTML 1.0), so you can't display fancy things like tables (you'll have to use the ICE Browser or write your own code for that).

Using a Server and showDocument()

You can POST (or PUT) your html to a server (e.g. using URLConnection) and have the server put the html in a file; then use AppletContext.showDocument() to retrieve that file and have it displayed in a new window (or frame).

Another possibility for very short html is to put the html in the query string of a url which is fetched via a showDocument(); the url itself then points to a simple echo cgi-script which returns the query string.

Using Javascript to display the HTML

If you have Netscape version 3.0b7 or later you can use the Javascript interface (see LiveConnect) or the "javascript:" URL to display html. To help you get started here is an example applet (Note: you must have Javascript enabled for these to work).

You need a java capable browser and java must be enabled if you want to view this example.

When you click on either button it will cause the browser to display the html code in the corresponding text field as a new document. The LiveConnect button does this via the LiveScript support, and the showDocument() button via the applet context's showDocument() method given a javascript: URL.

Here is the whole Applet:


import java.awt.Event;
import java.awt.Button;
import java.awt.TextField;
import java.awt.FlowLayout;
import java.applet.Applet;
import java.net.URL;
import java.net.MalformedURLException;
import netscape.javascript.JSObject;
import netscape.javascript.JSException;


public class JScriptExample extends Applet
{
    private String text1 = "<HTML><HEAD><TITLE>Wow</TITLE></HEAD><BODY><H1>Gimme more!</H1></BODY></HTML>";
    private String text2 = "<HTML><HEAD><TITLE>Wowee</TITLE></HEAD><BODY><H1>Gimme more!</H1></BODY></HTML> ";
    private TextField txt1, txt2;

    private JSObject win, doc;


    public void init()
    {
	setLayout(new FlowLayout(FlowLayout.LEFT));
	txt1 = new TextField(text1, 40);
	txt2 = new TextField(text2, 40);
	add(txt1);
	add(new Button("LiveConnect"));
	add(txt2);
	add(new Button("showDocument()"));
    }

    public void start()
    {
	win = JSObject.getWindow(this);
	doc = (JSObject) win.getMember("document");
    }

    public boolean action(Event evt, Object obj)
    {
        if (obj.equals("LiveConnect"))
        {
	    Object[] args = { txt1.getText() };
	    doc.call("writeln", args);
            return true;
        }
 
        if (obj.equals("showDocument()"))
        {
	    URL js;

	    try
		{ js = new URL("javascript:\"" + txt2.getText() + "\""); }
	    catch (MalformedURLException mue)
		{ return true; }
	    getAppletContext().showDocument(js);
            return true;
        }
 
        return super.action(evt, obj);
    }

}

Using LiveConnect basically what you do is get a handle on the current document (the getWindow() and getMember() methods) and then display the html with the Javascript writeln function (via the doc.call() method).

Since this uses the netscape.javascript package you must include the java_301.zip class archive in your classpath when compiling the applet. I actually just use a 'javac -classpath "java_301.zip:." ...'. Furthermore the Applet tag must include the MAYSCRIPT attribute:

<APPLET CODE="JScriptExample.class" WIDTH=500 HEIGHT=80 MAYSCRIPT>
</APPLET>

Paul Houle also has a nice demonstration of how to use LiveConnect; if you have trouble with the above example you might want to try his instead. It's similar, except that is uses the eval() call to open a window, write to it, and then close it.

[HTTPClient]


Ronald Tschalär / 19 March 2000 / ronald@innovation.ch.