![]() ![]() ![]() |
2
Creating a Document
Building Page Templates
Applying Page Templates
Creating a Printer
Creating a Document
Controlling Flow
In Basic Steps for Creating a JClass PageLayout Document, in Chapter 1, we outlined the five basic steps necessary to create the simplest document. In this chapter, we build on that foundation, giving you the specific information you need to make each of those steps.
2.1 Building Page Templates
In A Simple JClass PageLayout Program, in Chapter 1, you saw a JClass PageLayout program that outputs a single line of text to a printed page. Before you can flow content into a document, you need a page template that defines how the page is laid out. Page templates specify:
- the physical size of the page
- the location and size of the frames that will hold text and images
- the order text is to progress through those frames
- the next page to generate when the existing page and/or section is full
JClass PageLayout templates are written in the Extensible Markup Language (XML). The templates use a common Document Type Definition (DTD) that is built into the JClass PageLayout API. The DTD defines the tags and attributes used to specify the appearance of the page templates. It is located in com/klg/jclass/xml-dtd/JCPageTemplate.dtd.
For an introduction to XML, refer to:
http://www.javaworld.com/javaworld/jw-04-1999/jw-04-xml.html. There are many guides that provide a more comprehensive examination of XML, such as The XML Handbook, by Charles Goldfarb and Paul Prescod.JClass PageLayout provides default page templates for most standard page types. For the sake of simplicity, the Hello, World program uses a default page template, as follows:
doc = new JCDocument(printer, JCDocument.BLANK_8p5x11);The following table lists and describes the default page templates available to you.
Unlike the introductory example in the previous chapter, most applications require more than one type of output page. If your application requires custom output pages, the template must provide a definition for each type of page.
2.1.1 A Sample Template
The following is an XML document you could use to define an 8.5 x 11 (US Letter) page template that, unlike the standard template
<?xml version="1.0"?>Blank_8p5x11
, includes headers and footers.
<!DOCTYPE JCPAGETEMPLATE SYSTEM "JCPageTemplate.dtd">
<JCPAGETEMPLATE TITLE="8p5x11">
<PAGE NAME="8p5x11" UNIT="inches">
<LOCATION X="0" Y="0"/>
<SIZE WIDTH="8.5" HEIGHT="11"/>
<FRAME NAME="header" UNIT="inches" COLOR="grey">
<LOCATION X="1" Y="0.25"/>
<SIZE WIDTH="6.5" HEIGHT="0.75"/>
</FRAME>
<FRAME NAME="body" UNIT="inches">
<LOCATION X="1" Y="1"/>
<SIZE WIDTH="6.5" HEIGHT="9"/>
<COLUMN COUNT="2"/>
</FRAME>
<FRAME NAME="footer" UNIT="inches" COLOR="pink">
<LOCATION X="1" Y="10.25"/>
<SIZE WIDTH="6.5" HEIGHT="0.75"/>
</FRAME>
<FLOWFRAME NAME="body"/>
<FLOWPAGE NAME="8p5x11"/>
<FLOWSECTION NAME="8p5x11"/>
</PAGE>
</JCPAGETEMPLATE>
2.1.2 The Template DTD
The structure of JClass PageLayout templates is defined in an XML Document Type Definition (DTD) stored as a String in
JCPageTemplate
. We reprint it here to give you an idea of the hierarchy of elements in an XML template. For a complete description of the elements used in a JClass PageLayout template, refer to Template Elements and Attributes, in Chapter 2.Please note that the order of the attributes and child elements of each element is fixed; the order shown in the example below must be used.
<!-- DTD for JClass PageLayout Templates -->
<!ELEMENT JCPAGETEMPLATE (PAGE+)>
<!ATTLIST JCPAGETEMPLATE TITLE CDATA #IMPLIED>
<!ELEMENT PAGE (LOCATION,SIZE,FRAME+,FLOWFRAME*,FLOWPAGE,FLOWSECTION)>
<!ATTLIST PAGE NAME CDATA #REQUIRED
UNIT (inches|points|cm|cms|centimeters|centimetres) "inches"
COLOR CDATA #IMPLIED
ORIENTATION (automatic|portrait|landscape) "automatic"
FIRST (True|true|TRUE|False|false|FALSE) "false">
<!ELEMENT FRAME (LOCATION,SIZE,BORDER?,COLUMN?,MARGIN?)>
<!ATTLIST FRAME NAME CDATA #REQUIRED
UNIT (inches|points|cm|cms|centimeters|centimetres) "inches"
COLOR CDATA #IMPLIED>
<!ELEMENT LOCATION EMPTY>
<!ATTLIST LOCATION X CDATA #REQUIRED
Y CDATA #REQUIRED>
<!ELEMENT SIZE EMPTY>
<!ATTLIST SIZE WIDTH CDATA #REQUIRED
HEIGHT CDATA #REQUIRED>
<!ELEMENT BORDER EMPTY>
<!ATTLIST BORDER TYPE (blank|broken|dashed|double|none|plain|regular|single) "blank"
COLOR CDATA "black"
THICKNESS CDATA #IMPLIED>
<!ELEMENT COLUMN EMPTY>
<!ATTLIST COLUMN COUNT CDATA #REQUIRED
SPACING CDATA #IMPLIED>
<!ELEMENT MARGIN EMPTY>
<!ATTLIST MARGIN TOP CDATA #REQUIRED
RIGHT CDATA #REQUIRED
LEFT CDATA #REQUIRED
BOTTOM CDATA #REQUIRED>
<!ELEMENT FLOWFRAME EMPTY>
<!ATTLIST FLOWFRAME NAME CDATA #REQUIRED>
<!ELEMENT FLOWPAGE EMPTY>
<!ATTLIST FLOWPAGE NAME CDATA #REQUIRED>
<!ELEMENT FLOWSECTION EMPTY>
<!ATTLIST FLOWSECTION NAME CDATA #REQUIRED>
2.1.3 Template Elements and Attributes
The following table describes the elements and attributes used to define a page template.
Please note that the order of the attributes and child elements of each element is fixed; the order shown in the table below and in Section 2.1.2, The Template DTD, must be used.
2.2 Applying Page Templates
After writing your own XML page template, you can apply it to your document by loading it either as an internal String or an external XML file. The following table describes the various
JCPageTemplate
methods you can use to apply templates.
2.2.1 Loading External XML Files
Users of JClass PageLayout will need to include the JAR files jaxp.jar and crimson.jar1 in their CLASSPATH. These files replace the now obsolete parser.jar and xml.jar from earlier releases. They are distributed in the JCLASS_HOME/lib directory along with the JClass PageLayout JAR file.
The following example uses
JCDocument document = null;java.io.File
to load the external XML file8p5x11.xml
as a template.
try {
document = new JCDocument(printer, JCPageTemplate.loadTemplates
(new java.io.File("8p5x11.xml")));
}
catch (Exception e) {
System.err.println("Error loading template = " + e);
System.exit(1);
}
2.2.2 Loading XML Strings
The following example uses
JCDocument document = null;java.io.StringReader
to load an XML template that is defined as a String (template
) earlier in the program.
try {
document = new JCDocument(printer, JCPageTemplate.loadTemplates
(new StringReader(template)));
}
catch (Exception e) {
System.err.println("Error loading template = " + e);
System.exit(1);
}
2.3 Creating a Printer
Now that the page templates are defined, the next step is to instantiate the Printer object that defines the type of print output produced.
// Open the output file
try {
outfile = new FileOutputStream("test.pdf");
}
catch (FileNotFoundException e) {
System.out.println("Could not open file");
return;
}
// Create a PDF printer
printer = new JCPDFPrinter(outfile);This example creates a printer object which uses PostScript fonts, lays out the flow, and generates a PDF (Adobe Portable Document Format) file (
test.pdf
) when the document is printed.Other printer types include
JCHTMLPrinter
,JCPostScriptPrinter
andJCPCLPrinter
, which create output in Adobe's PostScript and the Hewlett-Packard Printer Control Language (PCL), respectively. UsingJCAWTPrinter
, you can print to the system printer.JCAWTScreenPrinter
is used for printing to a screen, which can be used withJCAWTPreviewer
for print preview mode. For more information on printing, refer to Printing Options, in Chapter 7.
2.4 Creating a Document
The
JCDocument document = new JCDocument(printer,JCDocument
object holds theJCPage
andJCFrame
objects into which text and images are flowed. In the Hello, World example, we defined theJCDocument
as follows:
JCDocument.BLANK_8p5X11);When you instantiate a new
JCDocument
, you can specify the printer to which you want to send its output, along with the name of the standard template it is to use as shown in the code line above, or by using theJCPageTemplate.loadTemplates()
method and passing a list of page templates. For information on defining a printer, refer to Creating a Printer, in Chapter 2. For information on standard templates, refer to Building Page Templates, in Chapter 2.
2.5 Controlling Flow
In cases where text is to flow from frame to frame, the page template specifies the basic flow of text within a document. Template Elements and Attributes, in Chapter 2, describes how to use
FlowFrameList
to direct the flow of text through frames,FlowPageTemplate
to direct the flow of text to the next page, andFlowSectionTemplate
to direct the flow of text after a section break.At times, you may want to advance the flow before it reaches the end of the current frame or page. For example, on a title page, you may want to flow the text containing the document title into a frame you've named Title, then advance the flow to print the author's name into another frame you've named Author.
Because you need to use
JCFrame
methods when you want to render text and images independently from the flow, these methods are extremely important to the text flow of your layout. When you want to direct the flow through frames and pages, useJCFlow
methods.
2.5.1 Frame Methods
Use
JCFrame
methods when you want to render content that is not part of the main flow. For example, the information contained in header and footer frames is rendered separately from the contents of the body frame. Until new instructions are given, information printed into the header frame of a template page will recur. For more information, refer to Headers and Footers, in Chapter 6.Content is not added directly into the
JCFrame
's render list; rather, content is appended to a current line until a complete line is built or the current line is flushed. The current line always begins as zero height - no assumption is made about the attributes of the elements that will subsequently be added to it. Thus, the current line will always fit immediately following the just-completed previous line, even if there is virtually no space available at the end of a frame. As content is added to the current line, its size will be adjusted to fit the new elements. If an element is added to the line which makes the line too tall for the available space, then the frame will attempt anewColumn()
action. In a case where thenewColumn()
action succeeds, the elements of the current line are mapped to their new positions and the flow continues. In the remainder of cases where there is no following column, the frame throws anEndOfFrameException
. For more information on exceptions, please see Exceptions, in Chapter 5.
JCFrame
methods cease rendering information when the content reaches the bottom of a frame, since they are not part of the flow. When the frame runs out of room, anEndOfFrameException
is thrown.
2.5.2 Flow Methods
When a
JCFlow
object is instantiated for a document, it generates the document's first page. This first page will normally have one or more flow frames, and the first of these will be initialized as the current frame. Once a current frame has been initialized, all flow content is passed to that frame until the frame becomes full.Note: If the first page does not have a flow frame, successive pages will be generated until a flow frame is discovered.
You create the flow by instantiating a
JCFlow
object, passing in aJCDocument
as a parameter. The passed-inJCDocument
is the only one that may be associated with theJCFlow
object. Note that there can be only oneJCDocument
object perJCFlow
; also, theJCDocument
object must be the one passed to theJCFlow
in the constructor.The template page's
FlowFrameList
,FlowPageTemplate
, andFlowSectionTemplate
attributes control the order by which the flow progresses through frames and pages. To control flow beyond the standard sequence specified by the templates, the program needs to callJCFlow
methods. The following table describes the methods used to control flow.
2.5.3 A Flow Programming Example
The following example of flow programming comes from sample.java, which you can find in the /examples/pagelayout/ folder of your JClass PageLayout installation directory.
// Flow simple text into the document
// while occasionally changing the text style.
flow.setCurrentTextStyle(normal);
normal.setFontStyle(Font.BOLD | Font.ITALIC);
flow.print("Hello, world!");
flow.newParagraph();
normal.setFontStyle(Font.PLAIN);
flow.print("This is a simple ");
normal.setFontStyle(Font.BOLD | Font.ITALIC);
flow.print("JClass PageLayout ");
normal.setFontStyle(Font.PLAIN);
flow.print("example which does a number of different things.");
flow.newParagraph();
// talk about headers and footers
flow.setCurrentTextStyle(heading);
flow.print("Headers and Footers");
flow.newParagraph();
flow.setCurrentTextStyle(normal);
flow.print("First off, what we have done is set up a simple page
with a ");
normal.setFontStyle(Font.ITALIC);
flow.print("header");
normal.setFontStyle(Font.PLAIN);
flow.print(" and a ");
normal.setFontStyle(Font.ITALIC);
flow.print("footer");
normal.setFontStyle(Font.PLAIN);
flow.print(". The header contains a right justified title and the ");
flow.print("footer contains a centered macro that prints the
current ");
flow.print("page number.");
2.5.4 Typical Content Flow Sequence
Several events are normally involved in adding content to the flow. These events are listed below.
- The application declares the addition of a text String to the flow, calling
JCFlow.print (String)
.JCFlow.print()
passes the String and the currentJCTextStyle
to the correspondingJCFrame.print(JCTextStyle, String)
method.JCFrame.print()
encapsulates the String object in aStringRender
object, using theJCTextStyle
to supply formatting information and font metrics information from the current Graphics (provided by theJCPrinter
).JCFrame.flowPrint()
is called with the newStringRender
object.flowPrint()
determines the amount of available space (subject to tab position and alignment, indentation and margin) on the current line to see whether the String will fit. If the text is too long to fit,flowPrint()
will attempt to split off part of the String to fit into the available space.- The text, or the portion of it that fits on the line, is added to the current line in memory, and any required adjustments are made to the height of the line and its baseline. (If the text is larger than previous elements on the line more space will be needed. Similarly, if the text is in superior subscript mode, then that may increase the height of the line.)
- If the line has been made too high to fit in the amount of vertical space currently available, then the action is abandoned and the current line is stored in a
EndOfFrameException
object which is thrown to be caught by theJCFlow
action.- If the line fits, but not all (or none) of the text was added to the line, the current line is pasted into the frame and a new line is begun. The remaining text is printed into the new line.
- If an
EndOfFrameException
is thrown, it is caught in theJCFlow.print()
method, which will then find the next flow frame and pass to it the current line of text which did not fit, followed by any other pending content.Please note that the same sequence is followed for embedded objects, except that it is not possible to split them; thus, if embedded objects do not fit on the current line, they are handed in their entirety to the following line.
1You may substitute for crimson.jar any parser that is compliant with Sun's JAXP 1.1 specification. See Sun's JAXP documentation for more information:
![]() ![]() ![]() |