stringWidth bei Graphics von JPanel und Printer unterschiedl

Status
Nicht offen für weitere Antworten.
K

Kipard

Gast
Hallo Forum,

ich schreibe an einem Programm, das in erste Linie einen Datensatz ausdrucken soll. Dazu möchte ich diesen Datensatz also Vorschau (über ein JPanel) anzeigen. Der Benutzer kann dann noch ein paar Optionen wählen und letztlich diesen Datensatz ausdrucken. Ich verwende eine Menge von Linien und Textblöcken, die ich auf ein Graphics2D Objekt zeichne. Bisher klappt das auch ganz gut, ich kann entweder auf ein Graphics eines JPanels malen (als Vorschau) oder auf das Graphics eines Druckers (um das Dokument tatsächlich auszudrucken). Leider stelle ich nun fest, dass die Methode FontMetrics.stringwidth("irgendeinTest") - unterschiedliche Längeninformationen zurück gibt. Die Schriftart und größe hab ich nicht verändern, ich vermute es liegt an den unterschiedlichen Graphics Objekten.
Nun zu meiner Frage: wie kann ich dafür sorgen, dass stringwidth für beide Graphics-Objekte dieselbe Information zurück gibt? Denn wenn sich Vorschau und Druck doch unterscheiden macht das ganze keinen Sinn.

Hier mein Minimalbeispiel. Zuerst wird das Dokument auf einem Drucker ausgegeben, danach (wenn man auf den entsprechenden Knopf clickt) wird es auf ein JPanel gezeichnet.

======= Dokument ========

Code:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

public class Dokument implements Printable {
	public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
		this.paint(g);
		return PAGE_EXISTS;
	}
	
	public void paint(Graphics g) {
		g.setFont(new Font("Arial", Font.PLAIN, 12));
		System.err.println(g.getFontMetrics().stringWidth("Hallo Welt"));
	}
}


======== GUI ===========
Code:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.lang.reflect.InvocationTargetException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends JFrame {
	private static final long serialVersionUID = 112787250344916458L;
	public static JFrame frame;
	public static JPanel z;
	
	public static void main(String[] args) throws InterruptedException, InvocationTargetException {
		javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
            	createAndShowGUI();
            }
        });		
		
		Book book = new Book();
		PrinterJob printJob = PrinterJob.getPrinterJob();
		PrintService private_druckerObjekt = null;
		
		//richtigen Drucker festlegen
		try {
			PrintServiceAttributeSet aset = new HashPrintServiceAttributeSet();
		    PrintService[] colorServices = PrintServiceLookup.lookupPrintServices(null, aset);
		    for (int i = 0; i < colorServices.length; i++) {
		    	if (colorServices[i].getName().equals("Win2PDF")) {
		    		private_druckerObjekt = colorServices[i];
		    		i = colorServices.length; //zum vorzeitigen Beenden der Schleife
		    	}
		    }
		    printJob.setPrintService(private_druckerObjekt);
	    } catch (PrinterException e) {
	    	System.err.println("Druckerfehler");	
	    }
		
	    
	    printJob.setJobName("test");
		PageFormat documentPageFormat = printJob.defaultPage();
		Paper papier = documentPageFormat.getPaper();
		papier.setImageableArea(0, 0, papier.getWidth(), papier.getHeight());
		documentPageFormat.setPaper(papier);
		
		book.append(new Dokument(), documentPageFormat);
		printJob.setPageable(book);
		try {
			printJob.print();
		} catch (PrinterException e) {
			e.printStackTrace();
		}
	}
	
	private static void createAndShowGUI() {
		JFrame.setDefaultLookAndFeelDecorated(true);
		frame = new JFrame("test");
		
		JButton laden = new JButton("testen!");
		ActionListener eventLaden = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Dokument d = new Dokument();
				d.paint(z.getGraphics());
			}
		};
		laden.addActionListener(eventLaden);
		
		frame.setSize(500, 600);
        frame.setLayout(new BorderLayout());
		frame.add(laden, BorderLayout.NORTH);
		
		//Display the window.
        frame.pack();
        frame.setVisible(true);
    }
}


Ich hoffe irgendwer kann mir jetzt sagen ich muss irgendein RenderingHint oder sonst was setzen, damit sich beide Graphics Objekte gleich verhalten. Im Moment bin ich ein bischen verzweifelt, denn ich finde keine brauchbare Hilfe im Netz.

Vielen Dank schon im Voraus,
Stefan
 

Marco13

Top Contributor
Hm - kann's grad nicht testen (hab keinen Drucker und kein Win2PDF...) aber in der Doku zu stringWidth steht da so ein bißchen laberabarber, von wegen "vielleicht doch lieber http://java.sun.com/j2se/1.4.2/docs/api/java/awt/FontMetrics.html#getStringBounds(java.lang.String,%20java.awt.Graphics) " verwenden... hast du das schon getestet?
 
G

Guest

Gast
Hi Marco13,
schon mal vielen Dank für Deinen ersten Hilfsversuch. Um das klar zu stellen, das Problem ist unabhängig vom gewählten Drucker. Dass ich da jetzt "Win2PDF" drin stehen habe ist reiner Zufall. Da kann jeder andere installierte Drucker stehen.
Mir fällt auf, dass mein Beispiel zwei Fehler enthält:
1. in der GUI Klasse hab ich vergessen das JPanel zu initialisieren, Zeile 21 sollte besser
Code:
public static JPanel z = new JPanel();
lauten und
2. hab ich vergessen das Panel auf das Frame zu adden: Man füge unter Zeile 80
Code:
frame.add(z,BorderLayout.CENTER);
ein. Beides ändert aber nichts am grundlegenden Problem.

