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 13 public class JArcDial extends JPanel { 14 15 private double oneTurn; 16 private double zero; 17 private double startValue; 18 private double endValue; 19 private double startAngle = -2*Math.PI/6; 20 private double endAngle = 2*Math.PI/6; 21 private double ha; 23 private double hb; 24 private double va; 25 private double vb; 26 private double minorTic = 5; 27 private double majorTic = 20; 28 private boolean setPaintMinorTicks = true; 29 private boolean setPaintMajorTicks = true; 30 private boolean setPaintLabels = true; 31 private double radius = 70; 32 private ArrayList pointers = new ArrayList(); 33 private ChangeListener changeListener = new ChangeListener() { 34 public void stateChanged(ChangeEvent event) { 35 repaint(); 36 } 37 }; 38 39 44 public JArcDial(double start,double end) { 45 startValue=start; 46 endValue=end; 47 oneTurn = (endValue-startValue)*2.0*Math.PI/(endAngle-startAngle); 48 zero = startAngle-2.0*Math.PI*startValue/oneTurn; 49 setArc(-2*Math.PI/6,2*Math.PI/6); 50 setSize((int)(2*radius),(int)(2*radius)); 51 addMouseListener(new TheMouseListener()); 52 addMouseMotionListener(new TheMouseMotionListener()); 53 } 54 55 64 public void setArc(double start,double stop) { 65 if (start>stop) { throw new IllegalArgumentException ("start angle >stop angle"); } 66 startAngle = start; 67 endAngle = stop; 68 oneTurn = (endValue-startValue)*2.0*Math.PI/(endAngle-startAngle); 69 zero = startAngle-2.0*Math.PI*startValue/oneTurn; 70 71 double f; 72 73 f=-Math.PI/2+2.0*Math.PI*Math.round(start); 74 while (f>start) f-=2.0*Math.PI;while (f<start) f+=2.0*Math.PI; 75 if (f<stop) ha=1.0; 76 else ha=Math.max(-Math.sin(start)+0.1,-Math.sin(stop)+0.1); 77 78 f=Math.PI/2+2.0*Math.PI*Math.round(start); 79 while (f>start) f-=2.0*Math.PI;while (f<start) f+=2.0*Math.PI; 80 if (f<stop) hb=1.0; 81 else hb=Math.max(Math.sin(start)+0.1,Math.sin(stop)+0.1); 82 83 f=2.0*Math.PI*Math.round(start); 84 while (f>start) f-=2.0*Math.PI;while (f<start) f+=2.0*Math.PI; 85 if (f<stop) va=1.0; 86 else va=Math.max(Math.cos(start)+0.1,Math.cos(stop)+0.1); 87 88 f=Math.PI+2.0*Math.PI*Math.round(start); 89 while (f>start) f-=2.0*Math.PI;while (f<start) f+=2.0*Math.PI; 90 if (f<stop) vb=1.0; 91 else vb=Math.max(-Math.cos(start)+0.1,-Math.cos(stop)+0.1); 92 93 setSize((int)((ha+hb)*radius),(int)((va+vb)*radius)); 94 repaint(); 95 } 96 97 98 public void setSize(int w,int h) { 99 super.setSize(w,h); 100 radius = Math.min(w/(ha+hb),h/(va+vb)); 101 updateMinorTics(); 102 updateMajorTics(); 103 repaint(); 104 } 105 106 107 public void setSize(Dimension d) { super.setSize(d); setSize((int)d.getWidth(),(int)d.getHeight()); } 108 109 110 public Dimension getPreferredSize() { return new Dimension((int)((ha+hb)*radius),(int)((va+vb)*radius)); } 111 112 115 public void setMinorTickSpacing(double s) { 116 minorTic = s; 117 updateMinorTics(); 118 repaint(); 119 } 120 121 124 public void setMajorTickSpacing(double s) { 125 majorTic = s; 126 updateMajorTics(); 127 repaint(); 128 } 129 130 133 public void setPaintMinorTicks(boolean b) { 134 setPaintMinorTicks = b; 135 repaint(); 136 } 137 138 141 public void setPaintMajorTicks(boolean b) { 142 setPaintMajorTicks = b; 143 repaint(); 144 } 145 146 149 public void setPaintLabels(boolean b) { 150 setPaintLabels = b; 151 repaint(); 152 } 153 154 private Line2D [] minorTics = null; 155 private Line2D [] majorTics = null; 156 private Point2D [] ticLabelPos = null; 157 private String [] ticLabelText = null; 158 private static NumberFormat formatter; 159 static { 160 formatter = NumberFormat.getNumberInstance(); 161 formatter.setMaximumFractionDigits(2); 162 formatter.setMaximumIntegerDigits(3); 163 } 164 165 private void updateMinorTics() { 166 int N =(int)Math.abs((endValue-startValue)/minorTic); 167 double from = (startValue<endValue)?startValue:endValue; 168 minorTics = new Line2D[N]; 169 for (int j=0;j<N;j++) 170 minorTics[j] = 171 new Line2D.Double( 172 radius+radius*0.65*Math.sin(zero+2.0*Math.PI*(from+j*minorTic)/oneTurn), 173 radius-radius*0.65*Math.cos(zero+2.0*Math.PI*(from+j*minorTic)/oneTurn), 174 radius+radius*0.75*Math.sin(zero+2.0*Math.PI*(from+j*minorTic)/oneTurn), 175 radius-radius*0.75*Math.cos(zero+2.0*Math.PI*(from+j*minorTic)/oneTurn) 176 ); 177 } 178 179 private void updateMajorTics() { 180 int N =(int)Math.abs((endValue-startValue)/majorTic)+1; 181 double from = (startValue<endValue)?startValue:endValue; 182 majorTics = new Line2D[N]; 183 ticLabelPos = new Point2D[N]; 184 ticLabelText = new String [N]; 185 for (int j=0;j<N;j++) { 186 majorTics[j] = 187 new Line2D.Double( 188 radius+radius*0.65*Math.sin(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn), 189 radius-radius*0.65*Math.cos(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn), 190 radius+radius*0.8*Math.sin(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn), 191 radius-radius*0.8*Math.cos(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn) 192 ); 193 ticLabelText[j] = formatter.format(from+j*majorTic); 194 ticLabelPos[j] = 195 new Point2D.Double( 196 radius+radius*0.9*Math.sin(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn) 197 -ticLabelText[j].length()*3, 198 radius-radius*0.9*Math.cos(zero+2.0*Math.PI*(from+j*majorTic)/oneTurn) 199 +6 200 ); 201 } 202 203 } 204 205 206 207 public void paintComponent(Graphics g) { 208 super.paintComponent(g); 209 Graphics2D g2 = (Graphics2D)g; 210 if (setPaintMinorTicks) 212 for (int j=0;j<minorTics.length;j++) 213 g2.draw(minorTics[j]); 214 if (setPaintMajorTicks) 215 for (int j=0;j<majorTics.length;j++) 216 g2.draw(majorTics[j]); 217 if (setPaintLabels) 218 for (int j=0;j<majorTics.length;j++) 219 g2.drawString(ticLabelText[j],(int)ticLabelPos[j].getX(),(int)ticLabelPos[j].getY()); 220 Color saveColor = g2.getColor(); 221 for (int j=0;j<pointers.size();j++) 222 ((JPointer)pointers.get(j)).paintOnDial(g2,radius,oneTurn,zero,radius*ha,radius*va); 223 g2.setColor(saveColor); 224 g2.fill(new Ellipse2D.Double(radius-3.0,radius-3.0,6.0,6.0)); 225 } 226 227 230 public void addJPointer(JPointer p) { 231 for (int j=0;j<pointers.size();j++) if (pointers.get(j).equals(p)) return; 232 pointers.add(p); 233 p.addChangeListener(changeListener); 234 repaint(); 235 } 236 237 240 public void removeJPointer(JPointer p) { 241 int j=0; 242 while (j<pointers.size()) { 243 if (pointers.get(j).equals(p)) pointers.remove(j); 244 else j++; 245 } 246 p.removeChangeListener(changeListener); 247 repaint(); 248 } 249 250 252 private JPointer dragged = null; 253 private double dragDelta; 254 private double theta(MouseEvent e) { return Math.atan2(e.getX()-radius,-(e.getY()-radius)); } 255 private class TheMouseListener extends MouseAdapter { 256 public void mousePressed(MouseEvent e) { 257 for (int j=pointers.size()-1;j>=0;j--) 258 if (((JPointer)pointers.get(j)).contains(e.getPoint())) { 259 dragged=(JPointer)pointers.get(j); 260 dragDelta=2.0*Math.PI*dragged.getValue()/oneTurn-theta(e); 261 dragged.setAdjusting(true); 262 break; 263 } 264 } 265 public void mouseReleased(MouseEvent e) { 266 if (dragged!=null) dragged.setAdjusting(false); 267 dragged = null; 268 boolean inside = false; 269 for (int j=0;j<pointers.size();j++) 270 if (((JPointer)pointers.get(j)).contains(e.getPoint())) { 271 inside=true; 272 break; 273 } 274 if (inside) setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 275 else setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 276 } 277 } 278 279 private class TheMouseMotionListener extends MouseMotionAdapter { 280 public void mouseMoved(MouseEvent e) { 281 boolean inside = false; 282 for (int j=0;j<pointers.size();j++) 283 if (((JPointer)pointers.get(j)).contains(e.getPoint())) { 284 inside=true; 285 break; 286 } 287 if (inside) setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 288 else setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 289 } 290 public void mouseDragged(MouseEvent e) { 291 if (dragged!=null) { 292 double to = (theta(e)+dragDelta); 293 if (zero+to>endAngle) to=endAngle-zero; 294 if (zero+to<startAngle) to=startAngle-zero; 295 to*=oneTurn/2.0/Math.PI; 296 dragged.setValue(to); 297 repaint(); 298 } 299 } 300 } 301 302 303 304 306 public static void main(String [] args) { 307 JFrame frm = new JFrame(); 308 frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 309 JArcDial d = new JArcDial(90.0,10.0); 310 d.setArc(-4*Math.PI/6,Math.PI/6); 311 frm.getContentPane().add(d); 312 d.setSize(260,260); 313 frm.pack(); 314 frm.show(); 315 try { Thread.sleep(3000); } catch (InterruptedException e) {} 316 JPointer p = new JPointer(JPointer.POINTER_SIMPLE_QUADRANGLE); 317 p.setColor(Color.MAGENTA); 318 p.setValue(25.0); 319 d.addJPointer(p); 320 try { Thread.sleep(3000); } catch (InterruptedException e) {} 321 JPointer p1 = new JPointer(JPointer.POINTER_SIMPLE_TRIANGLE); 322 p1.setColor(Color.CYAN); 323 p1.setValue(75.0); 324 d.addJPointer(p1); 325 326 p1.addChangeListener(new ChangeListener() { 327 public void stateChanged(ChangeEvent e) { 328 double v=((JPointer)e.getSource()).getValue(); 329 System.out.println("State changed: "+v); 330 } 331 }); 332 333 342 } 348 349 350 351 } 352 | Popular Tags |