import java.awt.* ; import java.awt.event.* ; import java.applet.* ; public class RollingCircle extends Applet implements Runnable, ActionListener { Thread th = null ; static final float rInner = 90 ; static final float rOuter = 30 ; int cWidth, cHeight ; int t = 0 ; Image backImg = null ; Graphics backG = null ; Button startStop = new Button("Start") ; Button resetBtn = new Button("Reset") ; Button stepBtn = new Button("Step") ; boolean isRunning = false ; public void init() { add(startStop) ; add(resetBtn) ; add(stepBtn) ; startStop.addActionListener(this) ; resetBtn.addActionListener(this) ; stepBtn.addActionListener(this) ; } public void actionPerformed(ActionEvent e) { if( e.getSource() == startStop ) { isRunning = !isRunning ; if( isRunning ) { startStop.setLabel("Stop") ; } else { startStop.setLabel("Start") ; } startStop.repaint() ; } else if( e.getSource() == resetBtn ) { isRunning = false ; t = 0 ; startStop.setLabel("Start") ; startStop.repaint() ; repaint() ; } else if( e.getSource() == stepBtn ) { if( !isRunning ) { t = (t+5)%360 ; repaint() ; } } } private void drawInner() { backG.setColor(Color.white) ; backG.fillRect(0,0,cWidth,cHeight) ; backG.setColor(Color.red) ; backG.drawLine(0, cHeight/2, cWidth-1, cHeight/2) ; backG.drawLine(cWidth/2, 0, cWidth/2, cHeight-1) ; backG.setColor(Color.black) ; backG.drawOval( cWidth/2-(int)rInner, cHeight/2-(int)rInner, (int)rInner*2, (int)rInner*2 ) ; } private void drawOuter() { int cx, cy ; int px, py ; int t2 ; cx = (int)((rInner+rOuter)*Math.cos((90.0-(float)t)*Math.PI/180.0)+0.5) ; cy = (int)((rInner+rOuter)*Math.sin((90.0-(float)t)*Math.PI/180.0)+0.5) ; px = cx - (int)(rOuter*Math.cos((90.0-(float)t*(1.0+rInner/rOuter))*Math.PI/180.0)+0.5) ; py = cy - (int)(rOuter*Math.sin((90.0-(float)t*(1.0+rInner/rOuter))*Math.PI/180.0)+0.5) ; backG.setColor(Color.black) ; for( t2=0 ; t2<360 ; t2+=120 ) { backG.fillArc( cWidth/2 +cx - (int)rOuter, cHeight/2-cy - (int)rOuter, (int)rOuter*2, (int)rOuter*2, (int)(-(float)t*(1.0+rInner/rOuter))+t2-60, 60) ; } backG.setColor(Color.blue) ; backG.drawOval( cWidth/2 +cx - (int)rOuter, cHeight/2-cy - (int)rOuter, (int)rOuter*2, (int)rOuter*2 ) ; backG.drawLine( cWidth/2 +cx, cHeight/2 -cy, cWidth/2 +px, cHeight/2 -py ) ; backG.fillOval( cWidth/2 +px-3, cHeight/2 -py-3, 6,6 ) ; } public void start() { cWidth = getSize().width ; cHeight = getSize().height ; backImg = createImage(cWidth, cHeight) ; backG = backImg.getGraphics() ; repaint() ; th = new Thread(this) ; th.start() ; } public void run() { while( th != null ) { repaint() ; try { th.sleep(50) ; } catch(InterruptedException e) { } if( isRunning ) { t = (t+5)%360 ; } } } public void update(Graphics g) { paint(g) ; } public void paint(Graphics g) { if( backImg != null ) { drawInner() ; drawOuter() ; g.drawImage(backImg,0,0,this) ; } } }