# Problem mit PageFormat beim Drucken



## MegaTefyt (27. Apr 2006)

Moin, ich habe folgendes Problem: ich benutze unten stehende Klasse zum Drucken von sehr großen JPanels. Das ganze klappt auch eigentlich ganz gut, ich benutze einfach *PrintUtilities.printComponent(labelPanel);* und er druckt das ganze JPanel auf mehrere Seiten, die ich dann für ein großes Bild zusammen legen kann. Im aufgehenden Druckerdialog kann ich dann auch den Drucker wählen und er druckt an der richtigen Schnittstelle (echter Drucker oder PDF-Datei). Allerdings tut sich nichts, wenn ich das Seitenformat ändere. Also ob ich nun Hoch- oder Querformat wähle, oder A4, A3, A2 oder sonstwas, das Teil druckt immer in der Einstellung "Letter" (also "Brief") mit ziemlich breitem Rand. Wenn ich danach noch mit dem PrintJob einen pageDialog aufmache, dann hat er auch die eingestellten Formatoptionen drinne, also speichern tut er sie irgendwie. Aber das PageFormat scheints nicht zu kümmern, denn das hat immer die gleichen Werte (bei pf.getImageableWidth() z.B.), egal welches Format ich einstelle. Selbst wenn ich testweise versuche mit pf.getPaper.setImageableBlahblah die Werte zu manipulieren bleiben sie gleich.

Kennt wer das Problem, bzw. was mache ich falsch? Nochmal in kurz: es funktioniert alles, bis auf das Einstellen des Seitenformats, PageFormat hat immer irgendwelche Standardwerte.



```
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.RepaintManager;
 
public class PrintUtilities implements Printable {
	
	private Component componentToBePrinted;
	
	public static void printComponent(Component _c) {
		new PrintUtilities(_c).print();
	}
  
	public PrintUtilities(Component _componentToBePrinted) {
		componentToBePrinted = _componentToBePrinted;
	}
 
	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 pf, int pageIndex) {
		int response = NO_SUCH_PAGE;
		
		Graphics2D g2 = (Graphics2D) g;
 
		disableDoubleBuffering(componentToBePrinted);
		
		Dimension d = componentToBePrinted.getSize();
		double panelWidth = d.width;
		double panelHeight = d.height;
		
		double pageHeight = pf.getImageableHeight();
		double pageWidth = pf.getImageableWidth();
		
		int linePages = (int)Math.ceil(panelWidth / pageWidth);
		int rowPages = (int)Math.ceil(panelHeight / pageHeight);
		
		
		int totalNumPages = linePages * rowPages;  
 
		if (pageIndex >= totalNumPages) {
			response = NO_SUCH_PAGE;
		} else {
 
			g2.translate(pf.getImageableX(), pf.getImageableY());
 
 
			g2.translate(-(pageIndex % linePages) * pageWidth, -((pageIndex / linePages) % rowPages) * pageHeight);
			
			componentToBePrinted.paint(g2);
			enableDoubleBuffering(componentToBePrinted);
			response = Printable.PAGE_EXISTS;
		}
		return response;
	}
 
 
	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);
	}
	
}
```
[/code]


----------



## Nova (7. Jun 2006)

Schöne Klasse!
Hab schon länger sowas gesucht aber nix hat funktioniert, schon gar nicht mehrseitig HTML drucken...

Falls es für dich noch interessant ist, ich hab die print-Methode etwas abgeändert und hardcodiert die Papiergröße vorgegeben:

```
public void print() {
      PrinterJob printJob = PrinterJob.getPrinterJob();
      Paper paper = new Paper();
      paper.setSize(595.0,841.0);
      paper.setImageableArea(60.0,40.0,495.0,761.0);
      PageFormat pf = new PageFormat();
      pf.setPaper(paper);
      printJob.setPrintable(this,pf);
      
      if (printJob.printDialog()){
         try {
            printJob.print();
         } catch(PrinterException pe){
            System.out.println("Error printing: " + pe);
         }
      }
   }
```

Scheinbar muss man die Papiergröße vorher angeben, keine Ahnung warum er die Einstellungen im Dialog ignoriert?!?
Wenn es wichtig ist das man das im Dialog einstellen kann könnte man eventuell einen neuen printJob aufmachen und dem die "Paper-Daten" der ersten beim erstellen übergeben (so wie ich es hardcodiert übergeben habe)?!?
Was mir aufgefallen ist:
Wenn ich übers Netzwerk drucken dauert es ca.20 Sekunden bis der Druckdialog da ist, führe ich das Programm an dem Rechner an dem der Drucker angeschlossen ist aus geht das in 1 Sekunde (obwohl dieser PC viel langsamer ist 750MHz<=>2200MHz). Das ist bei anderen Programmen nicht so, da merke ich keinen Unterschied.
Die CPU-Auslastung ist während dieser 20 Sekunden praktisch 0, was tut er also in der Zeit? Kommunikation mit dem Drucker?!? (=> eventuell werde da schon irgendwelche Einstellungen übertragen?!?)


Das drucken in Java ist echt noch stark verbesserungswürdig, genauso wie die HTML-Darstellung/HTML Parser (Darstellung nicht optimal und EXTREM langsam).


mfg
Christian


----------



## ulr!ch (27. Aug 2007)

@ MegaTefyt
echt coole Klasse! Merci

Für nachfolgende Generationen: Bei mir gab's Probleme bei der Bestimmung der Anzahl zu druckender Seite. Wenn man statt ceil floor schreibt, funktioniert's aber wunderbar!


----------

