1 7 8 package org.jdesktop.swing; 9 10 import java.awt.*; 11 import java.awt.geom.*; 12 import java.awt.print.*; 13 import java.text.*; 14 import javax.swing.*; 15 import javax.swing.table.*; 16 17 18 75 class TablePrintable implements Printable { 76 77 78 private JTable table; 79 80 81 private JTableHeader header; 82 83 84 private TableColumnModel colModel; 85 86 87 private int totalColWidth; 88 89 90 private int printMode; 91 92 93 private MessageFormat headerFormat; 94 95 96 private MessageFormat footerFormat; 97 98 99 private int last = -1; 100 101 102 private int row = 0; 103 104 105 private int col = 0; 106 107 108 private final Rectangle clip = new Rectangle(0, 0, 0, 0); 109 110 111 private final Rectangle hclip = new Rectangle(0, 0, 0, 0); 112 113 114 private final Rectangle tempRect = new Rectangle(0, 0, 0, 0); 115 116 117 private static final int H_F_SPACE = 8; 118 119 120 private static final float HEADER_FONT_SIZE = 18.0f; 121 122 123 private static final float FOOTER_FONT_SIZE = 12.0f; 124 125 126 private Font headerFont; 127 128 129 private Font footerFont; 130 131 147 public TablePrintable(JTable table, 148 int printMode, 149 MessageFormat headerFormat, 150 MessageFormat footerFormat) { 151 152 this.table = table; 153 154 header = table.getTableHeader(); 155 colModel = table.getColumnModel(); 156 totalColWidth = colModel.getTotalColumnWidth(); 157 158 if (header != null) { 159 hclip.height = header.getHeight(); 161 } 162 163 if (printMode != JXTable.PRINT_MODE_NORMAL && 164 printMode != JXTable.PRINT_MODE_FIT_WIDTH) { 165 166 throw new IllegalArgumentException ("Unknown Print Mode: " + 167 printMode); 168 } 169 170 this.printMode = printMode; 171 172 this.headerFormat = headerFormat; 173 this.footerFormat = footerFormat; 174 175 headerFont = table.getFont().deriveFont(Font.BOLD, 177 HEADER_FONT_SIZE); 178 footerFont = table.getFont().deriveFont(Font.PLAIN, 179 FOOTER_FONT_SIZE); 180 } 181 182 193 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 194 throws PrinterException { 195 196 final int imgWidth = (int)pageFormat.getImageableWidth(); 198 final int imgHeight = (int)pageFormat.getImageableHeight(); 199 200 if (imgWidth <= 0) { 201 throw new PrinterException("Width of printable area is too small."); 202 } 203 204 Object [] pageNumber = new Object []{new Integer (pageIndex + 1)}; 206 207 String headerText = null; 209 if (headerFormat != null) { 210 headerText = headerFormat.format(pageNumber); 211 } 212 213 String footerText = null; 215 if (footerFormat != null) { 216 footerText = footerFormat.format(pageNumber); 217 } 218 219 Rectangle2D hRect = null; 221 Rectangle2D fRect = null; 222 223 int headerTextSpace = 0; 225 int footerTextSpace = 0; 226 227 int availableSpace = imgHeight; 229 230 if (headerText != null) { 233 graphics.setFont(headerFont); 234 hRect = graphics.getFontMetrics().getStringBounds(headerText, 235 graphics); 236 237 headerTextSpace = (int)Math.ceil(hRect.getHeight()); 238 availableSpace -= headerTextSpace + H_F_SPACE; 239 } 240 241 if (footerText != null) { 244 graphics.setFont(footerFont); 245 fRect = graphics.getFontMetrics().getStringBounds(footerText, 246 graphics); 247 248 footerTextSpace = (int)Math.ceil(fRect.getHeight()); 249 availableSpace -= footerTextSpace + H_F_SPACE; 250 } 251 252 if (availableSpace <= 0) { 253 throw new PrinterException("Height of printable area is too small."); 254 } 255 256 double sf = 1.0D; 259 if (printMode == JXTable.PRINT_MODE_FIT_WIDTH && 260 totalColWidth > imgWidth) { 261 262 assert imgWidth > 0; 264 265 assert totalColWidth > 1; 267 268 sf = (double)imgWidth / (double)totalColWidth; 269 } 270 271 assert sf > 0; 273 274 while (last < pageIndex) { 282 if (row >= table.getRowCount() && col == 0) { 284 return NO_SUCH_PAGE; 285 } 286 287 int scaledWidth = (int)(imgWidth / sf); 291 int scaledHeight = (int)((availableSpace - hclip.height) / sf); 292 293 findNextClip(scaledWidth, scaledHeight); 295 296 last++; 297 } 298 299 Graphics2D g2d = (Graphics2D)graphics; 301 g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); 302 303 AffineTransform oldTrans; 305 306 if (footerText != null) { 308 oldTrans = g2d.getTransform(); 309 310 g2d.translate(0, imgHeight - footerTextSpace); 311 312 printText(g2d, footerText, fRect, footerFont, imgWidth); 313 314 g2d.setTransform(oldTrans); 315 } 316 317 if (headerText != null) { 320 printText(g2d, headerText, hRect, headerFont, imgWidth); 321 322 g2d.translate(0, headerTextSpace + H_F_SPACE); 323 } 324 325 tempRect.x = 0; 327 tempRect.y = 0; 328 tempRect.width = imgWidth; 329 tempRect.height = availableSpace; 330 g2d.clip(tempRect); 331 332 if (sf != 1.0D) { 335 g2d.scale(sf, sf); 336 337 } else { 340 int diff = (imgWidth - clip.width) / 2; 341 g2d.translate(diff, 0); 342 } 343 344 oldTrans = g2d.getTransform(); 346 Shape oldClip = g2d.getClip(); 347 348 if (header != null) { 351 hclip.x = clip.x; 352 hclip.width = clip.width; 353 354 g2d.translate(-hclip.x, 0); 355 g2d.clip(hclip); 356 header.print(g2d); 357 358 g2d.setTransform(oldTrans); 360 g2d.setClip(oldClip); 361 362 g2d.translate(0, hclip.height); 364 } 365 366 g2d.translate(-clip.x, -clip.y); 368 g2d.clip(clip); 369 table.print(g2d); 370 371 g2d.setTransform(oldTrans); 373 g2d.setClip(oldClip); 374 375 g2d.setColor(Color.BLACK); 377 g2d.drawRect(0, 0, clip.width, hclip.height + clip.height); 378 379 return PAGE_EXISTS; 380 } 381 382 393 private void printText(Graphics2D g2d, 394 String text, 395 Rectangle2D rect, 396 Font font, 397 int imgWidth) { 398 399 int tx; 400 401 if (rect.getWidth() < imgWidth) { 403 tx = (int)((imgWidth - rect.getWidth()) / 2); 404 405 } else if (table.getComponentOrientation().isLeftToRight()) { 408 tx = 0; 409 410 } else { 412 tx = -(int)(Math.ceil(rect.getWidth()) - imgWidth); 413 } 414 415 int ty = (int)Math.ceil(Math.abs(rect.getY())); 416 g2d.setColor(Color.BLACK); 417 g2d.setFont(font); 418 g2d.drawString(text, tx, ty); 419 } 420 421 432 private void findNextClip(int pw, int ph) { 433 final boolean ltr = table.getComponentOrientation().isLeftToRight(); 434 435 if (col == 0) { 437 if (ltr) { 438 clip.x = 0; 440 } else { 441 clip.x = totalColWidth; 443 } 444 445 clip.y += clip.height; 447 448 clip.width = 0; 450 clip.height = 0; 451 452 int rowCount = table.getRowCount(); 454 int rowHeight = table.getRowHeight(row); 455 do { 456 clip.height += rowHeight; 457 458 if (++row >= rowCount) { 459 break; 460 } 461 462 rowHeight = table.getRowHeight(row); 463 } while (clip.height + rowHeight <= ph); 464 } 465 466 if (printMode == JXTable.PRINT_MODE_FIT_WIDTH) { 469 clip.x = 0; 470 clip.width = totalColWidth; 471 return; 472 } 473 474 if (ltr) { 475 clip.x += clip.width; 477 } 478 479 clip.width = 0; 481 482 int colCount = table.getColumnCount(); 484 int colWidth = colModel.getColumn(col).getWidth(); 485 do { 486 clip.width += colWidth; 487 if (!ltr) { 488 clip.x -= colWidth; 489 } 490 491 if (++col >= colCount) { 492 col = 0; 494 495 break; 496 } 497 498 colWidth = colModel.getColumn(col).getWidth(); 499 } while (clip.width + colWidth <= pw); 500 501 } 502 503 } 504 | Popular Tags |