DGP - 1st printing
[debian/openrocket] / src / net / sf / openrocket / gui / print / PrintableFinSet.java
1 /*
2  * PrintableFinSet.java
3  */
4 package net.sf.openrocket.gui.print;
5
6 import net.sf.openrocket.rocketcomponent.FinSet;
7 import net.sf.openrocket.util.Coordinate;
8
9 import javax.swing.JPanel;
10 import java.awt.Color;
11 import java.awt.Graphics;
12 import java.awt.Graphics2D;
13 import java.awt.Image;
14 import java.awt.geom.GeneralPath;
15 import java.awt.image.BufferedImage;
16 import java.awt.print.PageFormat;
17 import java.awt.print.Printable;
18 import java.awt.print.PrinterException;
19
20 /**
21  * This class allows for a FinSet to be printable.  It does so by decorating an existing finset (which will not be
22  * modified) and rendering it within a JPanel.  The JPanel is not actually visualized on a display, but instead renders
23  * it to a print device.
24  */
25 public class PrintableFinSet extends JPanel implements Printable {
26
27     /**
28      * The actual fin set being printed.
29      */
30     private FinSet finset;
31
32     /**
33      * The object that represents the shape (outline) of the fin.  This gets drawn onto the Swing component.
34      */
35     private GeneralPath polygon = null;
36
37     /**
38      * The margin.
39      */
40     private final int margin = 20;
41     
42     /**
43      * Constructor.
44      *
45      * @param fs the finset to print
46      */
47     public PrintableFinSet (FinSet fs) {
48         super(false);
49         finset = fs;
50         init();
51         setBackground(Color.white);
52     }
53
54     /**
55      * Initialize the fin set polygon and set the size of the component.
56      */
57     private void init () {
58         Coordinate[] points = finset.getFinPointsWithTab();
59
60         polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
61         polygon.moveTo(0, 0);
62         
63         int minX = 0;
64         int minY = 0;
65         int maxX = 0;
66         int maxY = 0;
67
68         for (Coordinate point : points) {
69             final long x = PrintUnit.METERS.toPoints(point.x);
70             final long y = PrintUnit.METERS.toPoints(point.y);
71             minX = (int) Math.min(x, minX);
72             minY = (int) Math.min(y, minY);
73             maxX = (int) Math.max(x, maxX);
74             maxY = (int) Math.max(y, maxY);
75             polygon.lineTo(x, y);
76         }
77         polygon.closePath();
78         
79         setSize(maxX-minX+ margin, maxY-minY+ margin);
80     }
81
82     /**
83      * From the java.awt.print.Printable interface.
84      * 
85      * Prints the page at the specified index into the specified {@link java.awt.Graphics} context in the specified
86      * format. A <code>PrinterJob</code> calls the <code>Printable</code> interface to request that a page be rendered
87      * into the context specified by <code>graphics</code>.  The format of the page to be drawn is specified by
88      * <code>pageFormat</code>.  The zero based index of the requested page is specified by <code>pageIndex</code>. If
89      * the requested page does not exist then this method returns NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. The
90      * <code>Graphics</code> class or subclass implements the {@link java.awt.print.PrinterGraphics} interface to
91      * provide additional information.  If the <code>Printable</code> object aborts the print job then it throws a
92      * {@link java.awt.print.PrinterException}.
93      *
94      * @param graphics   the context into which the page is drawn
95      * @param pageFormat the size and orientation of the page being drawn
96      * @param pageIndex  the zero based index of the page to be drawn
97      *
98      * @return PAGE_EXISTS if the page is rendered successfully or NO_SUCH_PAGE if <code>pageIndex</code> specifies a
99      *         non-existent page.
100      *
101      * @throws java.awt.print.PrinterException
102      *          thrown when the print job is terminated.
103      */
104     @Override
105     public int print (final Graphics graphics, final PageFormat pageFormat, final int pageIndex)
106             throws PrinterException {
107
108         Graphics2D g2d = (Graphics2D) graphics;
109         PrintUtilities.translateToJavaOrigin(g2d, pageFormat);
110         PrintUtilities.disableDoubleBuffering(this);
111         paint(g2d);
112         PrintUtilities.enableDoubleBuffering(this);
113         return Printable.PAGE_EXISTS;
114     }
115
116     /**
117      * 
118      * Returns a generated image of the fin set.  May then be used wherever AWT images can be used, or
119      * converted to another image/picture format and used accordingly.
120      * 
121      * @return an awt image of the fin set
122      */
123     public Image createImage () {
124         int width = getWidth();
125         int height = getHeight();
126         // Create a buffered image in which to draw 
127         BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
128         // Create a graphics contents on the buffered image 
129         Graphics2D g2d = bufferedImage.createGraphics();
130         // Draw graphics 
131         g2d.setBackground(Color.white);
132         g2d.clearRect(0, 0, width, height);
133         paintComponent(g2d);
134         // Graphics context no longer needed so dispose it 
135         g2d.dispose();
136         return bufferedImage;
137     }
138
139     /**
140      * Render the fin set onto the graphics context.  This is done by creating a GeneralPath component that follows the
141      * outline of the fin set coordinates to create a polygon, which is then drawn onto the graphics context.
142      * Through-the-wall fin tabs are supported if they are present.
143      *
144      * @param g the Java2D graphics context
145      */
146     @Override
147     public void paintComponent (Graphics g) {
148         super.paintComponent(g);
149         Graphics2D g2d = (Graphics2D) g;
150
151         g2d.translate(margin +5, margin +15);
152         g2d.setPaint(TemplateProperties.getFillColor());
153         g2d.fill(polygon);
154         g2d.setPaint(TemplateProperties.getLineColor());
155         g2d.draw(polygon);
156     }
157
158 }