View Javadoc

1   // Copyright 2004-2005, FreeHEP.
2   package hep.wired.heprep.interaction;
3   
4   import java.awt.*;
5   import java.awt.event.*;
6   import java.awt.geom.*;
7   import java.util.*;
8   import java.util.List;
9   import javax.swing.*;
10  import javax.swing.border.*;
11  import javax.swing.event.*;
12  import javax.swing.table.*;
13  import javax.swing.tree.*;
14  
15  import org.freehep.application.mdi.ManagedPage;
16  import org.freehep.application.mdi.PageContext;
17  import org.freehep.swing.layout.TableLayout;
18  
19  import hep.graphics.heprep.HepRep;
20  import hep.graphics.heprep.HepRepAttDef;
21  import hep.graphics.heprep.HepRepAttValue;
22  import hep.graphics.heprep.HepRepDefaults;
23  import hep.graphics.heprep.HepRepInstance;
24  import hep.graphics.heprep.HepRepType;
25  import hep.graphics.heprep.HepRepTypeTree;
26  
27  import hep.wired.image.WiredBaseImage;
28  import hep.wired.services.GraphicsPanel;
29  import hep.wired.services.RecordPlot;
30  import hep.wired.services.InteractionHandler;
31  import hep.wired.util.OptionButton;
32  import hep.wired.util.JTristateTree;
33  import hep.wired.util.SortableListTableModel;
34  import hep.wired.util.TitledPanel;
35  
36  import hep.wired.heprep.plugin.WiredPlugin;
37  import hep.wired.heprep.graphicspanel.HepRepPanel;
38  import hep.wired.heprep.graphicspanel.ControlPanel;
39  import hep.wired.heprep.tree.TypeTreeModel;
40  import hep.wired.heprep.tree.TypeTristateTreeModel;
41  import hep.wired.util.ScientificTable;
42  import hep.wired.heprep.util.WiredHepRepUtil;
43  
44  /***
45   * Panel to show HepRep attribute information.
46   *
47   * @author Mark Donszelmann
48   * @version $Id: HepRepInfoPanel.java 2087 2005-07-20 23:49:09Z duns $
49   */
50  public class HepRepInfoPanel extends ControlPanel {
51  
52      private ButtonGroup group;
53      private JPanel shapePanel;
54  
55      private List/*<Flag>*/ layerList;
56      private TitledBorder layerBorder;
57      private LayerTableModel layerTableModel;
58      private JPanel layerPanel;
59  
60      private Set/*HepRepType*/ typeSet;
61      private TitledBorder typeBorder;
62  //    private TypeTreeModel typeTreeModel;
63      private TypeTristateTreeModel typeTristateModel;
64      private TreeModelListener typeTristateModelListener;
65      private JPanel typePanel;
66      private JTree typeTree;
67      
68      private List/*<String>*/ categoryList;
69      private TitledBorder categoryBorder;
70      private CategoryTableModel categoryTableModel;
71      private JPanel categoryPanel;
72  
73      // list of picked instances
74      private List/*<HepRepInstance>*/ instanceValues;
75      private InstanceTableModel instanceTableModel;
76      private JTable instanceTable;
77      private TitledPanel instancePanel;
78      // list of selected instances
79      private Set selectedInstances;
80  
81      private AttributeTableModel attributeTableModel;
82      private JTable attributeTable;
83      private TitledPanel attributePanel;
84  
85      private JButton zoomButton;
86      private JButton translateButton;
87      private JCheckBox pickWhileDragging;
88      
89      private transient PickHandler interactionHandler; 
90      private transient RecordPlot plot;
91  
92      public HepRepInfoPanel() {
93          super("Picking", "Information on Picked Objects", WiredBaseImage.getIcon("PickInfo%w", 16), HoverToPick.getInstance());
94          setLayout(new TableLayout());
95  
96          layerList = new ArrayList();
97          typeSet = new HashSet();
98          categoryList = new ArrayList();
99          instanceValues = new ArrayList();
100         selectedInstances = new HashSet();
101         
102         layerTableModel = new LayerTableModel(layerList) {
103             protected void changed() {
104                 interactionHandler.update(plot);
105             }
106         };
107         
108         typeTristateModelListener = new TreeModelListener() {
109             public void treeNodesChanged(TreeModelEvent e) {
110                  interactionHandler.update(plot);
111             }
112             
113             public void treeNodesInserted(TreeModelEvent e) {}
114             public void treeNodesRemoved(TreeModelEvent e) {} 
115             public void treeStructureChanged(TreeModelEvent e) {}
116         };
117                   
118         typeTristateModel = new TypeTristateTreeModel(new TypeTreeModel((HepRep)null));
119         typeTristateModel.addTreeModelListener(typeTristateModelListener);        
120             
121         categoryTableModel = new CategoryTableModel(categoryList) {
122             protected void changed() {
123                 updateAttributes();
124             }
125         };
126         
127         instanceTableModel = new InstanceTableModel(instanceValues);
128         instanceTable = new ScientificTable(instanceTableModel);
129         attributeTableModel = new AttributeTableModel(categoryList, categoryTableModel.getShownSet());
130         attributeTable = new ScientificTable(attributeTableModel);
131         
132         // connect the attribute table to the instance table
133         final ListSelectionModel selectionModel = instanceTable.getSelectionModel();
134         selectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
135                 
136         selectionModel.addListSelectionListener(new ListSelectionListener() {
137             public void valueChanged(ListSelectionEvent event) {
138                 if (event.getValueIsAdjusting()) return;
139 
140                 // adjust selectedInstances list
141                 for (int i=event.getFirstIndex(); i<=event.getLastIndex(); i++) {
142                     if (i<instanceValues.size()) {
143                         HepRepInstance instance = (HepRepInstance)instanceValues.get(i);
144                         if (selectionModel.isSelectedIndex(i)) {
145                             selectedInstances.add(instance); 
146                         } else {
147                             selectedInstances.remove(instance);
148                         }                        
149                     }
150                 }
151 
152                 // inform the interaction handler
153                 if (interactionHandler != null) interactionHandler.setSelected(plot, selectedInstances);
154 
155 
156                 // if contains only one, show attributes
157                 attributeTableModel.setInstance(selectedInstances.size() == 1 ? (HepRepInstance)selectedInstances.iterator().next() : null);
158                 updateAttributes();
159                 
160                 updateButtons();
161                 
162             }
163         });
164         
165         // setup typetree            
166         typeTree = new JTristateTree(typeTristateModel);        
167         
168         String insets = " [3 3 3 3] ";
169 
170         group = new ButtonGroup();
171         shapePanel = new JPanel();
172         shapePanel.setLayout(new TableLayout());
173         shapePanel.setBorder(new TitledBorder(new EtchedBorder(), "Shape"));      
174         add(shapePanel, "0 *"+insets+"w");
175 
176         final JPanel optionsPanel = new JPanel();
177         optionsPanel.setName("hep.wired.InstanceOptions");
178         optionsPanel.setLayout(new TableLayout());
179 
180         Border border = new EmptyBorder(0, 0, 0, 0);       
181 
182         layerPanel = new JPanel();
183         layerPanel.setLayout(new BorderLayout());
184         layerBorder = new TitledBorder(border, "Not set", TitledBorder.LEFT, TitledBorder.ABOVE_TOP);
185         layerPanel.setBorder(layerBorder);
186         layerPanel.add(BorderLayout.CENTER, new JScrollPane(new ScientificTable(layerTableModel), 
187                                                             JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
188                                                             JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
189         optionsPanel.add(layerPanel, "0 *"+insets+"wh");
190         
191         typePanel = new JPanel();
192         typePanel.setLayout(new BorderLayout());
193         typeBorder = new TitledBorder(border, "Show instances from types:", TitledBorder.LEFT, TitledBorder.ABOVE_TOP);
194         typePanel.setBorder(typeBorder);
195         typePanel.add(BorderLayout.CENTER, new JScrollPane(typeTree,
196                                                            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
197                                                            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
198         optionsPanel.add(typePanel, "0 *"+insets+"wh");
199         
200         categoryPanel = new JPanel();
201         categoryPanel.setName("hep.wired.AttributeOptions");
202         categoryPanel.setLayout(new BorderLayout());
203         categoryBorder = new TitledBorder(border, "Not set", TitledBorder.LEFT, TitledBorder.ABOVE_TOP);
204         categoryPanel.setBorder(categoryBorder);
205         categoryPanel.add(BorderLayout.CENTER, new JScrollPane(new ScientificTable(categoryTableModel), 
206                                                                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
207                                                                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
208 
209         // instance panel        
210         OptionButton instanceButton = new OptionButton("Options...", "Instance Table Options", optionsPanel, this);
211         instancePanel = new TitledPanel("Not set", 
212                                         new JScrollPane(instanceTable, 
213                                                         JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
214                                                         JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
215                                         instanceButton
216         );
217         
218         // attribute panel
219         OptionButton attributeButton = new OptionButton("Options...", "Attribute Table Options", categoryPanel, this);
220         attributePanel = new TitledPanel("Not set", 
221                                          new JScrollPane(attributeTable, 
222                                                          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
223                                                          JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
224                                          attributeButton
225         );
226         
227         JSplitPane dataPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
228         dataPanel.setTopComponent(instancePanel);
229         dataPanel.setBottomComponent(attributePanel);
230         dataPanel.setResizeWeight(0.30);
231         
232         // zoom button
233         zoomButton = new JButton("Zoom into Region");
234         zoomButton.setEnabled(false);
235         zoomButton.addActionListener(new ActionListener() {
236             public void actionPerformed(ActionEvent event) {
237                 interactionHandler.zoomIntoRegion(plot);
238                 zoomButton.setEnabled(interactionHandler.isRegionZoomable());
239             }
240         });
241         
242         // translate button
243         translateButton = new JButton("Translate to Picked Object");
244         translateButton.setEnabled(false);
245         translateButton.addActionListener(new ActionListener() {
246             public void actionPerformed(ActionEvent event) {
247                 interactionHandler.translateToPicked(plot);
248                 translateButton.setEnabled(interactionHandler.isPickedTranslateable());
249             }
250         });
251         
252         // pick while dragging
253         pickWhileDragging = new JCheckBox("Pick while Moving/Dragging");
254         pickWhileDragging.setEnabled(false);
255         pickWhileDragging.addActionListener(new ActionListener() {
256             public void actionPerformed(ActionEvent event) {
257                 interactionHandler.setPickWhileDragging(pickWhileDragging.isSelected());
258                 pickWhileDragging.setEnabled(interactionHandler.canSetPickWhileDragging());
259             }
260         });
261         
262         // selection panel
263         JPanel selectionPanel = new JPanel();
264         selectionPanel.setBorder(new TitledBorder(new EtchedBorder(), "Actions / Settings"));
265         selectionPanel.setLayout(new TableLayout());
266         selectionPanel.add(zoomButton, "0 * ltw");
267         selectionPanel.add(translateButton, "0 * ltw");
268         selectionPanel.add(pickWhileDragging, "0 * ltw");
269         
270         add(selectionPanel, "0 *"+insets+"w");
271         add(dataPanel, "0 *"+insets+"wh");        
272     }
273 
274     public void addHandler(final InteractionHandler h, boolean selected) {
275         if (h != null) {
276             final JToggleButton b = new JToggleButton(h.getIcon(16), selected);
277             b.setToolTipText(h.getDescription());
278             b.addActionListener(new ActionListener() {
279                 public void actionPerformed(ActionEvent event) {
280                     WiredPlugin.getPlugin().setInteractionHandler(h);
281                 }
282             });
283             group.add(b);        
284             shapePanel.add(b, "* * lt");
285         } else {
286             // FIXME table got to have a better way
287             shapePanel.add(new JLabel(), "* * ltW");
288         }
289     }
290 
291     public void setInteractionHandler(PickHandler interactionHandler, RecordPlot plot) {
292         this.interactionHandler = interactionHandler;
293         this.plot = plot;
294         updateButtons();        
295     }
296     
297     public void setInfo(HepRep heprep) {
298         
299         // layers
300         layerTableModel.set(heprep);
301         layerTableModel.fireTableDataChanged();
302         layerBorder.setTitle("Pick from layers ("+layerTableModel.getRowCount()+"):");
303         layerPanel.revalidate();
304         layerPanel.repaint();
305         
306         // rescue state of old types
307         typeTristateModel.removeTreeModelListener(typeTristateModelListener);
308         List expandedList = WiredHepRepUtil.getExpandedState(typeTristateModel, typeTree);
309      
310         // types
311         typeTristateModel = WiredHepRepUtil.copyTypeTree(typeTristateModel, heprep);
312         typeTree.setModel(typeTristateModel);
313         typeTristateModel.addTreeModelListener(typeTristateModelListener);
314         WiredHepRepUtil.setExpandedState(expandedList, typeTristateModel, typeTree);      
315 //        typeTreeModel.setRoot(heprep);
316 //        typeTreeModel.fireTreeStructureChanged();
317         
318         // categories
319         categoryTableModel.set(heprep);
320         categoryTableModel.fireTableDataChanged();
321         categoryBorder.setTitle("Show attributes from categories ("+categoryTableModel.getRowCount()+"):");
322         categoryPanel.revalidate();
323         categoryPanel.repaint();
324         
325         updateButtons();
326     }
327     
328     public void setInfo(HepRepInstance instance) {
329         if (instance == null) {
330             setInfo((Set)null);
331         } else {
332             Set s = new HashSet();
333             s.add(instance);
334             setInfo(s);
335         }
336     }
337     
338     public void setInfo(Set/*<HepRepInstance>*/ instances) {
339         instanceValues.clear();
340         selectedInstances.clear();
341         
342         Set/*<HepRepInstance>*/ parentInstances = new HashSet();
343         Set/*<HepRepInstance>*/ pickParentInstances = new HashSet();
344         
345         if (instances != null) {
346             for (Iterator i=instances.iterator(); i.hasNext(); ) {
347                 HepRepInstance instance = (HepRepInstance)i.next();
348                 while (instance.getAttValue("PickParent").getBoolean()) {
349                     // add all instances that were picked.
350                     pickParentInstances.add(instance);
351 
352                     // walk up the tree
353                     instance = instance.getSuperInstance();                    
354                 }
355                 
356                 parentInstances.add(instance);                
357             }
358             
359             instanceValues.addAll(parentInstances);
360             if (parentInstances.size() == 1) {
361                 // one parent, add all pickParent children
362                 instanceValues.addAll(pickParentInstances);
363             }
364         }
365        
366         updateInstances();
367         
368         // Select all instance
369         if (instances != null) {
370             ListSelectionModel selectionModel = instanceTable.getSelectionModel();
371             selectionModel.setSelectionInterval(0, instanceValues.size()-1);
372         }
373        
374         updateAttributes();
375         
376         updateButtons();
377     }
378     
379     private void updateButtons() {
380         if (interactionHandler != null) {
381             zoomButton.setEnabled(interactionHandler.isRegionZoomable());       
382             translateButton.setEnabled(interactionHandler.isPickedTranslateable()); 
383             pickWhileDragging.setSelected(interactionHandler.isPickWhileDragging());
384             pickWhileDragging.setEnabled(interactionHandler.canSetPickWhileDragging());
385         } else {
386             zoomButton.setEnabled(false);
387             translateButton.setEnabled(false);
388             pickWhileDragging.setSelected(false);
389             pickWhileDragging.setEnabled(false);
390         }
391     }
392     
393     private void updateInstances() {        
394         instanceTableModel.fireTableDataChanged();
395         instancePanel.setTitle("Picked objects ("+instanceTableModel.getRowCount()+"):");
396     }
397    
398     private void updateAttributes() {
399         attributeTableModel.update();
400         attributePanel.setTitle("Attributes of picked object ("+attributeTableModel.getRowCount()+"):");
401     }
402         
403     public List/*<String>*/ getLayers() {
404         List list = new ArrayList();
405         for (Iterator i=layerList.iterator(); i.hasNext(); ) {
406             Flag layer = (Flag)i.next();
407             if (layer.isSet()) list.add(layer.getName());
408         }
409         return list;   
410     }
411     
412     public Set/*<HepRepType>*/ getTypes() {
413         return typeTristateModel.getSelectedSet(HepRepType.class);
414     }
415 
416 }