1 package net.sf.openrocket.gui.dialogs.optimization;
4 import java.awt.Component;
6 import java.util.Enumeration;
10 import javax.swing.JTree;
11 import javax.swing.ToolTipManager;
12 import javax.swing.tree.DefaultMutableTreeNode;
13 import javax.swing.tree.DefaultTreeCellRenderer;
14 import javax.swing.tree.DefaultTreeModel;
15 import javax.swing.tree.TreePath;
17 import net.sf.openrocket.gui.components.BasicTree;
18 import net.sf.openrocket.gui.main.ComponentIcons;
19 import net.sf.openrocket.l10n.Translator;
20 import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
21 import net.sf.openrocket.rocketcomponent.Rocket;
22 import net.sf.openrocket.rocketcomponent.RocketComponent;
23 import net.sf.openrocket.startup.Application;
24 import net.sf.openrocket.util.TextUtil;
27 * A tree that displays the simulation modifiers in a tree structure.
29 * All nodes in the model are instances of DefaultMutableTreeNode. The user objects
30 * within are either of type RocketComponent, String or SimulationModifier.
32 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
34 public class SimulationModifierTree extends BasicTree {
36 private final List<SimulationModifier> selectedModifiers;
37 private static final Translator trans = Application.getTranslator();
42 * @param rocket the rocket.
43 * @param simulationModifiers the simulation modifiers, ordered and mapped by components
44 * @param selectedModifiers a list of the currently selected modifiers (may be modified).
46 public SimulationModifierTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers,
47 List<SimulationModifier> selectedModifiers) {
48 this.selectedModifiers = selectedModifiers;
50 populateTree(rocket, simulationModifiers);
51 this.setCellRenderer(new ComponentModifierTreeRenderer());
53 // Enable tooltips for this component
54 ToolTipManager.sharedInstance().registerComponent(this);
61 * Populate the simulation modifier tree from the provided information. This can be used to update
64 public void populateTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers) {
66 DefaultMutableTreeNode baseNode = new DefaultMutableTreeNode(rocket);
67 populateTree(baseNode, rocket, simulationModifiers);
69 this.setModel(new DefaultTreeModel(baseNode));
73 private static void populateTree(DefaultMutableTreeNode node, RocketComponent component,
74 Map<Object, List<SimulationModifier>> simulationModifiers) {
76 // Add modifiers (if any)
77 List<SimulationModifier> modifiers = simulationModifiers.get(component);
78 if (modifiers != null) {
79 DefaultMutableTreeNode modifierNode;
81 if (component.getChildCount() > 0) {
82 modifierNode = new DefaultMutableTreeNode(trans.get("SimulationModifierTree.OptimizationParameters"));
83 node.add(modifierNode);
88 for (SimulationModifier m : modifiers) {
89 modifierNode.add(new DefaultMutableTreeNode(m));
93 // Add child components
94 for (RocketComponent c : component.getChildren()) {
95 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(c);
97 populateTree(newNode, c, simulationModifiers);
104 * Expand the rocket components, but not the modifiers.
106 @SuppressWarnings("rawtypes")
107 public void expandComponents() {
108 DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) this.getModel().getRoot();
110 Enumeration enumeration = baseNode.breadthFirstEnumeration();
112 while (enumeration.hasMoreElements()) {
113 DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
114 Object object = node.getUserObject();
115 if (object instanceof RocketComponent) {
116 this.makeVisible(new TreePath(node.getPath()));
124 public class ComponentModifierTreeRenderer extends DefaultTreeCellRenderer {
125 private Font componentFont;
126 private Font stringFont;
127 private Font modifierFont;
130 public Component getTreeCellRendererComponent(
139 super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus2);
141 if (componentFont == null) {
146 // Customize based on line type
148 Object object = ((DefaultMutableTreeNode) value).getUserObject();
150 // Set icon (for rocket components, null for others)
151 setIcon(ComponentIcons.getSmallIcon(object.getClass()));
154 // Set text color/style
155 if (object instanceof RocketComponent) {
156 setForeground(Color.GRAY);
157 setFont(componentFont);
160 RocketComponent c = (RocketComponent) object;
161 String comment = c.getComment().trim();
162 if (comment.length() > 0) {
163 comment = TextUtil.htmlEncode(comment);
164 comment = "<html>" + comment.replace("\n", "<br>");
165 this.setToolTipText(comment);
167 this.setToolTipText(null);
169 } else if (object instanceof String) {
170 setForeground(Color.GRAY);
172 } else if (object instanceof SimulationModifier) {
174 if (selectedModifiers.contains(object)) {
175 setForeground(Color.GRAY);
177 setForeground(Color.BLACK);
179 setFont(modifierFont);
180 setText(((SimulationModifier) object).getName());
181 setToolTipText(((SimulationModifier) object).getDescription());
187 private void makeFonts() {
188 Font font = getFont();
189 componentFont = font.deriveFont(Font.ITALIC);
191 modifierFont = font.deriveFont(Font.BOLD);