From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100169.html | 452 +++++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100169.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100169.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100169.html b/Master/Reference Architectures and Patterns/hjp5/html/k100169.html new file mode 100644 index 0000000..35fc7d8 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100169.html @@ -0,0 +1,452 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 26 - Drucken +
+
+ + + + +

26.2 Drucken mit dem JDK 1.1

+
+ +
+ + + + +

26.2.1 Grundlagen

+ +

+Das Druck-API der Version 1.1 ist recht übersichtlich und leicht +zu verstehen. Es gibt zwar einige Restriktionen und Besonderheiten, +die beim Erstellen von Druckausgaben zu Problemen führen können, +aber für einfache Ausdrucke von Text und Grafik ist die Schnittstelle +dennoch geeignet. + +

+Grundlage der Druckausgabe ist die Methode getPrintJob +der Klasse Toolkit: +

+ + + + + +
+ +
+public PrintJob getPrintJob(
+   Frame frame,
+   String jobtitle,
+   Properties props
+)
+
+
+
+java.awt.Toolkit
+ +

+Sie liefert ein Objekt des Typs PrintJob, +das zur Initialisierung eines Druckjobs verwendet werden kann. Ein +Aufruf von getPrintJob +führt gleichzeitig dazu, dass ein plattformspezifischer Druckdialog +aufgerufen wird, der vom Anwender bestätigt werden muss. Bricht +der Anwender den Druckdialog ab, liefert getPrintJob +den Rückgabewert null. +Andernfalls wird der Drucker initialisiert und die Ausgabe kann beginnen. + +

+Die Klasse PrintJob +stellt einige Methoden zur Verfügung, die für den Ausdruck +benötigt werden: +

+ + + + + +
+ +
+public Graphics getGraphics()
+
+public Dimension getPageDimension()
+
+public int getPageResolution()
+
+public abstract void end()
+
+
+
+java.awt.PrintJob
+ +

+Die wichtigste von ihnen ist getGraphics. +Sie liefert den Devicekontext zur Ausgabe auf den Drucker. Der Rückgabewert +ist ein Objekt vom Typ PrintGraphics, +das aus Graphics +abgeleitet ist und wie ein normaler Devicekontext verwendet werden +kann (so, wie er beispielsweise auch an paint +übergeben wird). Mit Hilfe des von getGraphics +zurückgegebenen Devicekontexts können alle Grafik- und Textroutinen, +die auch in Graphics +zur Verfügung stehen, verwendet werden. Bezüglich der Verwendung +von Farben gilt scheinbar, dass diese bei den linienbezogenen Ausgaberoutinen +nicht unterstützt werden. Hier wird alles schwarz gezeichnet, +was nicht den Farbwert (255, 255, 255) hat. Im Gegensatz dazu +stellen die Füllfunktionen Farben (auf einem Schwarzweiß-Drucker) +als Grauwerte dar. Dabei kann - je nach Druckertyp - auch Weiß +eine Vollfarbe sein und dahinter liegende Objekte verdecken. + + + + +

26.2.2 Seitenweise Ausgabe

+ +

+Ein wichtiger Unterschied zu einem bildschirmbezogenen Devicekontext +besteht darin, dass jeder Aufruf von getGraphics +eine neue Druckseite beginnt. Die fertige Druckseite wird durch Aufruf +von dispose +an den Drucker geschickt. Für den Aufbau der Seite, das Ausgeben +von Kopf- oder Fußzeilen, die Seitennumerierung und ähnliche +Dinge ist die Anwendung selbst verantwortlich. Die Methode end +ist aufzurufen, wenn der Druckjob beendet ist und alle Seiten ausgegeben +wurden. Dadurch werden alle belegten Ressourcen freigegeben und die +Druckerschnittstelle geschlossen. +

+ + + + + + + + + + + +
+ +

+Bei der Druckausgabe ist es wichtig zu wissen, wie groß die +Abmessungen des Ausgabegeräts sind. Die hierzu angebotenen Methoden +getPageDimension +und getPageResolution +sind im JDK 1.1 leider vollkommen unbrauchbar. getPageResolution +liefert die tatsächliche Auflösung des Druckers in Pixel +per Zoll (also z.B. 600 für einen Laserjet IV), während +getPageDimension +die Anzahl der Pixel liefert, die sich errechnet, wenn man ein Blatt +Papier im US-Letter-Format (8,5 mal 11 Zoll) mit 72 dpi Auflösung +darstellen würde. Leider erfolgt die Druckausgabe nicht mit 72 +dpi, sondern in der aktuellen Bildschirmauflösung, wie sie von +der Methode getScreenResolution +der Klasse Toolkit +geliefert wird. Da diese typischerweise bei 120 dpi liegt, füllen +die von getPageResolution +gelieferten Abmessungen nur etwa 60 % einer Seite.

