// AClock.java // TEF 15 March 2007 // // Purpose: // Practicing Java. Present an analog clock, updated periodically. // Refactoring AnalogClock.java. I want only a single class file. // // // Interface: // Public Attributes: // Public Methods: // import javax.swing.*; import java.awt.*; import java.awt.event.*; public class AClock extends JPanel{ int hour = 0; int minute = 0; int second = 0; static boolean testing = false; public static void main (String[] args) { if(args.length > 0) { testing = args[0].contains("test"); } AClock gui = new AClock(); gui.go(); } public void go() { JFrame frame = new JFrame("Todd's Clock"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //ClockPanel clock = new AClock(); //clock instead of self: frame.getContentPane().add(BorderLayout.CENTER, this); frame.setSize(300,300); frame.setVisible(true); for (;;) { final int delay; if (testing) { // Test movement delay = 2; second += 10; minute += (second / 60); hour += (minute / 60); second %= 60; minute %= 60; hour %= 12; } else { delay = 20000; // 20,000ms = 20sec java.util.Calendar cal = java.util.Calendar.getInstance(); hour = cal.get(java.util.Calendar.HOUR); minute = cal.get(java.util.Calendar.MINUTE); second = cal.get(java.util.Calendar.SECOND); } //clock. repaint(); try { Thread.sleep(delay); } catch (Exception ex) { } } } // Going to reuse my root class so as to contain in a single class file. // class ClockPanel extends JPanel { double marginPercent; int width; int height; int centerX; int centerY; int radius; int margin; int diameter; public void paintComponent(Graphics g) { marginPercent = 0.1; width = getWidth(); height = getHeight(); centerX = width / 2; centerY = height / 2; radius = Math.min(centerX, centerY); margin = (int) (marginPercent * radius); radius -= margin; diameter = radius * 2; /* System.out.println("W = " + width + "; H = " + height + "; cX = " + centerX + "; cY = " + centerY + "; r = " + radius + "; margin = " + margin); */ Graphics2D g2d = (Graphics2D) g; GradientPaint myGrad = new GradientPaint( 0, height, Color.black, width, 0, new Color(100, 100, 100)); g2d.setPaint(myGrad); g2d.fillRect(0, 0, width, height); g2d.setColor(new Color(149, 255, 122)); g2d.fillOval(centerX - radius, centerY - radius, diameter, diameter); //centerX + radius, centerY + radius); // Interpret Time double decSec = second / 60.0; // decSec is the portion of a minute to add to decMin double decMin = (minute / 60.0) + (decSec / 60.0); // decMin is the portion of an hour to add to decHour double decHour = (hour / 12.0) + (decMin / 12.0); /* System.out.println("Time: " + hour + ":" + minute + ":" + second + " = " + decHour + " (" + decMin + ")"); */ // Draw the Hands (hour hand 3/4 length of minute hand) g2d.setColor(Color.blue); drawHand(g, decHour, (int)(3.0/4.0 * radius)); g2d.setColor(Color.red); drawHand(g, decMin, radius); } private void drawHand (Graphics g, double decTime, int length) { // The clock hand is a filled-in arc with the round part at // the center of the clock face and its origin on the circle. // Find where on the circle to perch the center of our arc double thetaRadians = decTime * 2.0 * Math.PI; int myCenterX = (int) (Math.sin(thetaRadians) * length) + centerX; // Advance the cos by 180 degrees to fit our application: thetaRadians += Math.PI; int myCenterY = (int) (Math.cos(thetaRadians) * length) + centerY; int myOrigX = myCenterX - length - margin; int myOrigY = myCenterY - length - margin; int myDiameter = 2 * (length + margin); // The arc's theta is measured in degrees. int arcTheta = (int) (decTime * 360.0); // The arc's theta should be 180 deg off the time since it's backward // (starting from the clock face and extending inward). arcTheta += 180; // It should lose 90 deg off because of the way the // fillArc function works, with 0 degrees at 3 o'clock. arcTheta -= 90; // Just to be safe, make sure arcTheta is under 360 arcTheta %= 360; // Finally, it should be negative since that's how fillArc counts // angles going clockwise. arcTheta *= -1; /* System.out.println("decTime = " + decTime + "\tHand angle = " + arcTheta); System.out.printf("Hand: x=%d, y=%d, diameter = %d\n", myOrigX, myOrigY, myDiameter); */ g.fillArc(myOrigX, myOrigY, myDiameter, myDiameter, arcTheta-2, 4); } //} }