PrinterJob.getPageFormat() funktioniert nicht

hansmueller

Bekanntes Mitglied
Hallo,

ich habe ein PrintRequestAttributeSet() und möchte daraus ein PageFormat haben.
Wenn ich die Api richtig verstehe geht das mit PrinterJob.getPageFormat(PrintRequestAttributeSet).
Aber diese Methode liefert mir anscheinend immer nur ein Standard-PageFormat.
Die Angaben bzgl. des Druckbereichs werden immer ignoriert.

Hier ein kleines Beispielprogramm:
Java:
import java.awt.Graphics;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;


public class MainProg
{
	PrinterJob Druckjob;
	PrintRequestAttributeSet aset;

	PageFormat Seitenformat;
	
	Book buch = null;
	
	public static void main(String[] args)
	{
		MainProg x = new MainProg();	
	}
	
	public MainProg()
	{
		Druckjob = PrinterJob.getPrinterJob();
		aset = new HashPrintRequestAttributeSet();
		
		aset.add(MediaSizeName.ISO_A4);
		// aset.add(new MediaPrintableArea(20, 20, 170, 257, MediaPrintableArea.MM));
		
		aset.add(new MediaPrintableArea(10, 15, 190, 272, MediaPrintableArea.MM));
		//aset.add(new MediaPrintableArea(25, 15, 175, 272, MediaPrintableArea.MM));
		aset.add(OrientationRequested.PORTRAIT);
		// aset.add(PrintQuality.NORMAL);
		// aset.add(Chromaticity.MONOCHROME);

		//Seitenformat = Druckjob.getPageFormat(aset);//Funktioniert so nicht???
		
		boolean ok = Druckjob.printDialog(aset);
						
		Seitenformat = Druckjob.getPageFormat(aset);//Funktioniert so nicht???
		
						
		buch = new Book();
		
		buch.append(new IrgendwaszumDrucken(), Seitenformat);
		
		Druckjob.setPageable(buch);
		
		MediaPrintableArea mpa = (MediaPrintableArea)aset.get(MediaPrintableArea.class);
		System.out.println(mpa);
		
		System.out.println(Seitenformat.getImageableX());
		System.out.println(Seitenformat.getImageableY());
		System.out.println(Seitenformat.getImageableWidth());
		System.out.println(Seitenformat.getImageableHeight());	

		/*if (ok)
		{
			try
			{
				Druckjob.print(aset);
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
			}
		}*/	
	}
	
		
	class IrgendwaszumDrucken implements Printable
	{
		@Override
		public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
		{			
			return 0;
		}
	}
}

Weiß jemand von euch, wie ich an das richtige PageFormat-Objekt komme?
Kann es sein, daß das MediaPrintableArea aus irgend einem Grund nicht berücksichtigt wird?

Ursprünglich habe ich zuerst mit der Kombination PrinterJob.pageDialog(PageFormat page) und PrinterJob.printDialog() gearbeitet. Den kombinierten Dialog von PrinterJob.printDialog(PrintRequestAttributeSet attributes) finde ich allerdings eleganter und daher wollte ich meine ursprüngliche Druckmethode umstellen. Deshalb sieht das Beispielprogramm vielleicht etwas merkwürdig aus.

MfG
hansmueller
 
Hallo Hans,

das [c]PageFormat[/c] ist ja in deinem Fall anscheinend für jede Seite identisch. Von daher könnten wir statt mit einem [c]Pageable[/c] auch einfach nur mit einem [c]Printable[/c] arbeiten. Das [c]PageFormat[/c] wird dann automatisch als Parameter an die Methode [c]print(Graphics graphics, PageFormat pageFormat, int pageIndex) [/c] übergeben und ist dort frei verfügbar.

Gruß,
André
 
Hallo André,

statt mit einem Pageable auch einfach nur mit einem Printable arbeiten

Tut mir leid, aber da kann ich dir jetzt nicht ganz folgen. Könntest du mir da ein Beispiel posten?

Ich befürchte aber, daß mir das allerdings nicht viel helfen wird, denn ich brauche die Höhe und Weite des Druckbereichs (in Pixel) bevor die print-Methode ausgeführt wird. (Die Werte werden für die Berechnung des Seitenumbruchs benötigt.)
Mein Code-Beispiel mit
Code:
buch.append(new IrgendwaszumDrucken(), Seitenformat);
ist nur eine Vereinfachung, damit das Beispielprogramm funktioniert. Tatsächlich spielen hier nicht nur eine Klasse
Code:
IrgendwaszumDrucken()
eine Rolle, sondern mehrere verschiedene Klassen zusammen. Und diese Klassen sind (leider) so aufgebaut, daß sie die Druckbreite und Druckhöhe als Integerwert brauchen. Das ganze ist ziehmlich kompliziert geraten wegen der Berechnung des Seitenumbruchs.

