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: x a 2 2 b y 2 2 1 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: M cos( sin( ) ) 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