/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