15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 import javax.swing.table.*; 29 import java.awt.*; 30 import java.awt.print.*; 31 import java.awt.geom.*; 32 import java.text.MessageFormat; 33 34 /** 35 * An implementation of <code>Printable</code> for printing 36 * <code>JTable</code>s. 37 * <p> 38 * This implementation spreads table rows naturally in sequence 39 * across multiple pages, fitting as many rows as possible per page. 40 * The distribution of columns, on the other hand, is controlled by a 41 * printing mode parameter passed to the constructor. When 42 * <code>JTable.PrintMode.NORMAL</code> is used, the implementation 43 * handles columns in a similar manner to how it handles rows, spreading them 44 * across multiple pages (in an order consistent with the table's 45 * <code>ComponentOrientation</code>). 46 * When <code>JTable.PrintMode.FIT_WIDTH</code> is given, the implementation 47 * scales the output smaller if necessary, to ensure that all columns fit on 48 * the page. (Note that width and height are scaled equally, ensuring that the 49 * aspect ratio remains the same). 50 * <p> 51 * The portion of table printed on each page is headed by the 52 * appropriate section of the table's <code>JTableHeader</code>. 53 * <p> 54 * Header and footer text can be added to the output by providing 55 * <code>MessageFormat</code> instances to the constructor. The 56 * printing code requests Strings from the formats by calling 57 * their <code>format</code> method with a single parameter: 58 * an <code>Object</code> array containing a single element of type 59 * <code>Integer</code>, representing the current page number. 60 * <p> 61 * There are certain circumstances where this <code>Printable</code> 62 * cannot fit items appropriately, resulting in clipped output. 63 * These are: 64 * <ul> 65 * <li>In any mode, when the header or footer text is too wide to 66 * fit completely in the printable area. The implementation 67 * prints as much of the text as possible starting from the beginning, 68 * as determined by the table's <code>ComponentOrientation</code>. 69 * <li>In any mode, when a row is too tall to fit in the 70 * printable area. The upper most portion of the row 71 * is printed and no lower border is shown. 72 * <li>In <code>JTable.PrintMode.NORMAL</code> when a column 73 * is too wide to fit in the printable area. The center of the 74 * column is printed and no left and right borders are shown. 75 * </ul> 76 * <p> 77 * It is entirely valid for a developer to wrap this <code>Printable</code> 78 * inside another in order to create complex reports and documents. They may 79 * even request that different pages be rendered into different sized 80 * printable areas. The implementation was designed to handle this by 81 * performing most of its calculations on the fly. However, providing different 82 * sizes works best when <code>JTable.PrintMode.FIT_WIDTH</code> is used, or 83 * when only the printable width is changed between pages. This is because when 84 * it is printing a set of rows in <code>JTable.PrintMode.NORMAL</code> and the 85 * implementation determines a need to distribute columns across pages, 86 * it assumes that all of those rows will fit on each subsequent page needed 87 * to fit the columns. 88 * <p> 89 * It is the responsibility of the developer to ensure that the table is not 90 * modified in any way after this <code>Printable</code> is created (invalid 91 * modifications include changes in: size, renderers, or underlying data). 92 * The behavior of this <code>Printable</code> is undefined if the table is 93 * changed at any time after creation. 94 * 95 * @author Shannon Hickey 96 */ 97 class TablePrintable implements Printable { 98 99 /** The table to print. */ 100 private JTable table; 101 102 /** For quick reference to the table's header. */ 103 private JTableHeader header; 104 105 /** For quick reference to the table's column model. */ 106 private TableColumnModel colModel; 107 108 /** To save multiple calculations of total column width. */ 109 private int totalColWidth; 110 111 /** The printing mode of this printable. */ 112 private JTable.PrintMode printMode; 134 135 /** Saves the creation of multiple rectangles. */ 136 private final Rectangle tempRect = new Rectangle(0, 0, 0, 0); 137 138 /** Vertical space to leave between table and header/footer text. */ 139 private static final int H_F_SPACE = 8; 140 141 /** Font size for the header text. */ 142 private static final float HEADER_FONT_SIZE = 18.0f; 143 144 /** Font size for the footer text. */ 145 private static final float FOOTER_FONT_SIZE = 12.0f; 146 147 /** The font to use in rendering header text. */ 148 private Font headerFont; 149 150 /** The font to use in rendering footer text. */ 151 private Font footerFont; 152 153 /** 154 * Create a new <code>TablePrintable</code> for the given 155 * <code>JTable</code>. Header and footer text can be specified using the 156 * two <code>MessageFormat</code> parameters. When called upon to provide 157 * a String, each format is given the current page number. 158 * 159 * @param table the table to print 160 * @param printMode the printing mode for this printable 161 * @param headerFormat a <code>MessageFormat</code> specifying the text to 162 * be used in printing a header, or null for none 163 * @param footerFormat a <code>MessageFormat</code> specifying the text to 164 * be used in printing a footer, or null for none 165 * @throws IllegalArgumentException if passed an invalid print mode 166 */ 167 public TablePrintable(JTable table, 168 JTable.PrintMode printMode, 169 MessageFormat headerFormat, 170 MessageFormat footerFormat) { 171 172 this.table = table; 173 174 header = table.getTableHeader(); 175 colModel = table.getColumnModel(); 176 totalColWidth = colModel.getTotalColumnWidth(); 177 178 if (header != null) { 179 // the header clip height can be set once since it's unchanging 180 hclip.height = header.getHeight(); 181 } 182 183 this.printMode = printMode; | 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 import javax.swing.table.*; 29 import java.awt.*; 30 import java.awt.print.*; 31 import java.awt.geom.*; 32 import java.text.MessageFormat; 33 34 /** 35 * An implementation of {@code Printable} for printing 36 * {@code JTable}s. 37 * <p> 38 * This implementation spreads table rows naturally in sequence 39 * across multiple pages, fitting as many rows as possible per page. 40 * The distribution of columns, on the other hand, is controlled by a 41 * printing mode parameter passed to the constructor. When 42 * {@code JTable.PrintMode.NORMAL} is used, the implementation 43 * handles columns in a similar manner to how it handles rows, spreading them 44 * across multiple pages (in an order consistent with the table's 45 * {@code ComponentOrientation}). 46 * When {@code JTable.PrintMode.FIT_WIDTH} is given, the implementation 47 * scales the output smaller if necessary, to ensure that all columns fit on 48 * the page. (Note that width and height are scaled equally, ensuring that the 49 * aspect ratio remains the same). 50 * <p> 51 * The portion of table printed on each page is headed by the 52 * appropriate section of the table's {@code JTableHeader}. 53 * <p> 54 * Header and footer text can be added to the output by providing 55 * {@code MessageFormat} instances to the constructor. The 56 * printing code requests Strings from the formats by calling 57 * their {@code format} method with a single parameter: 58 * an {@code Object} array containing a single element of type 59 * {@code Integer}, representing the current page number. 60 * <p> 61 * There are certain circumstances where this {@code Printable} 62 * cannot fit items appropriately, resulting in clipped output. 63 * These are: 64 * <ul> 65 * <li>In any mode, when the header or footer text is too wide to 66 * fit completely in the printable area. The implementation 67 * prints as much of the text as possible starting from the beginning, 68 * as determined by the table's {@code ComponentOrientation}. 69 * <li>In any mode, when a row is too tall to fit in the 70 * printable area. The upper most portion of the row 71 * is printed and no lower border is shown. 72 * <li>In {@code JTable.PrintMode.NORMAL} when a column 73 * is too wide to fit in the printable area. The center of the 74 * column is printed and no left and right borders are shown. 75 * </ul> 76 * <p> 77 * It is entirely valid for a developer to wrap this {@code Printable} 78 * inside another in order to create complex reports and documents. They may 79 * even request that different pages be rendered into different sized 80 * printable areas. The implementation was designed to handle this by 81 * performing most of its calculations on the fly. However, providing different 82 * sizes works best when {@code JTable.PrintMode.FIT_WIDTH} is used, or 83 * when only the printable width is changed between pages. This is because when 84 * it is printing a set of rows in {@code JTable.PrintMode.NORMAL} and the 85 * implementation determines a need to distribute columns across pages, 86 * it assumes that all of those rows will fit on each subsequent page needed 87 * to fit the columns. 88 * <p> 89 * It is the responsibility of the developer to ensure that the table is not 90 * modified in any way after this {@code Printable} is created (invalid 91 * modifications include changes in: size, renderers, or underlying data). 92 * The behavior of this {@code Printable} is undefined if the table is 93 * changed at any time after creation. 94 * 95 * @author Shannon Hickey 96 */ 97 class TablePrintable implements Printable { 98 99 /** The table to print. */ 100 private JTable table; 101 102 /** For quick reference to the table's header. */ 103 private JTableHeader header; 104 105 /** For quick reference to the table's column model. */ 106 private TableColumnModel colModel; 107 108 /** To save multiple calculations of total column width. */ 109 private int totalColWidth; 110 111 /** The printing mode of this printable. */ 112 private JTable.PrintMode printMode; 134 135 /** Saves the creation of multiple rectangles. */ 136 private final Rectangle tempRect = new Rectangle(0, 0, 0, 0); 137 138 /** Vertical space to leave between table and header/footer text. */ 139 private static final int H_F_SPACE = 8; 140 141 /** Font size for the header text. */ 142 private static final float HEADER_FONT_SIZE = 18.0f; 143 144 /** Font size for the footer text. */ 145 private static final float FOOTER_FONT_SIZE = 12.0f; 146 147 /** The font to use in rendering header text. */ 148 private Font headerFont; 149 150 /** The font to use in rendering footer text. */ 151 private Font footerFont; 152 153 /** 154 * Create a new {@code TablePrintable} for the given 155 * {@code JTable}. Header and footer text can be specified using the 156 * two {@code MessageFormat} parameters. When called upon to provide 157 * a String, each format is given the current page number. 158 * 159 * @param table the table to print 160 * @param printMode the printing mode for this printable 161 * @param headerFormat a {@code MessageFormat} specifying the text to 162 * be used in printing a header, or null for none 163 * @param footerFormat a {@code MessageFormat} specifying the text to 164 * be used in printing a footer, or null for none 165 * @throws IllegalArgumentException if passed an invalid print mode 166 */ 167 public TablePrintable(JTable table, 168 JTable.PrintMode printMode, 169 MessageFormat headerFormat, 170 MessageFormat footerFormat) { 171 172 this.table = table; 173 174 header = table.getTableHeader(); 175 colModel = table.getColumnModel(); 176 totalColWidth = colModel.getTotalColumnWidth(); 177 178 if (header != null) { 179 // the header clip height can be set once since it's unchanging 180 hclip.height = header.getHeight(); 181 } 182 183 this.printMode = printMode; |