United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4791650 : JTable needs printing support

Details
Type:
Enhancement
Submit Date:
2002-12-10
Status:
Resolved
Updated Date:
2003-05-13
Project Name:
JDK
Resolved Date:
2003-05-13
Component:
client-libs
OS:
solaris_7
Sub-Component:
javax.swing
CPU:
sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.4.0
Fixed Versions:
5.0 (tiger)

Related Reports
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
Subject says it all.
Child of 4632213.

                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger

FIXED IN:
tiger

INTEGRATED IN:
tiger
tiger-b07


                                     
2004-06-14
EVALUATION

Commit to fix in tiger. Note that this is a child of 4632213.
###@###.### 2003-01-23

Fix in progress...
###@###.### 2003-04-07

Will be fixed by adding a set of printing methods to JTable. They will appear in the form of a getPrintable method and a set of print convenience methods.
###@###.### 2003-04-10

Final API has been determined. See "Suggested Fix" for the proposed new API.
###@###.### 2003-04-24

A complete test suite for the new JTable printing API can be found in the attachments section. Save the following files into a folder:

Printing.java
SwingSet2.jar
testdoc.html

testdoc.html describes how to use the test suite and what types of tests to run.
###@###.### 2003-04-24

Fix approved and putback.
###@###.### 2003-04-29

4925524 will update this new API based on early feedback. When that bug is fixed, the attached test suite will be out of date and will no longer run. An updated version of the test suite will be attached to 4925524.
###@###.### 2003-10-08
                                     
2003-10-08
SUGGESTED FIX

Proposed spec:

All methods and fields in javax.swing.JTable:
 
/**
 * Printing mode that prints the table at its current size,
 * spreading both columns and rows across multiple pages if necessary.
 *
 * @since 1.5
 */
public static final int PRINT_MODE_NORMAL = 0;
 
 
/**
 * Printing mode that scales the output smaller, if necessary,
 * to fit the table's entire width (and thereby all columns) on each page;
 * Rows are spread across multiple pages as necessary.
 *
 * @since 1.5
 */
public static final int PRINT_MODE_FIT_WIDTH = 1;
 
 
/**
 * A convenience method that displays a printing dialog, and then prints
 * this <code>JTable</code> in mode <code>PRINT_MODE_FIT_WIDTH</code>,
 * with no header or footer text.
 *
 * @return true, unless the user cancels the print dialog
 * @throws PrinterException if an error in the print system causes the job
 *                          to be aborted
 * @see #print(int, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet)
 * @see #getPrintable
 *
 * @since 1.5
 */
public boolean print() throws PrinterException
 
 
/**
 * A convenience method that displays a printing dialog, and then prints
 * this <code>JTable</code> in the given printing mode,
 * with no header or footer text.
 *
 * @param  printMode        the printing mode that the printable should use:
 *                          <code>PRINT_MODE_NORMAL</code> or
 *                          <code>PRINT_MODE_FIT_WIDTH</code>
 * @return true, unless the user cancels the print dialog
 * @throws PrinterException if an error in the print system causes the job
 *                          to be aborted
 * @throws IllegalArgumentException if passed an invalid print mode
 * @see #print(int, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet)
 * @see #getPrintable
 *
 * @since 1.5
 */
public boolean print(int printMode) throws PrinterException
 
 
/**
 * A convenience method that displays a printing dialog, and then prints
 * this <code>JTable</code> in the given printing mode,
 * with the specified header and footer text.
 *
 * @param  printMode        the printing mode that the printable should use:
 *                          <code>PRINT_MODE_NORMAL</code> or
 *                          <code>PRINT_MODE_FIT_WIDTH</code>
 * @param  headerFormat     a <code>MessageFormat</code> specifying the text
 *                          to be used in printing a header,
 *                          or null for none
 * @param  footerFormat     a <code>MessageFormat</code> specifying the text
 *                          to be used in printing a footer,
 *                          or null for none
 * @return true, unless the user cancels the print dialog
 * @throws PrinterException if an error in the print system causes the job
 *                          to be aborted
 * @throws IllegalArgumentException if passed an invalid print mode
 * @see #print(int, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet)
 * @see #getPrintable
 *
 * @since 1.5
 */
