Generating HTML

J

Jason Cavett

I am attempting to generate HTML within my application for printing
documents. Due to various restrictions, I am using the
javax.swing.text.html.HTMLDocument package. That can't change (unless
it is impossible to do what I want to do).

My method takes in a TableModel and attempts to create an HTML
document from the data in the table, replicating the table within HTML
code. However, when I run the method below, I get the following
exception:

javax.swing.text.StateInvariantError: Illegal cast to
MutableAttributeSet
at javax.swing.text.AbstractDocument
$AbstractElement.checkForIllegalCast(AbstractDocument.java:2055)
at javax.swing.text.AbstractDocument
$AbstractElement.addAttributes(AbstractDocument.java:1988)
at javax.swing.text.AbstractDocument
$AbstractElement.<init>(AbstractDocument.java:1781)
at javax.swing.text.AbstractDocument
$BranchElement.<init>(AbstractDocument.java:2248)
at javax.swing.text.html.HTMLDocument
$BlockElement.<init>(HTMLDocument.java:3674)
at
javax.swing.text.html.HTMLDocument.createBranchElement(HTMLDocument.java:
379)
at
hasrd.gui.components.print.HasrdDocument.generateHTML(MyHTMLDocumentGenerator.java:
152)
...

Is it even possible to do what I want to do? If so, what am I doing
wrong?

Thanks

Here is the method in question. It is self-contained.

protected void generateHTML(TableModel dataTable) {
AbstractDocument.AttributeContext ctx = getAttributeContext();

// create default root element
BranchElement root = (BranchElement) this.createDefaultRoot();

// create the table
AttributeSet atts = ctx.getEmptySet();
atts = ctx.addAttribute(atts, StyleConstants.NameAttribute,
HTML.Tag.TABLE);
BranchElement table = (BranchElement)
createBranchElement(root, atts); // ERROR HAPPENS HERE
root.replace(0, 0, new Element[] { table });

// for each row in the table, add a row to the html
for (int row = 0; row < dataTable.getRowCount(); row++) {
// create the table
atts = ctx.getEmptySet();
atts = ctx.addAttribute(atts,
StyleConstants.NameAttribute,
HTML.Tag.TR);
BranchElement rowTag = (BranchElement)
createBranchElement(table,
atts);
table.replace(0, 0, new Element[] { rowTag });

// for each column
for (int col = 0; col < dataTable.getColumnCount(); col++)
{
// create the cell
atts = ctx.getEmptySet();
atts = ctx.addAttribute(atts,
StyleConstants.NameAttribute,
HTML.Tag.TD);
BranchElement cellTag = (BranchElement)
createBranchElement(
rowTag, atts);
rowTag.replace(0, 0, new Element[] { cellTag });

// put data into leaf node
atts = ctx.getEmptySet();
atts = ctx.addAttribute(atts,
StyleConstants.NameAttribute,
HTML.Tag.CONTENT);
atts = ctx.addAttribute(atts,
StyleConstants.ComposedTextAttribute,
dataTable
.getValueAt(row, col));
Element leaf = createLeafElement(cellTag, atts, 0, 1);
cellTag.replace(0, 0, new Element[] { leaf });
}
}
}
 
R

Roedy Green

Here is the method in question. It is self-contained.

Self-contained means something you an can compile and run without
extra stuff. You are one step away. Somebody still has to compose a
debugging harness to test your code.
 
R

Roedy Green

I am attempting to generate HTML within my application for printing
documents. Due to various restrictions, I am using the
javax.swing.text.html.HTMLDocument package.

for what you are doing, I think you would find it simpler to just use
a StringBuilder, and create a complete HTML stream starting with
<html><body>, then when you are done, feed it to the Document.

You would then avoid the complications of that rather ugly API, and
debugging becomes a snap. You squirt out your generated HTML to a
file and run it through an HTML Validator, and look at it in a
browser. see http://mindprod.com/jgloss/htmlvalidator.html

The catch is, you may inadvertently use HTML that Java does not
understand. Keep it very simple.

Cranking out HTML programmatically is very easy. You can invent
methods to do all the bullwork of balancing.
 
R

Roedy Green

javax.swing.text.StateInvariantError: Illegal cast to
MutableAttributeSet
I could not find included JavaDoc on StateInvariantError. However,
that is Eiffelian design by contract terminology for an assertion
failed that monitors the consistence of an object. That is not much
help.

MutableAttributeSet is an interface implemented by:

AbstractDocument.AbstractElement, SimpleAttributeSet,
StyleContext.NamedStyle

So it looks like fed you something an AttributeSet, but it needed a
MutableAttributeSet, but did not discover the problem until run time.

Classes implementing AttributeSet include:

AbstractDocument.AbstractElement, SimpleAttributeSet,
StyleContext.NamedStyle, StyleContext.SmallAttributeSet

I would do a

System.out.println( att.getClass() );

just prior to the problem to see just what sort of animal you are
actually passing. Use of interfaces may be great for maintainable
code, but they make debugging and comprehension harder.
 
J

Jason Cavett

Self-contained means something you an can compile and run without
extra stuff. You are one step away. Somebody still has to compose a
debugging harness to test your code.

Ah...point taken. I guess I meant that the method does not require
any outside "stuff" to run (other than the class declaration and
proper includes).
 
J

Jason Cavett

for what you are doing, I think you would find it simpler to just use
a StringBuilder, and create a complete HTML stream starting with
<html><body>, then when you are done, feed it to the Document.

You would then avoid the complications of that rather ugly API, and
debugging becomes a snap. You squirt out your generated HTML to a
file and run it through an HTML Validator, and look at it in a
browser. seehttp://mindprod.com/jgloss/htmlvalidator.html

The catch is, you may inadvertently use HTML that Java does not
understand. Keep it very simple.

Cranking out HTML programmatically is very easy. You can invent
methods to do all the bullwork of balancing.

Alright. I thought about doing that. The only thing is...I would
like the final document to be an HTMLDocument when I am finished (so
the printing code can handle it as it expects type HTMLDocument).
There doesn't seem to be a way to put associate the generated HTML
with the document.

I'll look into it more. Thanks.
 
R

Roedy Green

Alright. I thought about doing that. The only thing is...I would
like the final document to be an HTMLDocument when I am finished (so
the printing code can handle it as it expects type HTMLDocument).
There doesn't seem to be a way to put associate the generated HTML
with the document.

what about HTMLDocument.insertBeforeStart(Element elem, String
htmlText)?


Inserts the HTML specified as a string before the start of the given
element.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,602
Members
45,184
Latest member
ZNOChrista

Latest Threads

Top