Laboratorium z informatyki sem. II/ćw. 9 Wydział Transportu PW - 2016/17 MATERIAŁY POMOCNICZE DO ĆWICZENIA 9 Wybrane metody klasy Graphics Do tworzenia grafiki w aplecie Animacja wykorzystaliśmy metody klasy Graphics. Klasa Graphics udostępnia m.in. następujące metody: drawLine(int x1, int y1, int x2, int y2) – rysuje odcinek o końcach w punktach (x1, y1) i (x2, y2), używając bieżącego koloru fillRect(int x, int y, int width, int heigh) – wypełnia bieżącym kolorem prostokąt, którego lewy górny wierzchołek ma współrzędne (x, y); width - szerokość, heigh wysokość drawRect(int x, int y, int width, int heigh) – rysuje bieżącym kolorem prostokąt (łamaną, którą tworzą boki prostokąta); znaczenie parametrów – jak w metodzie fillRect() fillOval(int x, int y, int width, int heigh) –wypełnia bieżącym kolorem elipsę wpisaną w prostokąt, którego lewy górny wierzchołek ma współrzędne (x, y); width - szerokość, heigh wysokość drawOval(int x, int y, int width, int heigh) – rysuje bieżącym kolorem elipsę wspisaną w prostokąt, którego lewy górny wierzchołek ma współrzędne (x, y); width - szerokość, heigh wysokość fillArc(int x, int y, int width, int heigh, int a0, a) –wypełnia bieżącym kolorem wycinek elipsy wpisanej w prostokąt, którego lewy górny wierzchołek ma współrzędne (x, y); width - szerokość, heigh wysokość, a0 – kąt początkowy wycinka (w stopniach), a – kąt środkowy wycinka (w stopniach); kąty rosną przeciwnie do ruchu wskazówek zegara, kąt 0 jest na godzinie 3 drawArc(int x, int y, int width, int heigh, int a0, a) – rysuje bieżącym kolorem łuk elipsy; parametry identyczne jak w metodzie fillArc() fillPolygon(Polygon p) – wypełnia bieżącym kolorem obiekt klasy Polygon (wielokąt) Metoda rysowania wielokąta o danych wierzchołkach może też mieć nagłówek: fillPolygon(int []x, int[] y, int n) – gdzie x, y – tablice współrzędnych wierzchołków, n – liczba wierzchołków drawPolygon(Polygon p) – rysuje bieżącym kolorem obiekt klasy Polygon (łamaną zamkniętą) lub drawPolygon(int []x, int[] y, int n) – gdzie x, y – tablice współrzędnych wierzchołków, n – liczba wierzchołków drawImage(Image img, int x, int y, ImageObserver observer) – wyświetla obraz img umieszczając jego lewy górny wierzchołek w punkcie (x, y); parametr observer umożliwia kontrolę stanu obrazu, może być „pustym” obiektem (null) Wybrane metody klasy Polygon Utworzona przez nas klasa Pojazd dziedziczy pola i metody klasy bazowej Polygon. Są to m.in.: public int npoints – liczba wierzchołków wielokąta public int[] xpoints – tablica współrzędnych x wierzchołków wielokąta public int[] ypoints – tablica współrzędnych y wierzchołków wielokąta public boolean contains(int x, int y) –metoda zwraca wartość true, gdy punkt o współrzędnych (x,y) znajduje się wewnątrz wielokąta, false w przeciwnym przypadku public void invalidate() –metoda, którą należy wywołać po każdej bezpośredniej zmianie wartości w tablicach xpoints lub ypoints ; zapewnia poprawne działanie metod contains() i getBounds() public Rectangle getBounds() –zwraca obiekt klasy Rectangle reprezentujący najmniejszy prostokąt o bokach równoległych do osi układu współrzędnych, w którym całkowicie zawiera się wielokąt. Rozpatrując położenie pojazdu wywołaliśmy metodę getBounds() aby znaleźć prostokąt zawierający pojazd, a następnie wykorzystaliśmy pola klasy Rectangle opisujące prostokąt: public int x–współrzędna x lewego górnego wierzchołka prostokąta public int y–współrzędna y lewego górnego wierzchołka prostokąta public int width –szerokość prostokąta public int height – wysokość prostokąta public void translate(int dX, int dY) –metoda przesuwa wielokąt o dX w kierunku poziomym i dY w kierunku pionowym; Metody paint() i repaint() klasy Component Klasa JApplet dziedziczy metody związane z tworzeniem obrazu apletu na ekranie od klasy Component. paint() Metoda wywoływana automatycznie, kiedy musi być narysowany obraz komponentu, np. przy pierwszym wyświetleniu lub po powrocie na stronę apletu. repaint() Metoda wywoływana programowo w celu odświeżenia komponentu. Dla komponentu klasy JApplet wywołanie metody repaint() powoduje wywołanie metody paint(). Materiały do użytku wewnętrznego strona 1 Laboratorium z informatyki sem. II/ćw. 9 Wydział Transportu PW - 2016/17 Wątki w programie Javy i metoda sleep() Program Javy w czasie wykonania zawsze posiada wątek główny, ang. main thread i może posiadać inne równolegle realizowane wątki. Z zasady wykonanie programu Javy jest procesem wielowątkowym. Instrukcje każdej aplikacji lub apletu są wykonywane w pewnym wątku. W przypadku aplikacji jednowątkowych, z jakimi dotychczas mamy do czynienia, jest to wątek główny. Sterowanie przebiegiem wątków programu można uzyskać dzięki metodom klasy Thread z pakietu java.lang. W szczególności można na określony czas (podany w milisekundach) zatrzymać wykonanie bieżącego wątku za pomocą statycznej metody o sygnaturze: public static void sleep(long millis) throws InterruptedException Jak wynika z powyższej sygnatury, metoda ta wyrzuca wyjątek klasy InterruptedException, który wymaga obsługi. Dlatego wykorzystując w ćwiczeniu metodę sleep() dla uzyskania efektu animacji, umieszczamy jej wywołanie wewnątrz instrukcji try (z pustym blokiem catch, bo właściwie nie zależy nam na obsłużeniu tego błędu): try { Thread.sleep(10); } catch (InterruptedException e) { } Interfejsy W języku Java w uzupełnieniu do klas występują interfejsy, które stanowią mechanizm interakcji między niepowiązanymi wzajemnie obiektami różnych klas. W ćwiczeniu wykorzystano ten mechanizm do obsługi myszy. Interfejs to nazwany zbiór metod. Klasa może implementować interfejs, czyli zawarte w nim metody, odpowiednio do jej specyfiki. Dzięki takiemu rozwiązaniu różne klasy mogą w indywidualny sposób realizować metody, które z zewnątrz są dostępne w sposób jednorodny, tj. za pośrednictwem nagłówka określonego w definicji interfejsu. Interfejs definiuje zbiór (kolekcję) publicznych metod, zwykle powiązanych tematycznie i realizujących określoną funkcjonalność. W definicji interfejsu mogą ponadto występować stałe statyczne. Interfejs zawiera same nagłówki (sygnatury) definiowanych w nim metod abstrakcyjnych. Klasa implementująca interfejs musi zaimplementować wszystkie jego metody, albo będzie klasą abstrakcyjną. Nazwa interfejsu poprzedzona słowem kluczowym implements występuje na końcu nagłówka klasy, która go implementuje, po ewentualnej specyfikacji klasy nadrzędnej, np.: public class Grafika extends Applet implements MouseListener Klasa może dziedziczyć tylko z jednej klasy, natomiast może implementować wiele interfejsów. Wówczas ich nazwy, po słowie kluczowym implements, są oddzielone przecinkami. Interfejsy na równi z klasami mogą być organizowane w pakiety oraz tworzyć hierarchie dziedziczenia. Interfejs MouseListener i klasa MouseEvent Poniżej zamieszczono definicję wykorzystanego w ćwiczeniu interfejsu MouseListener, który zawiera metody obsługujące zdarzenia myszy. Interfejs MouseListener należy do pakietu Javy java.awt.event oraz dziedziczy od zdefiniowanego w pakiecie java.util (pustego) interfejsu EventListener. public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); //kliknięcie myszą public void mousePressed(MouseEvent e); //naciśnięcie przycisku myszy public void mouseReleased(MouseEvent e); //zwolnienie przycisku myszy public void mouseEntered(MouseEvent e); //nasunięcie kursora myszy public void mouseExited(MouseEvent e); //wycofanie kursora myszy } Parametrem każdej z powyższych metod jest obiekt klasy MouseEvent, reprezentujący zdarzenie związane z użyciem myszy. Aby w naszym aplecie sprawdzić, który przycisk myszy został wciśnięty i czy jednocześnie jest wciśnięty klawisz specjalny, wykorzystaliśmy następujące pola i metody klasy MouseEvent: public static final int BUTTON1 – pole oznaczające lewy przycisk myszy (button#1) podobnie pola BUTTON2 i BUTTON3 oznaczają przycisk środkowy i prawy - metoda zwracająca informację, który przycisk wystąpił w zdarzeniu public int getX()- metoda zwracająca współrzędną x położenia kursora myszy public int getY()- metoda zwracająca współrzędną y położenia kursora myszy public boolean isControlDown()- metoda zwracająca wartość true, gdy wciśnięty jest klawisz <Ctrl>, w przeciwnym przypadku metoda zwraca wartość false. analogicznie metody isAltDown() i isShiftDown()dotyczą klawiszy <Alt> i <Shift> public int getButton() Materiały do użytku wewnętrznego strona 2 Laboratorium z informatyki sem. II/ćw. 9 Wydział Transportu PW - 2016/17 Generowanie liczb losowych, klasa Random Oprócz metody random() klasy Math do generowania liczb losowych całkowitych lub rzeczywistych można wykorzystać metody klasy Random z pakietu java.util. Aby w programie generować liczby losowe, należy zadeklarować i utworzyć obiekt klasy Random: Random r = new Random(); // klasę Random należy zaimportować Do generowania kolejnych wartości losowych służą metody: – zwraca całkowitą liczbę losową o rozkładzie równomiernym z przedziału <0, n) – zwraca liczbę losową rzeczywistą o rozkładzie równomiernym w przedziale <0, 1), nextInt(int n) nextDouble() Liczby losowe całkowite z przedziału domkniętego <K, L> można uzyskać stosując wzór: K +r.nextInt( L + 1 - K ) Liczby losowe rzeczywiste z przedziału (A, B) można uzyskać stosując wzór A + r. nextDouble ( B - A ) Przykład: Aby generować wartość pola kolor o losowych składowych R, G, B z zakresu od 0 do 255 zastosowaliśmy instrukcję: kolor = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); Materiały do użytku wewnętrznego strona 3