2D-Grafik timer bei Analoguhr

maxe

Mitglied
Hallo, ich bin gerade daran eine Analoguhr zu programmieren, bei der man eine Uhrzeit eingibt und dann die Uhrzeit angezeigt wird. Zusätzlich soll die Uhrzeit an der Seite von dem angegebenen Zeitpunkt weiterlaufen. Anbei liegt der bisher geschriebene Code. Meine Frage ist dem timer gewidmet: Ich müsste die Variablen innerhalb einer Funktion aufrufen. Diese Funktion wird jedoch durch ein Runnable wiederholt. Die Variablen sollen aber nur am Anfang den vorher festgelegten Wert annehmen und in den weiteren durchgängen sollen sie sich immer wieder updaten. Ich hoffe ich konnte meine Frage Präzise genug formulieren. Ein Blick in den Code denke ich ist sogar noch verständlicher.
Ein Danke schonmal im Vorraus an jeden, der sich mit meinem Problem befasst.
 

Anhänge

  • Uhr.java
    12,8 KB · Aufrufe: 3

mihe7

Top Contributor
Ein Blick in den Code denke ich ist sogar noch verständlicher.
Ein Blick in diesen Code nicht wirklich... static, nicht static, direktes Zeichnen, zig Variablen, Benennungskonventionen nicht eingehalten, alles in einer Klasse... Da braucht man Stunden, um durchzublicken. Ganz davon abgesehen, dass die Berechnung der Zeiger falsch ist. Kurz: der Timer ist wirklich Dein kleinstes Problem.

Teil das ganze vernünftig auf Klassen auf. Beispiel: Du brauchst keine drei Variablen für eine Uhrzeit. Java hat dafür Klassen, z. B. LocalTime kann das richtig gut. Aber selbst, wenn Du nicht auf LocalTime zurückgreifen willst, hält Dich nichts davon ab, eine Klasse dafür zu implementieren. Die Analoguhr selbst ist eine Komponente, also schreib auch eine (extends JComponent und paintComponent überschreiben).

Ganz am Schluss hast Du das Programmfenster, in dem sich neben der Aanaloguhr auch die Eingabe befindet. Dort kannst Du auch einen Timer starten, die Zeit in der Analoguhr setzen, fertig.
 

Blender3D

Top Contributor
Ein Blick in den Code denke ich ist sogar noch verständlicher.
Ein Danke schonmal im Vorraus an jeden, der sich mit meinem Problem befasst.
Da der Blick in den Code leider nicht wirklich verständlich war, habe ich diesen etwas überarbeitet. Zum Testen die jar einfach herunterladen.
1667874551637.png
Java:
import javax.swing.JFrame;

public class StartWatch {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Watch");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        WatchPanel watch = new WatchPanel(300, 300);
        frame.add(watch);
        frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }
}
Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class WatchPanel extends JPanel implements WatchObserver {
    private GraphicWatch watch = new GraphicWatch(23, 59, 45);

    public WatchPanel(int width, int height) {
        setPreferredSize(new Dimension(width, height));
        watch.start();
        int size = 200;
        watch.setSize(size);
        watch.setPos((width - size) / 2, (height - size) / 2);
        watch.setObserver(this);
        setBackground(Color.DARK_GRAY);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        watch.draw(g, this);
    }

    @Override
    public void update(Object sender) {
        repaint();
    }

}
Java:
public interface WatchObserver {
    public void update(Object sender);
}
Java:
import java.awt.Graphics;
import java.awt.Point;

public class GraphicWatch extends Watch {
    private int x = 0;
    private int y = 0;
    private int size = 100;
    private WatchView view = new DefaultWatchView();

    public GraphicWatch(int hour, int min, int sec) throws IllegalArgumentException {
        super(hour, min, sec);
    }

    @Override
    public void draw(Graphics g) {
        view.draw(g, this);
    }

    public Point getCenter() {
        int radius = getRadius();
        return new Point(x + radius, y + radius);
    }

    public int getRadius() {
        return size / 2;
    }

    public int getSize() {
        return size;
    }

    public Point getPos() {
        return new Point(x, y);
    }

    public void setPos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public void setView(WatchView view) {
        this.view = view;
        if (view == null)
            view = new DefaultWatchView();
    }

}
Java:
public class Watch implements Runnable {
    private int hour;
    private int min;
    private int sec;
    public static final int HOUR_PER_DAY = 24;
    public static final int MIN_PER_HOUR = 60;
    public static final int SEC_PER_MIN = 60;
    private static final int MILLI_SEC_PER_SEC = 1000;
    private Thread timer;
    private boolean running = false;
    private WatchObserver observer;

    public Watch(int hour, int min, int sec) throws IllegalArgumentException {
        Watch.checkTimeRange(hour, min, sec);
        this.hour = hour;
        this.min = min;
        this.sec = sec;
        start();
    }

    public boolean isRunning() {
        return timer != null && timer.isAlive();
    }

