Orologio analogico in Java

Java - Varie Aggiungi commenti

orologioLe entità fondamentali utilizzate in questo articolo sono le classi java TimerTask e Canvas. L’orologio è costruito attraverso due classi: Quadrante e Orologio.
La classe Quadrante estende Canvas e si occupa del disegno delle lancette e del quadrante, mentre la classe Orologio estende TimerTask e si occupa dell’ottenimento dell’ora di sistema.
Un TimerTask è un oggetto che rappresenta
Il funzionamento è il seguente: la classe Orologio contiene, tra i vari metodi, run(), che viene chiamato ogni volta che il task è schedulato. Nel momento in cui si crea l’oggetto Orologio lo si  assoccia ad un oggetto Timer, stabilendo l’intervallo di tempo esistente fra uno scheduling e l’altro. La classe Quadrante, invece, ha il metodo draw() che prende come parametri tre interi (l’ora, i minuti ed i secondi) e disegna il quadrante con le lancette. Questo metodo verrà chiamato dal metodo run() del timertask, ogni secondo.
Vediamo come viene impostato lo scheduling del timertask Orologio, al momento della sua creazione, ovvero nel costruttore di Quadrante:

Orologio o = new Orologio(this);
Timer t = new Timer();
t.schedule(o, 500, 1000);

Il metodo schedule prende come parametri il timertask, l’intervallo di tempo iniziale (primo scheduling) e l’intervallo di tempo per gli scheduling successivi al primo.

Il disegno delle lancette e del quadrante si basa su dei calcoli trigonometrici per determinare i punti iniziali e i punti finali delle lancette e delle tacche. L’accorgimento da tenere quando si utilizzano le funzioni seno e coseno di Java è che gli angoli vengono considerati positivi girando in senso orario, il contrario di ciò che accade con la convenzione standard, e che le funzioni prendono come parametro l’angolo in radianti.

Ho notato che, aggiungendo l’orologio ad un JFrame contenente anche altri oggetti, si presenta un leggero lampeggio dovuto al tempo impiegato per disegnare la canvas. Il problema si è risolto adottando un sistema a doppio buffer: in sostanza è come avere 2 schermi sul quale disegnare, uno visibile e l’altro no. Le operazioni di disegno si effettuano sullo schermo invisibile (sul quale eventualmente si presenteranno lampeggi dell’immagine) mentre allo schermo visibile si trasferisce l’immagine completata. Per implementare quanto detto si utilizza la classe BufferStrategy, che permette di creare sistemi a n-buffer, se la macchina sulla quale lavoriamo lo supporta. La classe Quadrante avrà un attributo di tipo BufferStrategy chiamato strategy, inizializzato nel metodo draw() in questo modo:

if (strategy == null) {
    try {
        this.createBufferStrategy(2);
        strategy = this.getBufferStrategy();
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
Graphics g = strategy.getDrawGraphics();

a questo punto le operazioni di disegno avverranno sull’oggetto g. Al termine, l’immagine si trasferisce allo schermo visibile invocando il metodo show() su strategy. L’inizializzazione dentro draw() è necessaria in quanto per creare un BufferStrategy occorre che il componente (canvas in questo caso) sia stato già disegnato sullo schermo, altrimenti si genererà un’eccezione del tipo java.lang.IllegalStateException: Component must have a valid peer.

Codice Sorgente: Orologio Java (158)

Lascia un commento

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Collegati