INSTRUKCJA DO ĆWICZENIA 2 METODYKA POSTĘPOWANIA PRZY TWORZENIU MIDLETU Z DWOMA EKRANAMI EKRAN 1 GUI WYSOKIEGO POZIOMU (KLASA SCREEN) EKRAN 2 GUI NISKIEGO POZIOMU (KLASA CANVAS) I Podstawowy szkielet MIDetu. 1. Otwórz nowy projekt typu Mobile Application o nazwie JME-DwaEkrany na dysku Z:\ Nadaj nazwie MIDletu nazwę DwaEkrany. Czynności wykonaj zgodnie z instrukcją do ćwiczenia nr 1 (pkt.: I.1-7). 2. W odpowiednim miejscu wygeneruj instrukcje definiujące konstruktora klasy głównej DwaEkrany(). Uwaga: Wszystkie nowe instrukcje, które należy dodać do istniejącego programu, zaznaczono kolorem niebieskim. import javax.microedition.lcdui.*; import javax.microedition.midlet.midlet; public class DwaEkrany extends MIDlet{ public DwaEkrany() { public void startapp() { public void pauseapp() { public void destroyapp(boolean unconditional) { 3. Dodaj interfejs CommandListener do klasy głównej DwaEkrany, który pozwoli operować komendami, obsługując jednocześnie przyciski opcji. public class DwaEkrany extends MIDlet implements CommandListener { Ustal przyczynę błędu. Uzupełnij program o odpowiednią metodę. Pamiętaj, interfejs CommandListener wymaga zawsze zdefiniowania metody commandaction(). Wygeneruj ją tuż za metodą destroyapp() wybierając z menu podręcznego opcję Insert code Implements metod Usuń wygenerowaną instrukcję: II Projektowanie dwóch ekranów 1. Zadeklaruj istnienie dwóch ekranów Pierwszego informacyjnego klasy Form o nazwie form1 Drugiego graficznego o nazwie ekrang import javax.microedition.lcdui.*; import javax.microedition.midlet.midlet; throw new UnsupportedOperationException("Not supported yet.");. public class DwaEkrany extends MIDlet implements CommandListener{ // lista ekranów // klasa Screen - interfejs wysokiego poziomu private Form form1 = new Form("Ekran 1 - Informacyjny"); // ekrang - graficzny -> klasa Canvas - wymaga metody paint() - interfejs niskiego poziomu; EkranG ekrang; public DwaEkrany() { public void startapp() { public void pauseapp() { public void destroyapp(boolean unconditional) { private class EkranG extends Canvas { public EkranG(String txtlab) { protected void paint(graphics g) { Zbudowaliśmy wewnętrzną klasę Ekran rozszerzającą klasę Canvas, na końcu publicznej klasy DwaEkrany. 2. Utwórz obiekt klasy Display, który będzie logiczną reprezentacją ekranu: Display display; i przypisz mu odpowiednią referencję. (patrz ćwiczenie nr 1 pkt. III.3): display = Display.getDisplay(this); 3. Wyświetlimy na pierwszym ekranie Nazwisko i Imię autora programu. Tu wpiszesz swoje własne imię i nazwisko. Najłatwiej tego dokonać wpisując w konstruktorze głównej klasy instrukcję, która doda do ekranu tekst Autor: Jan Kowalski metodą append(). form1.append("autor: Jan Kowalski \n"); Materiały do użytku wewnętrznego. Opracował Zbigniew JANIK. 1
4. Dokonaj formatowania kodu programu. 5. Uruchom program <F6>. Dlaczego nic się nie dzieje. Nic się nie dzieje, ponieważ nie określiliśmy, który ekran ma być wyświetlany na starcie MIDletu. Należy zatem do metody startapp() dodać instrukcję: display.setcurrent(form1); 6. Uruchom program <F6>. III Tworzenie listy poleceń 1. W publicznej części klasy DwaEkrany (przed konstruktorem a za listą naszych ekranów) należy utworzyć odpowiednie polecenia wykorzystując klasę Command: // lista poleceń Command opcja_powrot = new Command("Powrót", Command.EXIT,2); Command opcja_wyjscie = new Command("Zakończ", Command.EXIT,2); Command drugiekran = new Command("Ekran graficzny", Command.SCREEN,2); 2. Z pierwszym ekranem zwiążemy komendy: Zakończ zamknięcie aplikacji Ekran graficzny przełączenie się na ekran graficzny ekrang Zatem wystarczy w konstruktorze DwaEkrany dopisać instrukcje dodające te polecenia do naszej formatki: public DwaEkrany() { // konstrukcja wyglądu pierwszego ekranu form1.append("autor: Jan Kowalski\n"); form1.addcommand(opcja_wyjscie); form1.addcommand(drugiekran); 3. Jednocześnie musimy dodać metodę pozwalającą zarejestrować CommandListener, który będzie powiadamiany o wszystkich aktywowanych komendach tej formatki Włącz nasłuchiwanie zdarzeń z ekranu dopisując poniższą instrukcję w metodzie startapp(): form1.setcommandlistener(this); 4. Uruchom MIDlet. Dlaczego nie działają polecenia? Jeśli chcemy operować komendami w naszej aplikacji, jedna z naszych klas musi implementować interfejs CommandListener. W naszym przypadku taki interfejs już zaimplementowaliśmy do klasy głównej DwaEkrany. A wiec to nie jest przyczyną dla której nie działają polecenia. Przyczyną jest brak obsługi zdarzeń w metodzie commandaction(). Musimy zatem rozpoznać wywołaną komendę i aktywny Displayable (ekran), i odpowiednio na nią zareagować. Wykonajmy te czynności. Obsługa komendy Zakończ w metodzie commandaction() powinna wyglądać następująco: if (cmnd == opcja_wyjscie) { destroyapp(true); notifydestroyed(); Obsługa komendy Ekran graficzny w metodzie commandaction() powinna wyglądać następująco: else if(cmnd == drugiekran) { display.setcurrent(ekrang); 5. Jaka jest przyczyna, że po uruchomieniu programu, brak jest reakcji po wybraniu opcji Ekran graficzny. Pierwszą przyczyną jest to, że zarówno klasa EkranG jak i jej metoda wewnętrzna paint() jest pusta (brak instrukcji, a więc nie mamy do wyświetlenia żadnego obiektu). IV Projektowanie wyglądu drugiego ekranu 1. Zadeklaruj w klasie EkranG dwie zmienne całkowite, na których przechowywać będziemy rozmiar ekranu: szerokość i długość ekranu (przed konstruktorem tej klasy): int ScreenWidth, ScreenHeight; 2. Wewnątrz metody paint() pobierz wysokość i szerokość dostępnego ekranu: //Pobieram wysokość i szerokość dostępnego ekranu: ScreenWidth = getwidth(); ScreenHeight = getheight(); 3. Wypełnij ekran graficzny tłem koloru zielonego umieszczając w metodzie paint() następujące instrukcje: Materiały do użytku wewnętrznego. Opracował Zbigniew JANIK. 2
//Malowanie tła: g.setcolor(0,255,0); //zmiana aktualnego koloru na zielony //Zamalowanie tła okna ekranu aktualnym kolorem: g.fillrect(0, 0, ScreenWidth, ScreenHeight); 4. Dlaczego po uruchomieniu programu, nadal brak reakcji na wybór polecenia Ekran graficzny. Odpowiedz jest prosta, nie został utworzony do tej pory obiekt klasy EkranG, więc nie ma co wyświetlać. Najlepszym miejscem do utworzenia takiego obiektu będzie konstruktor klasy DwaEkrany. Dopiszmy zatem na końcu poniższe instrukcje: // konstrukcja drugiego ekranu ekrang = new EkranG("Ekran 2 - graficzny"); V Rozbudowa aplikacji 1. Dodaj i zaprogramuj w konstruktorze klasy DwaEkrany obsługę polecenia Powrót, która spowoduje przejście z ekranu graficznego do pierwszego ekranu informacyjnego oraz polecenia Zakończ // konstrukcja drugiego ekranu ekrang = new EkranG("Ekran 2 - graficzny"); ekrang.addcommand(opcja_wyjscie); ekrang.addcommand(opcja_powrot); w metodzie startapp() dopisz ekrang.setcommandlistener(this); a w metodzie commandaction dopisz if (cmnd == opcja_wyjscie) { destroyapp(true); notifydestroyed(); else if(cmnd == drugiekran) { display.setcurrent(ekrang); else if (cmnd == opcja_powrot) { display.setcurrent(form1); 2. Dodaj do ekranu informacyjnego taki komponent, który pozwoli dopisać dodatkowe informacje o autorze programu (ok.. 200 znaków). Za listą poleceń utwórz obiekt info wykorzystując komponent TextField następująco: TextField info = new TextField("INFO o autorze:","",200,textfield.any); Dodaj do ekranu form1 w konstruktorze DwaEkrany nasz obiekt info instrukcją i sprawdź działanie MIDletu. form1.append(info); 3. Wyrysuj samodzielnie kwadrat z żółtym tłem w centralnej części ekranu o rozmiarze krawędzi 160 pikseli (Dopisz odpowiednie instrukcje na końcu metody paint). g.setcolor(255,255,0); //zmiana aktualnego koloru na żóty g.fillrect(screenwidth/2-80, ScreenHeight/2-80,160,160); 4. Dorysuj krawędzie kwadratu i jego przekątne kolorem czarnym. 5. Uruchom MIDlet. Sprawdź czy kwadrat wyświetla się prawidłowo w centralnej części ekranu. Obróć ekran emulatora telefonu o 90 naciskając przycisk lub naciskając klawisz F9. Czy kwadrat wyświetla się prawidłowo w centralnej części ekranu. g.setcolor(255,255,0); //zmiana aktualnego koloru na żóty g.fillrect(screenwidth/2-80, ScreenHeight/2-80,160,160); Materiały do użytku wewnętrznego. Opracował Zbigniew JANIK. 3
VI Publikacja Midletu zadanie dodatkowe do samodzielnego wykonania w domu. Aby móc uruchomić aplikację na prawdziwym urządzeniu, należy wykonać kilka poniższych czynności: 1. Przejdź w NetBeans do widoku Files 2. Rozwiń katalog JME-DwaEkrany/dist. Znajdują się tu pliki DwaEkrany.jad oraz DwaEkrany.jar. Musisz przetransportować je do telefonu. Istnieje wiele wariantów wykonania tej czynności: bezpośrednia; połączenie telefonu z komputerem łacze USB łącze IrDA, łącze Bluetooth, łącze RS-232 pośrednia; umieszczenie plików w Internecie (np.: na własnej stronie WWW) i pobraniu ich na telefon. Niemożliwe jest podanie jednego opisu, który uwzględniał by wszystkie rodzaje telefonów lub serwerów. Spróbuj sam przeprowadzić ten eksperyment. Uwaga: Jeśli będziesz chciał uruchomić MIDlet na swoim telefonie, wyświetl w NetBeans Właściwości projektu (Properties), przejdź do kategorii Platform i sprawdź czy twój telefon obsługuje wybraną konfigurację oraz profil. Większość telefonów obsługuje Profil MIDP 2.0 i Konfigurację CLDC 1.1 Dokonaj ustawień zgodnych z twoim telefonem, potwierdź zmiany, klikając OK. Ponownie uruchom aplikację w NetBeans. W przypadku publikowania przy użyciu serwera WWW należy wprowadzić pewne zmiany w plikach projektu. Po ustaleniu adresów URL, jakie będą miały pliki projektu (JAD i JAR) w pliku JAD w polu o nazwie Midlet Jar URL należy wprowadzić bezwzględny adres URL do pliku JAR (np.: http://www.mojastrona.pl/katalog/dwaekrany.jar). Dodatkowo trzeba upewnić się, że serwer WWW ma następujące typy MIME przypisane do rozszerzeń plików: JAD text/vnd.sun.j2me.app-descriptor JAR application/java-archive. Po wprowadzeniu tych ustawień wystarczy przesłać pliki na serwer, a następnie w urządzeniu podać adres URL do pliku JAD. MATERIAŁY POMOCNICZE DO ĆWICZENIA 2 Przygotowanie MIDletu do publikacji w Internecie (opis teoretyczny) Kiedy już stworzymy własny MIDlet, musimy przygotować go do dystrybucji. Na dystrybucyjną wersję MIDletu składają się dwa pliki: JAR i JAD. Plik JAR - Java ARchive - zawiera wszystkie pliki.class oraz potrzebne zasoby, jak np. ikony, dołączone pakiety czy inne pliki (mamy do nich dostęp podczas działania aplikacji) z zachowaniem hierarchii katalogów. Dodatkowo znaleźć tam można plik manifest.mf (manifest file), który opisuje zawartość archiwum. Podobny cel i treść ma już spoza archiwum JAR plik JAD - Java Application Descriptor. Ale jaki sens ma trzymanie tych samych informacji w dwóch miejscach jednocześnie? Otóż plik MF jest obowiązkowy przy budowie pliku JAR. Plik JAD natomiast okazuje się bardzo przydatny przy instalacji nowej aplikacji (np. poprzez protokół HTTP). Scenariusz pobrania aplikacji jest bowiem następujący: linki na stronie (na przykład stronie WAP) prowadzą do pliku JAD (to nie jest możliwość, a konieczność - nie można po prostu ściągnąć pliku JAR). Urządzenie Materiały do użytku wewnętrznego. Opracował Zbigniew JANIK. 4
pobiera pliki JAD i wykorzystując niektóre zawarte w nim informacje pytając użytkownika, czy ten chce ściągnąć MIDlet o takiej nazwie, o takiej wielkości z takiej lokalizacji. Może również wyświetlić wartość parametru MIDlet- Description, jeśli ten jest dostarczony. Jeśli użytkownik potwierdzi chęć pobrania aplikacji, ta jest instalowana. Cały ten proces możliwy jest dzięki dwóm obowiązkowym parametrom w pliku JAD: MIDlet-JAR-URL MIDlet-JAR-Size Informują one odpowiednio o lokalizacji pliku JAR i o jego wielkości. Takie podejście ma duże zalety. Przede wszystkim kładzie na barkach użytkownika odpowiedzialność za pobraną aplikację. W końcu to on naciska "Tak - pobierz". Poza tym pozwala użytkownikowi - po pobraniu małego pliku JAD określić czas potrzebny do pobrania aplikacji - i na tej podstawie podjąć decyzję o jej pobraniu lub nie. Informacje zawarte w obu plikach tekstowych mają formę pary: nazwa_atrybutu: wartość( Key : Value) Każda para umieszczona jest w osobnej linii pliku. Specyfikacja MIDP mówi oczywiście o atrybutach predefiniowanych. Te w większości zaczynają się od "MIDlet-", a niektóre wylistowane są w tabeli poniżej. Tabela ta zawiera również krótki opis atrybutu oraz dwie flagi informujące o konieczności jego dołączenia w plikach JAD i MF. (o - opcjonalny; k - konieczny; i - ignorowany). Atrybut MF JAD Opis MIDlet-Name k k Nazwa dystrybucji (MIDletSuit) zawartej w pliku JAR, która może zostać wyświetlona użytkownikowi. MIDlet-Version k k Numer wersji w formie a.b.c, gdzie bardziej znacząca wartość jest po lewej stronie. Wersjonowanie ma duże znaczenie, gdyż podczas instalacji nowszej wersji MIDletu, zachowywane są wartości zapisane w pamięci stałej. MIDlet-Vendor k k Producent dystrybucji. MicroEdition-Profile k i Określa wersje profili MIDP, na których MIDlet może pracować. Typową wartością jest MIDP-1.0. W przypadku kilku wartości, oddzielone są one spacją. MicroEdition-Configuration k i Konfiguracja wymagana przez MIDlet. MIDlet-Jar-URL i k URL wskazujący lokalizację pliku JAR opisanego przez te atrybuty. MIDlet-Jar-Size i k Wielkość - w bajtach - pliku JAR. Materiały do użytku wewnętrznego. Opracował Zbigniew JANIK. 5