Mariusz Chmielewski
1
Programowanie
Zdarzeniowe
Technologia Java Applet
Komponenty AWT
Delegacyjny model
zdarzeń
kpt. mgr inż. Mariusz Chmielewski
Instytut Systemów Informatycznych
Wydział Cybernetyki
Wojskowa Akademia Techniczna
Mariusz Chmielewski
2
Koncepcja
• Język Java został adoptowany do
wykorzystania w połączeniu z
HTML, do tworzenia
specjalnych programów
uruchamianych przez przeglądarki
HotJava na komputerach
klienckich.
• Aplety różnią się w porównaniu ze
standardowymi aplikacjami Javy
przede wszystkim środowiskiem
wykonania. Inne różnice dotyczą
struktury programu oraz sposób
jego uruchomienia.
• W aplikacji wykonanie rozpoczyna
się się od uruchomienia metody
main(), natomiast applet definiuje
specyficzną strukturę metod
pozwalających środowisku
uruchomieniowemu
przeprowadzanie
zaimplementowanych operacji w
zależności od stan appletu.
Mariusz Chmielewski
3
Schemat wykonania appletu ładowanego z
zasobów sieciowych
• Technologia appletów rozszerza
dokumenty HTML, udostępniając
możliwości prezentacji animacji,
dźwięku oraz innych efektów
specjalnych. Definiowanie specjalnego
schematu metod przez applet jest
spowodowane konstrukcją przeglądarki
HotJava, która pozwala na
wykorzystanie odpowiednich
interfejsów do komunikacji z appletem.
Schemat wykonania appletu ładowanego z
zasobów sieciowych
• Wykonanie appletu składa się z
następujących faz:
– przeglądarka generuje żądanie do modułu
ładującego (loadera) aby dostarczył klasę
appletu do którego odwołanie znajduje się w
kodzie HTML.
– W momencie pełnego załadowania
wymaganego kodu, następuje wykonanie
appletu. Wykonanie kodu następuje w
interpreterze dołączonym do przeglądarki.
– Przeglądarka działa jako kanał komunikacji
pomiędzy Maszyną Wirtualną wewnątrz
interpretera oraz interfejsem użytkownika.
Mariusz Chmielewski
4
Mariusz Chmielewski
5
Schemat wykonania appletu ładowanego z
zasobów sieciowych
• Klasa Applet dostarcza wymaganego szkieletu oraz narzędzi
dostępu do funkcjonalności dostarczanej przez przeglądarkę. Z
wykorzystaniem HotJava applet uzyskuje dostęp do grafiki,
dźwięku oraz operacji sieciowych.
• W odróżnieniu od aplikacji applet nie zaczyna działania od
metody main(). Cykl życia apletu wyznaczają cztery metody
zdefiniowane w klasie Applet: init(), start(), stop() i destroy().
• Kod HTML wykorzystuje znacznik appletu (applet tag) by
pozyskać wszystkie możliwe jego dane
Przykład:
<APPLET CODE = "lights.class" width=400 height=75
align=center >
<PARAM NAME="text" VALUE="Blink">
<BLOCKQUOTE>
<HR>
If you were using a Java(tm)-enabled browser,
you would see blinking lights instead of this paragraph.
<HR>
</BLOCKQUOTE>
</APPLET>
Mariusz Chmielewski
6
Szkielet appletu
• Applet jest specyficznym oprogramowaniem
uruchamianym w środowisku przeglądarki
HotJava. Wewnątrz środowiska przeglądarki
applet korzysta z możliwości wyświetlania
obrazów, odtwarzania plików dźwiękowych oraz
dostęp do Internetu.
• Ze względu na to, że applet jest wykonywany
lokalnie na maszynie klienta, wyposażony jest
bezpośrednio w możliwość interakcji z
przeglądarką stając się częścią strony
internetowej. Oparcie interaktywności stron
WWW o applety umożliwia korzystanie z
właściwości wykonania środowiska lokalnego
(wykorzystanie CGI wymusza przesyłanie danych
do serwera i wykonywanie żądań po stronie
serwera).
• Zastosowanie technologii appletów zwiększa
interaktywność oprogramowania, dodatkowo
zwiększając wydajność przetwarzania, ze
względu na odciążenie serwera w ramach
przetwarzania żądań.
• Wszystkie informacje o stanach wewnętrznych
środowiska przeglądarki rezydują lokalnie na
maszynie klienta i nie są przesyłane pomiędzy
przeglądarką a serwerem WWW.
Mariusz Chmielewski
7
Szkielet appletu
•
Główne metody sterujące w trakcie wykonania appletu - init, start, stop,
destroy oraz metoda paint:
init - wywoływana tylko raz, podczas ładowania strony WWW
zawierającej applet (pierwsze ładowanie), jeśli opuścimy stronę WWW
zawierającą applet i wrócimy na nią (przełączanie zadań), metoda init nie
będzie wywołana ponownie,
start - metoda wywoływana za każdym razem, w momencie gdy strona
zawiera applet i staje się stroną bieżącą w przeglądarce,
stop - metoda wywoływana w momencie, gdy następuje ładowanie innej
strony WWW w przeglądarce,
destroy - wykonywana, gdy applet kończy swoje działanie.
•
Podane metody nie muszą być nadpisywane, istnieje możliwość
korzystania z dostarczanych przez samą klasę Applet reprezentacji tych
metod (skazani jesteśmy jednak w takim przypadku na ograniczenie
funkcjonalności appletu).
Mariusz Chmielewski
8
Szkielet appletu
• Metoda init powinna
implementować funkcjonalność
zawieraną w konstruktorach.
Odpowiada ona bowiem za
inicjalizację appletu (pozyskanie
dodatkowych zasobów). Pomimo
tego, że applet posiada
konstruktor to nie gwarantuje on,
że dostępne jest całe środowisko
potrzebne do inicjalizacji apletu.
Metoda ładująca grafikę oraz
dźwięk nie jest dostępna w
konstruktorze apletu, a więc
pozyskanie tych zasobów powinno
odbywać się w metodzie init.
• Metoda start jest z
reguły nadpisywana w
implementowanym applecie. Jej
zadaniem jest definicja logiki
appletu,
uruchamiania ewentualnych
wątków, realizujących pracę
apletu (animacja grafiki = wątek
zmieniający położenie elementów
na ekranie i odrysowujący
grafikę).
Model
zdarzeniowy
Model
zdarzeniowy
Mariusz Chmielewski
9
• Definiowanie metody start
implikuje definicję metody
stop, wstrzymującej
wykonanie appletu, ale nie
zwalniającej potrzebnych
zasobów zajętych przez
wykonywany program.
Funkcjonalność tej metody
może być wykorzystana do
zawieszenie wątków,
działających w tle,
służących do
odrysowywania obiektów
graficznych na ekranie.
• Użycie metody destroy jest
możliwe w przypadku
appletów, które wymagają
jawnego zwolnienia zajętych
w metodzie init zasobów.
Kontrolowanie
wykorzystania zajętości
pamięci jest o tyle ważne,
że w przypadku stron, na
których znajduje się wiele
appletów może spowodować
błędy dostępności zasobów
(pamięć itd.).
Mariusz Chmielewski
10
Szkielet appletu - praktyczny przykład
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Font;
public class AppletMethodTest extends Applet {
private int m_metodaInit;
private int m_metodaStart;
private int m_metodaStop;
private int m_metodaDestroy;
private int m_metodaPaint;
private Font font;
public void init() {
font = new Font("Arial", Font.BOLD , 20);
m_metodaInit = dodajInfo(m_metodaInit);
}
public void start() {
m_metodaStart = dodajInfo(m_metodaStart);
}
public void stop() {
m_metodaStop = dodajInfo(m_metodaStop);
}
public void destroy() {
m_metodaDestroy = dodajInfo(m_metodaDestroy);
}
private int dodajInfo(int i) {
repaint();
return ++i;
}
public void paint(Graphics g) {
g.setFont(font);
this.setSize(400,200);
//Rysowanie ramki otaczającej aplet
g.drawRect(0, 0, size().width - 1, size().height - 1);
//rysowanie odpowiednich łańcuchów znakowych (w ramce)
g.drawString("Wywołań metody init : " + m_metodaInit, 10, 20);
g.drawString("Wywołań metody start : " + m_metodaStart, 10, 50);
g.drawString("Wywołań metody stop : " + m_metodaStop, 10, 80);
g.drawString("Wywołań metody destroy: " + m_metodaDestroy, 10, 110);
g.drawString("Wywołań metody paint : " + m_metodaPaint, 10, 140);
}
}
Przedstawiony applet prezentuje bardzo
okrojoną funkcjonalność pozwalającą na
zliczanie liczby wywołań poszczególnych metod
w trakcie jego działania i prezentacji jej na
ekranie przeglądarki. Korzystanie z opcji
dostarczanych przez przeglądarkę (ewentualnie
program appletviewer.exe) pozwala na zmianę
stanu appletu przechodząc przez poszczególne
etapy jego cyklu życia.
Mariusz Chmielewski
11
Metody rysujące elementy graficzne
• Oprócz metod definiujących elementy w cyklu
życia appletu, definiowane są metody
odpowiadające za graficzny dostęp do okna
przeglądarki.
• Do grupy tych metod zaliczamy : metodę paint
oraz update. Pierwsza pozwala na nanoszenie
elementów GUI (pozostałych prymitywów
graficznych) korzystając z okna przeglądarki,
metoda update pozwala na czyszczenie kolorem
tła obszaru okna przeglądarki.
• Brak jawnej definicji metody update powoduje
wystąpienie efektu migotania grafiki w trakcie jej
ciągłego odrysowywania (animacje). Jednym ze
sposobów wyeliminowania tego niepożądanego
efektu jest nadpisanie metody update tak, aby
usuwała "czyściła" wybrane elementy,
przeznaczone do usunięcia.
Mariusz Chmielewski
12
Metody rysujące elementy graficzne
import java.applet.*;
import java.awt.*;
public class AnimationApplet extends Applet implements Runnable {
private int koloX = 20, koloY = 30;
private int kwX = 140, kwY = 100;
private int kolodX = 10, kolodY = 10;
private int kwdX = 2, kwdY = 2;
// wątek obliczający dane do animacji
private Thread animWatek;
// czcionka w której wyprowadzane są na ekran napisy
private Font font;
public void init() {
// ustawienie czcionki (typ, rodzaj, wielkość) w której
// będą wyświetlane napisy
font = new Font("Arial", Font.BOLD, 20);
}
public void start() {
//powołaj
if (animWatek == null)
animWatek = new Thread(this, "Applet animacyjny");
animWatek.start();
}
public void stop() {
if (animWatek != null)
animWatek.stop();
animWatek = null;
System.gc();
}
…
Metody rysujące elementy
graficzne
Mariusz Chmielewski
13
public void run() {
// zmienna lewo określa czy współrzędne mają być obliczane dla
// przesuwania napisów w lewo(oraz dół) czy w prawo(oraz góra)
boolean lewo = true;
while (Thread.currentThread() == animWatek) {
if (!((koloX > 0) && (koloX < this.size().width - 40)))
kolodX = -kolodX;
if (!((koloY > 0) && (koloY < this.size().height - 40)))
kolodY = -kolodY;
if (!((kwX > 0) && (kwX < this.size().width - 50)))
kwdX = -kwdX;
if (!((kwY > 0) && (kwY < this.size().height - 50)))
kwdY = -kwdY;
koloX = koloX + kolodX;
koloY = koloY + kolodY;
kwX = kwX + kwdX;
kwY = kwY + kwdY;
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
public void paint(Graphics g) {
// wołamy update, ponieważ AWT niekiedy
// woła paint() bezpośrednio
update(g);
}
public void update(Graphics g) {
g.setFont(font);
g.setColor(Color.white);
g.fillRect(0, 0, this.size().width, this.size().height);
g.setColor(Color.red);
g.fillOval(koloX, koloY, 40, 40);
g.setColor(Color.blue);
g.fillRect(kwX, kwY, 50, 50);
}}
Mariusz Chmielewski
14
Zdarzenia - delegacyjny model zdarzeń
• Obecny model obsługi zdarzeń w AWT (Abstract
Window Toolkit) oparty jest na modelu tzw.
delegowania obsługi zdarzeń, charakteryzującym
się większą wydajnością w porównaniu z
poprzednią koncepcją opartą na dziedziczeniu.
• Delegacyjny model obsługi zdarzeń korzysta z
możliwości wykorzystania dowolnych obiektów,
które implementują odpowiedni interfejs
nasłuchujący (ang. listener interface).
• Jeden lub kilka obiektów klas nasłuchujących,
może zostać zarejestrowany do obsługi różnego
rodzaju zdarzeń pochodzących z różnych źródeł
(interakcje klawiatury, myszki).
• Delegacyjny model zdarzeń pozwala zarówno na
obsługę, jak i na generowanie zdarzeń.
Mariusz Chmielewski
15
Zdarzenia - delegacyjny model zdarzeń
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class AppletObsługaZdarzen extends Applet implements ActionListener {
//nowy komponent, pole tekstowe w którym będzie wyświtlana
// historia wszystkich wykonanych przez nas w aplecie operacji
private TextArea txtHistory = new TextArea(5, 20);
private Panel gridLayoutPanel() {
// implementacja odpowiedniego zarządcy rozmieszczenia
// elementów na ekranie
}
public void init() {
// nowe elementy metody init
// dodajemy na "zachodzie" apletu pole tekstowe
add("North", txtHistory);
txtHistory.setFont(new Font("Arial", Font.BOLD, 10));
}
public void actionPerformed(ActionEvent evt) {
// implementacja metody pozwalajacej
// na zadeklarowanie reakcji na przychodzące
// zdarzenia i wypisanie ich w komponencie txtHistory
// (metoda getActionCommand)
txtHistory.append(evt.getActionCommand()+ "\n");
}
}
Mariusz Chmielewski
16
Zdarzenia - delegacyjny model zdarzeń
1. Deklaracja klasy (przeznaczonej do obsługi) implementującej
odpowiedni interfejs nasłuchujący (lub dziedziczącą z klasy, która ten
interfejs implementuje).
public class MojAplet extends Applet implements ActionListener
2. Rejestracja dla danego komponentu obiektu klasy nasłuchującej:
klasaŹródłoZdarzeń.addRodzajNasłuchu(obiektKlasyNasłuchującej);
oznacza, że dla obsługi zdarzeń generowanych przez obiekt klasaŹródłoZdarzeń,
zarejestrowano obiekt obiektKlasyNasłuchującej implementujący interfejs
nasłuchujący (definiowany przez RodzajListener).
W wywołanie:
obiektKlasy.addActionListener(this);
jako obiekt klasy nasłuchującej rejestruje sam siebie (implementuje dany interfejs
nasłuchujący ActionListener).
3. Implementacja metod z interfejsu nasłuchującego.
Interfejs ActionListener posiada tylko jedną metodę do implementacji:
public void actionPerformed(ActionEvent evt) {
// deklaracja reakcji na zdarzenia
}
W modelu delegacyjnym Java definiuje bogaty zestaw interfejsów nasłuchujących,
metody każdego z tych interfejsów umożliwiają reakcję na zdarzenie określonego
typu.
Mariusz Chmielewski
17
Zestawienie generowanych typów
zdarzeń
Mariusz Chmielewski
18
Zestawienie generowanych typów
zdarzeń
Mariusz Chmielewski
19
Zestawienie generowanych typów
zdarzeń
Mariusz Chmielewski
20
Ograniczenia mechanizmu appletów
• Założeniem technologii appletów były również
względy bezpieczeństwa. Appety są
oprogramowaniem ściąganym z serwera WWW
na stację kliencką i uruchamiane w środowisku
przeglądarki, a więc wydają się być technologią
idealną dla rozwoju wirusów i oprogramowania
pozwalającego na nieuprawniony dostęp do
zasobów systemowych. Aby bronić się przed
takim dostępem wprowadzono dodatkowe
ograniczenia, w tym celu powołano obiekt
zarządcy bezpieczeństwa (SecurityManager)
mającego za zadanie kontrolowanie procesu
dostępu do zasobów. W przypadku, gdy zasady
bezpieczeństwa są naruszane, obiekt zarządcy
wywołuje wyjątek SecutityException.
Mariusz Chmielewski
21
Ograniczenia mechanizmu appletów
Aplety muszą spełniać następujące zasady
bezpieczeństwa (spełnienie tych zasad jest
kontrolowane przez zarządców bezpieczeństwa
poszczególnych przeglądarek):
1. Aplety nie mają prawa ładowania bibliotek (Java Native
Interface - metody native). Mogą one korzystać jedynie ze
swego własnego kodu Javy odnoszącego się do elementów
Java API dostarczonych przez przeglądarkę. Każda
przeglądarka zgodna z HotJava dostarcza Java API.
2. Applety nie mogą nawiązywać połączeń sieciowych poza
połączeniami z serwerem, z którego zostały załadowane.
Applet może jednak kontaktować się z innymi serwerami
poprzez komunikację z aplikacją działającą na serwerze
(CGI servlety), z którego applet załadowano.
3. Zapis i odczyt plików na komputerze klienckim jest
wzbroniony (w wypadku, kiedy ustawiamy prawa dostępu
SecurityManager możemy taki dostęp uzyskać). Applety w
przeglądarce mogą odczytywać pliki wyspecyfikowane
przez URL. Zapis danych realizowany jest z
wykorzystaniem zasobów serwera z którego kod appletu
został załadowany.
Mariusz Chmielewski
22
Ograniczenia mechanizmu appletów
4. Applet nie może tworzyć środowiska wykonania dla
zewnętrznych programów uruchamianych na komputerze
klienckim. W przypadku, gdy taka operacja jest wymagana
applet może wywołać usługę serwera, z którego został
załadowany i wykorzystując jego zasoby uruchomić
wymagane oprogramowanie.
5. Applet nie może czytać wszystkich właściwości systemu
(ang. system properities). Aplety mogą czytać jedynie
okrojone właściwości systemu:
- file.separator;
- java.class.version;
- java.vendor;
- java.vendor.url;
- java.version;
- line.separator;
- os.arch;
- os.name;
- path.separator;