A J2FlowPrinter instance will print one or more Flowables back-to-back either as a Pageable (starting and ending on page boundaries) or as a Flowable (which can be printed back-to-back with other Flowables).

Multiple J2TextPrinter, J2TablePrinter, J2TreePrinter, J2ListPrinter, J2ComponentPrinter, J2PanelPrinter, and even other J2FlowPrinter instances can be intermixed along with HorizontalLine, VerticalGap, and PageEject instances, as well as your own custom Flowables.  Each Flowable component within a J2FlowPrinter instance can be separately justified left, right, or center horizontally or top, bottom, or center vertically.

J2FlowPrinter allows you to construct complex documents made up of a series of any of the J2PrinterWorks printing components, such as a rich text document made up of several JTextPane instances, interspersed with instances of JTable, JTree, JList, Component, and JPanel (including Images and drawings), each with their own titles and captions.  This feature also allows the individual J2PrinterWorks family products like J2TablePrinter to print more than one table in a document and to surround these with titles, captions, and other smaller content.

The only restriction on the use of J2FlowPrinter is that the same Flowable instance cannot appear twice in the same J2FlowPrinter instance. However, if you need to do this, you can use the J2Printer clone method to create a duplicate copy of such a Flowable.


You will find it useful to begin your program with:
    import com.wildcrest.j2printerworks.*;

rather than spell out the full package name for all J2PrinterWorks classes.

J2FlowPrinter can instantiated with a zero-argument constructor:
    J2FlowPrinter flowPrinter = new J2FlowPrinter();

This creates a J2FlowPrinter object and initializes all values to their defaults (see the J2FlowPrinter Javadoc documentation ).  To specify the Flowables to be printed by J2FlowPrinter, you can use the following J2FlowPrinter methods:
    flowPrinter.setFlowable(oneFlowable);    // specifies one (or the first) Flowable to print
    flowPrinter.setFlowables(aVectorOfFlowables);    // specifies a set of Flowables to print
    flowPrinter.addFlowable(oneFlowable);    // adds a Flowable to the end of the current list of Flowables
    flowPrinter.clearFlowables();            // clears the current list of Flowables

Alternatively, you can use the following single-argument J2TreePrinter constructors:
    J2FlowPrinter flowPrinter = new J2FlowPrinter(oneFlowable);

    J2FlowPrinter flowPrinter = new J2FlowPrinter(aVectorOfFlowables);

The following is a simple but complete Java program (J2FlowPrinterSimplestTest.java) that sets up and prints a  J2FlowPrinter:

import java.awt.*;
import javax.swing.*;
import com.wildcrest.j2printerworks.*;

class J2FlowPrinterSimplestTest{

