Hello. I have a quesiton about implementing a clock in java. I have the followin
ID: 3736572 • Letter: H
Question
Hello. I have a quesiton about implementing a clock in java.
I have the following code:
(The 30 here represents 30 minutes)
double minuteHand = 30/60.0*2.0*Math.PI;
double minute = Math.PI/2.0-minuteHand;
GeneralPath minutePath = new GeneralPath();
minutePath.moveTo(r, r);
minutePath.lineTo((float)cX+Math.cos(minute)*450,(float) (cY+Math.sin(minute)*450));
g2.draw(minutePath);
This works except that it draws the clock upside down. Setting it to 30 places trhe minute hand at 12 o'clock. Setting it to 60 points to 6 o'clock. What do I need to do to reverse this.
I have included a picture:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
/**
A Clock face
*/
public class ClockFace extends JPanel
{
/**
Constructs a Clock
@param x the left of the bounding rectangle
@param y the top of the bounding rectangle
@param width the width of the bounding rectangle
*/
public ClockFace(int x, int y, int width)
{
this.x = x;
this.y = y;
this.width = width;
this.setOpaque(false);
this.setPreferredSize(new Dimension(width, width));
}
public void translate(int dx, int dy)
{
x += dx;
y += dy;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
// draw the ticks
int tickLen = 10;
int medTickLen = 15;
int longTickLen = 20;
int r = width/2; //radius of clock
int cX = x+(width)/2;
int cY = y+(width)/2;
Stroke tickStroke = new BasicStroke(2f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1f);
GeneralPath ticksPath = new GeneralPath();
Ellipse2D.Double clockFace = new Ellipse2D.Double(this.x,this.y,width, width);
g2.setColor(Color.WHITE);
g2.fill(clockFace);
for ( int i=1; i<= 60; i++){
// default tick length is short
int len = tickLen;
if ( i % 15 == 0 ){
// Longest tick on quarters (every 15 ticks)
len = longTickLen;
} else if ( i % 5 == 0 ){
// Medium ticks on the '5's (every 5 ticks)
len = medTickLen;
}
double di = (double)i; // tick num as double for easier math
// Get the angle from 12 O'Clock to this tick (radians)
double angleFrom12 = di/60.0*2.0*Math.PI;
// Get the angle from 3 O'Clock to this tick
// Note: 3 O'Clock corresponds with zero angle in unit circle
// Makes it easier to do the math.
double angleFrom3 = Math.PI/2.0-angleFrom12;
// Move to the outer edge of the circle at correct position
// for this tick.
ticksPath.moveTo(
(float)(cX+Math.cos(angleFrom3)*r),
(float)(cY-Math.sin(angleFrom3)*r)
);
// Draw line inward along radius for length of tick mark
ticksPath.lineTo(
(float)(cX+Math.cos(angleFrom3)*(r-len)),
(float)(cY-Math.sin(angleFrom3)*(r-len))
);
}
// Draw the full shape onto the graphics context.
g2.setColor(Color.BLACK);
g2.setStroke(tickStroke);
g2.draw(ticksPath);
g2.setColor(Color.RED);
for ( int i=1; i<=12; i++){
String numStr = ""+i;
FontMetrics fm = g2.getFontMetrics(g2.getFont());
int charWidth = fm.stringWidth(numStr);
int charHeight = fm.getHeight();
double di = (double)i;
double angleFrom12 = di/12.0*2.0*Math.PI;
double angleFrom3 = Math.PI/2.0-angleFrom12;
int tx = (int)(Math.cos(angleFrom3)*(r-longTickLen-charWidth));
int ty = (int)(-Math.sin(angleFrom3)*(r-longTickLen-charHeight));
g2.drawString(numStr, (int)cX+tx, (int)cY+ty);
}
double minuteHand = 30/60.0*2.0*Math.PI;
double minute = Math.PI/2.0-minuteHand;
GeneralPath minutePath = new GeneralPath();
minutePath.moveTo(r, r);
minutePath.lineTo((float)cX+Math.cos(minute)*450,(float) (cY+Math.sin(minute)*450));
g2.draw(minutePath);
}
private int x;
private int y;
private int width;
}
Explanation / Answer
import java.awt; import javax.swing; import java.uti; public class StillClock extends JPanel { private int hour; private int minute; private int second; public StillClock() { setCurrentTime(); } public StillClock(int hour, int minute, int second) { this.hour = hour; this.minute = minute; this.second = second; } public int getHour() { return hour; } public void setHour(int hour) { this.hour = hour; repaint(); } public int getMinute() { return minute; } public void setMinute(int minute) { this.minute = minute; repaint(); } public int getSecond() { return second; } /** Set a new second */ public void setSecond(int second) { this.second = second; repaint(); } protected void paintComponent(Graphics g) { super.paintComponent(g); int clockRadius = (int)(Math.min(getWidth(), getHeight()) * 0.8 * 0.5); int xCenter = getWidth() / 2; int yCenter = getHeight() / 2; g.setColor(Color.black); g.drawOval(xCenter - clockRadius, yCenter - clockRadius, 2 * clockRadius, 2 * clockRadius); g.drawString("12", xCenter - 5, yCenter - clockRadius + 12); g.drawString("9", xCenter - clockRadius + 3, yCenter + 5); g.drawString("3", xCenter + clockRadius - 10, yCenter + 3); g.drawString("6", xCenter - 3, yCenter + clockRadius - 3); int sLength = (int)(clockRadius * 0.8); int xSecond = (int)(xCenter + sLength * Math.sin(second * (2 * Math.PI / 60))); int ySecond = (int)(yCenter - sLength * Math.cos(second * (2 * Math.PI / 60))); g.setColor(Color.red); g.drawLine(xCenter, yCenter, xSecond, ySecond); int mLength = (int)(clockRadius * 0.65); int xMinute = (int)(xCenter + mLength * Math.sin(minute * (2 * Math.PI / 60))); int yMinute = (int)(yCenter - mLength * Math.cos(minute * (2 * Math.PI / 60))); g.setColor(Color.blue); g.drawLine(xCenter, yCenter, xMinute, yMinute); int hLength = (int)(clockRadius * 0.5); int xHour = (int)(xCenter + hLength * Math.sin((hour % 12 + minute / 60.0) * (2 * Math.PI / 12))); int yHour = (int)(yCenter - hLength * Math.cos((hour % 12 + minute / 60.0) * (2 * Math.PI / 12))); g.setColor(Color.BLACK); g.drawLine(xCenter, yCenter, xHour, yHour); } public void setCurrentTime() { Calendar calendar = new GregorianCalendar(); this.hour = calendar.get(Calendar.HOUR_OF_DAY); this.minute = calendar.get(Calendar.MINUTE); this.second = calendar.get(Calendar.SECOND); } public Dimension getPreferredSize() { return new Dimension(200, 200); } }
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.