Miniprojekt Zeigeruhr

Im folgenden Projekt soll eine Uhr mit Stunden-, Minuten- und Sekundenzeiger programmiert werden, die die aktuelle Uhrzeit darstellt.

notwendige Voraussetzungen und Kenntnisse:

Klasse Line als Zeiger

Die Entwicklungsumgebung stellt bereits eine grafische Klasse Line (engl. Wort für Linie) bereit, die wir als Zeiger verwenden können. Die grafischen Objekt werden dabei in einem Grafikfenster dargestellt, das 800 Pixel breit und 600 Pixel hoch ist. Der Ursprung liegt in der linken oberen Ecke des Fensters. Nach rechts verläuft die x-Achse, nach unten die y-Achse.

Wir analysieren zunächst einmal, welche Methoden die Klasse bereitstellt. Dazu wird eine Variable testlinie deklariert und anschließend ein neues Line-Objekt erzeugt. Der Konstruktor der Klasse Line erwartet die x- und y-Koordinaten des Anfangspunktes sowie die x- und y-Koordinate des Endpunktes.

Führe das Programm aus . Verändere die Anweisungen so, dass die Linie senkrecht verläuft, 200 Pixel lang ist und grün dargestellt wird.
Line testlinie;
testlinie = new Line(100, 200, 300, 200);
testlinie.setBorderColor(Color.green);


Der Zeiger soll sich im Laufe der Zeit natürlich auch drehen. Die Klasse Line besitzt die Methode rotate, mit deren Hilfe die Linie um einen bestimmten Winkel im Gradmaß gegen den Uhrzeigersinn gedreht werden kann.

Die Methode rotate() gibt es mit unterschiedlichen Signaturen, d.h. die Methoden haben verschiedene Parameter. Falls nur ein Parameter verwendet wird, ist dies der Drehwinkel. Gedreht wird dabei um den Mittelpunkt der Linienstrecke.
Die zweite gleichnamige Methode mit drei Parametern erwartet als Eingabe den Drehwinkel und die x- und y-Koordinate des Drehpunktes. Diese Methode ist hilfreich, um die Linie wie einen Uhrenzeiger zu drehen. Für eine Drehung einer Strecke um 40° gegen den Uhrzeigersinn gibt es die beiden folgenden Möglichkeiten:

Teste das Programm und verändere es so, dass sich der Zeiger fortlaufend im Uhrzeigersinn um den unteren Endpunkt dreht.
Nutze dazu eine for-Wiederholung oder eine while-Wiederholung.

Als Drehpunkt der Methode rotate muss man einen Endpunkt der Strecke wählen.

Line testlinie;
testlinie = new Line(400, 300, 400, 100);
testlinie.setBorderColor(Color.red);
for(int i = 0; i < 60; i++) {
   testlinie.rotate(-6, 400, 300); 
}      

Klasse Zeiger als Oberklasse aller Uhrenzeiger

Wir erstellen nun eine Klasse Zeiger, die von der Klasse Line erbt.

Die Klasse soll mit dem Attribut winkel den momentanen Winkel, den der Zeiger gegenüber der 12-Uhr-Position einnimmt, speichern. Die Methode setzeWinkel(double neuerWinkel) setzt diesen Winkel. Um 08:15 Uhr würde z. B. ein Minutenzeiger mit setzeWinkel(90); in die richtige Lage versetzt werden.
Die Methode setzeZeigerLänge(double länge) verändert die Länge des Zeigers. Innerhalb dieser Methode kann die Methode setPoints() verwendet werden, die das neue festlegen von Anfangs- und Endpunkt ermöglicht. Der Konstruktor der Klasse Uhr soll keinen Parameter benötigen. Er erzeugt einen Standardzeiger, der im Punkt (400/300) beginnt, senkrecht nach oben verläuft und 150 Pixel lang ist.

Ergänze den Quellcode der Klasse Zeiger. Führe dann das Programm aus, um die Klasse zu testen.

Klasse Sekundenzeiger als Unterklasse der Klasse Zeiger

Die Klasse Zeiger, besitzt alle wichtigen Methoden und Attribute, die wir für die verschiedenen Zeiger benötigten. Wir nutzen nun das Prinzip der Spezialisierung (Vererbung) um einen Sekundenzeiger zu erstellen, der die aktuellen Sekunden seit der letzten vollen Minute anzeigt.
Der Sekundenzeiger erweitert die Klasse Zeiger.

Im Konstruktor der Klasse Sekundenzeiger sorgen wir für die richtige Farbe (z. B. hellblau) und die richtige Länge von 200 Pixeln. Dabei helfen uns die Methoden setBorderColor() und die Methode setzeZeigerlänge().

