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 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 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 47 public void setZero(double z) { 48 zero = z; 49 } 50 51 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 61 public void setSize(Dimension d) { super.setSize(d); setSize((int)d.getWidth(),(int)d.getHeight()); } 62 63 64 public Dimension getPreferredSize() { return new Dimension((int)(2*radius),(int)(2*radius)); } 65 66 69 public void setMinorTickSpacing(double s) { 70 minorTic = s; 71 updateMinorTics(); 72 repaint(); 73 } 74 75 78 public void setMajorTickSpacing(double s) { 79 majorTic = s; 80 updateMajorTics(); 81 repaint(); 82 } 83 84 87 public void setPaintMinorTicks(boolean b) { 88 setPaintMinorTicks = b; 89 repaint(); 90 } 91 92 95 public void setPaintMajorTicks(boolean b) { 96 setPaintMajorTicks = b; 97 repaint(); 98 } 99 100 103 public void setPaintLabels(boolean b) { 104 setPaintLabels = b; 105 repaint(); 106 } 107 108 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 [] 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 [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 168 public void paintComponent(Graphics g) { 169 super.paintComponent(g); 170 Graphics2D g2 = (Graphics2D)g; 171 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 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 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 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 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 272 public static void main(String [] 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 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 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 310 } 316 317 318 319 } 320 | Popular Tags |