0

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 BufferedImage JTable print output:-

JTable to pdf output jTable pdf output

Community
  • 1
  • 1
user1709952
  • 169
  • 2
  • 7
  • 21
  • 1
    See also [Why does the JTable header not appear in the image?](http://stackoverflow.com/questions/7369814/why-does-the-jtable-header-not-appear-in-the-image) – trashgod Oct 13 '12 at 09:03
  • Hi I had added an update to print JTable on the bufferedImage. But on pdf it looks different. Please provide some good suggestion on above. – user1709952 Oct 13 '12 at 15:27
  • Please reopen this tophic since it is not a duplicate. – user1709952 Oct 13 '12 at 15:31
  • *"It looks good when I print it to a buffered image but later on the pdf"* 1) Why not write the BI to the PDF? 2) Don't go posting new questions just because your old question got closed. I will vote to re-open this one but am flagging the newest question. – Andrew Thompson Oct 13 '12 at 15:55

0 Answers0