Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Printing in Java, Part 4

Code the print framework

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Many 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.



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 <p>
  5| *
  6| * @author Jean-Pierre Dube <jpdube@videotron.ca>
  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 <p>
 20|    *
 21|    */
 22|   public PFInchUnit () {
 23|
 24|   }
 25|
 26|
 27|   /**
 28|    * Constructor: PFInchUnit <p>
 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 <p>
 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.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (1)
Login
Forgot your account info?

thankingBy Anonymous on December 16, 2008, 3:27 pmhey your effort is really great....u r poviding most valuable java theme in a such simple way..thank you

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources