Printing in
Java, Part 4 - JavaWorld February
2001
Tutorial Details:
Printing in Java, Part 4
Printing in Java, Part 4
By: By Jean-Pierre Dubé
Code the print framework
any of you have waited a long time for this month's article. In the last three articles, you have learned about the strengths and weaknesses of the Java Print API. In Part 1 , you learned about the different models that the Java API uses to produce printed output. Part 2 presented code examples of those models. Part 3 introduced you to the print framework. Now that everything is clear in your head, you can start implementing that framework.
Printing in Java: Read the whole series!
Part 1: Acquaint yourself with the Java printing model
Part 2: Print your first page and render complex documents
Part 3: Jean-Pierre Dubé introduces the print framework that works on top of the Java Print API
Part 4: Code the print framework
Part 5: Discover the print framework's support classes
The project's structure
Before you begin coding, I would like to explain how I organized the project, what tools I used for its development, how I tested it, and where to find the appropriate files.
I used an integrated development environment (IDE) called Java Development Environment (JDE), which is a nice add-on to Emacs. Written by Paul Kinnucan, JDE incorporates great features, like an integrated debugger, code completion, and comment generation.
I also used Ant 1.1 to build this project. Ant is a powerful scripting tool, similar to the make utility. But unlike make, Ant easily defines rules by using an XML file. Because it's written in Java, Ant is portable. If you are unfamiliar with the Ant tool, read Michael Cymerman's excellent article, " Automate your build process using Java and Ant " ( JavaWorld, October 20, 2000).
Listing 1 provides the content of my Ant file, build.xml :
Listing 1: build.xml
If you use my Ant file, don't forget to change the base directory at the top of the file to your base directory. Refer to Figure 1 for more details on this project's directory structure.
Every Java programmer should complete some form of unit testing. Unit testing not only tests your code, it can also provide excellent examples on how to use your code. In this series, all the code examples come from test fixtures.
To test my code, I used JUnit 3.2, a high-quality testing framework. I specifically like JUnit's ability to test code as either a black box, as the code-user will see it, or a white box, from the inside. The two testing modes differ based on the location of your test fixtures. If you place your test fixtures in the same package as your test program, then you perform white-box testing; you can do black-box testing by placing your test fixtures in another package. In this series, the test fixtures will feature black-box testing.
For the framework's file organization, see Figure 1. In the root directory named PrintFrameWork , you will find all the subdirectory files related to this project.
Figure 1. Project file structure
Table 1 defines each directory:
Name
Description
build
Contains the print framework library ( printframework.jar )
classes
Contains output directory for the Java compiler
test
Contains source code for unit testing
images
Contains images needed by the print framework library -- those images are copied by ANT to the classes subdirectory when a rebuild is complete
src
Contains source files for the print framework library
Table 1. Project file structure
Now that you know the files' location, you can begin coding. Start by implementing all the measurement classes. If you need to review the framework's design, refer to UML Diagram 1 .
Implement the measurement system classes
You must implement the measurement classes because every other class in the framework relies on them.
The PFUnit class forms the heart of the measurement system; only the getPoints() and setPoints() methods are left abstract . Place your code that converts the measurement unit to points in getPoints() , and the code that converts from points to the measurement unit, in the setPoints() method.
All the basic math operations have been implemented in PFUnit . The math methods support either a double value or a PFUnit class as their input. When you pass a double value in parameters, the method assumes that the value is in the measurement unit represented by the class. For example, a double value passed to one of the math methods in the PFInchUnit class is assumed to be in inches. The implementation of PFUnit is in Listing 2.
Listing 2: PFUnit
The next code segment shows how easily you can implement your own measurement system. This segment implements the PFInchUnit class.
1|package com.infocom.print;
2|
3|/**
4| * Class: PFInchUnit
5| *
6| * @author Jean-Pierre Dube
7| * @version 1.0
8| * @since 1.0
9| * @see PFUnit
10| */
11|
12|public class PFInchUnit extends PFUnit {
13|
14| //--- Private constants declarations
15| private final static int POINTS_PER_INCH = 72;
16|
17|
18| /**
19| * Constructor: PFInchUnit
20| *
21| */
22| public PFInchUnit () {
23|
24| }
25|
26|
27| /**
28| * Constructor: PFInchUnit
29| *
30| * @param parValue a value of type double
31| */
32| public PFInchUnit (double parValue) {
33|
34| super (parValue);
35|
36| }
37|
38|
39| /**
40| * Method: getPoints
41| *
42| * Return the result of the conversion from
43| * inches to points.
44| *
45| * @return a value of type double
46| */
47| public double getPoints () {
48|
49| return (getUnits () * POINTS_PER_INCH);
50|
51| }
52|
53|
54| /**
55| * Method: setPoints
56| *
57| * @param parPoints a value of type double
58| */
59| public void setPoints (double parPoints) {
60|
61| setUnits (parPoints / POINTS_PER_INCH);
62|
63| }
64|}// PFInchUnit
Line 49 in the code above returns the units (inches) converted to points. There are 72 points per inch, so converting inches to points requires simply multiplying the inch value by 72. The PFUnit library features two other measurement unit classes: PFCmUnit and PFPointUnit .
Next, implement the PFPoint , PFSize , and PFRectangle classes. Use those classes to represent geometrical coordinates with the aforementioned measurement system.
The PFPoint class has more functionality than the point classes included in the Java Print API. For example, PFPoint can add and subtract another PFPoint . Since the math operations are repetitive, I decided to include the code in the class itself; it also improves our object-oriented design.
To represent a size in the framework, use the PFSize class. Its only noteworthy feature is the scale() method, which allows you to scale the size by two factors: one for the width and one for the height. scale() is useful for zooming pages.
You can use the PFRectangle class to represent a rectangular area. PFRectangle offers two ways to set a rectangle's location and size: set the x, y, width, and height separately, or use a PFPoint class to set the location and a PFSize class to set the size. No matter how you set the coordinates and size, PFRectangle uses a PFPoint and a PFSize to keep track of its location and size.
This concludes our discussion on the measurement system implemented in the print framework. PFUnit provides the foundation; by extending PFUnit , you can create custom measurement systems like PFInchUnit and PFCmUnit . In addition, the PFPoint , PFSize , and the PFRectangle represent geometrical coordinates. Next I will explain the PFDocument class.
The PFDocument class
At the head of the print framework, you will find PFDocument -- the master class where every print or export operation instantiates. Let's examine PFDocument from the inside:
Listing 3: PFDocument
The class first acts as a page container. To store the pages, a Vector class is used. (See line 31.)
Next, two flags, located in lines 38 and 39 in Listing 3, will tell the print() method whether to show the page dialog and/or the print dialog.
Then come the headers instances (lines 42-45), which hold the header and footer for the current page.
I created several methods between lines 59 and 139 in Listing 3 that add and remove pages. The addPage() method (line 67) lets you append a page to the document. The additional addPage() method (line 84) allows you to insert a page after the page number passed in the parameter. Two removePage() methods complement the two addPage() methods. The first removePage() (line 100) removes a page using its page number; the other removePage() (line 115) removes a page using the PFPage source object.
Two methods -- showPrintDialog() and showPageDialog() -- control the page dialog and print dialogs. The methods, located between lines 188 and 218 in Listing 3, do not show the dialogs; they only set the appropriate flags. The print() method handles the display of the dialogs.
The print() method (lines 234-296 in Listing 3) links the print framework with the Java Print API. Let's examine that method.
First, a PFPage object is created; it will be used in the for loop to store each page that is printed. Then a PageFormat object is created; it will hold the page format settings from the page setup dialog. Those settings will only be used if the showPageDialog flag has been set.
Next, the page range passed in parameters is validated. If the page range falls outside the allowable range, the values adjust. A printerJob object is then created. The setJobName() method applies the document name to the PrinterJob object. Then, at line 262, the showPageSetupFlag is checked. If true, the page setup dialog displays.
You then must create the Book object, which will hold all the pages contained in the document. Enter in a loop that will add all the pages from the pageCollection to the Book object. In the loop, another if statement validates what PageFormat you should use. If the PFPageSetupDialog displays, every document page will set to the page setup that the user selected. Otherwise, the p
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Printing in
Java, Part 4 - JavaWorld February
2001
View Tutorial: Printing in
Java, Part 4 - JavaWorld February
2001
Related
Tutorials:
Web services hits
the Java scene,
Part 1
Web services hits
the Java scene,
Part 1 |
Connect the
enterprise with the JCA, Part 1
Connect the
enterprise with the JCA, Part 1 |
Java security evolution
and concepts, Part 2
Java security evolution
and concepts, Part 2 |
Java security evolution
and concepts, Part 4
Java security evolution
and concepts, Part 4 |
Java security evolution
and concepts, Part 5
Java security evolution
and concepts, Part 5 |
I want my AOP!,
Part 2
I want my AOP!,
Part 2 |
Achieve strong performance with threads,
Part 1
Achieve strong performance with threads,
Part 1 |
Achieve strong performance with threads,
Part 2
Achieve strong performance with threads,
Part 2 |
Jini's relevance emerges, Part
1
Jini's relevance emerges, Part
1 |
Java's character and assorted string
classes support text-processing
Java's character and assorted string
classes support text-processing |
J2SE 1.4
breathes new life into the CORBA community, Part
4
J2SE 1.4
breathes new life into the CORBA community, Part
4 |
Test email components in your software
Test email components in your software |
Very
interesting
Very
interesting |
JSP 2.0: The New Deal, Part 4
JSP 2.0: The New Deal, Part 4
In this final part of the "JSP 2.0: The New Deal" series, we look at two new features that make it much easier to develop custom tag libraries: tag files and the new simplified tag-handler Java API. |
Attribute-Oriented Programming with Java 1.5, Part 2
Peeking Inside the Box: Attribute-Oriented Programming with Java 1.5,Part
In the previous article in this series, "Peeking Inside the Box, Part 1," I introduced the concepts of Attribute-Oriented Programming, Java 1.5 annotations, and bytecode instrume |
What's New in Swing?
A new skinnable look and feel (Synth), printing support for |JTable| components, the ability to add components directly to a frame, these are a few of the new features in Swing for J2SE 5.0. |
Write custom appenders for log4j
The Apache Software Foundation's log4j logging library is one of the better logging systems around. It's both easier to use and more flexible than Java's built-in logging system. |
Just Forms PDF library
The JustFormsPDF library is a Java class library for filling or editing interactive PDF forms on-the-fly. Empower your applications with the industry-standard PDF forms technology using JustFormsPDF. |
Definition of Bioinformatics
Definition of Bioinformatics
Definition of Bioinformatics
About Bioinformatics
In February 2001, the human genome was finally deciphered! In other words, scientists have succeeded in reading the chain of more than 3 billion base pairs that |
Solaris 10 OS Certification Beta Exams
If you are an expert in system and network administration, you can get involved in the creation of three new Solaris 10 certification exams. These Beta exams count toward official Solaris Certification and allow you to provide comments and technical feedb |
|
|
|