Die Idee mit getStringBounds verhält sich ähnlich komisch wie stringWidth. Hier der Output:
Printer: java.awt.geom.Rectangle2D$Float[x=0.0,y=-11.05957,w=54.600002,h=13.798828]
JPanel: java.awt.geom.Rectangle2D$Float[x=0.0,y=-11.05957,w=56.0,h=13.798828]

Es gibt also weiterhin eine Diskrepanz zwsichen der Textlänge des Panels und des Druckers. Wie kann ich diese ausgleichen?
 

Marco13

Top Contributor
Hmja, ich hatte es gestartet, und nach ein bißchen tweaken "funktionierte" es auch, allerdings zeigt er bei mir eben beide male "55" als breite an... falls sich niemand meldet, versuch' ich morgen vielleicht nochmal, den Fehler wirklich zu reproduzieren...
 
K

Kipard

Gast
Ich habe nun folgenden RenderingHint hinzugefügt:
Code:
RenderingHints fractionalMetricON = new RenderingHints(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
internesG.setRenderingHints(fractionalMetricON);
Dadurch wird die Diskrepanz immerhin schon auf ein erträgliches Maß gesenkt, auch wenn es noch nicht exakt derselbe Wert der StringWidth für Printer und Panel ist.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Hashmap mit 2D Graphics Spiele- und Multimedia-Programmierung 7
FunnyO Graphics fillOval weiche Kanten Spiele- und Multimedia-Programmierung 8
kaoZ Graphics Objekt liefert null Spiele- und Multimedia-Programmierung 14
S Graphics Objekt weiterreichen? Spiele- und Multimedia-Programmierung 4
Steev Eigener Graphics-Context Spiele- und Multimedia-Programmierung 10
S Graphics.drawString (Graphics2D.drawString) Y-Problem Spiele- und Multimedia-Programmierung 4
G Wie bekomme ich einen Punkt (Graphics) Spiele- und Multimedia-Programmierung 2
P Graphics Klasse Spiele- und Multimedia-Programmierung 3
N Performance Problem bei mit Graphics Spiele- und Multimedia-Programmierung 6
V Graphics oder Graphics2D Zeichenfunktion gesucht? Spiele- und Multimedia-Programmierung 4
G Einen gif oder jpg Datei aus einem Graphics Objekt o. JFrame Spiele- und Multimedia-Programmierung 2
O transparente farbe in Image mit Graphics Spiele- und Multimedia-Programmierung 8
G Graphics bei Java aufteilen Spiele- und Multimedia-Programmierung 3
C Graphics 2D Zeichnen Spiele- und Multimedia-Programmierung 4
F einzelne Polygone(Graphics) schneller als and. Fig. zeichnen Spiele- und Multimedia-Programmierung 3
R JPanel wird erst im Fullscreen angezeigt Spiele- und Multimedia-Programmierung 1
P selectedItem aus einem Methodenerstellten JPanel auslesen. Spiele- und Multimedia-Programmierung 5
M JPanel mit Graphics2D Objekten mit JScrollpane Spiele- und Multimedia-Programmierung 6
K JPanel wechseln & Neu starten - SnakeSpiel Spiele- und Multimedia-Programmierung 2
A paintComponent in JPanel in JFrame Spiele- und Multimedia-Programmierung 7
N JPanel Inhalt aktualisiert nach Thread.sleep nicht Spiele- und Multimedia-Programmierung 2
S Thread und jpanel-paintcomponent kombinierbar?? Spiele- und Multimedia-Programmierung 14
E Animiertes JPanel dynamisch wechseln Spiele- und Multimedia-Programmierung 3
W Panel/JPAnel createImage() Exception Spiele- und Multimedia-Programmierung 2
R Probleme mit JPanel!KeyListener geht nicht Spiele- und Multimedia-Programmierung 6
T Problem bei LinkedList / JPanel Spiele- und Multimedia-Programmierung 4
C 2D Sprites an die JPanel Größe (Auflösung) anpassen/skalieren Spiele- und Multimedia-Programmierung 3
F Vektorgrafik in JPanel Spiele- und Multimedia-Programmierung 5
E Active Rendering im FSEM auf ein JPanel? Spiele- und Multimedia-Programmierung 4
L 2D-Spiele ruckeln auf JPanel Spiele- und Multimedia-Programmierung 7
A Mehrere geometrische Objekte in JPanel zeichnen Spiele- und Multimedia-Programmierung 4
X JPanel dynamisch (Koordinatensystem)? Spiele- und Multimedia-Programmierung 30
M Jpanel Graphik speichern Spiele- und Multimedia-Programmierung 6
DamienX Canvas vs JPanel Spiele- und Multimedia-Programmierung 15
S Problem mit JPanel bzw p a i n t Spiele- und Multimedia-Programmierung 6
R SimpleUniverse in JPanel Spiele- und Multimedia-Programmierung 4
M 1. Menüleiste wird doppelt gezeichnet 2. awt auf ein jpanel Spiele- und Multimedia-Programmierung 4
M Jpanel mit Keylistener Spiele- und Multimedia-Programmierung 6
D 2D Graphic Objekte in ein JPanel einfügen Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben