23.8 Writing HTML


The write( ) method from JEditorPane takes advantage of the writer installed as part of the HTMLEditorKit. In our previous example, that writer is the HTMLWriter class. Starting with a more generic styled document, you could also write HTML with MinimalHTMLWriter. The classes described in this section both extend from the AbstractWriter class. (See Figure 23-9.)

Figure 23-9. HTML document-writing class diagram
figs/swng2.2309.gif

23.8.1 The AbstractWriter Class

In this chapter, we've talked about a variety of strategies for saving document content. As of SDK 1.2, a new class provides some assistance in creating a rendition of an in-memory document structure suitable for saving as human-readable text. It relies on the ElementIterator class. AbstractWriter supports indentation to clarify the document structure as well as maximum line length to keep the generated output easy to read.

ElementIterator is a simple iterator class (somewhat obviously) devoted to working with Element objects. It has the usual next( ) and previous( ) methods of any bidirectional iterator. Both return objects of type Element. Unlike the new iterators in the Collections API, there is no hasNext( ) method. Instead, next( ) or previous( ) return null to signal the "end" of the stream. As with the constructors for AbstractWriter, an ElementIterator can be built on a Document or start from a particular Element. This class is covered in more depth in Chapter 22.

23.8.1.1 Properties

AbstractWriter defines the properties shown in Table 23-14.

Table 23-14. AbstractWriter properties

Property

Data type

get

is

set

Default value

canWrapLines1.3, p

boolean

·

 

·

true

currentLineLength1.3, p

int

·

 

·

 

documentp

Document

·

     

elementIteratorp

ElementIterator

·

     

endOffset1.3

int

·

     

indentLevel1.3, p

int

·

   

0

indentSpacep

int

·

 

·

2

lineEmpty1.3, p

boolean

 

·

   

lineLength1.3, p

int

·

 

·

100

lineSeparator1.3

String

·

 

·

line.separator system property

startOffset1.3

int

·

     

writer1.3, p

Writer

·

     

1.3since 1.3, pprotected

Several properties are read-only and simply help describe the state of the current writer. The document itself is available through the document property. The elementIterator, endOffset, indentLevel, startOffset, and writer properties all give you information about the writer (and a reference to the writer itself). If you are writing the entire document, startOffset is 0, and endOffset is the length of the document. The other read-only property, lineEmpty, can tell you if the current line the writer is working on is empty. The mutable properties help you configure how the output looks. The canWrapLines and lineLength let you dictate how long lines are "rendered" when written. If canWrapLines is true, and currentLineLength is greater than lineLength, the text is wrapped. How much space is used for each level of indentation is controlled by the indentSpace property. Likewise, the lineSeparator property dictates the line ending used during output.

23.8.1.2 Constant

Table 23-15 shows the single, protected constant defined by AbstractWriter.

Table 23-15. AbstractWriter constant

Constant

Data type

Description

NEWLINE

char

The newline character (\n)

23.8.1.3 Constructors
protected AbstractWriter(Writer w, Document doc)
protected AbstractWriter(Writer w, Document doc, int pos, int len)

Create an object that assists in writing the specified Document or portion (starting at pos and running for len characters) of doc.

protected AbstractWriter(Writer w, Element root)
protected AbstractWriter(Writer w, Element root, int pos, int len)

Create an object that assists in writing the elements below (and including) root. A portion of the elements (starting at pos and running for len characters) below root can also be specified.

23.8.1.4 Output-generating methods

The following methods write text to the Writer supplied in the constructor:

protected void indent( ) throws IOException

Write a series of blank spaces according to the current indent level (see decrIndent( ) and incrIndent( ) later in this chapter).

protected void text(Element elem) throws BadLocationException, IOException

Write the current text within the range of the given element (as returned by getText( ) which is discussed later in this chapter).

abstract protected void write( ) throws IOException, BadLocationException

Must be implemented by subclasses to write the document. The intention is that subclasses call getElementIterator( ) and then iterate over the elements, using the other methods supplied by this class to produce the output.

protected void write(char ch) throws IOException

Write the given character. If the maximum line length is reached, it also writes a NEWLINE character and calls indent( ).

protected void write(String str) throws IOException

Write the given string. If the string is too long to fit on the current line, the method checks to see if it would fit on a new line. If so, the entire string is written on a new line. If not, the line is split between the current line and the next line.

