JTable Druckfunktion anpassen
Seit Java 1.5 wird das Drucken der JTable unterstützt.
1. Die standard Druckfunktion
print() http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#print()
print(JTable.PrintMode) http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#print(javax.swing.JTable.PrintMode)
print(JTable.PrintMode, MessageFormat, MessageFormat) http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#print(javax.swing.JTable.PrintMode,%20java.text.MessageFormat,%20java.text.MessageFormat)
print(JTable.PrintMode, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean) http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#print(javax.swing.JTable.PrintMode,%20java.text.MessageFormat,%20java.text.MessageFormat,%20boolean,%20javax.print.attribute.PrintRequestAttributeSet,%20boolean)
JTable.PrintMode.NORMAL druckt die JTable mit der aktuellen Grösse. JTable.PrintMode.FIT_WIDTH verkleinert die JTable, wenn nötig, so daß alle Spalten auf eine Seite passen. Header und Footer Text kann hinzugefügt werden (ansonsten einfach null angeben); im MessageFormat kann man als ArgumentIndex 0 für die Seitennummer angegeben: Code:
new MessageFormat("Page {0}")
Mit dem ersten boolean Parameter kann man angeben ob der Druckdialog angezeigt werden soll oder nicht. "PrintRequestAttributeSet" ermöglicht die direkte Angabe von Druckattributen. Wenn der zweite boolean true ist (empfohlen), wird während des Druckvorgangs ein modaler Progressdialog angezeigt, mit Abbruchmöglichkeit.
2. Das Anpassen der Druckfunktion
Folgende Methode ist verfügbar für erweiterte Druckanforderungen:
getPrintable(JTable.PrintMode, MessageFormat, MessageFormat) http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#getPrintable(javax.swing.JTable.PrintMode,%20java.text.MessageFormat,%20java.text.MessageFormat)
Unten ist ein Demoprogramm das zeigt, wie man die JTable Druckfunktion anpassen kann. Als Beispiel drucken wir einen Reportheader mit zwei Zeilen und Rand.
3. Das Tutorial von Sun
Ein sehr gutes Tutorial über das Drucken von Tabellen, mit weiteren Einzelheiten: How to Print Tables http://java.sun.com/docs/books/tutorial/uiswing/misc/printtable.html
<code=java>/*
* TableReportDemo.java * This demo shows you how to customize the JTable print function. * As an example, we print a report header with two rows and a border. */
import java.awt.*; import java.awt.event.*; import java.awt.print.*; import java.util.logging.*; import javax.print.attribute.*; import javax.swing.*; import javax.swing.JTable.*; import javax.swing.table.*; public class TableReportDemo extends JFrame {
private JTable table; private JButton btPrint; private Action printAction = new AbstractAction("Print...") { public void actionPerformed(final ActionEvent e) { try { printJTable(); } catch (PrinterException ex) { Logger.getLogger(TableReportDemo.class.getName()).log(Level.SEVERE, null, ex); } } }; public TableReportDemo() { super("TableReportDemo"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); btPrint = new JButton(); add(btPrint, BorderLayout.SOUTH); btPrint.setAction(printAction); add(new JScrollPane(createTable()), BorderLayout.CENTER); pack(); } public JTable createTable() { String[] title = new String[]{"Title A", "Title B", "Title C", "Title D", "Title E"}; String[][] data = new String[][]{}; DefaultTableModel model = new DefaultTableModel(data, title); table = new JTable(model); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); for (int i = 0; i < 50; i++) { model.addRow(new String[]{String.valueOf(i), "", "", ""}); } return table; }
private void printJTable() throws PrinterException { // possibly prepare the table for printing here first // wrap in a try/finally so table can be restored even if something fails try { // fetch the printable Printable printable = new TableReport(table); PrinterJob job = PrinterJob.getPrinterJob();// fetch a PrinterJob job.setPrintable(printable);// set the Printable on the PrinterJob // create an attribute set to store attributes from the print dialog PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet(); // display a print dialog and record whether or not the user cancels it boolean printAccepted = job.printDialog(attr); if (printAccepted) {// if the user didn't cancel the dialog job.print(attr);// do the printing } } finally { // possibly restore the original table state here } } public static void main(final String[] args) { Runnable gui = new Runnable() {
@Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { ex.printStackTrace(); } new TableReportDemo().setVisible(true); } }; //GUI must start on EventDispatchThread: SwingUtilities.invokeLater(gui); }
} class TableReport implements Printable {
private Printable tablePrintable; private PageFormat pageFormatJTable; public TableReport(final JTable table) { tablePrintable = table.getPrintable(JTable.PrintMode.FIT_WIDTH, null, null); } public int print(final Graphics graphics, final PageFormat pageFormat, final int pageIndex) throws PrinterException { Graphics2D g = (Graphics2D) graphics; int x1 = (int) pageFormat.getImageableX(); int y1 = (int) pageFormat.getImageableY(); int w1 = (int) pageFormat.getImageableWidth(); int h1 = (int) pageFormat.getImageableHeight(); if (pageFormatJTable == null) { pageFormatJTable = (PageFormat) pageFormat.clone(); Paper paperJTable = pageFormatJTable.getPaper(); if(pageFormatJTable.getOrientation() == PageFormat.PORTRAIT){ paperJTable.setImageableArea(x1, y1 + 60,//skip header area w1, h1 - 90);//reserve space for header and footer }else{ paperJTable.setImageableArea(y1 + 60, x1,//skip header area h1 - 90, w1);//reserve space for header and footer } pageFormatJTable.setPaper(paperJTable); } String title = "Title"; String subtitle = "Subtitle"; Font f = g.getFont(); g.setFont(g.getFont().deriveFont(15f)); FontMetrics fm = g.getFontMetrics(); g.drawString(title, x1 + (w1-fm.stringWidth(title))/2, y1 + 15); g.setFont(f); fm = g.getFontMetrics(); g.drawString(subtitle, x1 + (w1-fm.stringWidth(subtitle))/2, y1 + 30); g.drawRect(x1, y1, w1, 40); String footer = "Page " + (pageIndex + 1); g.drawString(footer, x1 + (w1-fm.stringWidth(footer))/2, y1 + h1 - 10); //print the table: Graphics gCopy = g.create(); int retVal = tablePrintable.print(gCopy, pageFormatJTable, pageIndex); gCopy.dispose(); // return retVal; }
}</code=java>
Das Druckbild sieht dann etwa so aus (zwei Seiten):