2 * PartsDetailVisitorStrategy.java
4 package net.sf.openrocket.gui.print.visitor;
6 import com.itextpdf.text.BadElementException;
7 import com.itextpdf.text.Chunk;
8 import com.itextpdf.text.Document;
9 import com.itextpdf.text.DocumentException;
10 import com.itextpdf.text.Element;
11 import com.itextpdf.text.Font;
12 import com.itextpdf.text.Image;
13 import com.itextpdf.text.Phrase;
14 import com.itextpdf.text.Rectangle;
15 import com.itextpdf.text.pdf.PdfPCell;
16 import com.itextpdf.text.pdf.PdfPTable;
17 import com.itextpdf.text.pdf.PdfWriter;
18 import net.sf.openrocket.gui.main.ComponentIcons;
19 import net.sf.openrocket.gui.print.ITextHelper;
20 import net.sf.openrocket.gui.print.PrintUtilities;
21 import net.sf.openrocket.gui.print.PrintableFinSet;
22 import net.sf.openrocket.material.Material;
23 import net.sf.openrocket.rocketcomponent.BodyComponent;
24 import net.sf.openrocket.rocketcomponent.BodyTube;
25 import net.sf.openrocket.rocketcomponent.Coaxial;
26 import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
27 import net.sf.openrocket.rocketcomponent.ExternalComponent;
28 import net.sf.openrocket.rocketcomponent.FinSet;
29 import net.sf.openrocket.rocketcomponent.FreeformFinSet;
30 import net.sf.openrocket.rocketcomponent.InnerTube;
31 import net.sf.openrocket.rocketcomponent.LaunchLug;
32 import net.sf.openrocket.rocketcomponent.MassObject;
33 import net.sf.openrocket.rocketcomponent.NoseCone;
34 import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
35 import net.sf.openrocket.rocketcomponent.RingComponent;
36 import net.sf.openrocket.rocketcomponent.RocketComponent;
37 import net.sf.openrocket.rocketcomponent.Stage;
38 import net.sf.openrocket.rocketcomponent.Transition;
39 import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
40 import net.sf.openrocket.unit.Unit;
41 import net.sf.openrocket.unit.UnitGroup;
42 import net.sf.openrocket.util.Coordinate;
44 import javax.swing.ImageIcon;
45 import java.io.IOException;
46 import java.text.NumberFormat;
47 import java.util.Collection;
51 * A visitor strategy for creating documentation about parts details.
53 public class PartsDetailVisitorStrategy extends BaseVisitorStrategy {
56 * The number of columns in the table.
58 private static final int TABLE_COLUMNS = 7;
61 * The parts detail is represented as an iText table.
66 * Construct a strategy for visiting a parts hierarchy for the purposes of collecting details on those parts.
68 * @param doc The iText document
69 * @param theWriter The direct iText writer
70 * @param theStagesToVisit The stages to be visited by this strategy
72 public PartsDetailVisitorStrategy (Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit) {
73 super(doc, theWriter, theStagesToVisit);
74 PrintUtilities.addText(doc, PrintUtilities.BIG_BOLD, "Parts Detail");
81 public void visit (final Stage visitable) {
86 document.add(ITextHelper.createPhrase(visitable.getName()));
87 grid = new PdfPTable(TABLE_COLUMNS);
88 grid.setWidthPercentage(100);
89 grid.setHorizontalAlignment(Element.ALIGN_LEFT);
91 catch (DocumentException e) {
94 RocketComponent[] rc = visitable.getChildren();
103 public void visit (final ExternalComponent visitable) {
104 grid.addCell(iconToImage(visitable));
105 grid.addCell(createNameCell(visitable.getName(), true));
107 grid.addCell(createMaterialCell(visitable.getMaterial()));
108 grid.addCell(ITextHelper.createCell());
109 grid.addCell(createLengthCell(visitable.getLength()));
110 grid.addCell(createMassCell(visitable.getMass()));
112 RocketComponent[] rc = visitable.getChildren();
120 public void visit (final BodyComponent visitable) {
121 grid.addCell(visitable.getName());
123 RocketComponent[] rc = visitable.getChildren();
131 public void visit (final RingComponent visitable) {
132 grid.addCell(iconToImage(visitable));
133 grid.addCell(createNameCell(visitable.getName(), true));
134 grid.addCell(createMaterialCell(visitable.getMaterial()));
135 grid.addCell(createOuterDiaCell(visitable));
136 grid.addCell(createLengthCell(visitable.getLength()));
137 grid.addCell(createMassCell(visitable.getMass()));
139 RocketComponent[] rc = visitable.getChildren();
147 public void visit (final InnerTube visitable) {
148 grid.addCell(iconToImage(visitable));
149 final PdfPCell pCell = createNameCell(visitable.getName(), true);
151 grid.addCell(createMaterialCell(visitable.getMaterial()));
152 grid.addCell(createOuterDiaCell(visitable));
153 grid.addCell(createLengthCell(visitable.getLength()));
154 grid.addCell(createMassCell(visitable.getMass()));
156 RocketComponent[] rc = visitable.getChildren();
164 public void visit (final LaunchLug visitable) {
165 grid.addCell(iconToImage(visitable));
166 grid.addCell(createNameCell(visitable.getName(), true));
168 grid.addCell(createMaterialCell(visitable.getMaterial()));
169 grid.addCell(createOuterDiaCell(visitable));
170 grid.addCell(createLengthCell(visitable.getLength()));
171 grid.addCell(createMassCell(visitable.getMass()));
178 public void visit (final Transition visitable) {
179 grid.addCell(iconToImage(visitable));
180 grid.addCell(createNameCell(visitable.getName(), true));
181 grid.addCell(createMaterialCell(visitable.getMaterial()));
183 Chunk fore = new Chunk("Fore Dia: " + appendLength(visitable.getForeRadius() * 2));
184 fore.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
185 Chunk aft = new Chunk("Aft Dia: " + appendLength(visitable.getAftRadius() * 2));
186 aft.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
187 final PdfPCell cell = ITextHelper.createCell();
188 cell.addElement(fore);
189 cell.addElement(aft);
191 grid.addCell(createLengthCell(visitable.getLength()));
192 grid.addCell(createMassCell(visitable.getMass()));
194 RocketComponent[] rc = visitable.getChildren();
202 public void visit (final RadiusRingComponent visitable) {
203 grid.addCell(iconToImage(visitable));
204 grid.addCell(createNameCell(visitable.getName(), true));
205 grid.addCell(createMaterialCell(visitable.getMaterial()));
206 grid.addCell(createOuterDiaCell(visitable));
207 grid.addCell(createLengthCell(visitable.getLength()));
208 grid.addCell(createMassCell(visitable.getMass()));
209 RocketComponent[] rc = visitable.getChildren();
217 public void visit (final MassObject visitable) {
218 PdfPCell cell = ITextHelper.createCell();
219 cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
220 cell.setPaddingBottom(12f);
222 grid.addCell(iconToImage(visitable));
223 final PdfPCell nameCell = createNameCell(visitable.getName(), true);
224 nameCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
225 nameCell.setPaddingBottom(12f);
226 grid.addCell(nameCell);
230 grid.addCell(createMassCell(visitable.getMass()));
231 RocketComponent[] rc = visitable.getChildren();
239 public void visit (final NoseCone visitable) {
240 grid.addCell(iconToImage(visitable));
241 grid.addCell(createNameCell(visitable.getName(), true));
242 grid.addCell(createMaterialCell(visitable.getMaterial()));
243 grid.addCell(ITextHelper.createCell(visitable.getType().getName(), PdfPCell.BOTTOM));
244 grid.addCell(createLengthCell(visitable.getLength()));
245 grid.addCell(createMassCell(visitable.getMass()));
246 RocketComponent[] rc = visitable.getChildren();
254 public void visit (final BodyTube visitable) {
255 grid.addCell(iconToImage(visitable));
256 grid.addCell(createNameCell(visitable.getName(), true));
257 grid.addCell(createMaterialCell(visitable.getMaterial()));
258 grid.addCell(createOuterDiaCell(visitable));
259 grid.addCell(createLengthCell(visitable.getLength()));
260 grid.addCell(createMassCell(visitable.getMass()));
261 RocketComponent[] rc = visitable.getChildren();
269 public void visit (final TrapezoidFinSet visitable) {
270 visitFins(visitable);
277 public void visit (final EllipticalFinSet visitable) {
278 visitFins(visitable);
285 public void visit (final FreeformFinSet visitable) {
286 visitFins(visitable);
293 public void close () {
299 catch (DocumentException e) {
304 private PdfPCell createOuterDiaCell (final Coaxial visitable) {
305 PdfPCell result = new PdfPCell();
306 Phrase p = new Phrase();
308 result.setVerticalAlignment(Element.ALIGN_TOP);
309 result.setBorder(Rectangle.BOTTOM);
310 Chunk c = new Chunk();
311 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
316 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.SMALL_FONT_SIZE));
321 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
322 c.append(" " + appendLength(visitable.getOuterRadius() * 2));
324 createInnerDiaCell(visitable, result);
325 result.addElement(p);
329 private void createInnerDiaCell (final Coaxial visitable, PdfPCell cell) {
330 Phrase p = new Phrase();
332 Chunk c = new Chunk();
333 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
338 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.SMALL_FONT_SIZE));
343 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
344 c.append(" " + appendLength(visitable.getInnerRadius() * 2));
349 private void visitFins (FinSet visitable) {
352 java.awt.Image awtImage = new PrintableFinSet(visitable).createImage();
354 Collection<Coordinate> x = visitable.getComponentBounds();
357 img = Image.getInstance(writer, awtImage, 0.25f);
359 catch (BadElementException e) {
362 catch (IOException e) {
366 grid.addCell(iconToImage(visitable));
367 grid.addCell(createNameCell(visitable.getName() + " (" + visitable.getFinCount() + ")", true));
368 grid.addCell(createMaterialCell(visitable.getMaterial()));
369 grid.addCell(ITextHelper.createCell("Thick: " + appendLength(visitable.getThickness()), PdfPCell.BOTTOM));
370 final PdfPCell pCell = new PdfPCell();
371 pCell.setBorder(Rectangle.BOTTOM);
372 pCell.addElement(img);
374 grid.addCell(ITextHelper.createCell());
375 grid.addCell(createMassCell(visitable.getMass()));
377 RocketComponent[] rc = visitable.getChildren();
381 protected PdfPCell createLengthCell (double length) {
382 return ITextHelper.createCell("Len: " + appendLength(length), PdfPCell.BOTTOM);
385 protected PdfPCell createMassCell (double mass) {
386 return ITextHelper.createCell("Mass: " + appendMass(mass), PdfPCell.BOTTOM);
389 protected PdfPCell createNameCell (String v, boolean withIndent) {
390 PdfPCell result = new PdfPCell();
391 result.setBorder(Rectangle.BOTTOM);
392 Chunk c = new Chunk();
393 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
395 for (int x = 0; x < (level - 2) * 10; x++) {
400 result.setColspan(2);
401 result.addElement(c);
405 protected PdfPCell createMaterialCell (Material material) {
406 PdfPCell cell = ITextHelper.createCell();
407 cell.setLeading(13f, 0);
409 Chunk c = new Chunk();
410 c.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.NORMAL_FONT_SIZE));
411 c.append(appendMaterial(material));
413 Chunk density = new Chunk();
414 density.setFont(new Font(Font.FontFamily.HELVETICA, PrintUtilities.SMALL_FONT_SIZE));
415 density.append(appendMaterialDensity(material));
416 cell.addElement(density);
420 protected PdfPCell iconToImage (final RocketComponent visitable) {
421 final ImageIcon icon = (ImageIcon) ComponentIcons.getLargeIcon(visitable.getClass());
423 Image im = Image.getInstance(icon.getImage(), null);
424 im.scaleToFit(icon.getIconWidth() * 0.6f, icon.getIconHeight() * 0.6f);
425 PdfPCell cell = new PdfPCell(im);
426 cell.setFixedHeight(icon.getIconHeight() * 0.6f);
427 cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
428 cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
429 cell.setBorder(PdfPCell.NO_BORDER);
432 catch (BadElementException e) {
434 catch (IOException e) {
439 protected String appendLength (double length) {
440 final Unit defaultUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit();
441 return NumberFormat.getNumberInstance().format(defaultUnit.toUnit(length)) + defaultUnit.toString();
444 protected String appendMass (double mass) {
445 final Unit defaultUnit = UnitGroup.UNITS_MASS.getDefaultUnit();
446 return NumberFormat.getNumberInstance().format(defaultUnit.toUnit(mass)) + defaultUnit.toString();
449 protected String appendMaterial (Material material) {
450 return material.getName();
453 protected String appendMaterialDensity (Material material) {
454 return " (" + material.getType().getUnitGroup().getDefaultUnit().toStringUnit(material.getDensity()) + ")";