# Drucken von JPanel mit richtiger Skalierung



## Eule (7. Nov 2011)

Guten Tag Forum,

ich beschreibe mal kurz mein Problem ohne Code:

Ich möchte ein JPanel drucken in welchem 6 Diagramme plaziert sind. Die Anordnung ist in 3 Zeilen und 2 Spalten aufgteilt. Das Diagramm habe ich mit der paint() Methode selbst geschrieben, welche sich das Raster und den Start+Endwert in Abhängigkeit von der Breite des Panels. 
Drucke ich jetzt ein Diagramm alleine, also übergebe ihn das Graphics g und lass ihn darauf schreiben, passt er sich perfekt der Größe der Din A4 Seite an und setzt das Raster richtig. Anders ist jedoch, wenn ich das JPanel drucke: Dort ist alles total verzerrt was sich in der Art äußert, dass die momentane Größe des JPanel genommen und der Rest auf der rechten Seite trotzdem noch mit rein gequetscht wird.


Kann jemand mein Problem verstehen, oder muss ich ein Beispiel zusammenprogrammieren? Wäre nicht ganz einfach.

Danke schon mal
Eule


----------



## André Uhres (7. Nov 2011)

Eule hat gesagt.:


> Beispiel zusammenprogrammieren? Wäre nicht ganz einfach.



Hallo Eule,

versuch's mal mit folgendem Beispiel. Zum Skalieren benutzen wir die Methode 
	
	
	
	





```
Graphics2D#scale
```
:


```
import java.awt.*;
import java.awt.print.*;
import java.util.logging.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import javax.swing.*;

public class PrintDemo {

    private final ChartsPanel charts;
    private PrintRequestAttributeSet attr;

    public PrintDemo() {
        JFrame f = new JFrame("PrintDemo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 400);
        f.setLocationRelativeTo(null);
        charts = new ChartsPanel();
        f.add(charts);
        f.setVisible(true);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                print();
            }
        });
    }

    private void print() {
        PrinterJob pjob = PrinterJob.getPrinterJob();
        pjob.setPrintable(charts);
        charts.setScale(2);
        // create an attribute set to store attributes from the print dialog
        if (attr == null) {
            attr = new HashPrintRequestAttributeSet();
            attr.add(OrientationRequested.PORTRAIT);
            attr.add(MediaSizeName.ISO_A4);
            MediaSize mediaSize = MediaSize.ISO.A4;
            float mediaWidth = mediaSize.getX(Size2DSyntax.MM);
            float mediaHeight = mediaSize.getY(Size2DSyntax.MM);
            attr.add(new MediaPrintableArea(10, 10, mediaWidth - 20, mediaHeight - 20, Size2DSyntax.MM));
        }
        if (pjob.printDialog(attr)) {
            try {
                pjob.print(attr);
            } catch (final PrinterException ex) {
                Logger.getLogger("log").log(Level.SEVERE, null, ex);
            }
        }

    }

    public static void main(final String... args) {
        Runnable gui = new Runnable() {

            @Override
            public void run() {
                PrintDemo printDemo = new PrintDemo();
            }
        };
        SwingUtilities.invokeLater(gui);

    }

    private static class ChartsPanel extends JPanel implements Printable {

        private double scale = 1.0d;//scale factor for printing

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            for (int column = 0; column < 2; column++) {
                for (int row = 0; row < 3; row++) {
                    g.drawRect(10 + column * 100 + column * 10, 10 + row * 100 + row * 10, 100, 100);
                }
            }
        }

        public void setScale(final double scale) {
            this.scale = scale;
        }

        @Override
        public int print(final Graphics graphics, final PageFormat pageFormat, final int pageIndex) throws PrinterException {
            if (pageIndex > 0) {
                return NO_SUCH_PAGE;
            }
            Graphics2D g2d = (Graphics2D) graphics;
            g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
            g2d.scale(scale, scale);
            print(graphics);
            return PAGE_EXISTS;
        }
    }
}
```
Gruß,
André


----------



## Eule (8. Nov 2011)

Hallo André,

danke schon mal für deinen Beitrag. Allerdings ist #scale nicht das was ich suche, da es nur die aktuell angezeigte Größe skaliert. Im Anhang sind zwei Screenshots der PDFs die zeigen was ich meine (ich weiß nicht wie ich das in den Text hier einbaue, deswegen im Anhang).

Bei dem einen Diagramm, wurde es gedruckt, als das Fenster groß war. Das Resultat sind viele Unterlienen und gut zu lesende Schrift. Bei dem anderen Diagramm hingegen wurde das Fenster ganz klein gemacht und dann gedruckt. Die Anzahl der Unterlinien haben sich der Fenstergröße angepasst, wurden jedoch durch das skalieren einfach nur groß gezogen.

Drucke ich ein Diagramm alleine, also übergebe das graphics2D nur dem Diagramm, dann wird es auch immer richtig skaliert (ohne scale zu benutzen):

```
printPanel.paint(g)
```

Füge ich jedoch mehrere Diagramme zu einem JPanel hinzu, wird der Abstand anscheinend nicht aufgeteilt, was mich schon wundert. Dazu der Screenshot mit dem 4 Diagrammen in dem JPanel. Dort war auf dem Bildschirum alles gleichmäßig verteilt. Erstellt habe ich das JPanel ganz normal


```
JPanel div6Panel = new JPanel();
div6Panel.setLayout(new GridLayout(2,2));

Chart Antenna1Panel = new Chart();
Chart Antenna2Panel = new Chart();
Chart Antenna3Panel = new Chart();
Chart Antenna4Panel = new Chart();

div6Panel.add(Antenna1Panel);
div6Panel.add(Antenna2Panel);
div6Panel.add(Antenna3Panel);
div6Panel.add(Antenna4Panel);
```


----------



## André Uhres (9. Nov 2011)

Ach so, ich dachte Du hättest nur ein einziges Panel mit sechs Charts. Das sieht ja jetzt so aus, als hättest Du vier Panels mit jeweils nur einem einzigen Chart? Die fügst Du dann mit GridLayout in ein Hauptpanel ein? Und Du druckst das Hauptpanel? Und wenn du nur ein einziges Chart drucken willst, fügst Du sein Panel auch ins Hauptpanel ein und druckst das Hauptpanel? Und wenn Du nicht skalierst, wird das Skalieren vom Drucker gemacht?
??

Gruß,
André


----------



## Eule (9. Nov 2011)

Ups. Entschuldigung für die Verwirrung. Es ist schon so richtig, wie du es in deinem ersten Satz gesagt hast:

Ich habe ein Panel in dem ich direkt 4 (im Prinzip beliebig viele) Diagramme einfüge. Das Panel drucke ich dann aus. der Name Panel ist etwas blöd gewählt, jedoch habe ich die Diagramme von JPanel abgeleitet. 

Möchte ich nur ein Chart drucken, habe ich das testweise direkt gemacht, also ohne es vorher in ein Panel einzufügen. So wird es dann auch richtig skaliert.


----------



## André Uhres (9. Nov 2011)

Ist mir immer noch nicht ganz klar. Am besten Du zeigst etwas mehr Code von Deinen Klassen und Methoden, sowie davon, wie Du druckst. Ich fürchte, sonst reden wir hier aneinander vorbei . Alternativ könntest Du vielleicht mein Beispiel so ausbauen, dass es deinem Programm ungefähr entspricht.

Gruß,
André


----------

