Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
DRUCKEN von z.B. eines JFrame über print(Graphics g)
bitte entschuldigt ein neues Thema zum drucken, jedoch blicke ich wirklich gar nciht durch. Bislang war drucken bei uns nie ein Thema nun ist es jedoch aktuell und muss dringend zeitnah gelöst werden.
Ich habe mich mit den Tutorials bei Sun bereits rumgeschlagen. Dort wird jedoch bei JFrames einfach eine Funktion print() ohne Attribute angesprochen welche nicht (mehr?!) existiert.
Insgesamt sind alle Tutorials die ich fand total inkonsistent, sodass ich keinerlei Übersicht mehr habe was aktuell ist und was nicht.
Die Methode benötigt ja ein Graphics Objekt für den Drucker Zugriff.
Meine Frage:
Was ist denn aktuell die gängige Variante dazu? Ein Code Beispiel oder ein Link zu einem aktuellen und kompletten Beispiel wäre auch toll.
Ich habe echt noch nie so viel, und doch so wenig brauchbares zu einem Java API Thema gefunden. Total frustrierend.
Nach wie vor die Frage nach einem verständlichen und aktuellen Tutorial zum Thema. Habe gesehen, dass das Thema Drucken aus der Insel inzwischen komplett verschwunden ist. Früher war das da doch mal drin oder?
Ich hab übers Wochenende doch noch ein interessantes Beispiel zum Thema gefunden. Hier der Quellcode:
Java:
import java.awt.Component;
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.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.RepaintManager;
/**
* A simple utility class that lets you very simply print an arbitrary
* component. Just pass the component to the PrintUtilities.printComponent. The
* component you want to print doesn't need a print method and doesn't have to
* implement any interface or do anything special at all.
*
*
*
* If you are going to be printing many times, it is marginally more efficient
* to first do the following:
*
* <PRE>
* PrintUtilities printHelper = new PrintUtilities(theComponent);
* </PRE>
*
* then later do printHelper.print(). But this is a very tiny difference, so in
* most cases just do the simpler
* PrintUtilities.printComponent(componentToBePrinted).
*
* @author kaf9tr
*
*/
public class PrintUtilities implements Printable {
private Component componentToBePrinted;
public static void printComponent(Component c) {
new PrintUtilities(c).print();
}
public PrintUtilities(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
PageFormat pf = printJob.pageDialog(aset);
printJob.setPrintable(this, pf);
if (printJob.printDialog())
try {
printJob.print();
} catch (PrinterException pe) {
System.out.println("Error printing: " + pe);
}
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if (pageIndex > 0) {
return (NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
double scale = (pageFormat.getImageableWidth() / componentToBePrinted.getWidth());
g2d.scale(scale, scale);
disableDoubleBuffering(componentToBePrinted);
componentToBePrinted.paint(g2d);
enableDoubleBuffering(componentToBePrinted);
return (PAGE_EXISTS);
}
}
/**
* The speed and quality of printing suffers dramatically if any of the
* containers have double buffering turned on. So this turns if off
* globally.
*
* @see enableDoubleBuffering
*/
public static void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
/** Re-enables double buffering globally. */
public static void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
}
Das funktioniert soweit super, allerdings hänge ich noch an folgendem:
Ich möchte, dass die Component so gedruckt wird, als wäre vorher pack ausgeführt worden. Hintergrund ist, dass einige von mir zu druckende Components (JPanels) größer sind als sie sein müssen (Durch die Größe des Fensters ect.). Im Ausdruck sind dann ebenfalls die zu größen Flächen drin. Wenn die Component jedoch nicht komplett dargestellt wird wird sie auch nicht komplett gedruckt.
Mein Problem ist also, dass die Component genauso gedruckt wird wie sie dargestellt wird (Es wird ja auch paint(g) aufgerufen).
Weiss jemand wie man das so erweitern kann, dass die Conmponent immer in genau der Größe gedruckt wird die sie bräuchte? Die Skalierung soll natürlich bleiben.
Ich dachte zuerst daran die paint Methode zu wrappen. Das funktionierte jedoch nicht gut, da ich deren intere Abläufe nicht gut genug kenne.
Es kann nur gezeichnet und gedruckt werden was existiert. Entweder Du rufst vor dem Drucken pack() auf dem JFrame auf und setzt anschließend die Größe wieder zurück, oder Du erstellts einen "Klon" mit identischem Inhalt auf dem Du vor dem Drucken pack() aufrufst.
Es kann nur gezeichnet und gedruckt werden was existiert. Entweder Du rufst vor dem Drucken pack() auf dem JFrame auf und setzt anschließend die Größe wieder zurück, oder Du erstellts einen "Klon" mit identischem Inhalt auf dem Du vor dem Drucken pack() aufrufst.
Ich setze vor dem Print Befehl die Size auf die Preferred Size. Skaliere dann auf die mögliche Größe und führe nach dem Print ein Revalidate aus. Dadurch wird das Panel dann wieder so groß wie es sein muss.
- Das aktuellste Tutorial ist tatsächlich das von Oracel/Sun.
- Drucken ist wirklich sau aufwendig (außer eine Swing Component hat schon eine Print Funktion. AFAIK haben das aber nur Textkomponenten. Wirklich schön ist auch anders)
- Ich habe es so gelöst, dass mein Panel das Interface Printable implementiert und den Printerjob anlegt.
- Layouting muss man selber machen
- Scaling auch
In meinem Fall habe ich das JPanel nun erst mal auf die Preferred Size gestezt, damit alles gedruckt wird (sonst wird nur der sichtbare Teil gedruckt). Dann das Graphics Objekt skaliert damit alles auf die Seite passt und dann einen paint auf dem JPanel ausgeführt (mit dem graphics Objekt). Hinterher die Resizings wieder Rückgängig gemacht damits in der GUI aussieht wie zuvor.
Wer dann noch will kann natürlich Kopf und Fußzeilen anlegen. Muss man aber auch alles zu Fuß machen.
Wer nähere Fragen hat kann mir gerne auch ne PM schreiben.