JTextComponent and HTML Text Display (Java Foundation Classes) Book Home Java Enterprise in a Nutshell Search this book

3.21. JTextComponent and HTML Text Display

The most complex component in all of Swing is the JTextComponent, which is a powerful editor. It is part of the javax.swing.text package and generally is not used directly. Instead, you typically use one of its subclasses, such as JTextField, JPasswordField, JTextArea, or JEditorPane. The first three of these components are straightforward. They are for the entry of a single line of text, secret text such as a password, and simple, unformatted, multiline text, respectively.

It is the JEditorPane component that really makes use of the full power of JTextComponent. JEditorPane supports the display and editing of complex formatted text. In conjunction with the classes in the javax.swing.text.html and javax.swing.text.rtf packages, JEditorPane can display and edit HTML and RTF documents. The ability to display formatted text so easily is a very powerful feature. For example, the ability to display HTML documents makes it simple for a Swing application to add online help based on an HTML version of the application's user manual. Furthermore, formatted text is a professional-looking way for an application to display its output to the user.

Because HTML has become so ubiquitous, we'll focus on the display of HTML documents with JEditorPane, There are several different ways to get a JEditorPane to display an HTML document. If the desired document is available on the network, the easiest way to display it is simply to pass an appropriate java.net.URL object to the setPage() method of JEditorPane. setPage() determines the data type of the document and, assuming it is an HTML document, loads it and displays it as such. For example:

editor.setPage(new java.net.URL("http://www.my.com/product/help.htm"));

If the document you want to display is in a local file or is available from some kind of InputStream, you can display it by passing the appropriate stream to the read() method of JEditorPane. The second argument to this method should be null. For example:

InputStream in = new FileInputStream("help.htm");
editor.read(in, null);

Yet another way to display text in a JEditorPane is to pass the text to the setText() method. Before you do this, however, you must tell the editor what type of text to expect:

editor.setContentType("text/html");
editor.setText("<H1>Hello World!</H1>");

Calling setText() can be particularly useful when your application generates HTML text on the fly and wants to use a JEditorPane to display nicely formatted output to the user.

Example 3-4 shows one such use of the JEditorPane. This example is an alternative to Example 3-3: it displays the contents of a directory in tabular form but uses an HTML table instead of the JTable component. As a bonus, this example uses HTML hyperlinks to allow the user to browse from one directory to the next. (If you download and run the two examples, however, you'll probably notice that the JTable example is significantly faster, since it does not have to encode the directory contents into HTML and then parse that HTML into a table.) Figure 3-9 shows sample output from this example.

figure

Figure 3-9. The JEditorPane component displaying an HTML table

Example 3-4. Dynamically Generated HTML in JEditorPane

import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.util.Date;

/**
 * This class implements a simple directory browser using the HTML
 * display capabilities of the JEditorPane component
 **/
public class FileTableHTML {
  public static void main(String[] args) throws IOException {
    // Get the name of the directory to display
    String dirname = (args.length>0)?args[0]:System.getProperty("user.home");

    // Create something to display it in
    final JEditorPane editor = new JEditorPane();
    editor.setEditable(false);               // we're browsing not editing
    editor.setContentType("text/html");      // must specify HTML text
    editor.setText(makeHTMLTable(dirname));  // specify the text to display
  
    // Set up the JEditorPane to handle clicks on hyperlinks
    editor.addHyperlinkListener(new HyperlinkListener() {
      public void hyperlinkUpdate(HyperlinkEvent e) {
	// Handle clicks; ignore mouseovers and other link-related events
	if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
	  // Get the HREF of the link and display it.
	  editor.setText(makeHTMLTable(e.getDescription()));
	}
      }
    });

    // Put the JEditorPane in a scrolling window and display it
    JFrame frame = new JFrame("FileTableHTML");
    frame.getContentPane().add(new JScrollPane(editor));
    frame.setSize(650, 500);
    frame.setVisible(true);
  }

  // This method returns an HTML table representing the specified directory
  public static String makeHTMLTable(String dirname) {
    // Look up the contents of the directory
    File dir = new File(dirname);
    String[] entries = dir.list();

    // Set up an output stream we can print the table to.
    // This is easier than concatenating strings all the time.
    StringWriter sout = new StringWriter();
    PrintWriter out = new PrintWriter(sout);
    
    // Print the directory name as the page title
    out.println("<H1>" + dirname + "</H1>");

    // Print an "up" link, unless we're already at the root
    String parent = dir.getParent();
    if ((parent != null) && (parent.length() > 0)) 
      out.println("<A HREF=\"" + parent + "\">Up to parent directory</A><P>");

    // Print out the table
    out.print("<TABLE BORDER=2 WIDTH=600><TR>");
    out.print("<TH>Name</TH><TH>Size</TH><TH>Modified</TH>");
    out.println("<TH>Readable?</TH><TH>Writable?</TH></TR>");
    for(int i=0; i < entries.length; i++) {
      File f = new File(dir, entries[i]);
      out.println("<TR><TD>" + 
		  (f.isDirectory() ?
		     "<a href=\""+f+"\">" + entries[i] + "</a>" : 
		     entries[i]) +
		  "</TD><TD>" + f.length() +
		  "</TD><TD>" + new Date(f.lastModified()) + 
		  "</TD><TD align=center>" + (f.canRead()?"x":" ") +
		  "</TD><TD align=center>" + (f.canWrite()?"x":" ") +
		  "</TD></TR>");
    }
    out.println("</TABLE>");
    out.close();

    // Get the string of HTML from the StringWriter and return it.
    return sout.toString();
  }
}


Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.