m@0: import java.awt.*; m@0: import java.awt.geom.*; m@0: import javax.swing.*; m@0: m@0: /** Clocks displayed in a panel. */ m@0: public class Clock extends JPanel implements Runnable { m@0: m@0: /* The default colours */ m@0: static final Color BACKGROUND = Color.black; m@0: static final Color FOREGROUND = Color.white; m@0: m@0: /* Panel width, height and border. */ m@0: public static final int WIDTH = 450; m@0: public static final int BORDER = 50; m@0: m@0: /* Minutes in a day. */ m@0: public static final int ONE_DAY = 24 * 60; m@0: m@0: /* Show the clock? */ m@0: public Boolean showClock = false; m@0: public Boolean showFullClock = false; m@0: m@0: /* minutes since midnight, range 0 to (ONE_DAY - 1) inclusive */ m@0: private int minutes = 0; m@0: m@0: /* Milliseconds per tick of the minute hand */ m@0: private long millisecondsPerTick = 1000; m@0: public void setMillisecondsPerTick(long n) { millisecondsPerTick = n; } m@0: jeremy@27: private boolean debug; jeremy@27: m@0: /* Create a new Clock at time midnight. */ jeremy@27: public Clock(boolean d) { m@0: this.setBackground(BACKGROUND); m@0: this.setPreferredSize (new Dimension (WIDTH, WIDTH)); jeremy@27: debug = d; m@0: } m@0: m@0: public void run() { m@0: reset(); m@0: if (showClock == false) { m@0: showClock = true; m@0: repaint(); m@0: } m@0: for (int i = 0; i < 60; i++) { m@0: try { Thread.sleep (millisecondsPerTick); } m@0: catch (InterruptedException e) {} m@0: tick(1); m@0: repaint(); m@0: } m@4: showClock = false; m@4: showFullClock = false; jeremy@27: if (debug) jeremy@27: System.out.println("RUN CLOCK"); m@4: reset(); JShulver@23: revalidate(); m@4: repaint(); m@4: } m@0: m@0: /* Move time on by 1 second. */ m@0: public void tick(int n) { m@0: minutes = (minutes + n) % ONE_DAY; m@0: } m@0: m@0: /* Reset the clock to 00:00. */ m@0: public void reset() { jeremy@27: if (debug) jeremy@27: System.out.println("RESET!"); m@0: minutes = 0; m@0: } m@0: m@0: /* Draw the clock or fixation point. */ m@0: public void paintComponent (Graphics g) { JShulver@23: super.paintComponent (g); m@0: m@0: if (showClock == true) { m@0: paintClock(g); m@0: } else { JShulver@23: paintFixationPoint(g); m@0: } JShulver@23: //just ensure that java knows we want to draw new things JShulver@23: revalidate(); m@0: } m@0: m@0: private void paintFixationPoint(Graphics g) { m@4: //System.out.println("paintFixationPoint"); m@0: int left_edge = BORDER; m@0: int top = BORDER; m@0: int diameter = WIDTH - (BORDER * 2); m@0: int centrex = left_edge + (diameter / 2); m@0: int centrey = top + (diameter / 2); m@0: m@0: int linelength = diameter / 20; m@0: m@0: g.setColor(FOREGROUND); m@0: g.drawLine(centrey, centrex - linelength, centrey, centrex + linelength); m@0: g.drawLine(centrey - linelength, centrex, centrey + linelength, centrex); m@0: } m@0: m@0: private void paintClock (Graphics g) { m@4: //System.out.println("paintClock"); m@0: int minutes_angle = 90 - ((minutes % 60) * 6); m@0: int hours_angle = 90 - ((minutes / 60) * 30); m@0: int left_edge = BORDER; m@0: int top = BORDER; m@0: int diameter = WIDTH - (BORDER * 2); JShulver@23: int radius = diameter / 2; m@0: int centrex = left_edge + radius; m@0: int centrey = top + radius; m@0: m@0: g.setColor(FOREGROUND); m@0: m@0: // draw the clock as a black circle: m@0: g.drawOval(left_edge, top, diameter, diameter); m@0: m@0: // draw the hour numbers JShulver@23: int offset = 0; m@0: for(int i = 1; i <= 12; i++) { m@0: int hours_pos = 90 - (i * 30); m@0: int x = (centrex - offset) + m@0: (int)((radius - 5) * Math.cos(hours_pos * Math.PI / 180)); m@0: int y = (centrey + offset) - m@0: (int)((radius - 5) * Math.sin(hours_pos * Math.PI / 180)); m@0: //g.drawString(String.valueOf(i), x, y); m@0: g.drawOval(x, y, diameter / 200, diameter / 200); m@0: } m@0: m@0: // get the coordinate of the line_ends m@0: int minutesx = (int)((radius - 5) * m@0: Math.cos(minutes_angle * Math.PI / 180)); m@0: int minutesy = (int)((radius - 5) * m@0: Math.sin(minutes_angle * Math.PI /180)); m@0: m@0: // draw the minutes' hand m@0: g.drawLine(centrex, centrey, centrex + minutesx, centrey - minutesy); m@0: m@0: int arc_angle = minutes_angle - 90; m@0: Graphics2D g2 = (Graphics2D)g; m@0: g2.setPaint(FOREGROUND); m@0: jeremy@27: if (debug) jeremy@27: System.out.println("minutes_angle = " + minutes_angle + JShulver@23: "; arc_angle = " + arc_angle); m@0: m@0: if (arc_angle == 0 & showFullClock == true) { m@0: g2.fillOval(left_edge, top, diameter, diameter); m@0: showFullClock = false; m@0: } else { m@0: showFullClock = true; m@0: if (arc_angle >= -180) { m@0: Arc2D pie = new Arc2D.Float(centrex - radius, centrey - radius, m@0: 2 * radius, 2 * radius, m@0: 90, arc_angle, m@0: Arc2D.PIE); m@0: g2.fill(pie); m@0: } else { m@0: Arc2D pie1 = new Arc2D.Float(centrex - radius, centrey - radius, m@0: 2 * radius, 2 * radius, m@0: 90, -180, Arc2D.PIE); m@0: Arc2D pie2 = new Arc2D.Float(centrex - radius, centrey - radius, m@0: 2 * radius, 2 * radius, m@0: 270, arc_angle + 180, m@0: Arc2D.PIE); m@0: g2.fill(pie1); m@0: g2.fill(pie2); m@0: } m@0: } m@0: } m@0: }