MfG
hansmueller
 
Hallo André,

danke für den Link. Leider ist es zu aufwendig meinen bestehenden Code an das Beispiel anzupassen bzw. das Beispiel entsprechend zu erweitern. Aber trotzdem nochmals Danke.

Ich glaube ich habe inzwischen eine funktionierende Lösung gefunden:
Java:
import java.awt.Graphics;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;


public class MainProg
{
	PrinterJob Druckjob;
	PrintRequestAttributeSet aset;

	PageFormat Seitenformat;
	
	Book buch = null;
	
	public static void main(String[] args)
	{
		MainProg x = new MainProg();	
	}
	
	public MainProg()
	{
		Druckjob = PrinterJob.getPrinterJob();
		aset = new HashPrintRequestAttributeSet();
		
		aset.add(MediaSizeName.ISO_A4);
		// aset.add(new MediaPrintableArea(20, 20, 170, 257, MediaPrintableArea.MM));
		
		aset.add(new MediaPrintableArea(10, 15, 190, 272, MediaPrintableArea.MM));
		//aset.add(new MediaPrintableArea(25, 15, 175, 272, MediaPrintableArea.MM));
		aset.add(OrientationRequested.PORTRAIT);
		// aset.add(PrintQuality.NORMAL);
		// aset.add(Chromaticity.MONOCHROME);

		//Seitenformat = Druckjob.getPageFormat(aset);//Funktioniert so nicht richtig, es fehlt der Druckbereich
		
		boolean ok = Druckjob.printDialog(aset);
						
		Seitenformat = Druckjob.getPageFormat(aset);//Funktioniert so nicht richtig, es fehlt der Druckbereich
			
		
		//Dem PageFormat fehlen die Informationen für den Druckbereich.
		//Die anderen Infos wie z. B. MediaSize scheinen jedoch korrekt übernommen zu werden.
		//Daher wird der Druckbereich manuell in das PageFormat geschrieben:
		if(aset.containsKey(MediaPrintableArea.class))
		{			
			MediaPrintableArea mpa = (MediaPrintableArea) aset.get(MediaPrintableArea.class);
			
			//Pro Inch werden 72 Pixel gemalt. Daher wird der Inchwert mal 72 genommen.
			
			double mpax = (double) (mpa.getX(MediaPrintableArea.INCH) * 72);
			double mpay = (double) (mpa.getY(MediaPrintableArea.INCH) * 72);
			double mpawidth = (double) (mpa.getWidth(MediaPrintableArea.INCH) * 72);
			double mpaheight = (double) (mpa.getHeight(MediaPrintableArea.INCH) * 72);
			
			Paper papier = Seitenformat.getPaper();			
			
			papier.setImageableArea(mpax, mpay, mpawidth, mpaheight);			
			
			Seitenformat.setPaper(papier);
		}
		
		//Nur zum Vergleichen:
		//MediaSize ms = MediaSize.getMediaSizeForName(MediaSizeName.ISO_A4);
		//System.out.println(ms.getSize(MediaPrintableArea.INCH)[0] * 72);
		//System.out.println(ms.getSize(MediaPrintableArea.INCH)[1] * 72);
				
		buch = new Book();
		
		buch.append(new IrgendwaszumDrucken(), Seitenformat);
		
		Druckjob.setPageable(buch);
		
		MediaPrintableArea mpa = (MediaPrintableArea)aset.get(MediaPrintableArea.class);
		System.out.println(mpa);
				
		System.out.println(Seitenformat.getWidth());
		System.out.println(Seitenformat.getHeight());
		
		System.out.println(Seitenformat.getImageableX());
		System.out.println(Seitenformat.getImageableY());
		System.out.println(Seitenformat.getImageableWidth());
		System.out.println(Seitenformat.getImageableHeight());		
				
		/*if (ok)
        {
            try
            {
                Druckjob.print(aset);
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
        }*/
	}
	
		
	class IrgendwaszumDrucken implements Printable
	{
		@Override
		public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
		{			
			return 0;
		}
	}
}

Da dem PageFormat anscheinend nur die Werte für den Druckbereich fehlen, füge ich diese sozusagen nachträglich noch von Hand ein. (Siehe oben.)

Da ich die double-Werte für den Druckbereich sowieso nach int caste, sind evtl. Ungenauichkeiten nach der xten Stelle nach dem Komma zu vernachlässigen.

Somit kann ich dann schon mit den Werte arbeiten, bevor die print-Methode aufgeführt wird.

Falls jemand einen Fehler entdeckt, oder eine bessere Lösung hat - immer her damit.

MfG
hansmueller
 

Zurück
Oben