8. Aplety i podstawowe elementy grafiki
8.1. Prosty aplet
Aplety (applets = small applications) to małe programy umieszczane na stronach WWW. Ich przeznaczeniem jest wyświetlanie graficznych elementów, komunikacja z czytelnikiem strony za pomocą myszy i klawiatury, odtwarzanie plików dźwiekowych. W ten sposób strony WWW stają się dynamiczne i interaktywne. Podobne efekty można uzyskać za pomocą DHTML, JavaScript, czy JavaBeans.
Aplet jest klasą pochodną klasy Applet umieszczonej w pakiecie java.applet:
import java.applet.Applet;
public class Pusty extends java.applet.Applet {
… // ciało apletu
}
W odróżnieniu od aplikacji, aplet nie może działać samodzielnie. Musimy go umieścić na stronie WWW:
<HTML>
<TITLE> Pusty aplet </TITLE>
<BODY>
<HR>
<APPLET CODE=Pusty.class WIDTH=100 HEIGHT=50>
</APPLET>
<A HREF="Pusty.java"> Plik źródłowy. </A>
</BODY>
</HTML>
Wewnątrz znacznika APPLET można umieścić następujące parametry:
Nazwa |
Przykładowe wartośći |
Objaśnienie |
CODE |
CODE="Pusty.class" |
określa nazwę pliku zawierającego kod bajtowy apletu |
WIDTH HEIGHT |
WIDTH=100 HEIGHT=200 |
określają wymiar apletu w pikselach |
HSPACE VSPACE |
HSPACE=10 VSPACE=20 |
określają w pikselach odstęp pomiędzy apletem a otaczającym go tekstem |
CODEBASE |
CODEBASE= |
Określa ścieżkę dostępu do tego pliku. Jeżeli zbiór z kodem bajtowym jest w tej samej kartotece, co dokument HTML, to nie trzeba podawać ścieżki dostępu. Wartością CODEBASE może być również adres sieciowy URL. |
8.2. Rysowanie figur
Aby coś narysować wewnątrz apletu, trzeba wywołać metodę paint ( ):
public void paint ( Graphics g ) {
g.nazwaMetody ( parametry metody rysującej );
}
Argumentem tej metody jest obiekt klasy Graphics, którą należy jawnie importować:
import java.awt.Graphics;
Stosowany jest przy tym następujący układ współrzędnych:
Do rysowania figur służą nastepujace metody:
Nagłówek |
Przeznaczenie |
drawLine( xp, yp, xk, yk ) |
rysowanie prostej od punktu początkowego (xp, yp) do punktu końcowego (xk, yk) |
drawRect( xp, yp, b, h ) |
rysowanie prostokąta o wymiarach b × h i współrzędnych lewego górnego rogu |
drawPolygon( x, y, n ) |
rysowanie wieloboku o współrzędnych n wierzchołków (xi, yi) |
drawPolyline( x, y, n ) |
rysowanie n odcinków linii łamanej o współrzędnych załomów (xi, yi) |
drawOval( xp, yp, b, h ) |
rysowanie elipsy wpisanej w prostokąt |
drawArc( xp, yp, b, h, φp, φk ) |
rysowanie wycinka elipsy zawartego w sektorze kątowym (φp, φk) |
Przykład
import java.applet.Applet;
import java.awt.Graphics;
public class Figury extends java.applet.Applet {
public void paint ( Graphics g ) {
g.drawLine( 50, 50, 250, 150 );
g.drawRect( 50, 50, 200, 100 );
g.drawRoundRect( 50, 50, 200, 100, 30, 30 );
int tabX [ ] = { 50, 100, 150, 200 };
int tabY [ ] = { 50, 100, 50, 100 };
int n = tabX.length;
g.drawPolyline( tabX, tabY, n );
g.drawPolygon( tabX, tabY, n );
g.drawOval( 50, 50, 100, 100 );
g.drawOval( 50, 50, 200, 100 );
g.drawArc( 50, 50, 200, 100, 0, 180 );
}
}
8.3. Kolory
Kolory w Javie są obiektami klasy Color. Klasa ta udostępnia metody
setColor ( ), setBackground ( ), setForeground ( ), których argumentami są kolory. Można korzystać z zestawu standardowych kolorów ( Color.white, Color.black, Color.red itp.) lub tworzyć własne kolory jako dowolne kombinacje składowych RGB:
Color nowy = new Color ( 140, 120, 50 );
Wartości argumentów muszą być w przedziale 0÷255. Dodając do nazwy metody rysującej figury przedrostek fill można wypełniać figurę kolorem.
Przykład
import java.awt.Color;
import java.awt.Graphics;
public class Kolor extends java.applet.Applet {
public void paint ( Graphics g ) {
g.setColor( new Color( 120, 200, 100);
g.fillRect( 10, 10, 50, 50 );
g.setColor( Color.green );
g.fillOval( 100, 50, 20, 20 );
}
}
Metoda setColor ( ) ustala kolor, którym realizowane są kolejne operacje graficzne. Metody setBackground ( ) i setForeground ( ) ustalają, odpowiednio, kolor tła apletu i kolor wszystkich elementów rysowanych na tym tle. Są jeszcze metody getColor ( ), getBackground ( ), getForeground ( ) zwracające odpowiednie kolory apletu.
Przykład
import java.awt.Graphics;
import java.awt.Color;
public class Mozaika extends java.applet.Applet {
public void paint (Graphics g) {
int rval, gval, bval;
for (int j = 30; j < (getSize( ).height - 25); j += 30)
for (int i = 5; i < (getSize( ).width - 25); i += 30)
{
rval = (int) Math.floor(Math.random( ) * 256);
gval = (int) Math.floor(Math.random( ) * 256);
bval = (int) Math.floor(Math.random( ) * 256);
g.setColor( new Color( rval, gval, bval ));
g.fillRect( i, j, 25, 25);
g.setColor( Color.black);
g.drawRect( i-1, j-1, 25, 25);
}
}
}
8.4. Napisy i czcionki
Czcionki są w Javie obiektami klasy Font. Aby wyświetlić tekst w trybie graficznym, należy:
·utworzyć obiekt zawierający czcionkę;
·zadeklarować tę czcionkę jako aktualnie używaną;
·skorzystać z metody rysowania tekstu lub znaku.
Do zgłaszania aktualnie używanej czcionki służy metoda setFont ( ). Napis rysowany jest za pomocą metody drawString ( ), a znak - za pomocą metody drawChars ( ).
Przykład
import java.awt.Font;
import java.awt.Graphics;
public class Czcionka extends java.applet.Applet {
public void paint ( Graphics g ) {
Font f = new Font
( "TimesRoman", Font.PLAIN, 12 );
Font fb = new Font
( "TimesRoman", Font.BOLD, 12 );
g.setFont ( f );
g.drawString ("To jest normalna czcionka", 10, 25 );
g.setFont ( fb );
g.drawString ("To jest gruba czcionka", 10, 50 );
}
}
Parametry metody drawString ( ) określają współrzędne początku tekstu. Wymiary wiersza tekstu można uzyskać za pomocą metod stringWidth( ) oraz getHeight ( ). Przed korzystaniem z tych metod należy stworzyć obiekt klasy FontMetrics dla danej czcionki. Poniższy przykład pokazuje centrowanie napisu.
Przykład
import java.awt.Font;
import java.awt.Graphics;
import java.awt.FontMetrics;
public class Napis extends java.applet.Applet {
public void paint ( Graphics g ) {
Font f = new Font
( "TimesRoman", Font.PLAIN, 36);
FontMetrics fm = getFontMetrics( f );
g.setFont ( f );
String s = "Oto nadchodzi koniec świata!";
int xstart = ( getSize ( ).width -
fm.stringWidth ( s ) ) / 2;
int ystart = getSize ( ).height / 2;
g.drawString ( s, xstart, ystart );
}
}
8.5. Wstawianie plików graficznych
W pakiecie java.awt jest umieszczona klasa Image, która definiuje zachowania obrazów. Można korzystać z obrazów zapisanych w formatach GIF i JPEG.
Aby obraz pokazać w aplecie, musimy wykonać dwie operacje:
skopiować plik graficzny do apletu;
wyświetlić ten plik.
Metoda getImage ( ) klasy Applet służy do kopiowania pliku graficznego do apletu. Wynikiem działania tej metody jest obiekt klasy Image.
Metodę getImage ( ) można wywołać na dwa sposoby:
getImage ( < adres sieciowy > )
getImage ( < adres bazowy >, < adres względny > )
Adresy sieciowy i bazowy są obiektami klasy URL, a adres względny − łańcuchem znaków.
Zamiast wpisywać stałe adresy lepiej korzystać z metod pomocniczych:
getDocumentBase ( ) |
zwraca URL dokumentu HTML, który wywołał aplet |
getCodeBase ( ) |
zwraca napis definiujący kartotekę, w której jest kod apletu |
Przykładowo, jeżeli plik graficzny obrazek.gif jest w tej samej kartotece, co plik HTML, to ładujemy go do apletu poleceniem
Image img = getImage( getDocumentBase ( ),
”obrazek.gif” );
Natomiast, gdy pliki graficzne przechowujemy w podkartotece rysunki, to zlecenie ma postać
Image img = getImage ( getDocumentBase ( ),
”rysunki\obrazek.gif”);
Po załadowaniu obrazu możemy go wyświetlić na dwa sposoby:
drawImage ( nazwa, x, y, this );
lub
drawImage ( nazwa, x, y, b, h, this );
gdzie:
nazwa − nazwa obiektu klasy Image zawierającego obraz;
x, y − współrzędne lewego górnego rogu;
b, h − szerokość i wysokość obrazu w aplecie;
this − odwołanie do aktualnego obiektu.
Podając wymiary b i h możemy skalować obraz. Jeżeli chcemy zachować stosunek szerokości do wysokości, to możemy określić oryginalne wymiary obrazu za pomocą metod getWidth ( this ), getHeight ( this ).
Proces ładowania obrazu przebiega pod kontrolą interfejsu ImageObserver. Odwołanie this w metodach drawImage ( ), getWidth ( ), getHeight ( ) odnosi się do obiektu obserwatora. Pozwala on implementować różne zachowania apleta w trakcie dłuższego ładowania obrazu.
Po załadowaniu obrazka można go skopiować w inne miejsce. Służy do tego metoda
copyArea ( x, y, b, h, x1, y1 )
gdzie x1, y1 są współrzędnymi nowej pozycji.
Do czyszczenia, czyli wypełnienia podanego prostokąta kolorem tła apletu, służy metoda
clearRect ( x, y, b, h )
Jeżeli chcemy wyczyścić cały aplet, to korzystamy z metody size ( ), której zmienne width, height zawierają wymiary apletu:
clearRect ( x, y, size ( ).width, size ( ).height )
Przykład
import java.awt.Graphics;
import java.awt.Image;
public class Robot extends java.applet.Applet {
static final int A = 10;
Image robot;
public void paint ( Graphics g ) {
robot = getImage ( getCodeBase ( ),
"Rysunki/Robot.jpg");
int b = robot.getWidth(this);
int h = robot.getHeight(this);
g.drawImage(robot, A, A, this); //oryginał
// zmniejszamy o 1/4
g.drawImage(robot, A+b+A, A, b/4, h/4, this );
}
}
8.6. Wstawianie plików dźwiękowych
Ze względu na cyfrowy zapis odtwarzanie dźwięków niewiele się różni od wyświetlania obrazów. W klasie Applet dostępna jest metoda play ( ) stanowiąca odpowiednik getImage ( ) dla plików dźwiękowych:
play ( < adres sieciowy > )
play ( < adres bazowy >, < adres względny > )
Java odtwarza pliki dźwiękowe zapisane w formacie AU lub WAV. Ten drugi można wywoływać bezpośrednio z dokumentu HTML:
<A HREF = ”Sound.WAV”> melodia Gatesa </A>
W odróżnieniu od getImage ( ), metoda play ( ) nie tylko ładuje plik do apletu, lecz również odtwarza go jeden raz. Jeżeli chcemy odtwarzać klip dźwiękowy wielokrotnie, to musimy przekazać go do obiektu klasy AudioClip zdefiniowanej w pakiecie java.applet.
W tym celu wykonujemy zlecenie
AudioClip clip = getAudioClip
( < adres bazowy > , < adres względny > );
które powoduje załadowanie pliku dźwiękowego.
Plik ten możemy odtworzyć jeden raz −
clip.play( );
zatrzymać jego odtwarzanie −
clip.stop( );
lub odtwarzać w sposób ciągły −
clip.loop( );
Przykład
import java.awt.Graphics;
import java.applet.AudioClip;
import java.awt.Image;
public class Bar extends java.applet.Applet {
Image img;
AudioClip clip;
public void paint ( Graphics g ) {
img = getImage( getCodeBase ( ),
"Rysunki/Bar.gif" );
g.drawImage( img, 10, 10, 500, 300, this );
clip = getAudioClip( getCodeBase ( ),
"Dzwieki/Bar.au" );
clip.loop( );
}
}
W tym aplecie występują przerwy wyświetlaniu obrazu i odtwarzaniu dźwięku. Powodem tego jest niewłaściwe wykorzystanie metody
paint ( ). Powrócimy do zatem do baru Joego w następnym rozdziale.
8.7. Cykl życia apletu
Dotychczas wykorzystywaliśmy tylko metodę rysowania apletu paint ( ). Oznacza to, że metody init ( ), start ( ), stop ( ), destroy ( ), które każdy aplet dziedziczy po klasie bazowej Applet, pozostawały puste.
Ich przeznaczenie widać z poniższego schematu, który pokazuje cykl życia apletu:
Po otwarciu strony WWW,na której jest aplet, przeglądarka wywołuje jego metody init ( ) oraz start ( ). Metoda stop ( ) wywoływana jest:
gdy użytkownik zażąda tego w sposób jawny
(np. klikając myszą w odpowiedni przycisk);
gdy użytkownik opuszcza stronę zawierającą aplet;
gdy użytkownik opuszcza przeglądarkę.
Metoda destroy ( ) wywoływana jest przy opuszczaniu przeglądarki. Domyślnie metody init ( ), start ( ), stop ( ) i destroy ( ) są puste. Przesłaniając je możemy sterować zachowaniem się apletu.
Przykład
import java.awt.Graphics;
import java.applet.AudioClip;
import java.awt.Image;
public class BarInit extends java.applet.Applet {
Image img;
AudioClip clip;
int b, h;
static final float SKALA = 0.8F;
public void init ( ) {
b = ( int )( getSize ( ).width * SKALA );
h = ( int )( getSize ( ).height * SKALA );
img = getImage( getCodeBase ( ),
"Rysunki/Bar.gif" );
clip = getAudioClip( getCodeBase ( ),
"Dzwieki/Bar.au" );
clip.loop( );
}
public void paint ( Graphics g ) {
g.drawImage( img, 10, 40, b, h, this );
}
}
Adam Borkowski Język programowania „Java” 8−15
Przeglądarka
pobiera
aplet
Użytkownik
odwiedza
stronę WWW
stop ( )
destroy ( )
Użytkownik
opuszcza
stronę WWW
Użytkownik
opuszcza
przeglądarkę
Zatrzymany
Zniszczony
Załadowany
Działający
init ( )
start ( )
60,80
20,20
Y
X
0,0