0

I've got a school assignment where I have to create a simple analog and digital clock that displays the time like this "XX:XX" and draws a clock. As in this example:

simple clock

I've written something in Java, but I get all kinds of errors. The goal of this assignment was learning to implement classes and define methods, etc. If anyone can give me some tips (not the actual solution) on what is wrong or what I can improve, I would be very grateful.

Main code

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class ShowClock {

    public static void main (String[] args) {
        double hour = Double.parseDouble(JOptionPane.showInputDialog("What time is it (hours)?"));
        double minutes = Double.parseDouble(JOptionPane.showInputDialog("What time is it (minutes)?"));
        String time= String.valueOf(hour) + String.valueOf(minutes) ;

        JFrame frame = new JFrame("test app"); 
        frame.setSize(300,400); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setTitle("Hoe laat is het?");

        Klok k = new Klok(hour, minutes); 
        frame.add(k); 
        frame.setVisible(true);;
    }
}

Class Klok

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;

class Klok extends JComponent {
    private double hour;
    private double minutes;
    private String time;

    int anglehour = (int)((90 - (hour + minutes / 60) * 30 ) * Math.PI / 180);
    int angleminutes = (int)((90 - minutes * 6.0) * Math.PI / 180);
    int xendpointhour = (int)(150+(75*Math.cos(anglehour)));
    int yendpointhour = (int)(150-(75*Math.sin(anglehour)));
    int xendpointminutes = (int)(150+(75*Math.cos(angleminutes)));
    int yendpointminutes = (int)(150-(75*Math.sin(angleminutes)));

    public void draw (Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.drawString(time, 0, 400);
        g2.drawOval(75,75, 150, 150);
        g2.drawLine(150,150, xendpointhour, yendpointhour);
        g2.drawLine(150, 150, xendpointminutes, yendpointminutes);
    }
}

UPDATE: I still don't quite get it. I think I need a simple explanation on how constructors and methods work, because my book is not very descriptive. Sorry for bothering anyone wit these noob questions...

