KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > swing > JRoundDial


1 package JSci.swing;
2
3 import java.awt.*;
4 import java.awt.geom.*;
5 import java.awt.event.*;
6 import javax.swing.*;
7 import javax.swing.event.*;
8 import java.text.*;
9 import java.util.*;
10
11 /** A round dial, where the pointer can rotate many turns; the turns are indicated
12     by digits inside the dial. JPointer s must be added. */

13 public class JRoundDial extends JPanel {
14
15     private double oneTurn = 360;
16     private double zero = 0.0;
17     private double minorTic = 10;
18     private double majorTic = 30;
19     private boolean setPaintMinorTicks = true;
20     private boolean setPaintMajorTicks = true;
21     private boolean setPaintLabels = true;
22     private JPointer setPaintTurns = null;
23     private double radius = 70;
24     private ArrayList pointers = new ArrayList();
25     private ChangeListener changeListener = new ChangeListener() {
26         public void stateChanged(ChangeEvent event) {
27         repaint();
28         }
29     };
30
31     /** constructs a dial with no pointers
32      * @param o the value that corresponds to one turn
33      * (e.g. 360 for measures in degrees); negative values for
34      * counter-clockwise dial
35      */

36     public JRoundDial(double o) {
37     oneTurn = o;
38     setSize((int)(2*radius),(int)(2*radius));
39     addMouseListener(new TheMouseListener());
40     addMouseMotionListener(new TheMouseMotionListener());
41     }
42
43     /** define the position at which the zero of the dial will be placed
44      * @param z the angle (from the top, clockwise, in rads) where the zero of
45      * the dial will be placed
46      */

47     public void setZero(double z) {
48     zero = z;
49     }
50
51     /** as described in java.awt.Component */
52     public void setSize(int w,int h) {
53     super.setSize(w,h);
54     radius = (w<h)?w/2:h/2;
55     updateMinorTics();
56     updateMajorTics();
57     repaint();
58     }
59
60     /** as described in java.awt.Component */
61     public void setSize(Dimension d) { super.setSize(d); setSize((int)d.getWidth(),(int)d.getHeight()); }
62     
63     /** as described in java.awt.Component */
64     public Dimension getPreferredSize() { return new Dimension((int)(2*radius),(int)(2*radius)); }
65
66     /** set the spacing between minor tics
67      * @param s the spacing between minor tics
68      */

69     public void setMinorTickSpacing(double s) {
70     minorTic = s;
71     updateMinorTics();
72     repaint();
73     }
74
75     /** set the spacing between major tics
76      * @param s the spacing between major tics
77      */

78     public void setMajorTickSpacing(double s) {
79     majorTic = s;
80     updateMajorTics();
81     repaint();
82     }
83
84     /** show the minor tics?
85      * @param b show the minor tics?
86      */

87     public void setPaintMinorTicks(boolean b) {
88     setPaintMinorTicks = b;
89     repaint();
90     }
91
92     /** show the major tics?
93      * @param b show the major tics?
94      */

95     public void setPaintMajorTicks(boolean b) {
96     setPaintMajorTicks = b;
97     repaint();
98     }
99
100     /** show the tic labels?
101      * @param b show the tic labels?
102      */

103     public void setPaintLabels(boolean b) {
104     setPaintLabels = b;
105     repaint();
106     }
107
108     /** show the integer turn number of a JPointer
109      * @param p the JPointer that contains the number of turns; it must be
110      * already added as a JPointer
111      */

112     public void setPaintTurns(JPointer p) {
113     setPaintTurns = p;
114     repaint();
115     }
116
117     private Line2D [] minorTics = null;
118     private Line2D [] majorTics = null;
119     private Point2D [] ticLabelPos = null;
120     private String JavaDoc [] ticLabelText = null;
121     private static NumberFormat formatter;
122     static {
123     formatter = NumberFormat.getNumberInstance();
124     formatter.setMaximumFractionDigits(2);
125     formatter.setMaximumIntegerDigits(3);
126     }
127
128     private void updateMinorTics() {
129     int N =(int)Math.abs(oneTurn/minorTic);
130     minorTics = new Line2D[N];
131     for (int j=0;j<N;j++)
132         minorTics[j] =
133         new Line2D.Double(
134                   radius+radius*0.65*Math.sin(zero+2.0*Math.PI*j*minorTic/oneTurn),
135                   radius-radius*0.65*Math.cos(zero+2.0*Math.PI*j*minorTic/oneTurn),
136                   radius+radius*0.75*Math.sin(zero+2.0*Math.PI*j*minorTic/oneTurn),
137                   radius-radius*0.75*Math.cos(zero+2.0*Math.PI*j*minorTic/oneTurn)
138                   );
139     }
140
141     private void updateMajorTics() {
142     int N =(int)Math.abs(oneTurn/majorTic);
143     majorTics = new Line2D[N];
144     ticLabelPos = new Point2D[N];
145     ticLabelText = new String JavaDoc[N];
146     for (int j=0;j<N;j++) {
147         majorTics[j] =
148         new Line2D.Double(
149                   radius+radius*0.65*Math.sin(zero+2.0*Math.PI*j*majorTic/oneTurn),
150                   radius-radius*0.65*Math.cos(zero+2.0*Math.PI*j*majorTic/oneTurn),
151                   radius+radius*0.8*Math.sin(zero+2.0*Math.PI*j*majorTic/oneTurn),
152                   radius-radius*0.8*Math.cos(zero+2.0*Math.PI*j*majorTic/oneTurn)
153                   );
154         ticLabelText[j] = formatter.format(j*majorTic);
155         ticLabelPos[j] =
156         new Point2D.Double(
157                    radius+radius*0.9*Math.sin(zero+2.0*Math.PI*j*majorTic/oneTurn)
158                    -ticLabelText[j].length()*3,
159                    radius-radius*0.9*Math.cos(zero+2.0*Math.PI*j*majorTic/oneTurn)
160                    +6
161                    );
162     }
163
164     }
165
166
167     /** draw the component - don't call this directly, but use repaint() */
168     public void paintComponent(Graphics g) {
169     super.paintComponent(g);
170     Graphics2D g2 = (Graphics2D)g;
171     //g2.draw(new Ellipse2D.Double(0,0,2*radius,2*radius));
172
if (setPaintMinorTicks)
173         for (int j=0;j<minorTics.length;j++)
174         g2.draw(minorTics[j]);
175     if (setPaintMajorTicks)
176         for (int j=0;j<majorTics.length;j++)
177         g2.draw(majorTics[j]);
178     if (setPaintLabels)
179         for (int j=0;j<majorTics.length;j++)
180         g2.drawString(ticLabelText[j],(int)ticLabelPos[j].getX(),(int)ticLabelPos[j].getY());
181     if (setPaintTurns!=null) {
182         String JavaDoc t = formatter.format(Math.floor(setPaintTurns.getValue()/Math.abs(oneTurn)));
183         g2.drawString(t,(int)(radius-t.length()*3),(int)(radius/2));
184     }
185     Color saveColor = g2.getColor();
186     for (int j=0;j<pointers.size();j++)
187         ((JPointer)pointers.get(j)).paintOnDial(g2,radius,oneTurn,zero,radius,radius);
188     g2.setColor(saveColor);
189     g2.fill(new Ellipse2D.Double(radius-3.0,radius-3.0,6.0,6.0));
190     }
191
192     /** add a pointer; it will be the actual component that contains informations
193      * @param p the pointer that must be added
194      */

195     public void addJPointer(JPointer p) {
196     for (int j=0;j<pointers.size();j++) if (pointers.get(j).equals(p)) return;
197     pointers.add(p);
198     p.addChangeListener(changeListener);
199     repaint();
200     }
201
202     /** remove a pointer; it should have been added with addJPointer()
203      * @param p the pointer that must be removed
204      */

205     public void removeJPointer(JPointer p) {
206     int j=0;
207     while (j<pointers.size()) {
208         if (pointers.get(j).equals(p)) pointers.remove(j);
209         else j++;
210     }
211     p.removeChangeListener(changeListener);
212     repaint();
213     }
214
215     // Mouse listeners
216

217     private JPointer dragged = null;
218     private double dragDelta;
219     private double theta(MouseEvent e) { return Math.atan2(e.getX()-radius,-(e.getY()-radius)); }
220     private class TheMouseListener extends MouseAdapter {
221     public void mousePressed(MouseEvent e) {
222         for (int j=pointers.size()-1;j>=0;j--)
223         if (((JPointer)pointers.get(j)).contains(e.getPoint())) {
224             dragged=(JPointer)pointers.get(j);
225             dragDelta=2.0*Math.PI*dragged.getValue()/oneTurn-theta(e);
226             dragged.setAdjusting(true);
227             break;
228         }
229     }
230     public void mouseReleased(MouseEvent e) {
231         if (dragged!=null) dragged.setAdjusting(false);
232         dragged = null;
233         boolean inside = false;
234         for (int j=0;j<pointers.size();j++)
235         if (((JPointer)pointers.get(j)).contains(e.getPoint())) {
236             inside=true;
237             break;
238         }
239         if (inside) setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
240         else setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
241     }
242     }
243
244     private class TheMouseMotionListener extends MouseMotionAdapter {
245     public void mouseMoved(MouseEvent e) {
246         boolean inside = false;
247         for (int j=0;j<pointers.size();j++)
248         if (((JPointer)pointers.get(j)).contains(e.getPoint())) {
249             inside=true;
250             break;
251         }
252         if (inside) setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
253         else setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
254     }
255     public void mouseDragged(MouseEvent e) {
256         if (dragged!=null) {
257         double from = dragged.getValue();
258         double to = (theta(e)+dragDelta)*oneTurn/2.0/Math.PI;
259         to += (from-to)-(from-to)%oneTurn;
260         while (to<from-Math.abs(oneTurn/2)) to+=Math.abs(oneTurn);
261         while (to>from+Math.abs(oneTurn/2)) to-=Math.abs(oneTurn);
262         dragged.setValue(to);
263         repaint();
264         }
265     }
266     }
267
268
269
270     // Main
271

272     public static void main(String JavaDoc [] args) {
273     JFrame frm = new JFrame();
274     frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
275     JRoundDial d = new JRoundDial(360.0);
276     d.setZero(Math.PI/6.0);
277     frm.getContentPane().add(d);
278     d.setSize(260,260);
279     frm.pack();
280     frm.show();
281     try { Thread.sleep(3000); } catch (InterruptedException JavaDoc e) {}
282     JPointer p = new JPointer(JPointer.POINTER_SIMPLE_QUADRANGLE);
283     p.setColor(Color.MAGENTA);
284     p.setValue(20.0);
285     d.addJPointer(p);
286     try { Thread.sleep(3000); } catch (InterruptedException JavaDoc e) {}
287     JPointer p1 = new JPointer(JPointer.POINTER_SIMPLE_STOP);
288     p1.setColor(Color.CYAN);
289     p1.setValue(130.0);
290     d.addJPointer(p1);
291         
292     d.setPaintTurns(p1);d.repaint();
293
294     p1.addChangeListener(new ChangeListener() {
295         public void stateChanged(ChangeEvent e) {
296             double v=((JPointer)e.getSource()).getValue();
297             System.out.println("State changed: "+v);
298         }
299         });
300
301     //try { Thread.sleep(3000); } catch (InterruptedException e) {}
302
//p.setValue(p.getValue()+10.0);
303
//try { Thread.sleep(3000); } catch (InterruptedException e) {}
304
//p.setValue(p.getValue()+10.0);
305
//try { Thread.sleep(3000); } catch (InterruptedException e) {}
306
//p.setValue(p.getValue()+10.0);
307
//try { Thread.sleep(3000); } catch (InterruptedException e) {}
308
//p.setValue(p.getValue()+10.0);
309

310     //try { Thread.sleep(3000); } catch (InterruptedException e) {}
311
//d.removeJPointer(p);
312
//try { Thread.sleep(3000); } catch (InterruptedException e) {}
313
//d.removeJPointer(p1);
314
//try { Thread.sleep(3000); } catch (InterruptedException e) {}
315
}
316
317
318     
319 }
320
Popular Tags