188 // derive the header and footer font from the table's font
189 headerFont = table.getFont().deriveFont(Font.BOLD,
190 HEADER_FONT_SIZE);
191 footerFont = table.getFont().deriveFont(Font.PLAIN,
192 FOOTER_FONT_SIZE);
193 }
194
195 /**
196 * Prints the specified page of the table into the given {@link Graphics}
197 * context, in the specified format.
198 *
199 * @param graphics the context into which the page is drawn
200 * @param pageFormat the size and orientation of the page being drawn
201 * @param pageIndex the zero based index of the page to be drawn
202 * @return PAGE_EXISTS if the page is rendered successfully, or
203 * NO_SUCH_PAGE if a non-existent page index is specified
204 * @throws PrinterException if an error causes printing to be aborted
205 */
206 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
207 throws PrinterException {
208
209 // for easy access to these values
210 final int imgWidth = (int)pageFormat.getImageableWidth();
211 final int imgHeight = (int)pageFormat.getImageableHeight();
212
213 if (imgWidth <= 0) {
214 throw new PrinterException("Width of printable area is too small.");
215 }
216
217 // to pass the page number when formatting the header and footer text
218 Object[] pageNumber = new Object[]{Integer.valueOf(pageIndex + 1)};
219
220 // fetch the formatted header text, if any
221 String headerText = null;
222 if (headerFormat != null) {
223 headerText = headerFormat.format(pageNumber);
224 }
225
226 // fetch the formatted footer text, if any
227 String footerText = null;
228 if (footerFormat != null) {
229 footerText = footerFormat.format(pageNumber);
230 }
231
232 // to store the bounds of the header and footer text
285 assert sf > 0;
286
287 // This is in a loop for two reasons:
288 // First, it allows us to catch up in case we're called starting
289 // with a non-zero pageIndex. Second, we know that we can be called
290 // for the same page multiple times. The condition of this while
291 // loop acts as a check, ensuring that we don't attempt to do the
292 // calculations again when we are called subsequent times for the
293 // same page.
294 while (last < pageIndex) {
295 // if we are finished all columns in all rows
296 if (row >= table.getRowCount() && col == 0) {
297 return NO_SUCH_PAGE;
298 }
299
300 // rather than multiplying every row and column by the scale factor
301 // in findNextClip, just pass a width and height that have already
302 // been divided by it
303 int scaledWidth = (int)(imgWidth / sf);
304 int scaledHeight = (int)((availableSpace - hclip.height) / sf);
305
306 // calculate the area of the table to be printed for this page
307 findNextClip(scaledWidth, scaledHeight);
308
309 last++;
310 }
311
312 // create a copy of the graphics so we don't affect the one given to us
313 Graphics2D g2d = (Graphics2D)graphics.create();
314
315 // translate into the co-ordinate system of the pageFormat
316 g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
317
318 // to save and store the transform
319 AffineTransform oldTrans;
320
321 // if there's footer text, print it at the bottom of the imageable area
322 if (footerText != null) {
323 oldTrans = g2d.getTransform();
324
325 g2d.translate(0, imgHeight - footerTextSpace);
326
327 printText(g2d, footerText, fRect, footerFont, imgWidth);
328
329 g2d.setTransform(oldTrans);
330 }
331
332 // if there's header text, print it at the top of the imageable area
333 // and then translate downwards
334 if (headerText != null) {
335 printText(g2d, headerText, hRect, headerFont, imgWidth);
336
337 g2d.translate(0, headerTextSpace + H_F_SPACE);
338 }
339
340 // constrain the table output to the available space
341 tempRect.x = 0;
342 tempRect.y = 0;
343 tempRect.width = imgWidth;
344 tempRect.height = availableSpace;
345 g2d.clip(tempRect);
346
347 // if we have a scale factor, scale the graphics object to fit
348 // the entire width
349 if (sf != 1.0D) {
350 g2d.scale(sf, sf);
351
352 // otherwise, ensure that the current portion of the table is
353 // centered horizontally
354 } else {
355 int diff = (imgWidth - clip.width) / 2;
356 g2d.translate(diff, 0);
357 }
358
359 // store the old transform and clip for later restoration
360 oldTrans = g2d.getTransform();
361 Shape oldClip = g2d.getClip();
362
363 // if there's a table header, print the current section and
364 // then translate downwards
365 if (header != null) {
366 hclip.x = clip.x;
372
373 // restore the original transform and clip
374 g2d.setTransform(oldTrans);
375 g2d.setClip(oldClip);
376
377 // translate downwards
378 g2d.translate(0, hclip.height);
379 }
380
381 // print the current section of the table
382 g2d.translate(-clip.x, -clip.y);
383 g2d.clip(clip);
384 table.print(g2d);
385
386 // restore the original transform and clip
387 g2d.setTransform(oldTrans);
388 g2d.setClip(oldClip);
389
390 // draw a box around the table
391 g2d.setColor(Color.BLACK);
392 g2d.drawRect(0, 0, clip.width, hclip.height + clip.height);
393
394 // dispose the graphics copy
395 g2d.dispose();
396
397 return PAGE_EXISTS;
398 }
399
400 /**
401 * A helper method that encapsulates common code for rendering the
402 * header and footer text.
403 *
404 * @param g2d the graphics to draw into
405 * @param text the text to draw, non null
406 * @param rect the bounding rectangle for this text,
407 * as calculated at the given font, non null
408 * @param font the font to draw the text in, non null
409 * @param imgWidth the width of the area to draw into
410 */
411 private void printText(Graphics2D g2d,
412 String text,
492 if (ltr) {
493 // adjust clip to the left of the next set of columns
494 clip.x += clip.width;
495 }
496
497 // adjust clip width to be zero
498 clip.width = 0;
499
500 // fit as many columns as possible, and at least one
501 int colCount = table.getColumnCount();
502 int colWidth = colModel.getColumn(col).getWidth();
503 do {
504 clip.width += colWidth;
505 if (!ltr) {
506 clip.x -= colWidth;
507 }
508
509 if (++col >= colCount) {
510 // reset col to 0 to indicate we're finished all columns
511 col = 0;
512
513 break;
514 }
515
516 colWidth = colModel.getColumn(col).getWidth();
517 } while (clip.width + colWidth <= pw);
518
519 }
520
521 }
|
188 // derive the header and footer font from the table's font
189 headerFont = table.getFont().deriveFont(Font.BOLD,
190 HEADER_FONT_SIZE);
191 footerFont = table.getFont().deriveFont(Font.PLAIN,
192 FOOTER_FONT_SIZE);
193 }
194
195 /**
196 * Prints the specified page of the table into the given {@link Graphics}
197 * context, in the specified format.
198 *
199 * @param graphics the context into which the page is drawn
200 * @param pageFormat the size and orientation of the page being drawn
201 * @param pageIndex the zero based index of the page to be drawn
202 * @return PAGE_EXISTS if the page is rendered successfully, or
203 * NO_SUCH_PAGE if a non-existent page index is specified
204 * @throws PrinterException if an error causes printing to be aborted
205 */
206 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
207 throws PrinterException {
208 // for easy access to these values
209 final int imgWidth = (int)pageFormat.getImageableWidth();
210 final int imgHeight = (int)pageFormat.getImageableHeight();
211 if (imgWidth <= 0) {
212 throw new PrinterException("Width of printable area is too small.");
213 }
214
215 // to pass the page number when formatting the header and footer text
216 Object[] pageNumber = new Object[]{Integer.valueOf(pageIndex + 1)};
217
218 // fetch the formatted header text, if any
219 String headerText = null;
220 if (headerFormat != null) {
221 headerText = headerFormat.format(pageNumber);
222 }
223
224 // fetch the formatted footer text, if any
225 String footerText = null;
226 if (footerFormat != null) {
227 footerText = footerFormat.format(pageNumber);
228 }
229
230 // to store the bounds of the header and footer text
283 assert sf > 0;
284
285 // This is in a loop for two reasons:
286 // First, it allows us to catch up in case we're called starting
287 // with a non-zero pageIndex. Second, we know that we can be called
288 // for the same page multiple times. The condition of this while
289 // loop acts as a check, ensuring that we don't attempt to do the
290 // calculations again when we are called subsequent times for the
291 // same page.
292 while (last < pageIndex) {
293 // if we are finished all columns in all rows
294 if (row >= table.getRowCount() && col == 0) {
295 return NO_SUCH_PAGE;
296 }
297
298 // rather than multiplying every row and column by the scale factor
299 // in findNextClip, just pass a width and height that have already
300 // been divided by it
301 int scaledWidth = (int)(imgWidth / sf);
302 int scaledHeight = (int)((availableSpace - hclip.height) / sf);
303 // calculate the area of the table to be printed for this page
304 findNextClip(scaledWidth, scaledHeight);
305
306 if (!((table.getBounds()).intersects(clip))) {
307 return NO_SUCH_PAGE;
308 }
309 last++;
310 }
311
312 // create a copy of the graphics so we don't affect the one given to us
313 Graphics2D g2d = (Graphics2D)graphics.create();
314
315 // translate into the co-ordinate system of the pageFormat
316 g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
317
318 // to save and store the transform
319 AffineTransform oldTrans;
320
321 // if there's footer text, print it at the bottom of the imageable area
322 if (footerText != null) {
323 oldTrans = g2d.getTransform();
324
325 g2d.translate(0, imgHeight - footerTextSpace);
326
327 printText(g2d, footerText, fRect, footerFont, imgWidth);
328
329 g2d.setTransform(oldTrans);
330 }
331
332 // if there's header text, print it at the top of the imageable area
333 // and then translate downwards
334 if (headerText != null) {
335 printText(g2d, headerText, hRect, headerFont, imgWidth);
336
337 g2d.translate(0, headerTextSpace + H_F_SPACE);
338 }
339
340 // constrain the table output to the available space
341 tempRect.x = 0;
342 tempRect.y = 0;
343 tempRect.width = imgWidth;
344 tempRect.height = availableSpace;
345 g2d.clip(tempRect);
346 // if we have a scale factor, scale the graphics object to fit
347 // the entire width
348 if (sf != 1.0D) {
349 g2d.scale(sf, sf);
350
351 // otherwise, ensure that the current portion of the table is
352 // centered horizontally
353 } else {
354 int diff = (imgWidth - clip.width) / 2;
355 g2d.translate(diff, 0);
356 }
357
358 // store the old transform and clip for later restoration
359 oldTrans = g2d.getTransform();
360 Shape oldClip = g2d.getClip();
361
362 // if there's a table header, print the current section and
363 // then translate downwards
364 if (header != null) {
365 hclip.x = clip.x;
371
372 // restore the original transform and clip
373 g2d.setTransform(oldTrans);
374 g2d.setClip(oldClip);
375
376 // translate downwards
377 g2d.translate(0, hclip.height);
378 }
379
380 // print the current section of the table
381 g2d.translate(-clip.x, -clip.y);
382 g2d.clip(clip);
383 table.print(g2d);
384
385 // restore the original transform and clip
386 g2d.setTransform(oldTrans);
387 g2d.setClip(oldClip);
388
389 // draw a box around the table
390 g2d.setColor(Color.BLACK);
391
392 // compute the visible portion of table and draw the rect around it
393 Rectangle visibleBounds = clip.intersection(table.getBounds());
394 Point upperLeft = visibleBounds.getLocation();
395 Point lowerRight = new Point(visibleBounds.x + visibleBounds.width,
396 visibleBounds.y + visibleBounds.height);
397
398 int rMin = table.rowAtPoint(upperLeft);
399 int rMax = table.rowAtPoint(lowerRight);
400 if (rMin == -1) {
401 rMin = 0;
402 }
403 if (rMax == -1) {
404 rMax = table.getRowCount();
405 }
406 int rowHeight = 0;
407 for(int visrow = rMin; visrow < rMax; visrow++) {
408 rowHeight += table.getRowHeight(visrow);
409 }
410 g2d.drawRect(0, 0, visibleBounds.width, hclip.height + rowHeight);
411
412 // dispose the graphics copy
413 g2d.dispose();
414
415 return PAGE_EXISTS;
416 }
417
418 /**
419 * A helper method that encapsulates common code for rendering the
420 * header and footer text.
421 *
422 * @param g2d the graphics to draw into
423 * @param text the text to draw, non null
424 * @param rect the bounding rectangle for this text,
425 * as calculated at the given font, non null
426 * @param font the font to draw the text in, non null
427 * @param imgWidth the width of the area to draw into
428 */
429 private void printText(Graphics2D g2d,
430 String text,
510 if (ltr) {
511 // adjust clip to the left of the next set of columns
512 clip.x += clip.width;
513 }
514
515 // adjust clip width to be zero
516 clip.width = 0;
517
518 // fit as many columns as possible, and at least one
519 int colCount = table.getColumnCount();
520 int colWidth = colModel.getColumn(col).getWidth();
521 do {
522 clip.width += colWidth;
523 if (!ltr) {
524 clip.x -= colWidth;
525 }
526
527 if (++col >= colCount) {
528 // reset col to 0 to indicate we're finished all columns
529 col = 0;
530 break;
531 }
532
533 colWidth = colModel.getColumn(col).getWidth();
534 } while (clip.width + colWidth <= pw);
535
536 }
537
538 }
|