/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package misc;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.print.*;
import java.text.MessageFormat;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.image.BufferedImage;
/**
* Demonstration of how to provide a custom {@code JTable}
* {@code Printable} implementation, that wraps the default
* with extra decoration. This example prints the table inside
* a clipboard image.
*
* Requires the following other files:
*
* - TablePrintDemo1.java
*
- TablePrintDemo2.java
*
- images/passed.png
*
- images/failed.png
*
- images/passed-BW.png
*
- images/failed-BW.png
*
- images/clipBottom.png
*
- images/clipBottomLeft.png
*
- images/clipBottonRight.png
*
- images/clipLeft.png
*
- images/clipRight.png
*
- images/clipTop.png
*
- images/clipTopCenter.png
*
- images/clipTopLeft.png
*
- images/clipTopRight.png
*
- images/finalGrades.png
*
*
* @author Shannon Hickey
*/
public class TablePrintDemo3 extends TablePrintDemo2 {
/**
* Constructs an instance of the demo.
*/
public TablePrintDemo3() {
setTitle("Table Print Demo 3");
/* hide these fields - our printable will render its own header/footer */
String tooltipText = "Disabled - This Demo Prints Custom Header/Footers";
headerBox.setEnabled(false);
headerBox.setSelected(false);
headerBox.setToolTipText(tooltipText);
headerField.setEnabled(false);
headerField.setText("");
headerField.setToolTipText(tooltipText);
footerBox.setEnabled(false);
footerBox.setSelected(false);
footerBox.setToolTipText(tooltipText);
footerField.setEnabled(false);
footerField.setText("");
footerField.setToolTipText(tooltipText);
}
/**
* Overridden to return a subclass of JTable with a custom Printable
* implementation.
*/
protected JTable createTable(TableModel model) {
return new FancyPrintingJTable(model);
}
/**
* Start the application.
*/
public static void main(final String[] args) {
/* Schedule for the GUI to be created and shown on the EDT */
SwingUtilities.invokeLater(new Runnable() {
public void run() {
/* Don't want bold fonts if we end up using metal */
UIManager.put("swing.boldMetal", false);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
new TablePrintDemo3().setVisible(true);
}
});
}
/**
* Subclass of JTable that returns a fancy printable implementation.
*/
private static class FancyPrintingJTable extends JTable {
public FancyPrintingJTable(TableModel model) {
super(model);
}
/**
* Overridden to return a fancier printable, that wraps the default.
* Ignores the given header and footer. Renders its own header.
* Always uses the page number as the footer.
*/
public Printable getPrintable(PrintMode printMode,
MessageFormat headerFormat,
MessageFormat footerFormat) {
MessageFormat pageNumber = new MessageFormat("- {0} -");
/* Fetch the default printable */
Printable delegate = super.getPrintable(printMode, null, pageNumber);
/* Return a fancy printable that wraps the default */
return new FancyPrintable(delegate);
}
}
/**
* A custom Printable implementation that wraps another printable and
* decorates the output by placing the table inside an image of a clipboard.
*/
private static class FancyPrintable implements Printable {
/* The Printable to wrap */
private Printable delegate;
/* Images used to assemble a clipboard image around the painted table */
private BufferedImage clipTopLeft;
private BufferedImage clipTop;
private BufferedImage clipTopCenter;
private BufferedImage clipTopRight;
private BufferedImage clipBottomLeft;
private BufferedImage clipBottom;
private BufferedImage clipBottomRight;
private BufferedImage clipLeft;
private BufferedImage clipRight;
/* Image with text saying "Final Grades..." */
private BufferedImage finalGrades;
/* Whether or not the images loaded successfully */
boolean imagesLoaded;
/* Load the images */
{
try {
clipTopLeft = ImageIO.read(getClass().getResource("images/clipTopLeft.png"));
clipTop = ImageIO.read(getClass().getResource("images/clipTop.png"));
clipTopCenter = ImageIO.read(getClass().getResource("images/clipTopCenter.png"));
clipTopRight = ImageIO.read(getClass().getResource("images/clipTopRight.png"));
clipBottomLeft = ImageIO.read(getClass().getResource("images/clipBottomLeft.png"));
clipBottom = ImageIO.read(getClass().getResource("images/clipBottom.png"));
clipBottomRight = ImageIO.read(getClass().getResource("images/clipBottomRight.png"));
clipLeft = ImageIO.read(getClass().getResource("images/clipLeft.png"));
clipRight = ImageIO.read(getClass().getResource("images/clipRight.png"));
finalGrades = ImageIO.read(getClass().getResource("images/finalGrades.png"));
imagesLoaded = true;
} catch (IOException ioe) {
// can't load the image, so no clipboard
imagesLoaded = false;
}
}
/**
* Constructs a FancyPrintable to wrap the given Printable.
*/
public FancyPrintable(Printable delegate) {
this.delegate = delegate;
}
/**
* Prints the delegate Printable, wrapped inside an image of a clipboard.
* Gives the wrapped printable a smaller area to print into (which substracts
* the area needed to render the clipboard image), and then prints the
* clipboard image around the outside.
*/
public int print(Graphics g,
final PageFormat pf,
int pageIndex) throws PrinterException {
/*
* If we weren't able to load the images, we have nothing to wrap with,
* so just have the wrapped Printable do its thing, and return.
*/
if (!imagesLoaded) {
return delegate.print(g, pf, pageIndex);
}
/*
* Note: Since this is just a demo, we assume that there's enough room
* on the page to render the clipboard image and the table. A more robust
* application should check first, and render only the table if there's
* not enough room.
*/
/* top left of the imageable area */
int ix = (int)pf.getImageableX();
int iy = (int)pf.getImageableY();
/* width and height of the imageable area */
int iw = (int)pf.getImageableWidth();
int ih = (int)pf.getImageableHeight();
/* width of the clipboard image pieces to be painted on the left */
int leftWidth = clipLeft.getWidth();
/* width of the clipboard image pieces to be painted on the right */
int rightWidth = clipRight.getWidth();
/* height of the clipboard image pieces to be painted on the top */
int topHeight = clipTop.getHeight();
/* height of the clipboard image pieces to be painted on the bottom */
int bottomHeight = clipBottom.getHeight();
/* height of the final grades label */
int finalGradesHeight = finalGrades.getHeight();
/*
* First, calculate the shrunken area that we want the table to print
* into.
*/
/* inset the table from the left and right images by 10 */
final int tableX = ix + leftWidth + 10;
final int tableW = iw - (leftWidth + 10) - (rightWidth + 10);
/*
* inset the table top to leave space for the top image +
* 10 pixels + the final grades label + 10 pixels.
*/
final int tableY = iy + topHeight + 10 + finalGradesHeight + 10;
/* inset the table bottom by the height of the bottom image */
final int tableH = ih - (topHeight + 10) - (finalGradesHeight + 10) - bottomHeight;
/*
* Now print the table into this smaller area.
*/
/* create a new page format representing the shrunken area to print the table into */
PageFormat format = new PageFormat() {
public double getImageableX() {return tableX;}
public double getImageableY() {return tableY;}
public double getImageableWidth() {return tableW;}
public double getImageableHeight() {return tableH;}
};
/*
* We'll use a copy of the graphics to print the table to. This protects
* us against changes that the delegate printable could make to the graphics
* object.
*/
Graphics gCopy = g.create();
/* print the table into the shrunken area */
int retVal = delegate.print(gCopy, format, pageIndex);
/* if there's no pages left, return */
if (retVal == NO_SUCH_PAGE) {
return retVal;
}
/* dispose of the graphics copy */
gCopy.dispose();
/*
* Now that we've printed the table, assemble the clipboard image around
* the outside.
*/
int leftEnd = ix + leftWidth;
int clipTopCenterStart = ix + (int)((iw - clipTopCenter.getWidth()) / 2.0f);
int clipTopCenterEnd = clipTopCenterStart + clipTopCenter.getWidth();
int rightStart = ix + iw - rightWidth;
/* draw top left corner */
g.drawImage(clipTopLeft, ix, iy, null);
/* stretch top from top left corner to center image */
g.drawImage(clipTop, leftEnd, iy, clipTopCenterStart - leftEnd, topHeight, null);
/* stretch top from center image to top right corner */
g.drawImage(clipTop, clipTopCenterEnd, iy, rightStart - clipTopCenterEnd, topHeight, null);
/* draw top right corner */
g.drawImage(clipTopRight, rightStart, iy, null);
/* draw top center */
g.drawImage(clipTopCenter, clipTopCenterStart, iy, null);
int finalGradesStart = ix + (int)((iw - finalGrades.getWidth()) / 2.0f);
/* draw label */
g.drawImage(finalGrades, finalGradesStart, iy + topHeight + 10, null);
int bottomY = iy + ih - bottomHeight;
/* draw bottom left corner */
g.drawImage(clipBottomLeft, ix, bottomY, null);
/* draw bottom right corner */
g.drawImage(clipBottomRight, rightStart, bottomY, null);
/* stretch the bottom image from left to right */
g.drawImage(clipBottom, leftEnd, bottomY, rightStart - leftEnd, bottomHeight, null);
/* stretch left side from top to bottom */
g.drawImage(clipLeft, ix, iy + topHeight, leftWidth, bottomY - iy - topHeight, null);
/* stretch right side from top to bottom */
g.drawImage(clipRight, rightStart, iy + topHeight, rightWidth, bottomY - iy - topHeight, null);
return PAGE_EXISTS;
}
}
}