    static public void main(String args[]){
        System.out.println("\nJ2FlowPrinter test started...");

        // set up JTextPane
        JTextPane pane = new JTextPane();
        pane.setText("<html>Here are two lines of <b>HTML text</b>"
                   + "<br>that <i>will</i> be printed</html>");

        // set up JTable
        Object[] columns = {"This", "is", "a", "JTable"};
        Object[][] data = {{"table", "", "", ""}, {"", "data", "", ""},
                           {"", "", "goes", ""}, {"", "", "", "here"}};
        JTable table = new JTable(data, columns);
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setSize(new Dimension(250,83));

        // set up JTree
        JTree tree = new JTree();    // has default content
        for (int i=0; i<tree.getRowCount(); i++) tree.expandRow(i);

        // set up JPanel
        JPanel panel = new JPanel();
        panel.add(new JLabel("<html>This text is <i>a JLabel</i>"
           + "<br>displayed inside<font size=5> a JPanel</font></html>"));
        panel.setPreferredSize(new Dimension(200,50));

        // set up J2FlowPrinter
        J2FlowPrinter flowPrinter = new J2FlowPrinter();
        flowPrinter.addFlowable(new J2TextPrinter(pane));
        flowPrinter.addFlowable(new J2TablePrinter(table));
        flowPrinter.addFlowable(new J2TreePrinter(tree));
        flowPrinter.addFlowable(new J2PanelPrinter(panel));
        flowPrinter.addFlowable(new HorizontalLine());

        // set up J2Printer and print
        J2Printer printer = new J2Printer();

        System.out.println("\n...J2FlowPrinter test completed");

 The list of J2FlowPrinter methods, what they do, and their default values are given in the J2FlowPrinter Javadoc documentation .

General properties

When J2FlowPrinter prints a series of Flowables, you can control whether the individual Flowables are left, right, or center justified horizontally on a page, or top, bottom, or center justified within the remaining space on a page.  The J2FlowPrinter itself has no overall horizontal or vertical alignment setting.

Pageable properties

When J2FlowPrinter is used as a Pageable, it can have its own ("local") headers & footers (left, center, and right), margins (left, right, top, and bottom), and orientation (portrait & landscape).  Headers and footers can be specified as a String or a JLabel, can be different on the first page vs. the rest of the pages of the Pageable, and can include date, time, and page numbering.  The methods are the same as the parallel set of methods described in the J2Printer section under "Pageable properties".

If "local" values are not specified for this J2FlowPrinter instance, the "global" (overall, default) values set using the parallel J2Printer methods will be used.  You can force the J2Printer "global" values to be used by calling the J2FlowPrinter method(s) with the argument J2Printer.GLOBAL.

The Pageable properties of J2FlowPrinter will be ignored when the J2FlowPrinter is used as a Flowable.  This is because in this case the Pageable is the containing J2FlowPrinter, so page properties such as headers, footers, margins, and orientation will be controlled by the containing J2FlowPrinter Pageable, not any J2FlowPrinter used within it as a Flowable. Note, however, that scaling does work for J2FlowPrinter used as either a Pageable or a Flowable, that is, the J2FlowPrinter can appear at its own scale within an overall containing J2FlowPrinter sequence.

Fit-to-page scaling

In addition to regular percentage scaling accomplished using the setScale method, J2FlowPrinter also supports fit-to-page scaling when J2FlowPrinter is used as a Pageable using the following method:

setMaximumPages (int pagesWide, int pagesHigh)
          Set the maximum number of vertical and/or horizontal pages for printing this J2FlowPrinter (will minify to fit).

The setMaximumPages method causes your J2FlowPrinter to be scaled down until it fits within pagesHigh pages vertically and pagesWide pages horizontally.  This method cannot be used to magnify and instead will only minify your J2FlowPrinter (hence the name setMaximumPages).  The method works by starting at a scale of 1.0 and reducing the scale in increments of 0.005 (half a percent) until your J2FlowPrinter fits within the prescribed limits.  If either pagesHigh or pagesWide is set to 0 or less, this is taken as a signal that the scaling in that dimension is unconstrained, that is, the J2FlowPrinter can use as many pages as it needs.

NOTE: This method causes the rescaling to take place at the time it is called and does NOT remember or maintain the page limits you specify. Thus, if you change any printing parameters including your document content, headers, footers, margins, paper size, orientation, etc., you must call setMaximumPages again.

The percentage and fit-to-page scaling features interact.  You can call setMaximumPages(pagesWide, pagesHigh) to specify a number of pages and then use the method getScale() to find out the resulting scaling factor.  Or you can call setScale(factor) to scale to a desired percentage and then use getNumberOfPages() to find out the number of resulting pages.  The getNumberOfPages() method works for both magnification and minification (thus you could use it to implement your own fit-to-page feature for magnification, which you might call setMinimumPages(pagesWide, pagesHigh)).

Using J2FlowPrinter as a JavaBean

The J2PrinterWorks components are designed to work as a JavaBeans components in visual builder environments.  However, J2PrinterWorks uses APIs unique to the Java 2 system, and not all visual development environments currently work and build visually with Java 2-based components.  In particular, WebGain/Symantec Visual Cafe has to be specially configured to allow you to import the J2PrinterWorks components into its component library and exhibits other problems when using it visually. In contrast, Borland JBuilder and IBM VisualAge for Java can read and use J2PrinterWorks.jar as either a set of JavaBeans components or programmatically as classes.  See Installation & Compatibility for further details.  Since the J2PrinterWorks components are not GUI components per se, the need to work with them visually isn't great, so that using them programmatically isn't much of a limitation.

If J2PrinterWorks.jar is properly installed, you will see the J2PrinterWorks components, including J2Printer and J2FlowPrinter, in the component palette of your visual programming environment.  Click on the J2Printer bean and drop it on your work area and likewise drag the J2FlowPrinter bean and drop it on your work area.  You will see icons representing instances of these beans.  These will not be displayed at run-time.

When you bring up the property sheet for either component, you will be able to see and edit their properties.  The properties may be set as desired, with values as defined in the Javadoc documentation .

You can make the J2Printer bean print by using your visual programming environment to perform event wiring from an actionPerformed event such as a button push to the J2Printer "print" event target method.  You can use this to print the instance of J2FlowPrinter, using the setFlowable or addFlowable methods or the J2FlowPrinter constructor itself to specify your Flowable(s), which will be built up from the other J2PrinterWorks components used as Flowables.

All the J2PrinterWorks properties are bound properties.  You may use your visual programming environment to do property-to-property binding in either direction between the J2PrinterWorks components and your other beans.  None of the J2PrinterWorks properties are constrained properties.  This frees you from having to place try...catch blocks around your "set" calls in regular programming.

J2PrinterWorks components are fully serializable.  After customizing any properties, instances can be saved along with any other beans to which they may be wired.  When reloaded, the instances will come back with their customized values.  No J2PrinterWorks properties are declared transient.

Copyright 2009, Wildcrest Associates (http://www.wildcrest.com )