# Mehrseitiges Drucken - Book, Pageable, Printable?



## flashray (11. Februar 2006)

Hallo,

ich möchte einen String ausdrucken. Dazu habe ich aus dem "Sun SDK 1.2 Printing Tutorial" den Code aus "Listing 3: Using the print method: PrintText " als Basis genommen und einwenig abgeändert. Dieses Beispiel aus dem Tutorial ist eigentlich für das Drucken einer einzigen Seite gedacht. Habe leider noch keine genaue Idee, wie ich diesen für das ausdrucken mehrerer Seiten modifiziere.

Eines habe ich festgestellt: in der folgenden Zeile
while (measurer.getPosition() < charIterator.getEndIndex() )
durchläuft die Schleife den String bis zum Ende, egal ob es aus dem Druckbereich hinaus geht oder nicht. 
Eine Möglichkeit wäre die while-Schleife, dann abzubrechen wenn er den letzen char gedruckt hat, welche auf diese Seite noch Platz findet. Dessen index sollte dann in eine Variable gespeichert werden. So könnte ich für den Rest des Strings die Druckroutine nochmals aufrufen, und soweiter bis alles ausgedruckt ist.

Wie könnte ich festellen das ein bestimmter Schleifendurchgang die Zeile gedruckt hat welche auf die aktuelle Seite gerade noch passt um danach sofort die Schleife abzubrechen? Wenn das klappen würde könnte ich mit dem letzen Wert von measurer.getPosition() und substring() den Rest des ursprünglichen Strings nochmals zum Drucken weitergeben.

Noch eines, ist das das übliche Verfahren ein mehrseitiges Dokument aus einem String heraus zu drucken? Oder würdet Ihr da anders vorgehen?

Vg Erdal



```
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.*;
import java.text.*;

public class PrintText implements Printable {

	AttributedString mStyledText;
	
	PageFormat format;

	public PrintText(String text, Font font, PageFormat pageformat) {
		mStyledText = new AttributedString(text);
		mStyledText.addAttribute(TextAttribute.FONT, font);
		format = pageformat;
	}

	public void drucken() {
		PrinterJob printerJob = PrinterJob.getPrinterJob();
		
        Book book = new Book();
        book.append(this, format);
        
        printerJob.setPageable(book);

		boolean doPrint = printerJob.printDialog();
		if (doPrint) {
			try {
				printerJob.print();
			} catch (PrinterException exception) {
				System.err.println("Printing error: " + exception);
			}
		}
	}

	public int print(Graphics g, PageFormat format, int pageIndex) {
		if (pageIndex > 0)
			return Printable.NO_SUCH_PAGE;
		
		Graphics2D g2d = (Graphics2D) g;

		g2d.translate(format.getImageableX(), format.getImageableY());

		g2d.setPaint(Color.black);

		Point2D.Float pen = new Point2D.Float();
		AttributedCharacterIterator charIterator = mStyledText.getIterator();
		LineBreakMeasurer measurer = new LineBreakMeasurer(charIterator, g2d
				.getFontRenderContext());
		float wrappingWidth = (float) format.getImageableWidth();

		while (measurer.getPosition() < charIterator.getEndIndex() ) {
			TextLayout layout = measurer.nextLayout(wrappingWidth);
			pen.y += layout.getAscent();
			float dx = layout.isLeftToRight() ? 0 : (wrappingWidth - layout
					.getAdvance());

			layout.draw(g2d, pen.x + dx, pen.y);
			pen.y += layout.getDescent() + layout.getLeading();
		}
		return Printable.PAGE_EXISTS;
	}
}
```


----------



## elmato (11. Februar 2006)

Bin zwar gerade erst aufgestanden und noch nicht so ganz wach, aber hat Sun nicht eine neue Print Api (JPS)rausgebracht? SDK 1.2 hört sich ziemlich alt an...
schau mal hier http://www.torsten-horn.de/techdocs/java-print.htm und
hier http://java.sun.com/j2se/1.4.2/docs/guide/jps/ ,,
mfg
elmato


