views:

721

answers:

3

I am trying to create colored headers and footers when printing a JTable. Specifically, I am looking at getPrintable() in javax.swing.JTable, but MessageFormat does not give me the option to specify the color of the header or footer.

How can I do it?

clarification I am interested in setting the header/footers while printing. For example, notepad appends the filename as a header to what you print.

update Seems like there is no standard way of doing this, can someone give me some workarounds? The only answer posted so far has nothing to do with printing(as in send to a printer, not displaying to screen) header/footers.

Copied from my comment: I am interested in the printing header/footer. For example, when you are printing a document from notepad, it appends the filename as a header (or perhaps its the footer, I do not remember exactly)

A: 

This code is mainly from www.java2s.com with changes to show how to change the color. It is not the prettiest solution but hopefully will help you.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class MainClass {
  public static void main(String args[]) {
    String rows[][] = { { "A", "a" }, { "B", "b" }, { "E", "e" } };
    String headers[] = { "Upper", "Lower" };

    JFrame frame = new JFrame("Label Header");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTable table = new JTable(rows, headers);
    JScrollPane scrollPane = new JScrollPane(table);

    Border headerBorder = UIManager.getBorder("TableHeader.cellBorder");

    JLabel headerLabel1 = new JLabel(headers[0], JLabel.CENTER);
    headerLabel1.setBorder(headerBorder);

    // Here is where the color is changed.
    headerLabel1.setBackground(new Color(255, 0, 0));
    headerLabel1.setForeground(new Color(0, 0, 255));
    // End of color change.

    JLabel headerLabel2 = new JLabel(headers[1], JLabel.CENTER);
    headerLabel2.setBorder(headerBorder);

    TableCellRenderer renderer = new JComponentTableCellRenderer();

    TableColumnModel columnModel = table.getColumnModel();

    TableColumn column0 = columnModel.getColumn(0);
    TableColumn column1 = columnModel.getColumn(1);

    column0.setHeaderRenderer(renderer);
    column0.setHeaderValue(headerLabel1);

    column1.setHeaderRenderer(renderer);
    column1.setHeaderValue(headerLabel2);

    frame.add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}

class JComponentTableCellRenderer implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) {
    return (JComponent)value;
  }
}

The most important bit is:

    // Here is where the color is changed.
    headerLabel1.setBackground(new Color(255, 0, 0));
    headerLabel1.setForeground(new Color(0, 0, 255));
    // End of color change.

HTH let me know how you got on with it :)

Artur
If I'm not mistaken, you are setting table header/footers here. I am interested in the printing header/footer. For example, when you are printing a document from notepad, it appends the filename as a header (or perhaps its the footer, I do not remember exactly)
yx
+1  A: 

One solution I can think of is to use your own printable:

public class CustomTablePrintable implements Printable {

    Printable tablePrintable;

    public void setTablePrintable(Printable printable) {
        tablePrintable = printable;        
    }

    public int print(Graphics graphics, PageFormat pageFormat, 
            int pageIndex) throws PrinterException {
        if (pageIndex > 0) {
            return NO_SUCH_PAGE;
        }

        tablePrintable.print(graphics, pageFormat, pageIndex);

        Graphics2D g2d = (Graphics2D)graphics;
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

        // Draw header/footer here
        graphics.drawString(header, posx, posy);

        return PAGE_EXISTS;        
    }
}

When you call getPrintable from your JTable, inject it to a new instance to the custom printable and then use this with the PrinterJob.

You can now draw the header and footer as you wish, but you also lose some stuff:

  • You can't use MessageFormat to format the messages. I believe that you could easily add this functionality to your printable.
  • Header and footer aren't automatically positioned. You could have rough estimates for these though.

EDIT: I've looked at the Java Sources and there is the private class TablePrintable that does all the job. You can peak at the source code to see how the header and footer are printed. Then you can move this functionality to your Printable class.

kgiannakakis
looks good I'll give this a try
yx
A: 

This is a little out of left-field, but you could use a library like iText to create a PDF document, and then send that to the printer. You'll get a much greater level of control over the appearance and presentation of the document, including the ability to manage how the rows of your table break over page boundaries, and you'll be able to set the page header and footer very readily.

You can print a PDF in Java following these instructions: http://www.juixe.com/techknow/index.php/2008/01/17/print-a-pdf-document-in-java/

banjollity