Ergänze den Quellcode der Klasse Sekundenzeiger. Führe dann das Programm aus, um die Klasse zu testen.
   public Sekundenzeiger() {
      super(); // ruft den parameterlosen Konstruktor der Klasse Zeiger auf
      setBorderColor(Color.aqua); // setzt die Farbe des Zeigers auf ein helles Blau
      setzeZeigerlänge(200); // setzt die Zeigerlänge auf 200 Pixel
   }

Zeigerdrehung mit Hilfe der Methode act() und den Methoden der Klasse LocalDateTime

Natürlich soll sich der Sekundezeiger selbstständig drehen. Dazu benötigen wir einmal die aktuelle Uhrzeit. Die Klasse LocalDateTime hilft dabei weiter.
Zunächst erhält man mit LocalDatetime.now() ein Objekt, dass das aktuelle Datum mit Uhrzeit repräsentiert. Mit der Methode LocalDateTime.now().getSecond() ermittelt man die Anzahl der Sekunden, die seit der letzten vollen Minute vergangen sind.

Beispiel:

Die Klasse Sekundenzeiger soll nun immer wieder selbstständig abhängig von der Anzahl der Sekunden die Grafik des Zeigers in die richtige Position drehen.
Dabei nutzen wir eine besondere Methode. Alle Grafikklassen besitzen eine Methode act(), die ca. 60 mal in der Sekunde automatisch aufgerufen wird. Der Rumpf dieser Methode ist zunächst leer, d.h. die Methode zeigt keine Wirkung. Man kann nun aber in einer Unterklasse diese Methode überschreiben, also noch einmal implementieren. Das bedeutet, dass alles, was im Rumpf dieser Methode steht, mehrmals pro Sekunde ausgeführt wird.

Das folgende Beispiel zeigt das Verhalten. Auf der Konsole wird wiederholt die Anzahl der aktuellen Sekunden ausgegeben.

Verändere den Quellcode der Methode act() so, dass der Zeiger abhängig von der Sekundenzahl die richtige Drehposition einnimmt.
Überlege zunächst, wie sich der Drehwinkel eines Sekundenzeiger verändert, wenn eine Sekunde vergeht.
   public void act() { 
      int sekunde = LocalDateTime.now().getSecond();
      // Drehung des Sekundenzeigers in die richtige Position
      setzeWinkel(sekunde * 6);
   }

Der Minuten- und der Stundenzeiger

Für den Minuten- und den Stundenzeiger gehen wir genauso vor wie beim Sekundenzeiger. Wir erstellen eine neue Klasse Minutenzeiger und Stundenzeiger, die von der Klasse Zeiger erben.
Im jeweiligen Konstruktor passt man die Farbe und die Länge an. Ein Minutenzeiger könnte z.B. 150 Pixel lang sein, ein Stundenzeiger 100 Pixel. Außerdem muss wieder die Methode act() überschrieben werden. Die aktuelle Minute bzw. Stunde erhältst du mit

Für den Minutenzeiger ist das ganz ähnlich wie beim Sekundenzeiger.
Beim Stundenzeiger muss man beachten, dass der exakte Winkel nicht nur von den Stunden, sondern auch von den Minuten abhängt. Überlege dir, um welchen Winkel sich der Stundenzeiger für eine Stunde und für eine Minute dreht und addiere die beiden Winkel.

Ergänze den Quellcode in der Datei Minutenzeiger und in der Datei Stundenzeiger.
Die Datei Test erzeugt die drei Zeiger. Prüfe, ob deine Uhrenzeiger die korrekte Zeit anzeigen.

Das Ziffernblatt

Für eine schöne Uhr fehlt noch ein Ziffernblatt. Dafür können wir auf die Klasse Circle für die umgebende Kreislinie und auf die Klasse Text zur Darstellung von Zahlen zurückgreifen.
Hier ein Beispiel, wie man die Klassen nutzt.

Ergänze den Quellcode in der Datei Uhr, so dass ein Ziffernblatt (Kreis mit 12 Zahlen) gezeichnet wird.
Tipp: Starte das Programm einmal, so dass das Grafikfenster angezeigt wird. Die passenden x- und y-Koordinaten der Zahlen kannst du ermitteln, indem du den Mauszeiger über das Grafikfenster führst. Rechts oben wird dir dann die momentane Position des Mauszeigers angezeigt.

Weitere Ideen

Uhren müssen nicht immer einen Zeiger haben.
Probiere doch einmal, eine Digitaluhr zu programmieren.

Oder suche im Internet nach dem Begriff Wortuhr und versuche, mit Hilfe von Objekten der Klasse Text eine solche Uhr mit einem Programm nachzubilden.

Abschluss

Das war der Lehrgang zur Programmierung einer Zeigeruhr. Hoffentlich waren für dich alle Erklärungen verständlich, so dass du die Aufgaben selbst lösen konntest.<