Reputation: 31
I want to print a JTable
with background image or water mark. My code is:
public void actionPerformed(ActionEvent ae)
{
boolean status=false;
MessageFormat header = null;
header = new MessageFormat("Header");
MessageFormat footer = null;
footer = new MessageFormat("Page");
boolean fitWidth = true;
boolean showPrintDialog = true;
boolean interactive = true;
/* determine the print mode */
JTable.PrintMode mode = fitWidth ? JTable.PrintMode.FIT_WIDTH
: JTable.PrintMode.NORMAL;
try
{
status = jt.print(mode, header, footer,showPrintDialog,null,interactive);
if(status ==true)
{
frame.dispose();
}
}
catch(Exception ee)
{
System.out.println(ee.getMessage());
}
}
How can I pass or set the background image in this method?
Upvotes: 3
Views: 2219
Reputation: 51525
The problem has two parts
the second is addressed by @mKorbel (though not really solved because there is no nice solution :-)
To solve the first, I would go for a custom Printable and subclass JTable to return it, something like
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;
}
To achieve the second, both the JTable and its renderers must be transparent. Tricky, because:
A custom JTable could try to achieve that by forcing the rendering component's opacity in its 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;
}
Actually, that's not entirely valid: the code in the else block might be the wrong-thing-to-do for naturally transparent components. No really reliable solution available, I'm afraid.
Upvotes: 3
Reputation: 109813
there no easy way to set whatever for BackGround for whole JTable, but JViewPort from JScrollPane can do that easilly, then doesn't matter if is inside JScrollPane
a JTable
or another JComponents
for example
import java.awt.*;
import javax.swing.*;
class ImageAsTableBackround {
private JScrollPane sp;
private JTable table;
private String[] head = {"One", "Two", "Three", "Four", "Five", "Six"};
private String[][] data = new String[25][6];
public void buildGUI() {
sp = new JScrollPane();
// uncomment these codes lines for panting an image from package,
// but then block code table = new TableBackroundPaint0(data, head);
//sp.setViewport(new ImageViewport());
//table = new JTable(data, head);
//table.setOpaque(false);
// code for painting from generated code
table = new TableBackroundPaint0(data, head);
table.setBackground(new Color(0, 0, 0, 0));
table.setFillsViewportHeight(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
sp.setViewportView(table);
JFrame frame = new JFrame();
frame.getContentPane().add(sp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class ImageViewport extends JViewport {
private static final long serialVersionUID = 1L;
private Image img;
public ImageViewport() {
try {
ImageIcon image = new ImageIcon(getClass().getResource("resources/PICT6090.jpg"));
img = image.getImage();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
} else {
g.drawString("This space for rent", 50, 50);
}
}
}
class TableBackroundPaint0 extends JTable {
private static final long serialVersionUID = 1L;
TableBackroundPaint0(Object[][] data, Object[] head) {
super(data, head);
setOpaque(false);
((JComponent) getDefaultRenderer(Object.class)).setOpaque(false);
}
@Override
public void paintComponent(Graphics g) {
Color background = new Color(168, 210, 241);
Color controlColor = new Color(230, 240, 230);
int width = getWidth();
int height = getHeight();
Graphics2D g2 = (Graphics2D) g;
Paint oldPaint = g2.getPaint();
g2.setPaint(new GradientPaint(0, 0, background, width, 0, controlColor));
g2.fillRect(0, 0, width, height);
g2.setPaint(oldPaint);
for (int row : getSelectedRows()) {
Rectangle start = getCellRect(row, 0, true);
Rectangle end = getCellRect(row, getColumnCount() - 1, true);
g2.setPaint(new GradientPaint(start.x, 0, controlColor, (int) ((end.x + end.width - start.x) * 1.25), 0, Color.orange));
g2.fillRect(start.x, start.y, end.x + end.width - start.x, start.height);
}
super.paintComponent(g);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ImageAsTableBackround().buildGUI();
}
});
}
}
Upvotes: 3