Results 1 to 3 of 3
  1. #1
    flizbert is offline Member
    Join Date
    Jun 2010
    Rep Power

    Default Print not working on my JTable with custom CellRenderer

    I have a JTable and the first column has a custom cell renderer attached to it. It allows the display of multiline text. The rest of the cells I just used the DefaultCellRenderer as they only contain Integers. I want to be able to print the entire Jtable. But when I use the "convenience" JTable.print() method, it only prints a portion of my results.

    I'm not sure if this is helpful but here is the TextAreaRenderer. I have a print button that when selected does a table.print() and that's pretty much it. It doesn't matter whether I'm printing landscape or portrait, FILL_WIDTH or NORMAL. I only ever get about 1/2 or sometimes more of the Jtable when I print. I do have my table embedded in a scrollpanel and I have confirmed that the number displayed in my JTable is correct. Just can't for the life of me figure out why it won't print correctly. I assume it has to do with the fact that the first column height is twice the normal height.

    I would really appreciate any suggestions you might have.


    Java Code:
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import javax.swing.JTable;
    import javax.swing.JTextArea;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    import javax.swing.table.TableColumnModel;
    import org.apache.log4j.Logger;
    public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
    	private static final long serialVersionUID = 2423493279250608139L;
    	private static Logger log_ = Logger.getLogger(TextAreaRenderer.class);
    	private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
    	private final Map cellSizes = new HashMap();
    	public TextAreaRenderer() {
    	public Component getTableCellRendererComponent(JTable table, Object value,
    			boolean isSelected, boolean hasFocus, int row, int column) {
    		adaptee.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    		setFont(new Font("Courier", adaptee.getFont().getStyle(), 14));
    		TableColumnModel columnModel = table.getColumnModel();
    		setSize(columnModel.getColumn(column).getWidth(), 100000);
    		setPreferredSize(new Dimension(columnModel.getColumn(column).getWidth(), 32));  // added this and the next line because I thought it might help.  hasn't done anything
    		setMinimumSize(new Dimension(columnModel.getColumn(column).getWidth(), 32));
    		int height_wanted = (int) getPreferredSize().getHeight();
    		addSize(table, row, column, height_wanted);
    		height_wanted = findTotalMaximumRowSize(table, row);
    		if (height_wanted != table.getRowHeight(row)) {
    			table.setRowHeight(row, height_wanted);
    		return this;
    	private void addSize(JTable table, int row, int column,
                           int height) {
    		Map rows = (Map) cellSizes.get(table);
    		if (rows == null) {
    			cellSizes.put(table, rows = new HashMap());
    		Map rowheights = (Map) rows.get(new Integer(row));
    		if (rowheights == null) {
    			rows.put(new Integer(row), rowheights = new HashMap());
    		rowheights.put(new Integer(column), new Integer(height));
       * Look through all columns and get the renderer.  If it is
       * also a TextAreaRenderer, we look at the maximum height in
       * its hash table for this row.
    	private int findTotalMaximumRowSize(JTable table, int row) {
    		int maximum_height = 0;
    		Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
    		while (columns.hasMoreElements()) {
    			TableColumn tc = (TableColumn) columns.nextElement();
    			TableCellRenderer cellRenderer = tc.getCellRenderer();
    			if (cellRenderer instanceof TextAreaRenderer) {
    				TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
    				maximum_height = Math.max(maximum_height,
    						tar.findMaximumRowSize(table, row));
    		return maximum_height;
    	private int findMaximumRowSize(JTable table, int row) {
    		Map rows = (Map) cellSizes.get(table);
    		if (rows == null) return 0;
    		Map rowheights = (Map) rows.get(new Integer(row));
    		if (rowheights == null) return 0;
    		int maximum_height = 0;
    		for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {
    			Map.Entry entry = (Map.Entry);
    			int cellHeight = ((Integer) entry.getValue()).intValue();
    			maximum_height = Math.max(maximum_height, cellHeight);
    		return maximum_height;

  2. #2
    flizbert is offline Member
    Join Date
    Jun 2010
    Rep Power


    So I'd like to add that I just figured out that if I try to print after I have scrolled down through the entire list of results, it will print them all. But if I just get the results and print, then I only get a small subset. Now I'm really confused.

  3. #3
    SteveB is offline Member
    Join Date
    Jan 2008
    Rep Power

    Default JTable print method problem

    The problem is that JTable print uses some black-box algorithm to determine which cells to render and, apparently, for a table longer than a page or two, it doesn't render them all. In my opinion, this is a bug in the print method, which should ensure that all table cells are rendered before sending the image to be printed, but that's neither here nor there. I was having a similar problem until one of my colleagues suggested I force every cell to be rendered before executing the print. Here's the code that fixes the problem:

    * Force entire table to be rendered by visiting all table cells
    * @param jTable
    private void visitAllCellRenderers(final JTable jTable)
    for (int colIdx = 0; colIdx < jTable.getColumnCount(); colIdx++)
    for (int rowIdx = 0; rowIdx < jTable.getRowCount(); rowIdx++)
    TableColumnModel columnModel = jTable.getColumnModel();
    TableColumn column = columnModel.getColumn(colIdx);
    TableCellRenderer renderer = column.getCellRenderer();
    Object cellValue = jTable.getValueAt(rowIdx, colIdx);

    renderer.getTableCellRendererComponent(jTable, cellValue, false, false, rowIdx, colIdx);

    Calling this method on the table before calling table.print() cured it.

Similar Threads

  1. Working with Jtable
    By blu_fox88 in forum AWT / Swing
    Replies: 3
    Last Post: 02-20-2010, 05:49 PM
  2. Replies: 6
    Last Post: 11-12-2009, 11:50 AM
  3. Print the text file and print preview them
    By Java Tip in forum java.awt
    Replies: 0
    Last Post: 06-23-2008, 12:04 AM
  4. Replies: 8
    Last Post: 05-28-2008, 08:00 AM
  5. Replies: 2
    Last Post: 05-15-2008, 11:15 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts