Inhalt 1. Printing API 1. Übersicht 2. Vorgehen 3. Beispiel 2. Klasse PrintUtils 3. Mehrere Seiten drucken Folie 1 Lernziele Sie wissen, wie Sie Swing-Komponenten ausdrucken können Sie kennen den Aufbau der Printer-API Sie wissen, wie Sie über mehrere Seiten Drucken können Sie sind in der Lage Druck-Funktionen in eigenen Swing-Applikationen zu integrieren Folie 2 2004 Diego Schmidlin Seite 1
1.1 Übersicht (1) Seit JDK 1.2 steht eine API für das Drucken zur Verfügung Die Printer-API ist im Packagejava.awt.print enthalten Damit lässt sich alles drucken, was einen Renderer für den Graphics-Kontext oder Graphics2D besitzt Alle Swing-Komponenten besitzen einen solchen Renderer -> Drucken von Swing-Komponenten ist daher sehr einfach Folie 3 1.1 Übersicht (2) Das Packagejava.awt.print enthält: Interfaces Pageable Repräsentiert eine Anzahl von Seiten Printable Definiert Print-Methode, die vom Printer-System zum Rendern einer Komponente aufgerufen wird PrinterGraphics Wird von Graphics implementiert Dient zum Auffinden des Printer-Jobs Folie 4 2004 Diego Schmidlin Seite 2
1.1 Übersicht (3) Klassen Book Repräsentiert mehrere Seiten, die unterschiedliche Formate haben können PageFormat Beschreibt Grösse und Ausrichtung einer Seite Paper Beschreibt Grösse einer Seite Dient zum Umwandeln von Koordinatensystemen PrinterJob Kontrolliert den Druckvorgang Folie 5 1.1 Übersicht (4) Exceptions PrinterException Mutter-Klasse für Printer-Exceptions PrinterAbortException Abbruch durch den Benutzer während des Druckvorganges PrinterIOException Ein-/Ausgabe-Fehler auf Drucker Folie 6 2004 Diego Schmidlin Seite 3
1.2 Vorgehen (1) Erzeugen eines PrinterJob-Objektes: PrinterJob printjob = PrinterJob.getPrinterJob(); In den PrinterJob die zu zeichnende Komponente eintragen: Die Komponente muss die Schnittstelle Printable implementieren printjob.setprintable(component); Druckerdialog anzeigen (optional): liefert true, wenn gedruckt werden soll printjob.printdialog(); Ausdruck starten: try{ printjob.print(); catch( PrinterException ex ) { ex.printstacktrace(); Folie 7 1.2 Vorgehen (2) Aufruf der print-methode der zu druckenden Komponente: public int print(graphics g, PageFormat pageformat, int pageindex) throws PrinterException { // Wenn nur eine Seite vorhanden ist if (pageindex >= 1) { return Printable.NO_SUCH_PAGE; // Aufrufen der print-methode der Komponente print(g); // Es könnte auch die Methoden // printall oder paint aufgerufen werden // printall(g); // paint(g); return Printable.PAGE_EXISTS; Folie 8 2004 Diego Schmidlin Seite 4
1.3 Beispiel (1) import java.awt.*; import java.awt.event.*; import java.awt.print.*; import javax.swing.*; class MyButton extends JButton implements Printable { public MyButton(String label) { super(label); Folie 9 1.3 Beispiel (2) // Methode print von Interface printabel implementieren public int print(graphics g, PageFormat pf, int pi) throws PrinterException { // Es ist nur eine Seite vorhanden if (pi >= 1) { return Printable.NO_SUCH_PAGE; Graphics2D g2 = (Graphics2D)g; g2.translate(pf.getimageablex(), pf.getimageabley()); Fontf=new Font("Monospaced", Font.PLAIN, 10); g2.setfont(f); // Methode printall von JButton aufrufen printall(g2); return Printable.PAGE_EXISTS; Folie 10 2004 Diego Schmidlin Seite 5
1.3 Beispiel (3) public class PrintButton extends JPanel implements ActionListener { public PrintButton() { setbackground(color.white); MyButton b = new MyButton("Print"); b.addactionlistener(this); add(b); public void actionperformed(actionevent e) { PrinterJob printjob = PrinterJob.getPrinterJob(); printjob.setprintable((mybutton)e.getsource()); if (printjob.printdialog()) { try { printjob.print(); catch (Exception PrintException) { Folie 11 1.3 Beispiel (4) public static void main(string s[]) { WindowListener l = new WindowAdapter() { public void windowclosing(windowevent e) { System.exit(0); ; Framef=new Frame("printbutton"); f.addwindowlistener(l); f.add("center", new PrintButton()); f.pack(); f.setsize(new Dimension(400, 300)); f.show(); Folie 12 2004 Diego Schmidlin Seite 6
2. Klasse PrintUtilities (1) Um eine Swing-Komponente zu drucken wurde bis jetzt eine Subklasse (Ableitung) erzeugt das Interface Printable implementiert Dies ist nicht sinnvoll! Für jede Komponente muss eine abgeleitete Klasse erzeugt werden Besser: Erzeugen einer Drucker-Klasse, die beliebige Komponenten drucken kann Folie 13 2. Klasse PrintUtilities (2) import java.awt.*; import javax.swing.*; import java.awt.print.*; public class PrintUtilities implements Printable { private Component componenttobeprinted; public static void printcomponent(component c) { new PrintUtilities(c).print(); public PrintUtilities(Component componenttobeprinted) { this.componenttobeprinted = componenttobeprinted; Folie 14 2004 Diego Schmidlin Seite 7
2. Klasse PrintUtilities (3) public void print() { PrinterJob printjob = PrinterJob.getPrinterJob(); printjob.setprintable(this); if (printjob.printdialog()) { try { printjob.print(); catch (PrinterException pe) { System.out.println("Error printing: " + pe); public int print(graphics g, PageFormat pageformat, int pageindex) { if (pageindex > 0) { return (NO_SUCH_PAGE); else { Graphics2D g2d = (Graphics2D)g; g2d.translate(pageformat.getimageablex(),pageformat.getimageabley()); disabledoublebuffering(componenttobeprinted); componenttobeprinted.paint(g2d); enabledoublebuffering(componenttobeprinted); return (PAGE_EXISTS); Folie 15 2. Klasse PrintUtilities (4) public static void disabledoublebuffering(component c) { RepaintManager currentmanager = RepaintManager.currentManager(c); currentmanager.setdoublebufferingenabled(false); public static void enabledoublebuffering(component c) { RepaintManager currentmanager = RepaintManager.currentManager(c); currentmanager.setdoublebufferingenabled(true); Folie 16 2004 Diego Schmidlin Seite 8
3. Mehrere Seiten drucken (1) Die Printer-API unterstützt auch das Drucken von mehreren Seiten durch die Book-API Leider berechnet die Book-API keine Seitenumbrüche Drucken von nur einer Seite // In Methode print(graphics g, PageFormat pf, int pageindex)) if( pageindex >= 1 ) { return Printable.NO_SUCH_PAGE; Drucken von mehreren einer Seite // In Methode print(graphics g, PageFormat pf, int pageindex)) if( pageindex >= TotalPages) { return Printable.NO_SUCH_PAGE; Folie 17 3. Mehrere Seiten drucken (2) Das Printing-Framework ruft print() solange auf, bispageindex >= TotalPages ist Erstreckt sich eine Komponente über mehrere Seiten, so muss jeweils der richtige Bereich ausgedruckt werden Dazu können Methoden aus der Klasse Graphics2D bzw. Graphics verwendet werden setclip(int x, int y, int width, int height) Schneidet den Bereich im Rechteck x, y, with, height aus translate(int x, int y) Translation der Original-Koordinaten an den neuen Punkt x, y Folie 18 2004 Diego Schmidlin Seite 9
3. Mehrere Seiten drucken (3) Gedruckte Seite Komponente 0 / 0 0 / 0 translate (0, 0) 600 setclip (0, 0, 600, 400) 600 / 400 Folie 19 3. Mehrere Seiten drucken (4) Gedruckte Seite Komponente 0 / 0 0 / 600 translate (0, -600) 1200 setclip (0, 600, 600, 400) 600 / 400 Folie 20 2004 Diego Schmidlin Seite 10
3. Mehrere Seiten drucken (5) Gedruckte Seite Komponente 0 / 0 0 / 1200 translate (0, -1200) 600 / 400 1800 setslip (0, 1200, 600, 400) Folie 21 3. Mehrere Seiten drucken (6) Folie 22 2004 Diego Schmidlin Seite 11
Zusammenfassung Alle Swing-Komponenten lassen sich mit der Printer-API drucken Zum Drucken muss das Interface Printable implementiert werden In der Methode print() des Interface Printable werden die Komponenten auf einen Kontext Graphics oder Graphics2D ausgegeben Zum Drucken über mehrere Seiten, müssen die Anzahl Seiten selbst ermittelt werden Zum Drucken einer Komponente über mehrere Seiten, kann man die Methoden translate() und setclip() verwenden Folie 23 @ Übungsaufgabe U11.1 Schauen Sie sich das Beispiel SalesReport.java an Finden Sie heraus wie hier über mehrere Seiten gedruckt werden kann Folie 24 2004 Diego Schmidlin Seite 12