+ + + + +
 Warnung 
+
+ +

+Derzeit gibt es keine portable Lösung für dieses Problem. +Ein Workaround besteht darin, die Papiergröße als fest +anzunehmen (beispielsweise DIN A4 mit 21,0*29,7 cm), davon den nicht +bedruckbaren Rand abzuziehen, das Ergebnis durch 2,54 (Anzahl cm je +Zoll) zu teilen und mit der Auflösung von 120 dpi malzunehmen. +Wir werden später ein Beispiel sehen, in dem diese Technik angewandt +wird. Portabel ist sie allerdings nicht, denn das Programm muss Annahmen +über die Papier- und Randgröße machen. Es bleibt demnach +zu hoffen, dass die nachfolgenden Versionen des JDK die Bestimmung +der Abmessungen auf eine flexiblere Weise ermöglichen. +

+ + + + + + + + + + + +
+ +

+Durch die fixe Einstellung der Ausgabeauflösung ergibt sich ein +weiteres Problem. So kann ein Drucker mit 600 dpi aus Java heraus +nämlich nur mit der aktuellen Bildschirmauflösung (z.B. +120 dpi) angesteuert werden. Das bedeutet zwar nicht automatisch, +dass Schriften oder schräge Linien mit Treppenmustern dargestellt +werden, denn sie werden meist als Vektorgrafiken an den Drucker übergeben. +Allerdings können Pixelgrafiken beispielsweise nicht in der aktuellen +Druckerauflösung ausgegeben werden, denn die Positioniergenauigkeit +eines einzelnen Pixels liegt bei 120 dpi. Eine Lösung für +dieses Problem ist derzeit nicht bekannt.

+ + + + +
 Warnung 
+
+ + + + +

26.2.3 platzierung des Codes zur Druckausgabe

+ +

+Es gibt grundsätzlich zwei Möglichkeiten, die Druckausgabe +im Programm zu platzieren. Einmal kann die paint-Methode +dazu verwendet werden, sowohl Bildschirm- als auch Druckausgaben zu +realisieren. Bei einem Aufruf der Methode print +oder printAll +der Klasse Component +wird nämlich ein PrintJob +erstellt, daraus der Grafikkontext beschafft und an paint +übergeben: +

+ + + + + +
+ +
+public void print(Graphics g)
+
+public void printAll(Graphics g)
+
+
+
+java.awt.Component
+ +

+Auf diese Weise kann bereits ohne zusätzliche Erweiterungen eine +einfache Druckausgabe realisiert werden, die der Bildschirmausgabe +relativ ähnlich sieht. Im Gegensatz zu print +gibt printAll +dabei nicht nur die aktuelle Komponente, sondern die komplette Container-Hierarchie +eines komplexen Dialogs aus. Soll innerhalb von paint +zwischen Bildschirm- und Druckerausgabe unterschieden werden, kann +mit dem Ausdruck g instanceof PrintGraphics +das übergebene Graphics-Objekt +g auf Zugehörigkeit zur +Klasse PrintGraphics +getestet werden. + +

+Die zweite Möglichkeit, die Druckausgabe zu platzieren, besteht +darin, eine eigene Methode zu schreiben, die nur für die Ausgabe +auf den Drucker verantwortlich ist. Diese könnte zunächst +den PrintJob +und das PrintGraphics-Objekt +beschaffen und anschließend die Abmessungen der Ausgabefläche +wie zuvor besprochen bestimmen. Die Methode müsste dann nicht +so programmiert werden, dass sie für Bildschirm- und Druckausgabe +vernünftige Resultate liefert, sondern könnte ihre Ausgaben +ausschließlich für die Druckausgabe optimieren. Der Nachteil +bei dieser Löung ist natürlich, dass Programmcode zum Erstellen +der Ausgabe möglicherweise doppelt vorhanden ist und doppelt +gepflegt werden muss. + +

