Проблема состоит из двух частей
- печать изображение на каждой странице
- убедитесь, что изображение "просвечивает" стол
второй адрес @mKorbel (хотя на самом деле не решен, потому что нет хорошего решения :-)
Чтобы решить первое, я бы пошел для пользовательского Printable и подкласса JTable, чтобы вернуть его, что-то вроде
public class BackgroundPrintable implements Printable {
Printable tablePrintable;
JTable table;
MessageFormat header;
MessageFormat footer;
BufferedImage background;
public BackgroundPrintable(MessageFormat header, MessageFormat footer) {
this.header = header;
this.footer = footer;
}
public void setTablePrintable(JTable table, Printable printable) {
tablePrintable = printable;
this.table = table;
}
@Override
public int print(Graphics graphics, PageFormat pageFormat,
int pageIndex) throws PrinterException {
printImage(graphics, pageFormat, pageIndex);
int exists = tablePrintable.print(graphics, pageFormat, pageIndex);
if (exists != PAGE_EXISTS) {
return exists;
}
return PAGE_EXISTS;
}
private void printImage(Graphics graphics, PageFormat pageFormat,
int pageIndex) {
// grab an untainted graphics
Graphics2D g2d = (Graphics2D)graphics.create();
// do the image painting
....
// cleanup
g2d.dispose();
}
}
// use in JTable subclass
@Override
public Printable getPrintable(PrintMode printMode,
MessageFormat headerFormat, MessageFormat footerFormat) {
Printable printable = super.getPrintable(printMode, null, null);
BackgroundPrintable custom = new BackgroundPrintable(headerFormat, footerFormat);
custom.setTablePrintable(this, printable);
return custom;
}
Чтобы достичь второго, JTable и его средства визуализации должны быть прозрачными. Хитро, потому что:
- возможно только при печати - в противном случае они должны иметь свою обычную непрозрачность
- все рендера должны быть прозрачными, и не существует абсолютно безопасного способа получить их всех
Пользовательский JTable может попытаться добиться этого, принудительно установив непрозрачность компонента рендеринга в его prepareRenderer:
@Override
public Component prepareRenderer(TableCellRenderer renderer,
int row, int column) {
JComponent comp = (JComponent) super.prepareRenderer(renderer, row, column);
if (isPaintingForPrint()) {
comp.setOpaque(false);
} else {
comp.setOpaque(true);
}
return comp;
}
На самом деле, это не совсем верно: код в блоке else может быть неправильным для естественных прозрачных компонентов. Боюсь, нет действительно надежного решения.