Possible Duplicate:
Why does the JTable header not appear in the image?
Drawing JTable rows and columns on a Panel
I am working on a report application in which I have to export a JTable in the form of report. But when I try to directly paint JTable on the PDF, it doesn't show the 1st row and column border. For this I tried by using default color grid Left Top borders. Which gives me a darker line in the PDF. However when try to fill any particular cell with color and export it on PDF output, all the grid lines are invisible.
SimpleTableDemo.java:
package com.swing.table;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import com.swing.data.BorderCellRenderer;
public class SimpleTableDemo extends JPanel implements ActionListener {
private boolean DEBUG = false;
private int spacing = 6;
private Map columnSizes = new HashMap();
String[] columnNames = { "First Name", "Last Name", "Sport", "# of Years",
"Vegetarian" };
Object[][] data = {
{
"Kathy",
"Smith",
"SnowboardingXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
new Integer(5), new Boolean(false) },
{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },
{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) },
{ "Jane", "White", "Speed reading", new Integer(20),
new Boolean(true) },
{ "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };
final JTable table = new JTable(data, columnNames);
public SimpleTableDemo() {
super(new GridLayout(0, 1));
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
// table.setFillsViewportHeight(true);
// Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
BorderCellRenderer cellRenderer = new BorderCellRenderer();
cellRenderer.setBorder(new LineBorder(Color.BLACK));
table.setDefaultRenderer(Object.class, cellRenderer);
table.repaint();
// Add the scroll pane to this panel.
add(scrollPane);
JButton button = new JButton("Create Pdf");
button.addActionListener(this);
add(button);
}
public void actionPerformed(ActionEvent e)
{
print();
}
private void print() {
Document document = new Document(PageSize.A4.rotate());
try {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/jTable.pdf"));
document.open();
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
PdfTemplate pdfTemplate = cb.createTemplate(table.getWidth(), table.getHeight());
Graphics2D g2 = pdfTemplate.createGraphics(table.getWidth(), table.getHeight());
/*g2.setColor(Color.BLACK);
g2.drawRect(x-2, y-2, table.getWidth()+2, table.getHeight()+2);*/
table.print(g2);
cb.addTemplate(pdfTemplate, 20, 20);
g2.dispose();
cb.restoreState();
} catch (Exception e) {
System.err.println(e.getMessage());
}
document.close();
}
/**
Create the GUI and show it. For thread safety, this method should be
invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
BorderCellRenderer.java:
package com.swing.data;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
/**
* @version 1.0 03/06/99
*/
public class BorderCellRenderer extends JLabel
implements TableCellRenderer {
protected Border noFocusBorder;
protected Border columnBorder;
protected Font font;
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
public BorderCellRenderer() {
noFocusBorder = new EmptyBorder(1, 2, 1, 2);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText((value == null) ? "" : value.toString());
Border b;
b = BorderFactory.createCompoundBorder();
// b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,0,1,0,table.getGridColor()));
// b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,0,0,1,table.getGridColor()));
/* if(row == 0 && column == 0)
{
setBackground(Color.CYAN);
}
else
{
setBackground(Color.WHITE);
}
*/
if(row==0 || column == 0)
{
if(row ==0 && column==0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,1,0,0,table.getGridColor()));
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(1,0,0,0,table.getGridColor()));
}
if(row == 0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(1,0,0,0,table.getGridColor()));
setBackground(Color.CYAN);
}
if(column == 0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,1,0,0,table.getGridColor()));
}
}
else
{
b = table.getBorder();
setBackground(Color.WHITE);
}
setBorder(b);
return this;
}
public void setColumnBorder(Border border) {
columnBorder = border;
}
public Border getColumnBorder() {
return columnBorder;
}
}
Please try with the above code and help me to get one to one PDF output with grid lines and filled cell color.
Update 1:- I modified the code for actionPerformed() method as below:-
public void actionPerformed(ActionEvent e)
{
int x = table.getWidth();
int y = table.getHeight();
BufferedImage bi = null;
if(x>0 && y>0)
{
bi = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
if(bi != null)
{
Graphics g = bi.createGraphics();
table.paint(g);
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
}
}
print();
}
Thanks for a look at my code. My requirement is not to display table headers. I didn't want to print headers as expected. That's why my 1st row top border and 1st column left is missing. To correct this I manually added a default grid border to 1st column and row. This makes the top border looks dark gray. Apart from this I also have to fill cells with color. It looks good when I print it to a buffered image but later on the pdf it removes my grid lines from the below screenshots:-
JTable to bufferedImage output
JTable to pdf output