1 package net.sf.openrocket.gui.print.components;
3 import net.sf.openrocket.gui.print.PrintUnit;
4 import net.sf.openrocket.gui.print.PrintableComponent;
8 import java.awt.Graphics;
9 import java.awt.Graphics2D;
12 * This class creates a Swing ruler. The ruler has both vertical and horizontal rules, as well as divisions for both
13 * inches and centimeters.
15 public class Rule extends PrintableComponent {
17 public static enum Orientation {
22 public static final int TINIEST_TICK_LENGTH = 3;
23 public static final int MINOR_TICK_LENGTH = 6;
24 public static final int MID_MAJOR_TICK_LENGTH = 9;
25 public static final int MAJOR_TICK_LENGTH = 14;
27 private Orientation orientation;
32 * @param theOrientation defines if the horizontal ruler should be on the top or bottom; the vertical is always
35 public Rule(Orientation theOrientation) {
36 orientation = theOrientation;
37 int dim = (int) PrintUnit.INCHES.toPoints(2) + 32;
42 * Render the component onto a graphics context.
44 * @param g the opaque graphics context
46 public void paintComponent(Graphics g) {
47 Graphics2D g2 = (Graphics2D) g;
49 double div = PrintUnit.INCHES.toPoints(1) / 8; //1/8 inch increment
50 final int width = (int) PrintUnit.INCHES.toPoints(2);
53 boolean inchOutSide = true;
55 g2.translate(getOffsetX(), getOffsetY());
57 if (orientation == Orientation.TOP) {
59 g.setFont(f.deriveFont(f.getSize() - 2f));
60 g.drawString("in cm", x - MAJOR_TICK_LENGTH, y + width + 20);
61 g.drawString("in", x + width + 4, y + 4);
62 g.drawString("cm", x + width + 4, y + 18);
65 drawVerticalRule(g2, true, inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
66 drawHorizontalRule(g2, true, !inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
67 div = PrintUnit.MILLIMETERS.toPoints(1); //mm increment
68 drawVerticalRule(g2, true, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
69 drawHorizontalRule(g2, true, inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
73 g.setFont(f.deriveFont(f.getSize() - 2f));
74 g.drawString("in cm", x - MAJOR_TICK_LENGTH, y);
75 g.drawString("cm", x + width + 6, y + width + 4);
76 g.drawString("in", x + width + 6, y + width + 18);
79 //Draw Inches first, with 1/2", 1/4", and 1/8" tick marks.
80 drawVerticalRule(g2, false, inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
81 drawHorizontalRule(g2, true, inchOutSide, x, y + width, width, 0, div * 2, div * 4, div * 8);
82 div = PrintUnit.MILLIMETERS.toPoints(1); //mm increment
83 //Draw cm (10mm) and 1/2 cm (5mm) marks
84 drawVerticalRule(g2, false, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
85 drawHorizontalRule(g2, true, !inchOutSide, x, y + width, width, 0, 0, div * 5, div * 10);
90 * Draw a horizontal ruler.
92 * @param g the graphics context
93 * @param vertexAtLeft true if the horizontal/vertical vertex is oriented to the top
94 * @param drawTicksDown true if the ruler should draw interval tick marks to the underside of the solid ruler line
95 * @param x starting x position of the ruler
96 * @param y starting y position of the rule
97 * @param length the number of points in length to extend the vertical ruler
98 * @param tinyEveryX the number of points for each tiny division tick line; if zero or negative tiny will not be
100 * @param minorEveryX the number of points for each minor division tick line; if zero or negative minor will not
102 * @param midMajorEveryX the number of points for each mid-major division tick line
103 * @param majorEveryX the number of points for each major division tick line (this is typically the inch or cm
104 * distance in points).
106 private void drawHorizontalRule(Graphics2D g,
107 boolean vertexAtLeft,
108 boolean drawTicksDown,
109 int x, int y, int length,
112 double midMajorEveryX,
113 double majorEveryX) {
115 //Draw solid horizontal line
116 g.setColor(Color.black);
117 g.drawLine(x, y, x + length, y);
119 int tiniest = drawTicksDown ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
120 int minor = drawTicksDown ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
121 int mid = drawTicksDown ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
122 int major = drawTicksDown ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
124 //Draw vertical rule ticks for the horizontal ruler
127 int end = initial + length;
128 double increment = tinyEveryX;
129 boolean lessThanEqual = true;
131 initial = x + length;
133 lessThanEqual = false;
136 if (tinyEveryX > 0) {
138 increment = -1 * increment;
140 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
141 g.drawLine((int) xtick, y, (int) xtick, y + tiniest);
145 if (minorEveryX > 0) {
147 increment = -1 * minorEveryX;
150 increment = minorEveryX;
152 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
153 g.drawLine((int) xtick, y, (int) xtick, y + minor);
157 //Draw mid-major ticks
158 if (midMajorEveryX > 0) {
160 increment = -1 * midMajorEveryX;
163 increment = midMajorEveryX;
165 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
166 g.drawLine((int) xtick, y, (int) xtick, y + mid);
170 increment = -1 * majorEveryX;
173 increment = majorEveryX;
176 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
177 g.drawLine((int) xtick, y, (int) xtick, y + major);
183 * Draw a vertical ruler.
185 * @param g the graphics context
186 * @param vertexAtTop true if the horizontal/vertical vertex is oriented to the top
187 * @param drawTicksRight true if the ruler should draw interval tick marks to the right side of the solid ruler
189 * @param x starting x position of the ruler
190 * @param y starting y position of the rule
191 * @param length the number of points in length to extend the vertical ruler
192 * @param tinyEveryY the number of points for each tiny division tick line; if zero or negative tiny will not be
194 * @param minorEveryY the number of points for each minor division tick line; if zero or negative minor will not
196 * @param midMajorEveryY the number of points for each mid-major division tick line
197 * @param majorEveryY the number of points for each major division tick line (this is typically the inch or cm
198 * distance in points).
200 private void drawVerticalRule(Graphics2D g,
202 boolean drawTicksRight, int x, int y, int length,
205 double midMajorEveryY,
206 double majorEveryY) {
208 int tiniest = drawTicksRight ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
209 int minor = drawTicksRight ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
210 int mid = drawTicksRight ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
211 int major = drawTicksRight ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
213 //Draw solid vertical line
214 g.setColor(Color.black);
215 g.drawLine(x, y, x, y + length);
217 //Draw horizontal rule ticks for the vertical ruler
220 int end = initial + length;
221 double increment = tinyEveryY;
222 boolean lessThanEqual = true;
224 initial = y + length;
226 lessThanEqual = false;
229 if (tinyEveryY > 0) {
231 increment = -1 * increment;
233 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
234 g.drawLine(x, (int) tick, x - tiniest, (int) tick);
239 if (minorEveryY > 0) {
241 increment = -1 * minorEveryY;
244 increment = minorEveryY;
246 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
247 g.drawLine(x, (int) tick, x - minor, (int) tick);
251 //Draw mid-major ticks
253 increment = -1 * midMajorEveryY;
256 increment = midMajorEveryY;
258 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
259 g.drawLine(x, (int) tick, x - mid, (int) tick);
264 increment = -1 * majorEveryY;
267 increment = majorEveryY;
269 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
270 g.drawLine(x, (int) tick, x - major, (int) tick);