bed1fdf9ddaeb476912cd469a50b55533a39fef8
[debian/openrocket] / core / 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.*;
10 import java.awt.*;
11 import java.awt.geom.GeneralPath;
12 import java.awt.image.BufferedImage;
13 import java.awt.print.PageFormat;
14 import java.awt.print.Printable;
15 import java.awt.print.PrinterException;
16
17 /**
18  * This class allows for a FinSet to be printable.  It does so by decorating an existing finset (which will not be
19  * modified) and rendering it within a JPanel.  The JPanel is not actually visualized on a display, but instead renders
20  * it to a print device.
21  */
22 public class PrintableFinSet extends PrintableComponent {
23
24     /**
25      * The object that represents the shape (outline) of the fin.  This gets drawn onto the Swing component.
26      */
27     protected GeneralPath polygon = null;
28
29     /**
30      * The X margin.
31      */
32     private final int marginX = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
33     /**
34      * The Y margin.
35      */
36     private final int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
37     /**
38      * The minimum X coordinate.
39      */
40     private int minX = 0;
41     /**
42      * The minimum Y coordinate.
43      */
44     private int minY = 0;
45
46     /**
47      * Constructor.
48      *
49      * @param fs the finset to print
50      */
51     public PrintableFinSet (FinSet fs) {
52         this(fs.getFinPointsWithTab());
53     }
54
55     /**
56      * Construct a fin set from a set of points.
57      *
58      * @param points an array of points.
59      */
60     public PrintableFinSet (Coordinate[] points) {
61         //super(false);
62         init(points);
63         //setBackground(Color.white);
64     }
65
66     /**
67      * Initialize the fin set polygon and set the size of the component.
68      *
69      * @param points an array of points.
70      */
71     private void init (Coordinate[] points) {
72
73         polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
74         polygon.moveTo(0, 0);
75
76         int maxX = 0;
77         int maxY = 0;
78
79         for (Coordinate point : points) {
80             final long x = PrintUnit.METERS.toPoints(point.x);
81             final long y = PrintUnit.METERS.toPoints(point.y);
82             minX = (int) Math.min(x, minX);
83             minY = (int) Math.min(y, minY);
84             maxX = (int) Math.max(x, maxX);
85             maxY = (int) Math.max(y, maxY);
86             polygon.lineTo(x, y);
87         }
88         polygon.closePath();
89
90         setSize(maxX - minX, maxY - minY);
91     }
92
93     /**
94      * Get the X-axis margin value.
95      *
96      * @return margin, in points
97      */
98     protected double getMarginX () {
99         return marginX;
100     }
101
102     /**
103      * Get the Y-axis margin value.
104      *
105      * @return margin, in points
106      */
107     protected double getMarginY () {
108         return marginY;
109     }
110
111     /**
112      * Returns a generated image of the fin set.  May then be used wherever AWT images can be used, or converted to
113      * another image/picture format and used accordingly.
114      *
115      * @return an awt image of the fin set
116      */
117     public Image createImage () {
118         int width = getWidth() + marginX;
119         int height = getHeight() + marginY;
120         // Create a buffered image in which to draw 
121         BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
122         // Create a graphics contents on the buffered image 
123         Graphics2D g2d = bufferedImage.createGraphics();
124         // Draw graphics 
125         g2d.setBackground(Color.white);
126         g2d.clearRect(0, 0, width, height);
127         paintComponent(g2d);
128         // Graphics context no longer needed so dispose it 
129         g2d.dispose();
130         return bufferedImage;
131     }
132
133     /**
134      * Render the fin set onto the graphics context.  This is done by creating a GeneralPath component that follows the
135      * outline of the fin set coordinates to create a polygon, which is then drawn onto the graphics context.
136      * Through-the-wall fin tabs are supported if they are present.
137      *
138      * @param g the Java2D graphics context
139      */
140     @Override
141     public void paintComponent(Graphics g) {
142         Graphics2D g2d = (Graphics2D) g;
143
144         int x = 0;
145         int y = 0;
146
147         // The minimum X/Y can be negative (primarily only Y due to fin tabs; rarely (never) X, but protect both anyway).
148         if (minX < marginX) {
149             x = marginX + Math.abs(minX);
150         }
151         if (minY < marginY) {
152             y = marginY + Math.abs(minY);
153         }
154         // Reset the origin.
155         g2d.translate(x + getOffsetX(), y + getOffsetY());
156         g2d.setPaint(TemplateProperties.getFillColor());
157         g2d.fill(polygon);
158         g2d.setPaint(TemplateProperties.getLineColor());
159         g2d.draw(polygon);
160     }
161 }