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);
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 drawVerticalRule(g2, false, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
84 drawHorizontalRule(g2, true, !inchOutSide, x, y + width, width, 0, 0, div * 5, div * 10);
89 * Draw a horizontal ruler.
91 * @param g the graphics context
92 * @param vertexAtLeft true if the horizontal/vertical vertex is oriented to the top
93 * @param drawTicksDown true if the ruler should draw interval tick marks to the underside of the solid ruler line
94 * @param x starting x position of the ruler
95 * @param y starting y position of the rule
96 * @param length the number of points in length to extend the vertical ruler
97 * @param tinyEveryX the number of points for each tiny division tick line; if zero or negative tiny will not be
99 * @param minorEveryX the number of points for each minor division tick line; if zero or negative minor will not
101 * @param midMajorEveryX the number of points for each mid-major division tick line
102 * @param majorEveryX the number of points for each major division tick line (this is typically the inch or cm
103 * distance in points).
105 private void drawHorizontalRule(Graphics2D g,
106 boolean vertexAtLeft,
107 boolean drawTicksDown,
108 int x, int y, int length,
111 double midMajorEveryX,
112 double majorEveryX) {
114 //Draw solid horizontal line
115 g.setColor(Color.black);
116 g.drawLine(x, y, x + length, y);
118 int tiniest = drawTicksDown ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
119 int minor = drawTicksDown ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
120 int mid = drawTicksDown ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
121 int major = drawTicksDown ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
123 //Draw vertical rule ticks for the horizontal ruler
126 int end = initial + length;
127 double increment = tinyEveryX;
128 boolean lessThanEqual = true;
130 initial = x + length;
132 lessThanEqual = false;
135 if (tinyEveryX > 0) {
137 increment = -1 * increment;
139 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
140 g.drawLine((int) xtick, y, (int) xtick, y + tiniest);
144 if (minorEveryX > 0) {
146 increment = -1 * minorEveryX;
149 increment = minorEveryX;
151 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
152 g.drawLine((int) xtick, y, (int) xtick, y + minor);
156 //Draw mid-major ticks
157 if (midMajorEveryX > 0) {
159 increment = -1 * midMajorEveryX;
162 increment = midMajorEveryX;
164 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
165 g.drawLine((int) xtick, y, (int) xtick, y + mid);
169 increment = -1 * majorEveryX;
172 increment = majorEveryX;
175 for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
176 g.drawLine((int) xtick, y, (int) xtick, y + major);
182 * Draw a vertical ruler.
184 * @param g the graphics context
185 * @param vertexAtTop true if the horizontal/vertical vertex is oriented to the top
186 * @param drawTicksRight true if the ruler should draw interval tick marks to the right side of the solid ruler
188 * @param x starting x position of the ruler
189 * @param y starting y position of the rule
190 * @param length the number of points in length to extend the vertical ruler
191 * @param tinyEveryY the number of points for each tiny division tick line; if zero or negative tiny will not be
193 * @param minorEveryY the number of points for each minor division tick line; if zero or negative minor will not
195 * @param midMajorEveryY the number of points for each mid-major division tick line
196 * @param majorEveryY the number of points for each major division tick line (this is typically the inch or cm
197 * distance in points).
199 private void drawVerticalRule(Graphics2D g,
201 boolean drawTicksRight, int x, int y, int length,
204 double midMajorEveryY,
205 double majorEveryY) {
207 int tiniest = drawTicksRight ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
208 int minor = drawTicksRight ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
209 int mid = drawTicksRight ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
210 int major = drawTicksRight ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
212 //Draw solid vertical line
213 g.setColor(Color.black);
214 g.drawLine(x, y, x, y + length);
216 //Draw horizontal rule ticks for the vertical ruler
219 int end = initial + length;
220 double increment = tinyEveryY;
221 boolean lessThanEqual = true;
223 initial = y + length;
225 lessThanEqual = false;
228 if (tinyEveryY > 0) {
230 increment = -1 * increment;
232 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
233 g.drawLine(x, (int) tick, x - tiniest, (int) tick);
238 if (minorEveryY > 0) {
240 increment = -1 * minorEveryY;
243 increment = minorEveryY;
245 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
246 g.drawLine(x, (int) tick, x - minor, (int) tick);
250 //Draw mid-major ticks
252 increment = -1 * midMajorEveryY;
255 increment = midMajorEveryY;
257 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
258 g.drawLine(x, (int) tick, x - mid, (int) tick);
263 increment = -1 * majorEveryY;
266 increment = majorEveryY;
268 for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
269 g.drawLine(x, (int) tick, x - major, (int) tick);