public boolean print(int printMode,
                     MessageFormat headerFormat,
                     MessageFormat footerFormat) throws PrinterException
 
 
/**
 * Print this <code>JTable</code>. Takes steps that the majority of
 * developers would take in order to print a <code>JTable</code>.
 * In short, it prepares the table, calls <code>getPrintable</code> to
 * fetch an appropriate <code>Printable</code>, and then sends it to the
 * printer.
 * <p>
 * A <code>boolean</code> parameter allows you to specify whether or not
 * a printing dialog is displayed to the user. When it is, the user may
 * use the dialog to change printing attributes or even cancel the print.
 * Another parameter allows for printing attributes to be specified
 * directly. This can be used either to provide the initial values for the
 * print dialog, or to supply any needed attributes when the dialog is not
 * shown.
 * <p>
 * Before fetching the printable, this method prepares the table in order
 * to get the most desirable printed result. If the table is currently
 * in an editing mode, it terminates the editing as gracefully as
 * possible. It also ensures that the the table's current selection and
 * focused cell are not indicated in the printed output. This is handled on
 * the view level, and only for the duration of the printing, thus no
 * notification needs to be sent to the selection models.
 * <p>
 * See {@link #getPrintable} for further description on how the
 * table is printed.
 *
 * @param  printMode        the printing mode that the printable should use:
 *                          <code>PRINT_MODE_NORMAL</code> or
 *                          <code>PRINT_MODE_FIT_WIDTH</code>
 * @param  headerFormat     a <code>MessageFormat</code> specifying the text
 *                          to be used in printing a header,
 *                          or null for none
 * @param  footerFormat     a <code>MessageFormat</code> specifying the text
 *                          to be used in printing a footer,
 *                          or null for none
 * @param  showPrintDialog  whether or not to display a print dialog
 * @param  attr             a <code>PrintRequestAttributeSet</code>
 *                          specifying any printing attributes,
 *                          or null for none
 * @return true, unless the print dialog is shown and the user cancels it
 * @throws PrinterException if an error in the print system causes the job
 *                          to be aborted
 * @throws IllegalArgumentException if passed an invalid print mode
 * @see #getPrintable
 *
 * @since 1.5
 */
public boolean print(int printMode,
                     MessageFormat headerFormat,
                     MessageFormat footerFormat,
                     boolean showPrintDialog,
                     PrintRequestAttributeSet attr) throws PrinterException
 
 