----------



## flashray (11. Februar 2006)

Hallo Elmato,

also das neue JPS ist auch nicht das wahre, was das drucken von Text angeht. Ich habe im folgenden drei Beispiele zusammengestellt, wovon zwei garnicht funktionieren bzw. nicht unterstüzt werden. Die Methode printTest1 druckt zwar, jedoch sind die umlaute falsch, als auch druckt er über den Seitenrand hinaus, noch beachtet er die Einstellung für Hoch- und Querformat.

In Methode zwei soll er aus einem Stream drucken, das klappt nicht. In Methode drei habe ich versucht einen String zu drucken, das schlug auch fehl.

Wie bereits schon gesagt funktioniert das Drucken mit Methode 1 aus einem URL mit den angegebenen Fehlern.

Fazit: Ich glaube jetzt, das es keine so gute Idee ist einen Text direkt zu drucken. Also muss ich doch über "Graphics" drucken. Schau ma mal ob ich das mathematisch hinbekomme einen formatierten String seitenweise zu splitten und an das Seitenformat passend mehrseitig zu drucken.

Vg Erdal



```
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;

public class PrintTest {

	public static void main(String[] args) {
		printTest_1();
		//printTest_2();
		//printTest_3();
	}

	public static void printTest_1() {
		DocFlavor printFlavor = DocFlavor.URL.AUTOSENSE;
		PrintService service = PrintServiceLookup.lookupDefaultPrintService();
		DocPrintJob job = service.createPrintJob();
		PrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
		set.add(MediaSizeName.ISO_A4);
		set.add(OrientationRequested.PORTRAIT);
		try {
			Doc doc = new SimpleDoc(new File("c:\\test.txt").toURL(),
					printFlavor, null);
			job.print(doc, set);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void printTest_2() {
		FileInputStream textStream = null ;
		try  {
			textStream = new FileInputStream("test.txt") ;
		} catch(FileNotFoundException ex)  {;}

		DocFlavor format = DocFlavor.INPUT_STREAM.TEXT_PLAIN_US_ASCII ; 
		Doc myDoc = new SimpleDoc(textStream, format, null) ;

		PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet() ;
		aset.add(MediaSizeName.ISO_A4) ;
		aset.add(OrientationRequested.PORTRAIT);

		PrintService[] services = PrintServiceLookup.lookupPrintServices(format, aset) ;

		if(services.length > 0)  {
			DocPrintJob job = services[0].createPrintJob() ;
			try  {
				job.print(myDoc, aset) ;
			} catch(PrintException ex)  {;}
		}
	}
	
	public static void printTest_3() {
		DocFlavor format = DocFlavor.STRING.TEXT_PLAIN ;
		Doc myDoc = new SimpleDoc("String", format, null) ;

		PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet() ;
		aset.add(MediaSizeName.ISO_A4) ;
		aset.add(OrientationRequested.PORTRAIT);
		
		PrintService[] services = PrintServiceLookup.lookupPrintServices(format, aset) ;

		if(services.length > 0)  {
			DocPrintJob job = services[0].createPrintJob() ;
			try  {
				job.print(myDoc, aset) ;
			} catch(PrintException ex)  {;}
		}
	}
}
```


----------



## elmato (11. Februar 2006)

leider habe ich nur einen Drucker mit eingetrockneter Patrone im Moment sonst würde ich es mal versuchen :/
tut mir leid...
wenn ich noch was finde melde ich mich..
edit:
vielleicht findest du hier was..
http://www.java2s.com/Code/Java/2D-Graphics-GUI/Print.htm


----------



## Romsl (11. Februar 2006)

Ich empfehle, um Papier und Tinte zu sparen, den Ausdruck in eine Datei umzuleiten ;-)


----------