Main Class

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class KlokTonen {

public static void main(String[] args) {
    double hour = Double.parseDouble(JOptionPane.showInputDialog("What time is it (hours)?"));
    double minutes = Double.parseDouble(JOptionPane.showInputDialog("What time is it (minutes)?"));
    String time= String.valueOf(hour) + String.valueOf(minutes) ;

    JFrame frame = new JFrame("test app"); frame.setSize(300,400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("Hoe laat is het?");
    Klok k = new Klok(hour, minutes); 
    frame.add(k); 
    frame.setVisible(true);;
}
}

Second Class

import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;

public class Klok extends JComponent {
private double hour; 
private double minutes;
private String time;
public void draw (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int angleHour = (int)((90 - (hour + minutes / 60) * 30 ) * Math.PI / 180);
int angleMinutes = (int)((90 - minutes * 6.0) * Math.PI / 180);
int xEndPointHour = (int)(150+(75*Math.cos(angleHour)));
int yEndPointHour = (int)(150-(75*Math.sin(angleHour)));
int xEndPointMinutes = (int)(150+(75*Math.cos(angleMinutes)));
int yEndPointMinutes = (int)(150-(75*Math.sin(angleMinutes)));
g2.drawString(time, 0, 400);
g2.drawOval(75,75, 150, 150);
g2.drawLine(150,150, xEndPointHour, yEndPointHour);
g2.drawLine(150, 150, xEndPointMinutes, yEndPointMinutes);
}
}
  • Hi Robin, what errors do you get? – Mark Pope Oct 14 '13 at 15:42
  • Thanks for your question! If you could post the stack trace or some of the errors you're getting, we can help locate the problem better. – dsrees Oct 14 '13 at 15:44
  • Eclipse is not relevant to this problem. Your issues are Java compilation errors (and bugs) ... and they have nothing to do with using Eclipse. – Stephen C Oct 14 '13 at 16:00
  • for public class Klok extends JComponent { in my second class I get: "The serializable class Klok does not declare a static final serialVersionUID field of type long" and for my main class I get "Multiple markers at this line - The constructor Klok(double, double) is undefined - Line breakpoint:KlokTonen [line: 14] - main(String[])" for Klok k = new Klok (hour,minutes) –  Oct 14 '13 at 16:06
  • "The constructor Klok(double, double) is undefined": This comes from the line in KlokTonen.java `Klok k = new Klok(hour, minutes);`. This is trying to construct a new `Klok` with two double values. Make sure the constructor in `Klok` takes two doubles: `public Klok(double hour, double minutes){ ... }` – Kenogu Labz Oct 14 '13 at 19:57
  • "The serializable class Klok does not declare a static final serialVersionUID field of type long": This is just a warning, and one that I'm pretty sure shouldn't affect the correctness of your application. – Kenogu Labz Oct 14 '13 at 19:58

4 Answers4

3

Hints:

  1. You need to declare a Klok constructor to match this: new Klok(hour, minutes)

  2. The calculation of angleHour, angleMinutes etcetera depends on the value of hour and minutes ... but at the point you are evaluating those expressions, you haven't given values for those variables.

  3. Presumably the hour and minute values of a Klok can change ...


While I have your attention, when you compose a Java identifier from multiple words, you should use "camel case"; e.g. angleHour not anglehour.


A Klok constructor matching that signature would look like this:

    public Klok (int hours, int minutes) {
        // ... you fill in the rest ...
    }

However, if you also want to initialize the time field with something computed in main, you need to pass that too ...

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Presumably, but not necessarily. Could just be a one-time display. – Kenogu Labz Oct 14 '13 at 15:50
  • 2
    @KenoguLabz - well the OP can decide. (He's the one with the requirements for his application.) – Stephen C Oct 14 '13 at 15:52
  • Okay thanks a lot! I still don't quite understand how to declare my constructor. The other 2 remarks are quite clear :) –  Oct 14 '13 at 16:14
  • Would that be in my main class or my Clock class? (I'm sorry, but I've never worked with java before...) –  Oct 14 '13 at 16:31
  • Constructors are always put in the class that is being constructed. Since you want to make a `Klok` object, put the constructor in the `Klok` class. Notice that the constructor name and class name always match: that's how you can tell where it should be! – Kenogu Labz Oct 14 '13 at 18:35
  • @KenoguLabz thanks for the info! I'm still stuck, program still won't run. I think I'm just horrible at understanding Java :( –  Oct 14 '13 at 18:46
  • Again, describe what errors the compiler is giving. 'Won't run' doesn't help you figure out the problem. – Kenogu Labz Oct 14 '13 at 19:53
1

In Klok, the variables listed from anglehour through yendpointminutes are using what is called an initializer block. This block is run before your constructor, which means that hour and minutes won't have values yet!

It may be more appropriate to define those variables at the top of the draw method:

public void draw (Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    int anglehour = ...;
    ...
}

Secondly, you'll need to actually set the values for hour, minutes and time. You already call a constructor when creating a new instance: Klok k = new Klok(hour, minutes);.
Now you just need to define this constructor in your Klok class. It'll take in values for hour and minutes and store them in the appropriate variables in the Klok object. For example:

public Klok(double hour, double minutes){
    ...
}
Community
  • 1
  • 1
Kenogu Labz
  • 1,094
  • 1
  • 9
  • 20
  • Are you sure about the "no code outside" part? These seem syntactically valid. (semantically it is obviously invalid...) – ppeterka Oct 14 '13 at 15:52
  • Yeah; I wrote than, then looked again and realized that the actual logic is inside a method. The mechanics of initializer blocks can be deceiving, so I'll focus on that instead. – Kenogu Labz Oct 14 '13 at 15:56
1

Java is not a declarative language. This

int anglehour = (int)((90 - (hour + minutes / 60) * 30 ) * Math.PI / 180);

expression is only executed at each instantiation of the Klok class. It does not declare the relation between the values of the variables: it does not have the meaning let the anglehour have the value that is calculated this way, for the current values fo the hour and minute variables. You always have to execute the calculation

You should rather omit the anglehour, angleminutes ... yendpointminutes variables, and create methods like this:

public int getAngleHour() {
  return (int)((90 - (hour + minutes / 60) * 30 ) * Math.PI / 180);
}

And use appropriately, after having assigned values the instance variables hour and minutes of course...

ppeterka
  • 20,583
  • 6
  • 63
  • 78
0

Your angles are not right because you are using integer arithmetic.

I would also suggest combining your hours and minutes into a decimal time, so that 12:30 becomes 12.5 (half an hour after 12).

Here's some code to work out the angle of the hour hand, to get you started. This assumes the top (12) is at angle 0 (or 360) and expresses the angle in degrees:

double time = (double)hour + ((double)minutes/60.0);
double anglehour = (360/12) * time;
NickJ
  • 9,380
  • 9
  • 51
  • 74
  • Well the formulas for my arrows of my clock were given by my teacher, so I'm not going to modify them :) –  Oct 14 '13 at 16:11
  • 1
    Fair enough then, but you still can't use all integers. – NickJ Oct 14 '13 at 16:13
  • @RobinHaveneers - it is not the formulae that are the problem. It is the way that the formulae have been coded that is the problem. (OTOH, the inaccuracy in the hand positions won't be that noticeable.) – Stephen C Oct 14 '13 at 22:32