    private static void checkTimeRange(int hour, int min, int sec) {
        checkHourRange(hour);
        checkMinRange(min);
        checkSecRange(sec);
    }

    private static void checkHourRange(int hour) {
        if (hour < 0 || hour >= HOUR_PER_DAY)
            throw new IllegalArgumentException("Hour range is from 0-" + (HOUR_PER_DAY - 1));
    }

    private static void checkMinRange(int min) {
        if (min < 0 || min >= MIN_PER_HOUR)
            throw new IllegalArgumentException("Minute range is from 0-" + (MIN_PER_HOUR - 1));
    }

    private static void checkSecRange(int sec) {
        if (sec < 0 || sec >= SEC_PER_MIN)
            throw new IllegalArgumentException("Second range is from 0-" + (SEC_PER_MIN - 1));
    }

    public int getHours() {
        return hour;
    }

    public int getMinutes() {
        return min;
    }

    public int getSeconds() {
        return sec;
    }

    public void resetTime() {
        hour = min = sec = 0;
    }

    @Override
    public void run() {
        while (running) {
            try {
                Thread.sleep(MILLI_SEC_PER_SEC);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            tick();
            if (observer != null)
                observer.update(this);
        }
    }

    public void setObserver(WatchObserver observer) {
        this.observer = observer;
    }

    public void start() {
        stop();
        running = true;
        timer = new Thread(this);
        timer.start();
    }

    public void stop() {
        running = false;
        while (isRunning())
            ;
        timer = null;
    }

    private void tick() {
        sec++;
        if (sec >= SEC_PER_MIN) {
            sec = 0;
            min++;
            if (min >= MIN_PER_HOUR) {
                min = 0;
                hour++;
                if (hour >= HOUR_PER_DAY)
                    resetTime();
            }
        }
    }

    @Override
    public String toString() {
        return String.format("%02d:%02d:%02d", hour, min, sec);
    }

}
Java:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;

public class DefaultWatchView implements WatchView {

    @Override
    public void draw(Graphics g, GraphicWatch w) {
        Graphics2D g2 = (Graphics2D) g;
        drawDial(g2, w);
        drawShortHand(g2, w);
        drawMinuteHand(g2, w);
        drawSecondHand(g2, w);
    }

    public void drawDial(Graphics g, GraphicWatch w) {
        Graphics2D g2D = (Graphics2D) g;
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2D.setBackground(Color.BLACK);
        Point pos = w.getPos();
        int size = w.getSize();
        g2D.fillOval((int) (pos.x), (int) (pos.y), (int) size, (int) size);
        g2D.setColor(Color.WHITE);
        g2D.setStroke(new BasicStroke(2));
        g2D.drawOval(pos.x, pos.y, size, size);
        drawNumbers(g2D, w);
    }

    private void drawNumbers(Graphics2D g2d, GraphicWatch w) {
        Point pos = w.getCenter();
        g2d.setStroke(new BasicStroke(10));
        g2d.setColor(Color.WHITE);
        double angle;
        int x, y;
        double radius = w.getRadius() * .8;
        Font font = g2d.getFont().deriveFont((float) (radius / 3));
        int fontSize = font.getSize();
        g2d.setFont(font);
        FontMetrics fm = g2d.getFontMetrics();
        for (int i = 1; i <= Watch.HOUR_PER_DAY / 2; i++) {
            angle = i * Math.PI / 6;
            x = (int) (radius * Math.sin(angle));
            y = (int) (radius * Math.cos(angle));
            String val = i + "";
            int width = fm.stringWidth(val);
            g2d.drawString(val, pos.x + x - width / 2, pos.y - y + fontSize / 2);
        }
    }

    public void drawHand(GraphicWatch w, Graphics2D g, Point handPos) {
        Point center = w.getCenter();
        g.drawLine(center.x, center.y, handPos.x, handPos.y);
    }

    private void drawMinuteHand(Graphics2D g2, GraphicWatch w) {
        Point handPos = getHandTopPos(w, w.getMinutes(), Watch.MIN_PER_HOUR, 3 * w.getRadius() / 4);
        g2.setColor(Color.WHITE);
        g2.setStroke(new BasicStroke(1.5f));
        drawHand(w, g2, handPos);
    }

    private void drawSecondHand(Graphics2D g2, GraphicWatch w) {
        Point handPos = getHandTopPos(w, w.getSeconds(), Watch.SEC_PER_MIN, 7 * w.getRadius() / 8);
        g2.setColor(Color.RED);
        g2.setStroke(new BasicStroke(1.5f));
        drawHand(w, g2, handPos);
        Point center = w.getCenter();
        int size = (int)(w.getSize()*.07);
        g2.fillOval(center.x-size/2, center.y-size/2, size, size);
    }

    private void drawShortHand(Graphics2D g2, GraphicWatch w) {
        Point handPos = getHandTopPos(w, w.getHours(), Watch.HOUR_PER_DAY / 2, w.getRadius() / 2);
        g2.setColor(Color.WHITE);
        g2.setStroke(new BasicStroke(2.5f));
        drawHand(w, g2, handPos);
    }

