Hi there,
I need to write a program that draws a clock face with a time that the user enters in two text fields (one for the hours, one for the minutes).
As far as I can tell I have all the code written, it's now just a matter of drawing the clock (even though it looks like it *should* draw).
Even though I have added the ClockViewerComponent to the JPanel in ClockViewerFrame, it doesn't draw before or after inputing the hour and minute. I can not figure out why :S. As I understand it, it should draw a clock with time 12:00 before any input - and then change accordingly after the input and click of the 'draw' button. Any tips/pointers in a mistake I made - or something I missed, would be very much appreciated.
import javax.swing.JFrame;
/**
* This program displays a clock face with a time
* the the user specified.
*/
public class ClockViewer {
public static void main (String[] args) {
JFrame frame = new ClockViewerFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("ClockViewer");
frame.setVisible(true);
}
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import java.util.Random;
import java.awt.geom.Line2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
/**
* This programs draws a clock based on the hour and minutes.
*/
public class ClockViewerComponent extends JComponent {
private double hours;
private double minutes;
private final double RADIUS = 100;
private final double MINUTES_PER_HOUR = 60;
private final double HOURS_PER_DAY = 12;
private final double HOUR_HAND = 75;
private final double MINUTE_HAND = 90;
/**
* Initilizes the component with a default time of 12:00.
*/
public ClockViewerComponent() {
hours = 12;
minutes = 0;
}
/**
* Sets the time of the clock.
* @param anHour the hour
* @param aMinute the minute(s)
*/
public void setHourAndMinute(double anHour, double aMinute) {
minutes = aMinute;
hours = anHour;
}
/**
* Paints the clock within the JFrame.
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double face = new Ellipse2D.Double(0, 0, 2 * RADIUS,
2 * RADIUS);
g2.draw(face);
Point2D.Double center = new Point2D.Double(RADIUS, RADIUS);
double angle = Math.PI /2 - 2 * Math.PI * minutes / MINUTES_PER_HOUR;
Point2D.Double minutePoint = new Point2D.Double(RADIUS + MINUTE_HAND
* Math.cos(angle), RADIUS - MINUTE_HAND * Math.sin(angle));
Line2D.Double minuteHand = new Line2D.Double(center, minutePoint);
g2.draw(minuteHand);
angle = Math.PI / 2 - 2 * Math.PI * (hours * MINUTES_PER_HOUR +
minutes) / (MINUTES_PER_HOUR * HOURS_PER_DAY);
Point2D.Double hourPoint = new Point2D.Double(RADIUS + HOUR_HAND *
Math.cos(angle), RADIUS - HOUR_HAND * Math.sin(angle));
Line2D.Double hourHand = new Line2D.Double(center, hourPoint);
g2.draw(hourHand);
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* This program creates a template JFrame for our clock.
*/
public class ClockViewerFrame extends JFrame {
private JLabel hourLabel;
private JLabel minuteLabel;
private JTextField hourField;
private JTextField minuteField;
private JButton button;
private JPanel panel;
private final int FRAME_WIDTH = 400;
private final int FRAME_HEIGHT = 400;
final ClockViewerComponent component;
/**
* Initializes the framer with the ClockViewer component,
* helper methods, and the frame size.
*/
public ClockViewerFrame() {
component = new ClockViewerComponent();
createTextField();
createButton();
createPanel();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
}
/**
* Creates the label and text field for the user to read,
* and input desired values.
*/
public void createTextField() {
final int FIELD_WIDTH = 5;
hourLabel = new JLabel("Hour = ");
hourField = new JTextField(FIELD_WIDTH);
hourField.setText("");
minuteLabel = new JLabel("Minute = ");
minuteField = new JTextField(FIELD_WIDTH);
minuteField.setText("");
}
/**
* Creates the button the user clicks when finishing entering input,
* Takes the input and passes it to the component.
*/
public void createButton() {
button = new JButton("Draw");
class DrawListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
double hour = Double.parseDouble(hourField.getText());
double minute = Double.parseDouble(minuteField.getText());
component.setHourAndMinute(hour, minute);
component.repaint();
}
}
ActionListener listener = new DrawListener();
button.addActionListener(listener);
}
/**
* Adds the panel and adds each part to it.
*/
private void createPanel() {
panel = new JPanel();
panel.add(hourLabel);
panel.add(hourField);
panel.add(minuteLabel);
panel.add(minuteField);
panel.add(button);
panel.add(component);
add(panel);
}
}