# JTable drucken



## Plunder (5. Dez 2009)

Hallo liebe Java-Gemeinde,

ich drucke meine JTable mit 
	
	
	
	





```
myJTable.print()
```
 Nun möchte ich die Breite der Seitenränder auf einen bestimmten Wert voreinstellen (z.B. 10mm) und dies nicht jedes Mal über den Print Dialog neu einstellen müssen. Kann mir jemand helfen?


----------



## André Uhres (5. Dez 2009)

Versuch's mal so:

```
private PrintRequestAttributeSet attr;
...
private void print() {
    if (attr == null) {
        attr = new HashPrintRequestAttributeSet();
        float leftMargin = 10;
        float rightMargin = 10;
        float topMargin = 10;
        float bottomMargin = 10;
        attr.add(OrientationRequested.PORTRAIT);
        attr.add(MediaSizeName.ISO_A4);
        MediaSize mediaSize = MediaSize.ISO.A4;
        float mediaWidth = mediaSize.getX(Size2DSyntax.MM);
        float mediaHeight = mediaSize.getY(Size2DSyntax.MM);
        attr.add(new MediaPrintableArea(
                leftMargin, topMargin,
                (mediaWidth - leftMargin - rightMargin),
                (mediaHeight - topMargin - bottomMargin), Size2DSyntax.MM));
    }
    try {
        jTable1.print(JTable.PrintMode.FIT_WIDTH, null, null, true, attr, true);
    } catch (PrinterException ex) {
        ex.printStackTrace();
    } catch (HeadlessException ex) {
        ex.printStackTrace();
    }
}
```


----------



## mathieu (7. Dez 2009)

Hi,
was Sie geschrieben haben, funktionniert hammer. Ich möchte noch kurz was wissen.
Wie kann man ein Kopfzeile und Fusszeile setzen?

Danke
MfG aus Paris

Mathieu


----------



## André Uhres (8. Dez 2009)

mathieu hat gesagt.:


> Wie kann man ein Kopfzeile und Fusszeile setzen?


Dazu dient der zweite und dritte Parameter (MessageFormat):

```
print(JTable.PrintMode, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean)
```

*Header und Footer Text *kann hinzugefügt werden (ansonsten einfach null angeben); 
im MessageFormat kann man als ArgumentIndex 0 für die Seitennummer angegeben: [c]new MessageFormat("Page {0}") [/c]

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.
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.


----------



## mathieu (8. Dez 2009)

Hi André,
 Ok für den print(), einverstanden.
print(JTable.PrintMode, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean)


MessageFormat header= new MessageFormat("Hi This is my JTable");
MessageFormat footer = new MessageFormat("Page {0,number,#.#}"); 

print(JTable.PrintMode, header, footer, true, PrintRequestAttributeSet, true)

Wie kann man in Kopfzeile ein multi line text schreiben? 

MfG aus Paris
Mathieu


----------



## André Uhres (9. Dez 2009)

mathieu hat gesagt.:


> Wie kann man in Kopfzeile ein multi line text schreiben?


Folgende Methode ist verfügbar für erweiterte Druckanforderungen: 

```
getPrintable(JTable.PrintMode, MessageFormat, 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. 
Ein sehr gutes Tutorial über das Drucken von Tabellen, mit weiteren Einzelheiten: How to Print Tables 

```
/*
 * 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;
    }
}
```


----------



## Tom_ (28. Mrz 2011)

@André Funktioniert super! Wobei ich das Kernstück nicht herauslesen kann, wenn ich es nachprogrammiere, dann druckt es mir nur den äußeren Rahmen von dem JTable.
Hab mich jetzt dazu entschlossen demo einfach zu Parametrieren. 

Verstehe ich es richtig, dass man mit  int x1 = (int) pageFormat.getImageableX();
        int y1 = (int) pageFormat.getImageableY();
        int w1 = (int) pageFormat.getImageableWidth();
        int h1 = (int) pageFormat.getImageableHeight();
indirekt auch die Row's pro Seite bestimmen kann?

Wie weit gehen die theoretischen Möglichkeiten beim Java-drucken. Kann ich ganze Seiten designen also mit Graphik -und Textelementen?

lg
Tom


----------



## André Uhres (28. Mrz 2011)

Hallo Tom,

es freut mich, dass du den Code nützlich findest. Allerdings machen wir bei so alten Threads gewöhnlich einen neuen auf und verweisen lediglich auf den alten. Das aber nur nebenbei.

Die "ImageableHeight" entspricht der bedruckbaren Seitenhöhe und wird oft benutzt, um die Anzahl von Zeilen pro Seite zu bestimmen, abhängig von der Zeilenhöhe. Die "ImageableWidth" wird oft benutzt, um einen "scale factor" zu bestimmen, damit die Breite des Dokuments ganz auf eine Seite passt.

Mit Java können wir ganze Seiten mit allen möglichen Graphik- und Textelementen entwerfen.

Gruß,
André


----------



## Tom_ (29. Mrz 2011)

ok!  Danke für den Hinweis. Bin über google auf den Thread gekommen, ist mir gar nicht aufgefallen wie alt der schon ist.
Das reicht mir im Moment zum weiter machen, wenn ich mehr Fragen habe, dann machen ich einen neunen Thread auf.

lg
Tom


----------