    private Point getHandTopPos(GraphicWatch w, int timeValue, int maxTimeValue, double handSize) {
        Point pos = w.getPos();
        Point center = w.getCenter();
        double angle = timeToAngle(timeValue, maxTimeValue);
        pos.x = center.x + (int) ((int) handSize * Math.cos(angle));
        pos.y = center.y + (int) ((int) handSize * Math.sin(angle));
        return pos;
    }

    private double timeToAngle(int time, int maxTime) {
        return Math.toRadians((time * (360.0 / maxTime)) - 90);
    }
}
Java:
import java.awt.Graphics;

public interface WatchView {
    public void draw(Graphics g, GraphicWatch w);
}
 

Anhänge

  • watch.jar
    14,3 KB · Aufrufe: 0
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
E JDialog mit count down timer AWT, Swing, JavaFX & SWT 1
A Timer AWT, Swing, JavaFX & SWT 1
H Timer ohne alles lahmzulegen? AWT, Swing, JavaFX & SWT 2
O Timer in JOptionPane anzeigen AWT, Swing, JavaFX & SWT 2
ralfb1105 Swing Timer in SwingWorker stoppen AWT, Swing, JavaFX & SWT 4
T Timer und GIF Animationen pausieren während Maus sich bewegt AWT, Swing, JavaFX & SWT 4
W Swing JLabel jede Sekunde aktualisieren, ohne Timer zu benutzen AWT, Swing, JavaFX & SWT 4
D Timer für Bildfolge in einem jLabel AWT, Swing, JavaFX & SWT 5
M Event Handling MousePressed vs. Timer! AWT, Swing, JavaFX & SWT 5
F Java Timer Bug? AWT, Swing, JavaFX & SWT 6
B Timer, TimerTask und Warten AWT, Swing, JavaFX & SWT 4
R Performance Drag and Drop & Timer AWT, Swing, JavaFX & SWT 3
E Problem mit Timer und Swing AWT, Swing, JavaFX & SWT 8
N AWT Timer überschreiben? AWT, Swing, JavaFX & SWT 8
P Label rotieren mit Timer AWT, Swing, JavaFX & SWT 5
F Swing GUI und Model mit Timer AWT, Swing, JavaFX & SWT 13
K Threads - Timer - run() mehrfach parallel? AWT, Swing, JavaFX & SWT 2
J Nach Timer ausführen AWT, Swing, JavaFX & SWT 6
S Timer oder Thread.sleep AWT, Swing, JavaFX & SWT 3
D Timer JFrame AWT, Swing, JavaFX & SWT 7
F Swing timer nimmt delay nicht an AWT, Swing, JavaFX & SWT 2
S Swing Timer, Countdown AWT, Swing, JavaFX & SWT 2
F Timer welches JPanel aktualisiert AWT, Swing, JavaFX & SWT 6
H Timer/Stoppuhr in MenuBar anzeigen AWT, Swing, JavaFX & SWT 4
D Applet Methode in Timer einbinden AWT, Swing, JavaFX & SWT 6
F Applet Applet starten...(+Timer?) AWT, Swing, JavaFX & SWT 12
R Probleme mit Swing Timer AWT, Swing, JavaFX & SWT 6
C Timer Problem AWT, Swing, JavaFX & SWT 5
VfL_Freak Swing kann ich einen laufenden Timer mitten in der Ausführung abbrechen? AWT, Swing, JavaFX & SWT 6
H Swing Timer Probleme AWT, Swing, JavaFX & SWT 5
Burny91 Swing Mit Timer JLabel updaten AWT, Swing, JavaFX & SWT 2
P Game of Life - PaintComponent-Problem / Timer? AWT, Swing, JavaFX & SWT 8
B JLabel mittels Timer und setLocation verschieben AWT, Swing, JavaFX & SWT 3
O Swing es können keine neuen Labels hinzufügt werden während der Timer läuft AWT, Swing, JavaFX & SWT 14
C Timer erstellen? AWT, Swing, JavaFX & SWT 2
E AWT Problem mit Repaint (in Loop oder Timer) AWT, Swing, JavaFX & SWT 3
K Timer und Threads ruckeln für Fotoschwenk AWT, Swing, JavaFX & SWT 3
L Timer Swing GUI AWT, Swing, JavaFX & SWT 2
G Swing Timer stoppen AWT, Swing, JavaFX & SWT 4
B Swing-Timer AWT, Swing, JavaFX & SWT 4
D javax.swing.Timer bringt NullPointerException AWT, Swing, JavaFX & SWT 4
J Swing timer? AWT, Swing, JavaFX & SWT 2
C Timer, Darstellung einer Uhr AWT, Swing, JavaFX & SWT 4
Z javax.swing.Timer: wie stoppen??? AWT, Swing, JavaFX & SWT 9

Ähnliche Java Themen

Neue Themen


Oben