/**
 * Return a <code>Printable</code> for use in printing this JTable.
 * <p>
 * The <code>Printable</code> can be requested in one of two printing modes.
 * In both modes, it spreads table rows naturally in sequence across
 * multiple pages, fitting as many rows as possible per page.
 * <code>PRINT_MODE_NORMAL</code> specifies that the table be
 * printed at its current size. In this mode, there may be a need to spread
 * columns across pages in a similar manner to that of the rows. When the
 * need arises, columns are distributed in an order consistent with the
 * table's <code>ComponentOrientation</code>.
 * <code>PRINT_MODE_FIT_WIDTH</code> specifies that the output be
 * scaled smaller, if necessary, to fit the table's entire width
 * (and thereby all columns) on each page. Width and height are scaled
 * equally, maintaining the aspect ratio of the output.
 * <p>
 * The <code>Printable</code> heads the portion of table on each page
 * with the appropriate section from the table's <code>JTableHeader</code>,
 * if it has one.
 * <p>
 * Header and footer text can be added to the output by providing
 * <code>MessageFormat</code> arguments. The printing code requests
 * Strings from the formats, providing a single item which may be included
 * in the formatted string: an <code>Integer</code> representing the current
 * page number.
 * <p>
 * You are encouraged to read the documentation for
 * <code>MessageFormat</code> as some characters, such as single-quote,
 * are special and need to be escaped.
 * <p>
 * Here's an example of creating a <code>MessageFormat</code> that can be
 * used to print "Duke's Table: Page - " and the current page number:
 * <p>
 * <pre>
 *     // notice the escaping of the single quote
 *     // notice how the page number is included with "{0}"
 *     MessageFormat format = new MessageFormat("Duke''s Table: Page - {0}");
 * </pre>
 * <p>
 * The <code>Printable</code> constrains what it draws to the printable
 * area of each page that it prints. Under certain circumstances, it may
 * find it impossible to fit all of a page's content into that area. In
 * these cases the output may be clipped, but the implementation
 * makes an effort to do something reasonable. Here are a few situations
 * where this is known to occur, and how they may be handled by this
 * particular implementation:
 * <ul>
 *   <li>In any mode, when the header or footer text is too wide to fit
 *       completely in the printable area -- print as much of the text as
 *       possible starting from the beginning, as determined by the table's
 *       <code>ComponentOrientation</code>.
 *   <li>In any mode, when a row is too tall to fit in the
 *       printable area -- print the upper-most portion of the row
 *       and paint no lower border on the table.
 *   <li>In <code>JTable.PRINT_MODE_NORMAL</code> when a column
 *       is too wide to fit in the printable area -- print the center
 *       portion of the column and leave the left and right borders
 *       off the table.
 * </ul>
 * <p>
 * It is entirely valid for this <code>Printable</code> to be wrapped
 * inside another in order to create complex reports and documents. You may
 * even request that different pages be rendered into different sized
 * printable areas. The implementation must be prepared to handle this
 * (possibly by doing its layout calculations on the fly). However,
 * providing different heights to each page will likely not work well
 * with <code>PRINT_MODE_NORMAL</code> when it has to spread columns
 * across pages.
 * <p>
 * It is important to note that this <code>Printable</code> prints the
 * table at its current visual state, using the table's existing renderers.
 * <i>Before</i> calling this method, you may wish to <i>first</i> modify
 * the state of the table (such as to change the renderers, cancel editing,
 * or hide the selection).
 * <p>
 * Here's a simple example that calls this method to fetch a
 * <code>Printable</code>, shows a cross-platform print dialog, and then
 * prints the <code>Printable</code> unless the user cancels the dialog:
 * <p>
 * <pre>
 *     // prepare the table for printing here first (for example, hide selection)
 *
 *     // wrap in a try/finally so table can be restored even if something fails
 *     try {
 *         // fetch the printable
 *         Printable printable = table.getPrintable(JTable.PRINT_MODE_FIT_WIDTH,
 *                                                  new MessageFormat("My Table"),
 *                                                  new MessageFormat("Page - {0}"));
 *
 *         // fetch a PrinterJob
 *         PrinterJob job = PrinterJob.getPrinterJob();
 *
 *         // set the Printable on the PrinterJob
 *         job.setPrintable(printable);
 *
 *         // create an attribute set to store attributes from the print dialog
 *         PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
 *
 *         // display a print dialog and record whether or not the user cancels it
 *         boolean printAccepted = job.printDialog(attr);
 *
 *         // if the user didn't cancel the dialog
 *         if (printAccepted) {
 *             // do the printing (may need to handle PrinterException)
 *             job.print(attr);
 *         }
 *     } finally {
 *         // restore the original table state here (for example, restore selection)
 *     }
 * </pre>
 *
 * @param  printMode     the printing mode that the printable should use:
 *                       <code>PRINT_MODE_NORMAL</code> or
 *                       <code>PRINT_MODE_FIT_WIDTH</code>
 * @param  headerFormat  a <code>MessageFormat</code> specifying the text to
 *                       be used in printing a header, or null for none
 * @param  footerFormat  a <code>MessageFormat</code> specifying the text to
 *                       be used in printing a footer, or null for none
 * @return a <code>Printable</code> for printing this JTable
 * @throws IllegalArgumentException if passed an invalid print mode
 * @see #PRINT_MODE_NORMAL
 * @see #PRINT_MODE_FIT_WIDTH
 * @see Printable
 * @see PrinterJob
 *
 * @since 1.5
 */

###@###.### 2003-04-24
                                     
2003-04-24



Hardware and Software, Engineered to Work Together