Wykład 9

Transkrypt

Wykład 9
Java
Wykład 9
Piotr Tronczyk
Zegar analogowy
 Tarcza
 Cyferblat
 Wskazówki
 Timer
2
Zegar analogowy
Tym razem postaramy się napisać program, który wyświetlał
będzie zegar analogowy.
Część odpowiedzialna za pobieranie daty oraz godziny, będzie
identyczna jak w przypadku zegara cyfrowego jednak istotna
różnicą będzie sposób wyświetlania i malowania zegara.
3
Zegar analogowy
4
Zegar analogowy
Najpierw napiszemy kod odpowiedzialny za malowanie
tarczy zegara w postaci metody DrawClock i umieścimy
jej wywołanie w obsłudze zdarzenia paintComponent.
narysowanie tarczy zegara sprowadzi się do narysowania
dwóch elips jednej wypełnionej kolorem, drugiej w postaci
konturu jak obwódki.
Do rysowania elips posłużymy się metodami
fillOval
drawOval
5
Zegar analogowy
public void paintComponent(Graphics g) {
setBackground(new Color(0f,1f,0f,0.5f));
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
Dimension size = getSize();
int width = size.width;
int height = size.height;
g2d.setColor(Color.lightGray);
g2d.fillOval(10,10,width-20,height-20);
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.blue);
g2d.drawOval(10,10,width-20,height-20);
6
Godziny
Kolejnym krokiem będzie namalowanie na tarczy zegara
liczb reprezentujących godziny, najpierw jednak troche
powtórki z matematyki.
7
Godziny
Tarcza naszego zegara jest elipsą, matematycznie elisą
możemy opisać następującym równaniem:
2
2
x
y


1
2
2
a
b
8
Godziny
Współrzędne punktu na obwodzie elipsy możemy więc
wyznaczyć w następujący sposób:
x  a cos( )
y  b sin( )
0    2
9
Godziny
Układ współrzędnych związany z oknem aplikacji ma punkt
(0,0) w górnym lewym narożniku okna, wartości x rosną w
prawo, natomiast y do dołu.
10
Godziny
Godziny na tarczy zostaną wyświetlone przy użyciu metody
drawString, ponieważ napis wyświetlamy poprzez
zdefiniowanie prostokąta otaczającego musimy wyznaczyć
jego współrzędne, szerokość oraz wysokość.
Szerokość oraz wysokość zależy od czcionki jaką
wyświetlamy napis, musimy więc dowiedzieć się ile miejsca
zajmie dany napis wyświetlony wybraną czcionką
11
Godziny
Klasa FontMetrics umożliwi na pobranie wymaganych
informacji:
FontMetrics fm =g2d.getFontMetrics(this.getFont());
String s = „Napis testowy”;
int ws=fm.stringWidth(s);
int wh = fm.getAscent();
x=x-ws/2;
y=y+wh/2;
g2d.drawString(s,x,y);
12
Godziny
Wyznaczając współrzędne x, y prostokątów otaczających napisy,
przyjmiemy, że cyferblat zegara będzie rozmieszczony na okręgu
o promieniu mniejszym niż promień tarczy zegara.
13
Godziny
Ponieważ układ współrzędnych związany z oknem wygląda tak,
że współrzędne y rosną w dół okna, kąty wyznaczamy w
następujący sposób:
14
Godziny
Na tarczy mamy 12 godzin, pełny kąt wynosi 360 stopni, tak
więc kolejne godziny rozmieszczone są na tarczy co 30 stopni.
Rysowanie godzin wykonamy w pętli od godziny 1 do 12.
Godzina pierwsza startuje od kąta –60 stopni.
15
Godziny
float ang = -60.0f;
for (int i=1; i<=12; i++){
String ss=String.format("%d",i);
x = (float) ((r1)*Math.cos(ang*Math.PI/180.0f));
y = (float) ((r2)*Math.sin(ang*Math.PI/180.0f));
x+=midX;
y+=midY;
int ws=fm.stringWidth(ss);
int wh = fm.getAscent();
x=x-ws/2;
y=y+wh/2;
g2d.drawString(ss,x,y);
ang += 30.0f;
16
Godziny
Po wykonaniu kodu dostaniemy liczby rozmieszczone na tarczy
zegara
17
Wskazówki
Ostatnim krokiem jest namalowanie wskazówek sekundnika,
minut, oraz godzin. Możemy malować je w sposób podobny do
tego jaki został użyty przy malowaniu godzin.
18
Wskazówki
Zacznijmy najpierw od sekundnika, ponieważ pełen obieg
wskazówki sekundnika oznacza upływ minuty, sekunda jest
1/60 częścią minuty, wskazówka sekundnika, będzie malowana
w 60 różnych położeniach, stopień o jaki należy ją obrócić po
upływie sekundy to 360/60=6.
19
Wskazówki
Współrzędne końca wskazówki możemy wyznaczyć na więcej
niż jeden sposób. Jeżeli przyjmiemy, że będziemy obracali je
względem punktu znajdującego się w środku tarczy
20
Wskazówki
Współrzędne po obrocie wyznaczymy:
x  x cos( )  y sin( )
'
y  x sin( )  y cos( )
'
21
Wskazówki
Możemy zapisać te wyrażenia w postaci następującego równania
macierzowego:
p  Mp
'
22
Wskazówki
Gdzie macierz M wygląda następująco:
 cos( )  sin( ) 

M  
 sin( ) cos( ) 
23
Wskazówki
Oczywiście możemy uprościć sobie obliczenia przyjmując, że
obracamy punkt względem środka układu współrzędnych, należy
wtedy pamiętać, że po obrocie należy zmodyfikować otrzymane
współrzędne, czyli dokonać translacji punktu
24
Wskazówki
Wskazówka minutowa zostanie narysowana w podobny sposób
jak sekundowa.
Należy jednak pamiętać, że na kąt wychylenia wskazówki
minutowej ma również wpływ liczba sekund jaka upłynęła w
bieżącej minucie, 30 sekund do pół minuty, ponieważ w godzinie
mamy 60 minut wskazówka minutowa po upływie pełnej minuty
obróci się o 6 stopni.
float mang = 6.0f*(min+sec/60.0f)-90.0f;
25
Wskazówki
Ostatnim krokiem jest namalowanie wskazówki godzinowej
Pełen obieg tarczy przez wskazówkę godzinową to 12 godzin,
czyli kąt obrotu wskazówki wynosi w tym przypadku 360/12=30
Należy oczywiście uwzględnić liczbę minut, która upłynęła w
bieżącej godzinie:
float hang = 30.0f*(ho+min/60.0f)-90.0f;
26
Wskazówki
Wskazówki będą różniły się nie tylko długością, ale też
grubością. Aby wybrać grubość linii użyjemy następującego
kodu:
g2d.setStroke(new BasicStroke(3));
BasicStrike jest klasą reprezentującą linię ciągłą o zadanej
grubości.
27
Timer
Bieżącą godzinę będziemy pobierali w metodzie
actionPerformed klasy Timer
javax.swing.Timer t = new javax.swing.Timer(1000,
new ActionListener() {
public void actionPerformed(ActionEvent e) {
...
}
28
Koniec
29