View Javadoc

1   // Copyright 2004-2005, FreeHEP.
2   package hep.wired.heprep.interaction;
3   
4   import java.awt.*;
5   import java.awt.geom.*;
6   import javax.swing.*;
7   import javax.swing.table.*;
8   
9   import org.freehep.swing.layout.TableLayout;
10  
11  import hep.graphics.heprep.HepRep;
12  
13  import hep.wired.feature.HasBoundingBox;
14  import hep.wired.edit.Scale;
15  import hep.wired.edit.Rotate;
16  import hep.wired.viewport.RectangularViewPort;
17  import hep.wired.heprep.services.GraphicsMode;
18  import hep.wired.heprep.services.Projection;
19  import hep.wired.services.RecordPlot;
20  import hep.wired.services.ViewPort;
21  import hep.wired.heprep.graphicspanel.HepRepGraphicsMode;
22  
23  /***
24   * Panel to specify a 3D location in an UV and its 90 degree rotated WV and UW projections.
25   *
26   * @author Mark Donszelmann
27   * @version $Id: SetLocationPanel.java 653 2005-03-01 01:12:16Z duns $
28   */
29  public class SetLocationPanel extends JPanel {
30  
31      private static final double popupSizeFactor = 0.8;
32  
33      private JButton selectButton;
34      private RecordPlot plot;
35  
36      private RecordPlot uvPlot, wvPlot, uwPlot;
37      private double uSize, vSize, wSize;
38  
39      private int u = -1;
40      private int v = -1;
41      private int w = -1;
42      private boolean uIsFixed = false;
43      private boolean vIsFixed = false;
44      private boolean wIsFixed = false;
45  
46  
47      public SetLocationPanel(RecordPlot plot, JButton select) {
48          this.plot = plot;
49          this.selectButton = select;
50          selectButton.setEnabled(false);
51          
52          setLayout(new TableLayout());
53  
54          
55          // setup table
56          final AbstractTableModel tableModel = new AbstractTableModel() {
57               
58              private String[] columnNames = { "Name", "Value", "Fixed" };
59              private String[] rowNames = { "U", "V", "W" };
60              
61              public String getColumnName(int col) {
62                  return columnNames[col];
63              }
64              
65              public int getColumnCount() {
66                  return columnNames.length;
67              }
68              
69              public int getRowCount() {
70                  return rowNames.length;
71              }
72              
73              public boolean isCellEditable(int row, int col) {
74                  return false;
75              }
76              
77              public Class getColumnClass(int c) {
78                  switch (c) {
79                      case 0: return String.class;
80                      case 1: return Integer.class;
81                      case 2: return Boolean.class;
82                      default: return String.class;
83                  }
84              }
85              
86              public Object getValueAt(int row, int col) {
87                  switch(col) {
88                      case 0: return rowNames[row];
89                      case 1: return new Integer(row == 0 ? u : row == 1 ? v : w);
90                      case 2: return new Boolean(row == 0 ? uIsFixed : row == 1 ? vIsFixed : wIsFixed);
91                      default: return "";
92                  }
93              }
94          };
95          JTable table = new JTable(tableModel);
96          // install special renderer to show "not set"
97          table.setDefaultRenderer(Integer.class, new DefaultTableCellRenderer() {
98              public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
99                  if ((column == 1) && (((Integer)value).intValue() == -1)) {
100                     return new JLabel("Not set");
101                 }
102                 return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
103             }
104         });
105         
106         JPanel tablePanel = new JPanel();
107         tablePanel.setLayout(new BorderLayout());
108         tablePanel.add(table.getTableHeader(), BorderLayout.NORTH);
109         tablePanel.add(table, BorderLayout.CENTER);
110                 
111         // FIXME WIRED-388 needs clone
112         // FIXME WIRED-388 needs explanation text in html?
113         HepRep heprep = (HepRep)plot.getRecord();
114 
115         uvPlot = plot.copy("UV", heprep, false);
116         wvPlot = plot.copy("WV", heprep, false);
117         uwPlot = plot.copy("UW", heprep, false);
118         
119         final ClickToSetLocation uv = new ClickToSetLocation();
120         uvPlot.setInteractionHandler(uv);
121         
122         final ClickToSetLocation wv = new ClickToSetLocation();
123         wvPlot.setInteractionHandler(wv);
124         wvPlot.postEdit(new Rotate(Math.PI/2, 0, 1, 0));
125 
126         final ClickToSetLocation uw = new ClickToSetLocation();
127         uwPlot.setInteractionHandler(uw);
128         uwPlot.postEdit(new Rotate(Math.PI/2, 1, 0, 0));
129 
130         uv.addLocationListener(new LocationListener() {
131             public void setLocation(RecordPlot plot, int newU, int newV, boolean fixU, boolean fixV) {
132                 u = newU; uIsFixed = fixU;
133                 v = newV; vIsFixed = fixV;
134                 wv.setLocation(wvPlot, w, v, wIsFixed, vIsFixed);
135                 uw.setLocation(uwPlot, u, w, uIsFixed, wIsFixed);
136                 selectButton.setEnabled(uIsFixed && vIsFixed && wIsFixed);
137                 tableModel.fireTableRowsUpdated(0,tableModel.getRowCount());
138             } 
139         });
140 
141         wv.addLocationListener(new LocationListener() {
142             public void setLocation(RecordPlot plot, int newW, int newV, boolean fixW, boolean fixV) {
143                 w = newW; wIsFixed = fixW;
144                 v = newV; vIsFixed = fixV;
145                 uv.setLocation(uvPlot, u, v, uIsFixed, vIsFixed);
146                 uw.setLocation(uwPlot, u, w, uIsFixed, wIsFixed);
147                 selectButton.setEnabled(uIsFixed && vIsFixed && wIsFixed);
148                 tableModel.fireTableRowsUpdated(0,tableModel.getRowCount());
149             } 
150         });
151 
152         uw.addLocationListener(new LocationListener() {
153             public void setLocation(RecordPlot plot, int newU, int newW, boolean fixU, boolean fixW) {
154                 u = newU; uIsFixed = fixU;
155                 w = newW; wIsFixed = fixW;
156                 uv.setLocation(uvPlot, u, v, uIsFixed, vIsFixed);
157                 wv.setLocation(wvPlot, w, v, wIsFixed, vIsFixed);
158                 selectButton.setEnabled(uIsFixed && vIsFixed && wIsFixed);
159                 tableModel.fireTableRowsUpdated(0,tableModel.getRowCount());
160             } 
161         });
162     
163         // Find out the bounding boxes
164         Rectangle2D rectangle;
165         rectangle = ((HasBoundingBox)uvPlot.getGraphicsPanel().getFeature(HasBoundingBox.class)).getBoundingBoxForPlot();
166 System.out.println(rectangle);
167         uSize = (rectangle == null) ? 500 : rectangle.getWidth();
168         vSize = (rectangle == null) ? 500 : rectangle.getHeight();
169         rectangle = ((HasBoundingBox)wvPlot.getGraphicsPanel().getFeature(HasBoundingBox.class)).getBoundingBoxForPlot();
170 System.out.println(rectangle);
171         wSize = (rectangle == null) ? 500 : rectangle.getWidth();
172 
173         // calculate scale factors to fit plots
174         // FIXME WIRED-388 cast!
175         RectangularViewPort viewPort = (RectangularViewPort)plot.getGraphicsPanel().getViewPort();
176         uvPlot.postEdit(new Scale(Math.max(viewPort.getWidth() / uSize, viewPort.getHeight() / vSize)));
177         wvPlot.postEdit(new Scale(Math.max(viewPort.getWidth() / wSize, viewPort.getHeight() / vSize)));
178         uwPlot.postEdit(new Scale(Math.max(viewPort.getWidth() / uSize, viewPort.getHeight() / wSize)));
179 
180         // setup layout correctly
181         String insets = " [3 3 3 3]";
182         add(new JLabel(), "0 *");
183         add(new JLabel("U"), "1 *"+insets);
184         add(new JLabel("W"), "2 *"+insets);
185         
186         add(new JLabel("V"), "0 * [1 1 1 1]");
187         add((Component)uvPlot, "1 *"+insets+" {"+(int)uSize+", "+(int)vSize+"} wh");
188         add((Component)wvPlot, "2 *"+insets+" {"+(int)wSize+", "+(int)vSize+"} wh");
189         
190         add(new JLabel("W"), "0 *"+insets);
191         add((Component)uwPlot, "1 *"+insets+" {"+(int)uSize+", "+(int)wSize+"} wh");
192         add(tablePanel, "2 *"+insets+" {"+(int)wSize+", "+(int)wSize+"} wh");
193     }
194     
195     /***
196      * Returns the chosen XYZ location.
197      */
198     public double[] getXYZ() throws UnsupportedOperationException {
199         double xyz[] = new double[3];
200         xyz[0] = xyz[1] = xyz[2] = 0;
201 
202 /* FIXME WIRED-388
203         // Depending on if u, v and/or w are set, calculate via inverse viewports the 
204         // xyz that belong to it. This translation is with respect to the viewports.
205         if (u != -1) {
206             if (v != -1) {
207                 // u and v known
208                 ViewPort uvPort = uvPlot.getGraphicsPanel().getViewPort();
209                 xyz[0] = uvPort.inverseTransformX(u, v);
210                 xyz[1] = uvPort.inverseTransformY(u, v);
211                 if (w != -1) {
212                     // u, v, w known
213                     xyz[2] = wvPlot.getGraphicsPanel().getViewPort().inverseTransformX(w, v);
214                 }
215             } else if (w != -1) {
216                 // u and w known
217                 ViewPort uwPort = uwPlot.getGraphicsPanel().getViewPort();
218                 xyz[0] = uwPort.inverseTransformX(u, w);
219                 xyz[2] = uwPort.inverseTransformY(u, w);
220             }
221         } else {
222             if ((v != -1) && (w != -1)) {
223                 // v and w known
224                 ViewPort wvPort = wvPlot.getGraphicsPanel().getViewPort();
225                 xyz[2] = wvPort.inverseTransformX(w, v);
226                 xyz[1] = wvPort.inverseTransformY(w, v);                
227             }
228         }
229 */        
230         // run the translation through the inverse delta of the uvPlot, since that one
231         // may have a different scale than the original plot.
232         xyz = ((Projection)uvPlot.getGraphicsPanel().getFeature(Projection.class)).inverseDeltaTransform(xyz);
233     
234         // The resulting translate needs to be run through the delta projection of the original
235         // plot to get a transform relative to that scale factor.
236         return ((Projection)plot.getGraphicsPanel().getFeature(Projection.class)).deltaTransform(xyz);
237     }
238     
239     public Dimension getPreferredSize() {
240         Dimension d = ((JComponent)plot).getTopLevelAncestor().getSize();
241         d.width *= popupSizeFactor;
242         d.height *= popupSizeFactor;
243         double ratio = (uSize + wSize) / (vSize + wSize);
244         d = (ratio > 1) ? new Dimension((int)d.getWidth(), (int)(d.getWidth()/ratio)) : 
245                           new Dimension((int)(d.getHeight()*ratio), (int)d.getHeight()); 
246         return d;
247     }
248     
249     public void setBounds(int x, int y, int width, int height) {
250 // FIXME WIRED-388 calculate offset here in either X or Y...
251         System.out.println("OldBounds: "+getX()+", "+getY()+", "+getWidth()+", "+getHeight());
252 // FIXME, WIRED-388 recalculate the scale factors
253         // constrain ratio
254         double ratio = (uSize + wSize) / (vSize + wSize);
255         if (width > height) {
256             super.setBounds(x, y, (int)(ratio * height), height);
257         } else {
258             super.setBounds(x, y, width, (int)(width / ratio));
259         }
260     }
261 }