+Das nachfolgende Listing kombiniert beide Varianten und zeigt den +Ausdruck einer Testseite. Das Programm erstellt ein Hauptfenster und +ruft zwei Sekunden später die Methode printTestPage +zur Druckausgabe auf. Darin wird zunächst ein PrintJob +erzeugt und dann gemäß dem oben beschriebenen Verfahren +die Ausgabegröße ermittelt. Anschließend wird der +Grafikkontext beschafft und ein Rahmen, einige Textzeilen mit Angaben +zu den Metriken und eine Graustufenmatrix ausgegeben. Nach Ende der +Druckausgabe wird die Seite mit dispose +ausgegeben und der Druckjob mit end +geschlossen. Der Code für die Darstellung der Graustufenmatrix +wurde in der Methode paintGrayBoxes +implementiert und wird von der Bildschirm- und Druckausgabe gemeinsam +verwendet: + + +

+ + + + + +
+ +
+001 /* Listing2601.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 
+006 public class Listing2601
+007 extends Frame
+008 {
+009   public static void main(String[] args)
+010   {
+011     Listing2601 wnd = new Listing2601();
+012   }
+013 
+014   public Listing2601()
+015   {
+016     super("Drucken");
+017     addWindowListener(new WindowClosingAdapter(true));
+018     setBackground(Color.lightGray);
+019     setSize(400,400);
+020     setVisible(true);
+021     //Ausdruck in 2 Sekunden starten
+022     try {
+023       Thread.sleep(2000);
+024     } catch (InterruptedException e) {
+025       //nichts
+026     }
+027     printTestPage();
+028   }
+029 
+030   public void paint(Graphics g)
+031   {
+032     paintGrayBoxes(g, 40, 50);
+033   }
+034 
+035   public void printTestPage()
+036   {
+037     PrintJob pjob = getToolkit().getPrintJob(
+038       this,
+039       "Testseite",
+040       null
+041     );
+042     if (pjob != null) {
+043       //Metriken
+044       int pres = pjob.getPageResolution();
+045       int sres = getToolkit().getScreenResolution();
+046       Dimension d2 = new Dimension(
+047         (int)(((21.0 - 2.0) / 2.54) * sres),
+048         (int)(((29.7 - 2.0) / 2.54) * sres)
+049       );
+050       //Ausdruck beginnt
+051       Graphics pg = pjob.getGraphics();
+052       if (pg != null) {
+053         //Rahmen
+054         pg.drawRect(0, 0, d2.width, d2.height);
+055         //Text
+056         pg.setFont(new Font("TimesRoman",Font.PLAIN,24));
+057         pg.drawString("Testseite",40,70);
+058         pg.drawString(
+059           "Druckerauflösung : " + pres + " dpi",
+060           40,
+061           100
+062         );
+063         pg.drawString(
+064           "Bildschirmauflösung : " + sres + " dpi",
+065           40,
+066           130
+067         );
+068         pg.drawString(
+069           "Seitengröße : " + d2.width + " * " + d2.height,
+070           40,
+071           160
+072         );
+073         //Graustufenkästchen
+074         paintGrayBoxes(pg, 40, 200);
+075         //Seite ausgeben
+076         pg.dispose();
+077       }
+078       pjob.end();
+079     }
+080   }
+081 
+082   private void paintGrayBoxes(Graphics g, int x, int y)
+083   {
+084     for (int i = 0; i < 16; ++i) {
+085       for (int j = 0; j < 16; ++j) {
+086         int level = 16 * i + j;
+087         g.setColor(Color.black);
+088         g.drawRect(x + 20 * j, y + 20 * i, 20, 20);
+089         g.setColor(new Color(level, level, level));
+090         g.fillRect(x + 1 + 20 * j, y + 1 + 20 * i, 19, 19);
+091       }
+092     }
+093   }
+094 }
+
+
+Listing2601.java
+ +Listing 26.1: Ausdruck einer Testseite

+ +

+Die Bildschirmausgabe des Programms kann Abbildung 26.1 +entnommen werden. Die Druckausgabe sieht ähnlich aus, enthält +aber zusätzlich noch einen Rahmen und die Textausgabe mit den +Informationen zu den Druckmetriken. +

+ + +

+ +

+Abbildung 26.1: Das Programm zur Druckausgabe

+
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3