1e7e47f0318fecf0c52cb52cd2cdf9fbf133552c
[debian/openrocket] / core / src / net / sf / openrocket / gui / dialogs / optimization / SimulationModifierTree.java
1 package net.sf.openrocket.gui.dialogs.optimization;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.Font;
6 import java.util.Enumeration;
7 import java.util.List;
8 import java.util.Map;
9
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;
16
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;
23
24 /**
25  * A tree that displays the simulation modifiers in a tree structure.
26  * <p>
27  * All nodes in the model are instances of DefaultMutableTreeNode.  The user objects
28  * within are either of type RocketComponent, String or SimulationModifier.
29  * 
30  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
31  */
32 public class SimulationModifierTree extends BasicTree {
33         
34         private final List<SimulationModifier> selectedModifiers;
35         
36         /**
37          * Sole constructor.
38          * 
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).
42          */
43         public SimulationModifierTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers,
44                         List<SimulationModifier> selectedModifiers) {
45                 this.selectedModifiers = selectedModifiers;
46                 
47                 populateTree(rocket, simulationModifiers);
48                 this.setCellRenderer(new ComponentModifierTreeRenderer());
49                 
50                 // Enable tooltips for this component
51                 ToolTipManager.sharedInstance().registerComponent(this);
52                 
53                 expandComponents();
54         }
55         
56         
57         /**
58          * Populate the simulation modifier tree from the provided information.  This can be used to update
59          * the tree.
60          */
61         public void populateTree(Rocket rocket, Map<Object, List<SimulationModifier>> simulationModifiers) {
62                 
63                 DefaultMutableTreeNode baseNode = new DefaultMutableTreeNode(rocket);
64                 populateTree(baseNode, rocket, simulationModifiers);
65                 
66                 this.setModel(new DefaultTreeModel(baseNode));
67         }
68         
69         
70         private static void populateTree(DefaultMutableTreeNode node, RocketComponent component,
71                         Map<Object, List<SimulationModifier>> simulationModifiers) {
72                 
73                 // Add modifiers (if any)
74                 List<SimulationModifier> modifiers = simulationModifiers.get(component);
75                 if (modifiers != null) {
76                         DefaultMutableTreeNode modifierNode;
77                         
78                         if (component.getChildCount() > 0) {
79                                 modifierNode = new DefaultMutableTreeNode("Optimization parameters");
80                                 node.add(modifierNode);
81                         } else {
82                                 modifierNode = node;
83                         }
84                         
85                         for (SimulationModifier m : modifiers) {
86                                 modifierNode.add(new DefaultMutableTreeNode(m));
87                         }
88                 }
89                 
90                 // Add child components
91                 for (RocketComponent c : component.getChildren()) {
92                         DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(c);
93                         node.add(newNode);
94                         populateTree(newNode, c, simulationModifiers);
95                 }
96                 
97         }
98         
99         
100         /**
101          * Expand the rocket components, but not the modifiers.
102          */
103         @SuppressWarnings("rawtypes")
104         public void expandComponents() {
105                 DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) this.getModel().getRoot();
106                 
107                 Enumeration enumeration = baseNode.breadthFirstEnumeration();
108                 
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()));
114                         }
115                 }
116         }
117         
118         
119
120
121         public class ComponentModifierTreeRenderer extends DefaultTreeCellRenderer {
122                 private Font componentFont;
123                 private Font stringFont;
124                 private Font modifierFont;
125                 
126                 @Override
127                 public Component getTreeCellRendererComponent(
128                                 JTree tree,
129                                 Object value,
130                                 boolean sel,
131                                 boolean expanded,
132                                 boolean leaf,
133                                 int row,
134                                 boolean hasFocus2) {
135                         
136                         super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus2);
137                         
138                         if (componentFont == null) {
139                                 makeFonts();
140                         }
141                         
142
143                         // Customize based on line type
144                         
145                         Object object = ((DefaultMutableTreeNode) value).getUserObject();
146                         
147                         // Set icon (for rocket components, null for others)
148                         setIcon(ComponentIcons.getSmallIcon(object.getClass()));
149                         
150
151                         // Set text color/style
152                         if (object instanceof RocketComponent) {
153                                 setForeground(Color.GRAY);
154                                 setFont(componentFont);
155                                 
156                                 // Set tooltip
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);
163                                 } else {
164                                         this.setToolTipText(null);
165                                 }
166                         } else if (object instanceof String) {
167                                 setForeground(Color.GRAY);
168                                 setFont(stringFont);
169                         } else if (object instanceof SimulationModifier) {
170                                 
171                                 if (selectedModifiers.contains(object)) {
172                                         setForeground(Color.GRAY);
173                                 } else {
174                                         setForeground(Color.BLACK);
175                                 }
176                                 setFont(modifierFont);
177                                 setText(((SimulationModifier) object).getName());
178                                 setToolTipText(((SimulationModifier) object).getDescription());
179                         }
180                         
181                         return this;
182                 }
183                 
184                 private void makeFonts() {
185                         Font font = getFont();
186                         componentFont = font.deriveFont(Font.ITALIC);
187                         stringFont = font;
188                         modifierFont = font.deriveFont(Font.BOLD);
189                 }
190                 
191         }
192         
193 }