Results 1 to 14 of 14
Thread: Analog Clock Help
- 04-29-2009, 02:43 AM #1
Member
- Join Date
- Feb 2009
- Posts
- 3
- Rep Power
- 0
Analog Clock Help
I am starting to code an analog clock. So far I have got the face and hands set at a fixed time but I cannot figure out how to change the position of the hands without screwing up the hands. Eventually I will have input boxes for hr and min in order to set the time, but I want to get the hand movement right first before coding buttons and textboxes. Any help would be appreciated!
import java.awt.;
import java.awt.event.;
import java.awt.geom.;
import javax.swing.;
public class clocky extends Frame {
final int centerX = 150;
final int centerY = 180;
Shape circle = new Ellipse2D.Double(50, 80, 200, 200);
public void paint(Graphics g)
{
Graphics2D ga = (Graphics2D)g;
ga.draw(circle);
//mins hand
ga.drawLine(240, 180, centerX, centerY);
//hrs hand
ga.drawLine(150, 140, centerX, centerY);
}
public static void main(String args[]) {
Frame frame = new clocky();
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
frame.setSize(300, 300);
frame.setVisible(true);
}
-
A couple of suggestions:
1) Get it out of a JFrame and put it into a JPanel and override paintComponent not paint. This will give you Swing's double buffering and make your animation smoother. You can later put the JPanel into a JFrame (or JApplet) when you're ready to display the final product.
2) Make this clock a true OOP class and give it methods that allow you to change its state -- mainly its time -- when desired. I'd give it a setTime(long t) method.
3) In a separate class have a Swing Timer object call setTime(...) every xxx milliseconds, and this can be the animation that drives your app.
Also, you would do well to read the Sun tutorials on doing Graphics with Java and Swing and the tutorial on using a Swing Timer.Last edited by Fubarable; 04-29-2009 at 03:01 AM.
- 04-29-2009, 03:03 AM #3
Moderator
- Join Date
- Feb 2009
- Location
- New Zealand
- Posts
- 4,547
- Rep Power
- 11
> So far I have got the face and hands set at a fixed time
I see two lines being draw to a "center" point - but nothing in the clock that represent the time (whether fixed or not).
Add an instance variable of an appropriate type to represent the time being displayed by the clock. Then figure out how to draw the hands at this moment in time.
A little trigonometry will help. Eg the minute hand: this thing goes around in 60 minutes. So how many degrees will it travel in one minute? Once you have that figured out it will be easy to figure out how many degrees it will move for some general time m minutes.
Suppose the clock has a hand with length r. Then at a time when the angle is a, the situation will look like this:
Then we useJava Code:(an arbitrary vertical line) . . . x ....../ . /length r . / . . / . y .a/ . ./ .
x= r * sin(a)
y= - r * cos(a)
(I think that's right - the computer uses positive=down. If not you'll later see the clock run backwards or be out by 15 seconds: things like that. Then you can change sin<->cos and alter the signs ad lib.)
Finally, of course you add the x and y values to the center values to obtain the coordinates of the end of the line.
Be warned that Java uses radians, not degrees when calculating sin and cos. But there's a method for converting between the two.
If I were you I would start here. Ie: get the clock able to draw its minute hand for any arbitrary time. The hour hand is not a lot different.
-
cross-posted in the sun java programming forum
- 04-29-2009, 03:53 AM #5
Member
- Join Date
- Feb 2009
- Posts
- 3
- Rep Power
- 0
Thanks
Thanks for the help everyone!
- 06-01-2010, 08:18 PM #6
Member
- Join Date
- Jun 2010
- Posts
- 4
- Rep Power
- 0
// minute hand
float fminutes = (float)(minutes + fseconds/60.0);
float minuteAngle = threePi - (radPerSecMin * fminutes);
drawRadius(g, centerX, centerY, minuteAngle, 0, minuteRadius);
can anybody explain me why is used threePi - (radPerSecMin * fminutes) ????
- 06-01-2010, 08:31 PM #7
Look at the definition for the parms for the drawRadius() method. What is the fourth parameter?
Then you need the value of threePi.
- 06-01-2010, 08:32 PM #8
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 11,427
- Blog Entries
- 7
- Rep Power
- 17
- 06-01-2010, 08:50 PM #9
Member
- Join Date
- Jun 2010
- Posts
- 4
- Rep Power
- 0
- 06-01-2010, 10:45 PM #10
What is it? How is it used in the method?radPerSecMin*sec
The method must do some trigonometry with that value to decide where to draw a line.
Look at the code in the method.
- 06-02-2010, 04:38 PM #11
Member
- Join Date
- Jun 2010
- Posts
- 4
- Rep Power
- 0
what the part with bold mean ?? i cant understand them. can anyone help me pls??
// An analog clock -- Using Timer and Calendar.
//Programi perdor Buffered drawing per te
// Grupi A1;Viti II
// 01/06/2010
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.Timer;
///////////////////////////////////////////////////////////// ClockAnalog
public class ClockAnalog extends JFrame {
Clock clockFace;
//================================================== =============== main
public static void main(String[] args) {
JFrame windo = new ClockAnalog();
windo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
windo.setVisible(true);
}//end main
//================================================== ======== constructor
public ClockAnalog() {
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
clockFace = new Clock();
content.add(clockFace, BorderLayout.CENTER);
this.setTitle("Analog Clock");
this.pack(); // Layout components
clockFace.start();
}//end constructor
}//end class ClockAnalog
//////////////////////////////////////////////////////////////// Clock class
class Clock extends JPanel {
private int hours = 0;
private int minutes = 0;
private int seconds = 0;
private int millis = 0;
private static final int spacing = 10;
private static final float twoPi = (float)(2.0 * Math.PI);
private static final float threePi = (float)(3.0 * Math.PI);
// Kendet per funksionet trigonometrike maten ne radiane
// The following in the number of radians per sec or min.
private static final float radPerSecMin = (float)(Math.PI / 30.0); // rrethi eshte 360 grade ndersa ora ka 60 min ndaj 2PI/60=PI/30
private int size; // height dhe width te ores
private int centerX; // x coord qendres se ores
private int centerY; // y coord qendres se ores
private BufferedImage clockImage;
private Timer t;
//================================================== == Clock constructor
public Clock() {
this.setPreferredSize(new Dimension(300,300));
this.setBackground(Color.gray);
t = new Timer(1000,
new ActionListener() {
public void actionPerformed(ActionEvent e) {
update();
}
});
}//end constructor
//================================================== ============= update
// Replace the default update so that the plain background
// doesn't get drawn.
public void update() {
this.repaint();
}//end update
//================================================== ============== start
public void start() {
t.start(); // start the timer
}//end start
//================================================== =============== stop
public void stop() {
t.stop(); // stop the timer
}//end stop
//================================================== ===== paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g); // paint background, borders
Graphics2D g2 = (Graphics2D)g;
// Paneli mund te kete ndryshuar permasa, marrim dimensionin aktual te tij
int w = getWidth();
int h = getHeight();
size = ((w<h) ? w : h) - 2*spacing;
centerX = size/2 + spacing;
centerY = size/2 + spacing;
// krijojme backgroundin e ores nqs po krijohet per here te pare
// ose nqs permasat e panelit ndryshojne
if (clockImage == null
|| clockImage.getWidth() != w
|| clockImage.getHeight() != h) {
clockImage = (BufferedImage)(this.createImage(w, h)); //krijimi i imazhit
// now get a graphics context from this image
Graphics2D gc = clockImage.createGraphics();
drawClockFace(gc);
}
//Marrim oren dhe vizatojme akrepat.
Calendar now = Calendar.getInstance();
hours = now.get(Calendar.HOUR);
minutes = now.get(Calendar.MINUTE);
seconds = now.get(Calendar.SECOND);
millis = now.get(Calendar.MILLISECOND);
// vizatojme oren nga imazhi i paracaktuar
g2.drawImage(clockImage,0, 0,this);
// Draw the clock hands
drawClockHands(g);
}//end paintComponent
//================================================== ===== drawClockHands
private void drawClockHands(Graphics g) {
int secondRadius = size/2; // sa rrezja
int minuteRadius = secondRadius * 3/4;
int hourRadius = secondRadius/2;
// second hand
float fseconds = seconds + (float)millis/1000;
float secondAngle = threePi - (radPerSecMin * fseconds);
drawRadius(g, centerX, centerY, secondAngle, 0, secondRadius);
// minute hand
float fminutes = (float)(minutes + fseconds/60.0);
float minuteAngle = threePi - (radPerSecMin * fminutes);
drawRadius(g, centerX, centerY, minuteAngle, 0, minuteRadius);
// hour hand
float fhours = (float)(hours + fminutes/60.0);
float hourAngle = threePi - (5 * radPerSecMin * fhours);
drawRadius(g, centerX, centerY, hourAngle, 0, hourRadius);
}//end drawClockHands
//================================================== ====== drawClockFace
private void drawClockFace(Graphics g) {
// clock face
g.setColor(Color.white);
g.fillOval(spacing, spacing, size, size);
g.setColor(Color.black);
g.drawOval(spacing, spacing, size, size);
// tic marks
for (int sec = 0; sec<60; sec++) {
int ticStart;
if (sec%5 == 0) {
ticStart = size/2-10;
} else {
ticStart = size/2-5;
}
drawRadius(g, centerX, centerY, radPerSecMin*sec, ticStart , size/2);
}
}//endmethod drawClockFace
//================================================== ========= drawRadius
private void drawRadius(Graphics g, int x, int y, double angle,
int minRadius, int maxRadius) {
float sine = (float)Math.sin(angle);
float cosine = (float)Math.cos(angle);
int dxmin = (int)(minRadius * sine);
int dymin = (int)(minRadius * cosine);
int dxmax = (int)(maxRadius * sine);
int dymax = (int)(maxRadius * cosine);
g.drawLine(x+dxmin, y+dymin, x+dxmax, y+dymax);
}//end drawRadius
}//endclass Clock
- 06-02-2010, 05:08 PM #12
Defines a variable.private BufferedImage clockImage;
Evaluate an expression and assigns its value to a variablefloat secondAngle = threePi - (radPerSecMin * fseconds);
float hourAngle = threePi - (5 * radPerSecMin * fhours);
ticStart = size/2-10;
The assignment statements and equations are typical of a program that is computing some complicated value. Some equations are simpler. For example to find the time it takes to travel 5 miles at 2 miles per hour you would use the equation: 5(miles)/2(miles per hr).
You need to know trigonometry and perhaps some other mathematics to understand what the equations are doing.
This is NOT a java programming problem. Try asking a mathematician. Or the author of the program.
- 06-02-2010, 05:19 PM #13
Member
- Join Date
- Jun 2010
- Posts
- 4
- Rep Power
- 0
- 06-02-2010, 05:29 PM #14
The program you posted seems to work as you'd expect.
It has the code for moving the second hand.
You need to desk check the code to see how it works. That means taking a piece of paper and calculator and doing each of the steps and writing down the results. After you've done that you'll see how the equations work.
Similar Threads
-
java clock
By bugmenot in forum JCreatorReplies: 0Last Post: 04-07-2009, 10:25 PM -
Desktop Clock
By olamide in forum Threads and SynchronizationReplies: 1Last Post: 03-19-2009, 05:28 PM -
Need help with Java clock
By adz666 in forum New To JavaReplies: 1Last Post: 10-15-2008, 02:18 AM -
Break Clock
By BruenorBH in forum Advanced JavaReplies: 20Last Post: 09-12-2008, 05:27 AM -
Help please in digital clock
By jaidod in forum Java AppletsReplies: 1Last Post: 04-17-2008, 04:05 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks