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.optimization.rocketoptimization.SimulationModifier;
20 import net.sf.openrocket.rocketcomponent.Rocket;
21 import net.sf.openrocket.rocketcomponent.RocketComponent;
22 import net.sf.openrocket.util.TextUtil;
25 * A tree that displays the simulation modifiers in a tree structure.
27 * All nodes in the model are instances of DefaultMutableTreeNode. The user objects
28 * within are either of type RocketComponent, String or SimulationModifier.
30 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
32 public class SimulationModifierTree extends BasicTree {
34 private final List<SimulationModifier> selectedModifiers;
39 * @param rocket the rocket.
40 * @param simulationModifiers the simulation modifiers, ordered and mapped by components
41 * @param selectedModifiers a list of the currently selected modifiers (may be modified).
43 public SimulationModifierTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers,
44 List<SimulationModifier> selectedModifiers) {
45 this.selectedModifiers = selectedModifiers;
47 populateTree(rocket, simulationModifiers);
48 this.setCellRenderer(new ComponentModifierTreeRenderer());
50 // Enable tooltips for this component
51 ToolTipManager.sharedInstance().registerComponent(this);
58 * Populate the simulation modifier tree from the provided information. This can be used to update
61 public void populateTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers) {
63 DefaultMutableTreeNode baseNode = new DefaultMutableTreeNode(rocket);
64 populateTree(baseNode, rocket, simulationModifiers);
66 this.setModel(new DefaultTreeModel(baseNode));
70 private static void populateTree(DefaultMutableTreeNode node, RocketComponent component,
71 Map<Object, List<SimulationModifier>> simulationModifiers) {
73 // Add modifiers (if any)
74 List<SimulationModifier> modifiers = simulationModifiers.get(component);
75 if (modifiers != null) {
76 DefaultMutableTreeNode modifierNode;
78 if (component.getChildCount() > 0) {
79 modifierNode = new DefaultMutableTreeNode("Optimization parameters");
80 node.add(modifierNode);
85 for (SimulationModifier m : modifiers) {
86 modifierNode.add(new DefaultMutableTreeNode(m));
90 // Add child components
91 for (RocketComponent c : component.getChildren()) {
92 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(c);
94 populateTree(newNode, c, simulationModifiers);
101 * Expand the rocket components, but not the modifiers.
103 @SuppressWarnings("rawtypes")
104 public void expandComponents() {
105 DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) this.getModel().getRoot();
107 Enumeration enumeration = baseNode.breadthFirstEnumeration();
109 while (enumeration.hasMoreElements()) {
110 DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
111 Object object = node.getUserObject();
112 if (object instanceof RocketComponent) {
113 this.makeVisible(new TreePath(node.getPath()));
121 public class ComponentModifierTreeRenderer extends DefaultTreeCellRenderer {
122 private Font componentFont;
123 private Font stringFont;
124 private Font modifierFont;
127 public Component getTreeCellRendererComponent(
136 super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus2);
138 if (componentFont == null) {
143 // Customize based on line type
145 Object object = ((DefaultMutableTreeNode) value).getUserObject();
147 // Set icon (for rocket components, null for others)
148 setIcon(ComponentIcons.getSmallIcon(object.getClass()));
151 // Set text color/style
152 if (object instanceof RocketComponent) {
153 setForeground(Color.GRAY);
154 setFont(componentFont);
157 RocketComponent c = (RocketComponent) object;
158 String comment = c.getComment().trim();
159 if (comment.length() > 0) {
160 comment = TextUtil.htmlEncode(comment);
161 comment = "<html>" + comment.replace("\n", "<br>");
162 this.setToolTipText(comment);
164 this.setToolTipText(null);
166 } else if (object instanceof String) {
167 setForeground(Color.GRAY);
169 } else if (object instanceof SimulationModifier) {
171 if (selectedModifiers.contains(object)) {
172 setForeground(Color.GRAY);
174 setForeground(Color.BLACK);
176 setFont(modifierFont);
177 setText(((SimulationModifier) object).getName());
178 setToolTipText(((SimulationModifier) object).getDescription());
184 private void makeFonts() {
185 Font font = getFont();
186 componentFont = font.deriveFont(Font.ITALIC);
188 modifierFont = font.deriveFont(Font.BOLD);