protected void writeAttributes(AttributeSet attr) throws IOException

Write a textual representation of the given set of attributes. Each attribute is written as "name=value".

23.8.1.5 Formatting methods
protected void incrIndent( )

Increment the indent level. The indent level is initially 0.

protected void decrIndent( )

Decrement the indent level.

23.8.2 The HTMLWriter Class

The HTMLWriter class is a fairly intricate example of extending AbstractWriter. HTMLWriter outputs HTMLDocument objects to a stream. The writer keeps all the tags (even ones it doesn't understand) intact and produces reasonably formatted HTML. Tags carry attributes exactly as you would expect. All attributes are enclosed in double quotes (<tag attribute="value">) to keep embedded spaces of attribute values intact and to conform to the HTML specification.

23.8.2.1 Constructors

Two constructors build a writer from a given HTMLDocument:

public HTMLWriter(Writer w, HTMLDocument doc)
public HTMLWriter(Writer w, HTMLDocument doc, int pos, int len)

Both constructors require a Writer object (w) and an HTML document (doc) to write. The writer can be any valid writer, including a FileWriter or possibly an OutputStreamWriter chained on top of a Socket. The second version of the constructor creates a writer for a subset of doc specified by the starting offset pos and extending for len characters.

23.8.2.2 Writing method

Only one public writing method exists:

public void write( ) throws IOException, BadLocationException

Write the document (or specified portion) to the given output stream. It loops through the element structure of the document and drives calls to the appropriate protected methods for the various elements it encounters. For example, if it encounters an HTML comment, it invokes the comment( ) method.

23.8.3 MinimalHTMLWriter

If you have a simple StyledDocument that was not initially an HTML document, you can still write it as HTML using the MinimalHTMLWriter. For example, we could add a "Save As" option to our StyledEditor class to output the document as HTML in addition to the usual method. Here's the code for the new Action:

class SaveAsHtmlAction extends AbstractAction {   public SaveAsHtmlAction( ) {     super("Save As...", null);   }   // Query user for a filename and attempt to open and write the text   // component's content to the file.   public void actionPerformed(ActionEvent ev) {     JFileChooser chooser = new JFileChooser( );     if (chooser.showSaveDialog(StyledEditor.this) !=           JFileChooser.APPROVE_OPTION)       return;     File file = chooser.getSelectedFile( );     if (file == null)       return;     FileWriter writer = null;     try {       writer = new FileWriter(file);         MinimalHTMLWriter htmlWriter = new MinimalHTMLWriter(writer,            (StyledDocument)textComp.getDocument( ));       htmlWriter.write( );     }     catch (IOException ex) {       JOptionPane.showMessageDialog(StyledEditor.this,           "HTML File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);     }     catch (BadLocationException ex) {       JOptionPane.showMessageDialog(StyledEditor.this,           "HTML File Corrupt", "ERROR", JOptionPane.ERROR_MESSAGE);     }     finally {       if (writer != null) {         try {           writer.close( );         } catch (IOException x) {}       }     }   } }

You should see two substantive changes to the SaveAction class from the previous example. First, rather than let the textComp object (an instance of JEditorPane) write itself out, we create our MinimalHTMLWriter from a FileWriter object and the document from our textComp. The write( ) method of the htmlWriter( ) spits out an HTML version of our document. Unfortunately, you still have to be careful with this writer it's not perfect yet. Figure 23-10 shows a screenshot of a simple document in our styled editor and the same document as HTML displayed inside a browser. Note that the HTML version is not quite perfect, as you can see from the fact that it displays differently in the browser than it does in our editor.

Figure 23-10. The StyledEditor document saved (not perfectly) as HTML and displayed in a browser
figs/swng2.2310.gif
23.8.3.1 Constructors

MinimalHTMLWriter has two constructors:

public MinimalHTMLWriter(Writer w, StyledDocument doc)
public MinimalHTMLWriter(Writer w, StyledDocument doc, int pos, int len)

Build writers for the given doc. The second version writes len characters of content starting from pos.

23.8.3.2 Public writing method

MinimalHTMLWriter has one public method for starting the writing process:

public void write( ) throws IOException, BadLocationException

Write the document (or the specified part of the document) to the writer given in the constructor.



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net