/Users/lyon/j4p/src/sound/OscopePanel.java

1    package sound; 
2     
3    /** 
4     * Created by 
5     * User: lyon 
6     * Date: Nov 29, 2003 
7     * Time: 11:11:38 AM 
8     * 
9     */ 
10    
11   import gui.run.RunScroll; 
12    
13   import javax.swing.JPanel; 
14   import java.awt.BorderLayout; 
15   import java.awt.Color; 
16   import java.awt.Container; 
17   import java.awt.Dimension; 
18   import java.awt.Graphics; 
19   import java.awt.Graphics2D; 
20   import java.awt.GridLayout; 
21   import java.awt.Rectangle; 
22   import java.awt.Scrollbar; 
23   import java.awt.geom.Line2D; 
24    
25   public class OscopePanel 
26           extends JPanel { 
27       private RunScroll topSb; 
28       private RunScroll bottomSb; 
29       private RunScroll leftSb; 
30       private RunScroll rightSb; 
31       private double[] doubleData; 
32       private int dx = 0; 
33       private int oldDx = 0; 
34       private int dy = 0; 
35       private int oldDy = 0; 
36       private final double 
37               xScaleFactors[] = {50000, 25000, 10000, 5000, 2500, 1000, 
38                                  500, 250, 100, 50, 25, 10, 
39                                  5, 2.5, 1, .5, .25, .1, 
40                                  .05, .025, .01, .005, .0025, .001, 
41                                  .0005}; 
42       private final String xSFLabels[] = {"0.05 u", "0.1 u", "0.25 u", 
43                                           "0.5 u", "1 u", "2.5 u", 
44                                           "5 u", "10 u", "25 u", 
45                                           "50 u", "100 u", "250 u", 
46                                           "500 u", "1 m", "2.5 m", 
47                                           "5 m", "10 m", "25 m", 
48                                           "50 m", "100 m", "250 m", 
49                                           "500 m", "1 ", "2.5 ", 
50                                           "5 "}; 
51       private final int xsfStartIndex = 14; 
52       private double xScaleFactor = xScaleFactors[xsfStartIndex]; 
53       private double oldXScaleFactor = xScaleFactors[xsfStartIndex]; 
54       private String xSFLabel = new String(xSFLabels[xsfStartIndex]); 
55       private boolean labelsVisible = true; 
56    
57       public void setLabelsVisible(boolean b) { 
58           labelsVisible = b; 
59       } 
60    
61       public static final double 
62               yScaleFactors[] = { 
63                   50000, 
64                   25000, 
65                   10000, 
66                   5000, 
67                   2000, 
68                   1000, 
69                   500, 
70                   200, 
71                   100, 
72                   50, 
73                   20, 
74                   10, 
75                   5, 2, 1, .5, .2, .1}; 
76       public static final String 
77               ySFLabels[] = { 
78                   "1 m", "2.5 m", 
79                   "5 m", "10 m", 
80                   "25 m", "50 m", 
81                   "100 m", "250 m", 
82                   "500 m", 
83                   "1 ", "2.5 ", 
84                   "5 ", "10 ", 
85                   "20 ", "50 ", 
86                   "100 ", "250 ", "500 "}; 
87       private final int yScaleFactorStartIndex = 8; 
88       private double yScaleFactor = 1; 
89       private double oldYScaleFactor = 1; 
90       private String ySFLabel = new String(ySFLabels[yScaleFactorStartIndex]); 
91       private TracePanel tracePanel = new TracePanel(); 
92    
93       /** 
94        * This constructor uses a 440 Hz sine wave 
95        * as the default waveform. 
96        */ 
97       public OscopePanel() { 
98           this(new Oscillator(440, 1000).getSineWave()); 
99       } 
100   
101      public Dimension getPreferredSize() { 
102          return new Dimension(400, 200); 
103      } 
104   
105      /** 
106       * This constructor uses the <code>doubleData</code> 
107       * as the source for the default waveform. 
108       * 
109       * @param doubleData an array of data to be displayed 
110       * @param title      title of the panel. 
111       */ 
112      public OscopePanel(double doubleData[]) { 
113          this.doubleData = doubleData; 
114          setLayout(new BorderLayout()); 
115          topSb = 
116                  new RunScroll(Scrollbar.HORIZONTAL) { 
117                      public void run() { 
118                          int i = getValue(); 
119                          xScaleFactor = xScaleFactors[i]; 
120                          if (xScaleFactor != oldXScaleFactor) { 
121                              xSFLabel = xSFLabels[i]; 
122                              tracePanel.repaint(500); 
123                              oldXScaleFactor = xScaleFactor; 
124                          } 
125                      } 
126                  }; 
127          // Set top scrollbar characteristics 
128          topSb.setValues(xsfStartIndex, 0, 0, 24); 
129          bottomSb = 
130                  new RunScroll(Scrollbar.HORIZONTAL) { 
131                      public void run() { 
132                          dx = getValue(); 
133                          if (dx != oldDx) { 
134                              tracePanel.repaint(500); 
135                              oldDx = dx; 
136                          } 
137                      } 
138                  }; 
139          leftSb = 
140                  new RunScroll(Scrollbar.VERTICAL) { 
141                      public void run() { 
142                          dy = getValue(); 
143                          if (dy != oldDy) { 
144                              tracePanel.repaint(500); 
145                              oldDy = dy; 
146                          } 
147                      } 
148                  }; 
149          rightSb = 
150                  new RunScroll(Scrollbar.VERTICAL) { 
151                      public void run() { 
152                          int i = getValue(); 
153                          yScaleFactor = yScaleFactors[i]; 
154                          if (yScaleFactor != oldYScaleFactor) { 
155                              ySFLabel = ySFLabels[i]; 
156                              tracePanel.repaint(500); 
157                              oldYScaleFactor = yScaleFactor; 
158                          } 
159                      } 
160                  }; 
161          // Set right scrollbar characteristics 
162          rightSb.setValues(yScaleFactorStartIndex, 0, 0, 
163                  yScaleFactors.length - 1); 
164   
165   
166          // Set left scrollbar characteristics 
167          leftSb.setValues(0, 0, -300, 300); 
168          add(topSb, BorderLayout.NORTH); 
169          add(bottomSb, BorderLayout.SOUTH); 
170          add(leftSb, BorderLayout.WEST); 
171          add(rightSb, BorderLayout.EAST); 
172          add(tracePanel, BorderLayout.CENTER); 
173          setBackground(Color.white); 
174          // Set bottom scrollbar characteristics based on sample length 
175          bottomSb.setValues(0, 0, 0, this.doubleData.length); 
176      } 
177   
178      public void setData(double d[]) { 
179          doubleData = d; 
180          bottomSb.setValues(0, 0, 0, d.length); 
181          repaint(); 
182      } 
183   
184      public RunScroll getTopSb() { 
185          return topSb; 
186      } 
187   
188      public RunScroll getBottomSb() { 
189          return bottomSb; 
190      } 
191   
192      public RunScroll getLeftSb() { 
193          return leftSb; 
194      } 
195   
196      public RunScroll getRightSb() { 
197          return rightSb; 
198      } 
199   
200      public JPanel getTracePanel() { 
201          return tracePanel; 
202      } 
203   
204      public void setTopSb(RunScroll topSb) { 
205          this.topSb = topSb; 
206      } 
207   
208      class TracePanel extends JPanel { 
209          private boolean drawGrid = true; 
210          private Color gridColor = new Color(0, 255, 0); 
211          private Dimension dim; 
212          private int height, width; 
213   
214          public void setGridColor(Color c) { 
215              gridColor = c; 
216          } 
217   
218          public void grid(int grid_spacing, Graphics g, Color c) { 
219              Rectangle r = g.getClipBounds(); 
220              int w = r.width; 
221              int h = r.height; 
222              Color oldColor = g.getColor(); 
223              g.setColor(c); 
224              for (int x = 0; x < w; x = x + grid_spacing) { 
225                  g.drawLine(x, 0, x, h); 
226              } 
227              for (int y = 0; y < h; y = y + grid_spacing) { 
228                  g.drawLine(0, y, w, y); 
229              } 
230              g.setColor(oldColor); 
231          } 
232   
233          public void paint(Graphics g) { 
234              drawData(g); 
235              if (!labelsVisible) return; 
236              drawXScaleLabel(g); 
237              drawYScaleLabel(g); 
238          } 
239   
240          private void drawData(Graphics gOld) { 
241              Graphics2D g = (Graphics2D) gOld; 
242              double limit = (doubleData.length * xScaleFactor); 
243              dim = getSize(); 
244              height = dim.height; 
245              width = dim.width; 
246              g.clearRect(0, 0, width, height); 
247              if (drawGrid) 
248                  grid(20, g, gridColor); 
249              if (limit > width) limit = (double) width; 
250              int j = dx; 
251              done: 
252              for (double i = 0; i < limit; i += xScaleFactor) { 
253                  if (j >= (doubleData.length - 1)) 
254                      break done; 
255                  double x1 = i; 
256                  double y1 = (height - ( 
257                          (doubleData[j] * yScaleFactor) 
258                          * height / 4 + height / 2)) - dy; 
259                  double x2 = (i + xScaleFactor); 
260                  double y2 = (height - ( 
261                          (doubleData[j + 1] * yScaleFactor) 
262                          * height / 4 + height / 2)) - dy; 
263                  g.draw(new Line2D.Double(x1, y1, x2, y2)); 
264                  j++; 
265              } 
266          } 
267   
268          private void drawXScaleLabel(Graphics g) { 
269              int height = 10; 
270              int xloc = 20; 
271              int yloc = 20; 
272              String xsfLabel = xSFLabel + "sec/div"; 
273              int string_width = getFontMetrics(g.getFont()).stringWidth(xsfLabel); 
274              int string_height = getFontMetrics(g.getFont()).getHeight(); 
275              g.clearRect(xloc, yloc, string_width, string_height); 
276              g.drawString(xsfLabel, xloc, height + yloc); 
277          } 
278   
279          private void drawYScaleLabel(Graphics g) { 
280              int height = 10; 
281              int xloc = 20; 
282              int yloc = dim.height - 60; 
283              String ysfLabel = ySFLabel + "v/div"; 
284              int string_width = getFontMetrics(g.getFont()).stringWidth(ysfLabel); 
285              int string_height = getFontMetrics(g.getFont()).getHeight(); 
286              g.clearRect(xloc, yloc, string_width, string_height); 
287              g.drawString(ysfLabel, xloc, height + yloc); 
288          } 
289      } 
290   
291      public static void main(String args[]) { 
292          double da[] = new double[100]; 
293          for (int i = 0; i < da.length; i++) 
294              da[i] = Math.random(); 
295          OscopePanel osp = new OscopePanel(da); 
296          gui.ClosableJFrame cf = new gui.ClosableJFrame(); 
297          Container c = cf.getContentPane(); 
298          c.add(osp); 
299          c.setLayout(new GridLayout(1, 0)); 
300          cf.setSize(400, 400); 
301          cf.show(); 
302      } 
303  } 
304   
305