Proz S8 id 402998 Nieznany

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 1

8. Multimedia. Klasa

Graphics



8.1 Operowanie na obrazach
8.2 Animacje
8.3 D

ź

wi

ę

ki

8.4

Graphics



8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 2

8.1 Operowanie na obrazach

Operacje na obrazach wspomagaj

ą

pakiety:

java.applet, java.awt, java.awt.image.


Obraz reprezentowany jest jako obiekt klasy

java.awt.Image

.




Podstawowa metoda dla obrazu w klasie

java.awt.Graphics

to

drawImage

, w klasie

java.awt.Toolkit

- metoda

getImage

a tak

ż

e

metody klasy

java.awt.MediaTracker

.



W pakiecie

java.applet

metoda klasy

Applet -

getImage

– umo

ż

liwia

pobieranie obrazów z plików graficznych.



Pakiet

java.awt.image

zapewnia interfejsy i klasy dla tworzenia, (np..

MemoryImageSource

),

przetwarzania

(np.

ConvolveOp,

RGBImageFilter

) i nadzorowania ładowania (np.

ImageObserver

).

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 3

1) Ładowanie obrazów

Metody

getImage()

Obrazy w formatach

GIF

,

JPEG

lub

PNG

ładowane mog

ą

by

ć

metodami

getImage

()

deklarowanymi w klasach

Applet

i

Toolkit

. Np.

myImage = getImage(URL);

// w klasach pochodnych od Applet

// LUB w klasach pochodnych od Toolkit:

myImage = Toolkit.getDefaultToolkit().getImage(nazwaPlikuLubURL);


Metody

getImage()

powracaj

ą

natychmiast

, nie oczekuj

ą

c na

potwierdzenie istnienia obrazu ani na jego załadowanie. Ładowanie
odb

ę

dzie si

ę

wtedy, gdy obraz po raz pierwszy b

ę

dzie malowany w

programie.

W klasie

Toolkit

istniej

ą

dwie deklaracje metod o tej nazwie:

public abstract

Image getImage(URL url);

public abstract

Image getImage(String filename);

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 4

Metody te mog

ą

by

ć

wołane w aplikacjach lub apletach (ale w tym

drugim przypadku aplety musz

ą

spełnia

ć

warunki dost

ę

pu).

Np.

Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image1 = toolkit.getImage("nazwaObrazu.gif");

Image image2 = toolkit.getImage(new URL("http://www.pw.edu.pl/pw.gif"));

W klasie

Applet

istniej

ą

dwie wersje tej metody:

public

Image getImage(URL url);

public

Image getImage(URL url, String name);

Mog

ą

by

ć

wołane tylko w apletach i dopiero po uzyskaniu pełnego

kontekstu przez aplet – nie w konstruktorze ani w instrukcji deklaracji
obiektu.
Np.

// W metodzie pewnej klasy pochodnej od Applet:

Image image1 = getImage(getCodeBase(), "pw.gif");
Image image2 = getImage(getDocumentBase(), "pw.jpeg");
Image image3 = getImage( new URL("http://www.pw.edu.pl/pw.gif"));

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 5

2) Tworzenie obrazów za pomoc

ą

klasy

MemoryImageSource

Nowe obrazy mog

ą

by

ć

tworzone od pocz

ą

tku dzi

ę

ki klasie

java.awt.image.

MemoryImageSource

.

Przykład 8.1.

Fragment programu przeznaczony dla utworzenia obrazu

o rozmiarze 100 x 100, przedstawiaj

ą

cego odcienie od czarnego do

niebieskiego (wzdłu

ż

osi X) i odcienie od czarnego do czerwonego

(wzdłu

ż

osi Y):

int w = 100;
int h = 100;
int[] pix = new int[w * h];
int index = 0;
for (int y = 0; y < h; y++) {
int red = (y * 255) / (h - 1);
for (int x = 0; x < w; x++) {
int blue = (x * 255) / (w - 1);
pix[index++] = (255 << 24) | (red << 16) | blue;

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 6

}
}
Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));

3) Nadzorowanie ładowania obrazów

Proces ładowania obrazu mo

ż

e by

ć

nadzorowany przez klas

ę

java.awt.

MediaTracker

lub przez implementacj

ę

metody

imageUpdate()

(zdefiniowanej w interfejsie

java.awt.image.

ImageObserver

).


Interfejs

ImageObserver

Wymaga implementacji metody

imageUpdate()

i rejestracji obiektu jako

„obserwatora” – zwykle ma to miejsce poprzez przekazanie obiektu
typu implementuj

ą

cego

ImageObserver

do metody

drawImage

().

public boolean imageUpdate(Image img,

int infoflags, int x, int y, int width, int height);

Metoda powinna zwróci

ć

false wtedy, gdy przakzane argumenty

wskazuj

ą

,

ż

e cały obraz został juz załadowany.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 7

4) Rysowanie obrazu

Metoda

drawImage()

wołana dla obiektu klasy

Graphics

przekazanego

do metody

paintComponent().

Np.:

// Normalny rozmiar obrazu. Lokalizacja pocz

ą

tku w górnym lewym

// rogu obszaru komponentu.

g.drawImage(myImage, 0, 0, this);

// Obraz przeskalowany do rozmiaru: 300 x 62 piksele i lokalizacji
// pocz

ą

tku w punkcie (90, 0) obszaru komponentu:

g.drawImage(myImage, 90, 0, 300, 62, this);


Metoda

drawImage

tak

ż

e (jak

getImage()

) działa asynchronicznie

wzgl

ę

dem ładowania obrazu - powraca po narysowaniu fragmentu

obrazu, który został dot

ą

d załadowany.


Cztery metody

drawImage

w klasie

Graphics

(zwracaj

ą

wynik typu

boolean

”):

boolean drawImage (Image img, int x, int y, ImageObserver observer)
boolean drawImage (Image img, int x, int y, int width, int height,

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 8

ImageObserver observer)

boolean drawImage (Image img, int x, int y, Color bgcolor,

ImageObserver observer)

boolean drawImage (Image img, int x, int y, int width, int height,

Color bgcolor, ImageObserver observer)

Znaczenie parametrów metod

drawImage()

:



Image img – rysowany obraz;



int x, int y – współrzędne górnego lewego rogu obrazu ;



int width, int height – szerokość i wysokość obrazu (w pikselach);



Color bgcolor – kolor tła.



ImageObserver observer – rejestracja obiektu implementującego
interfejs ImageObserver – ten obiekt będzie powiadamiany o ładowaniu
obrazu.

Klasa

Component

implementuje interfejs

ImageObserver

, czyli ka

ż

dy

komponent GUI mo

ż

e przekaza

ć

siebie (poprzez

this

) jako

obserwatora. Ta implementacja metody

imageUpdate

interfejsu

wywołuje metod

ę

repaint

, gdy obraz jest ładowany.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 9

8.2 Wykonanie animacji

1) P

ę

tla animacji z wykorzystaniem klasy

Timer

P

ę

tla animacji powinna wykonywa

ć

si

ę

w osobnym w

ą

tku, a nie w

metodzie

paintComponent()

, gdy

ż

to umie

ś

ciłoby animacj

ę

w w

ą

tku

obsługi zdarze

ń

(“event-dispatching”).

Przykład 8.2

. Prosta animacja podaj

ą

ca kolejny numer ramki z

cz

ę

sto

ś

ci

ą

10 ramek na sekund

ę

:

public class AnimatorClass ... implements ActionListener {
int frameNumber = -1;
Timer timer;
boolean frozen = false;

// Nie blokujemy animacji

JLabel label;

// Komponent realizujący rysowanie

// W kodzie inicjalizacji GUI:
// Na podstawie liczby ramek na sekundę fps określamy odstęp czasu - delay

delay = (fps > 0) ? (1000 / fps) : 100;

...

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 10

// Obiekt klasy Timer będzie wołał obsługę akcji w naszym obiekcie.

timer = new Timer(delay, this);

// Obiekt klasy Timer generować będzie

// zdarzenie akcji co pewną liczbę „delay” milisekund

// i dalsze ustawienie komponentów w GUI.

...

// Gdy pojawi się GUI aplikacji:

startAnimation();

// Gdy GUI jest ukrywane:

stopAnimation();

//Obsługa zdarzenia akcji dla timer-a:

public void actionPerformed(ActionEvent e) {
frameNumber++;

// Zwiększ numer ramki

label.setText("Frame " + frameNumber);

// Zmiana tekstu i narysowanie

}

// Metody uruchamiania i zatrzymywania animacji:

public synchronized void startAnimation() {
if (frozen) {

// Nie wykonuj animacji

.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 11

} else {

// Rozpocznij animację !

...
timer.start();
}
public synchronized void stopAnimation() {
...
timer.stop();
}

Uruchamianie i zatrzymanie animacji mo

ż

e by

ć

te

ż

inicjowane w

obsłudze zdarze

ń

myszy dla komponentu realizuj

ą

cego animacj

ę

:

public void mousePressed(MouseEvent e) {
if (frozen) { frozen = false;
startAnimation();
} else { frozen = true;
stopAnimation();
}
}

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 12

2) Przesuwanie obrazu po ekranie

Przykład 8.3.

Program realizuje animacj

ę

, podczas której obraz rakiety

przesuwa si

ę

na tle obrazu gwiazd:

rocketship.gif:

starfield.gif:


Jedna klatka animacji:

Obraz rakiety posiada przezroczyste tło.

W panelu definiowanym przez programist

ę

malowane s

ą

dwa obrazy, z

których pozycja jednego nie zale

ż

y a drugiego zale

ż

y od numeru

aktualnej ramki.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 13

...// Miejsce inicjalizacji obrazów:

Image background = getImage(getCodeBase(), "images/rocketship.gif");
Image foreground = getImage(getCodeBase(), "images/starfield.gif");
...
public void paintComponent(Graphics g) {
super.paintComponent(g);

// Rysuje obszar komponentu

int compWidth = getWidth();
int compHeight = getHeight();

// Namaluj obraz w tle, je

ś

li posiada wła

ś

ciwy rozmiar:

imageWidth = background.getWidth(this);
imageHeight = background.getHeight(this);
if ((imageWidth > 0) && (imageHeight > 0)) {
g.drawImage(background, (compWidth - imageWidth)/2,
(compHeight - imageHeight)/2, this);
}

// Namaluj obraz na 1-szym planie, je

ś

li posiada wła

ś

ciwy rozmiar:

imageWidth = foreground.getWidth(this);
imageHeight = foreground.getHeight(this);

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 14

if ((imageWidth > 0) && (imageHeight > 0)) {
g.drawImage(foreground,
((frameNumber*5) % (imageWidth + compWidth)) - imageWidth,
(compHeight - imageHeight)/2, this);
}
}


Program wymaga jeszcze synchronizacji rysowania z załadowaniem
obu obrazów – odczekania na pełne załadowanie obu obrazów – i
przeskalowania obrazu tła tak, aby wypełniał cały obszar panelu.
Do tego celu posłu

ż

y klasa

MediaTracker

, omówiona w punkcie 4.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 15

3) Wy

ś

wietlanie sekwencji obrazów

Przykład 8.4.

Aplet wy

ś

wietla sekwencj

ę

10 obrazów:

T1.gif:

T2.gif:

T3.gif:

T4.gif:

T5.gif:

T6.gif:

T7.gif:

T8.gif:

T9.gif:

T10.gif:

. . .// W kodzie inicjalizacji:

Image[] images = new Image[10];
for (int i = 1; i <= 10; i++) {
images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif");
}

. . .// W metodzie

paintComponent

- w zale

ż

no

ś

ci od numeru ramki:

g.drawImage(images[frameNumber % 10], 0, 0, this);


Alternatywna metoda animacji to wykorzystanie komponentu etykiety

JLabel

i ustawianie wy

ś

wietlanego obrazu metod

ą

setIcon

.

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 16

4) Animacja z wykorzystaniem

MediaTracker

Klasa

MediaTracker

umo

ż

liwi efektywne ładowanie obrazów i opó

ź

ni

ich wy

ś

wietlenie do momentu, gdy b

ę

d

ą

one dost

ę

pne w cało

ś

ci.

Klasa

MediaTracker

posiada metody dla wcze

ś

niejszego ni

ż

potrzebne

(tzn. podczas rysowania komponentu) załadowania obrazów.

Poni

ż

sze metody sprawdzaj

ą

, czy pozostały jeszcze fragmenty obrazu

(lub obrazy) wymagaj

ą

ce załadowania.

public boolean checkAll()







 checkAll(false, true)

// sprawdza, czy

wszystkie obrazy nadzorowane przez ten obiekt zostały załadowane (lub
wystąpił błąd ładowania)

public boolean checkAll(boolean load)







 checkAll(load, true)

//

sprawdza, czy wszystkie obrazy nadzorowane przez ten obiekt zostały
załadowane (lub wystąpił błąd ładowania); jeśli load = true to inicjuje
ładowanie wszystkich przewidzianych ale jeszcze nieładowanych
obrazów.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 17

public boolean checkID(int id)

// sprawdza, czy obrazy o podanym

identyfikatorze, nadzorowane przez ten obiekt, zostały załadowane (lub
wystąpił błąd ładowania)

public boolean checkID(int id, boolean load)

// sprawdza, czy obrazy o

podanym obrazy o podanym identyfikatorze, nadzorowane przez ten
obiekt, zostały załadowane (lub wystąpił błąd ładowania); jeśli load = true
to inicjuje ładowanie wszystkich jeszcze nieładowanych obrazów.

Poni

ż

sze metody inicjuj

ą

ładowanie i oczekuj

ą

na załadowanie całych

obrazów:

public void waitForID (int id)

// inicjuje ładowanie obrazów o podanym

identyfikatorze i czeka na zakończenie ładowania

public void waitForID (int id, long ms)

// inicjuje ładowanie obrazów o

podanym identyfikatorze i czeka na zakończenie ładowania, ale nie dłużej
niż liczbę ms milisekund

public void waitForAll()

// inicjuje ładowanie obrazów nadzorowanych

przez ten obiekt i czeka na zakończenie ładowania

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 18

public void waitForAll(long ms)

// inicjuje ładowanie obrazów

nadzorowanych przez ten obiekt i czeka na zakończenie ładowania, ale nie
dłużej niż liczbę ms milisekund

Sprawdzenie stanu ładowania obrazów.

public int statusID(int id, boolean load)

// sprawdza stan ładowania

obrazów o podanym identyfikatorze id, nadzorowanych przez dany obiekt,
w postaci bitowej jao wynik operacji OR na stanie wszystkich tych
obrazów – możliwe stany to: 0 – ładowanie jeszcze nie rozpoczęte,
LOADING, ABORTED, ERRORED, COMPLETE;

jeśli load = true to

inicjuje ładowanie wszystkich jeszcze nieładowanych obrazów.

public int statusAll(boolean load)

// sprawdza stan ładowania wszystkich

obrazów, nadzorowanych przez dany obiekt.

Metody klasy

MediaTracker

dla dodawania nadzorowanych obrazów:

public void addImage(Image image, int id)

// dodaj obraz z podanym

identyfikatorem

public synchronized void addImage(Image image, int id, int w, int h)

//

dodaj obraz z podanym identyfikatorem; obraz ma być skalowany na
podany rozmiar

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 19

Przykład 8.5

. Modyfikacja poprzedniego apletu (z przykładu 8.4)

korzysta z metod

MediaTracker

- waitForAll

i

checkAll

. Do momentu

pełnego załadowania wszystkich obrazów wy

ś

wietla komunikat:

"Please wait..."

Fragmenty kodu z wyró

ż

nionymi zmianami w porównaniu z

poprzednim przykładem:
...// W miejscu deklaracji obiektów :

MediaTracker tracker;
tracker = new MediaTracker(this);

...// W metodzie init:

for (int i = 1; i <= 10; i++) {
images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif");
}

...// W metodzie buildUI, wołanej przez init (dla apletu) wzgl. main
// (dla aplikacji)

for (int i = 1; i <= 10; i++) {
tracker.addImage(images[i-1], 0);

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 20

}

...// Na pocz

ą

tku obsługi w metodzie actionPerformed :

try {

// Rozpocznij ładowanie obrazów. Czekaj na ich załadowanie.

tracker.waitForAll();
} catch (InterruptedException e) {}

...// W metodzie paintComponent:

// Jeśli nie załadowano wszystkich obrazów to wyczyść tło i wyświetl
// napis ze stanem ładowania:

if (!tracker.checkAll()) {
g.clearRect(0, 0, d.width, d.height);
g.drawString("Please wait...", 0, d.height/2);
}

// ale jeśli wszystkie obrazy zostały załadowane – namaluj je:

else {

...// ten sam kod co uprzednio ...

}

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 21

5) Efektywno

ść

ładowania obrazu

Ładowanie pojedynczych obrazów poprzez adresy URL (jak to zwykle
czyni

ą

aplety) zajmuje du

ż

o czasu, głównie z potrzeby inicjalizacji

poł

ą

czenia HTTP.

Sytuacj

ę

mo

ż

e poprawi

ć

umieszczenie szeregu obrazów w

pojedynczym pliku (np. pliku typu JAR). Np. pasek 4 obrazów jack.gif:

Przykład programu wykre

ś

lania paska obrazów.Niech:

//

imageStrip

– to obiekt klasy

Image

reprezentuj

ą

cy pasek obrazów.

//

imageWidth

– szeroko

ść

pojedynczego obrazu w pasku.

//

imageNumber

– indeks obrazu w pasku (od 0 do

numImages

).

int stripWidth = imageStrip.getWidth(this);
int stripHeight = imageStrip.getHeight(this);
int imageWidth = stripWidth / numImages;
g.clipRect(0, 0, imageWidth, stripHeight);
g.drawImage(imageStrip, -imageNumber*imageWidth, 0, this);

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 22

8.3 D

ź

wi

ę

ki

Java Sound Engine

jest bibliotek

ą

, wyst

ę

puj

ą

c

ą

w maszynie wirtualnej,

zapewniaj

ą

c

ą

odtwarzanie 64-kanałowego d

ź

wi

ę

ku i programow

ą

syntez

ę

d

ź

wi

ę

ku według protokołu MDI.


Klipy d

ź

wi

ę

kowe mog

ą

by

ć

nast

ę

puj

ą

cych formatów:

AIFF, AU, WAV , MIDI (typu 0 lub 1) , RMF .


Dane mog

ą

by

ć

długo

ś

ci 8- lub 16-bitów. Standardowo odtwarzanie

plików audio odbywa si

ę

z cz

ę

sto

ś

ci

ą

22 kHz i w trybie 16-bitów stereo,

ale mo

ż

liwe s

ą

te

ż

tryby 8-bitów lub mono.

Java Sound API

umo

ż

liwia u

ż

ytkownikowi odczyt, odtwarzanie i zapis

d

ź

wi

ę

ku.

Usługi wy

ż

szego rz

ę

du zwi

ą

zane z multimediami (np. kompresja,

dekompresja, synchronizacja audio i wideo, transport w sieci)
zapewnia tzw.

Java Media Framework (JMF)

.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 23

1) Odtwarzanie d

ź

wi

ę

ku w aplecie

Do

załadowania

d

ź

wi

ę

ku

z

miejsca

URL

słu

ż

y

metoda

Applet.getAudioClip.

public AudioClip getAudioClip(URL url)
public AudioClip getAudioClip(URL url, String name)

albo statyczna metoda

public final static AudioClip newAudioClip(URL url)

Obie wersje metody

getAudioClip

tworz

ą

obiekt klasy (zale

ż

nej od

kontekstu apletu) implementuj

ą

cej interfejs

AudioClip

a metoda

newAudioClip

– klasy

sun.applet.AppletAudioClip

, ale wracaj

ą

natychmiast bez wzgl

ę

du na to, czy istnieje podany adres czy te

ż

nie.

Klip b

ę

dzie ładowany przy 1-szej próbie „grania” go przez aplet.

Do natychmiastowego ładowania i „grania” słu

żą

metody apletu

play

.


Do odtwarzania klipu słu

żą

metody interfejsu

java.applet.

AudioClip

:

play, loop

i

stop

.

Ładowanie danych ma miejsce przed pierwszym odtworzeniem.

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 24

Przykład 8.6

. W aplecie

SoundApplet

pokazano odtwarzanie klipów

ż

nych typów -

AU , AIFF , WAV

i

MIDI

– umieszczonych pod

wspólnym adresem.

import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class SoundApplet extends JApplet
implements ActionListener, ItemListener {
AppletSoundList soundList;

// Lista obiektów klipów dźwiękowych

String chosenFile;

// Nazwa aktualnie wybranego pliku dźwiękowego

AudioClip onceClip, loopClip;

// Tu będą referowane 2 obiekty klipów

...

// Korzystamy z klasy pomocniczej
// class AppletSoundList extends java.util.Hashtable,
// która zarządza listą plików dźwiękowych o podanych nazwach,

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 25

// położonych względem wspólnego globalnego URL:

soundList = new AppletSoundList(this, getCodeBase());

// W metodzie obsługi zdarzenia przycisków w oknie apletu

public void actionPerformed(ActionEvent event) {

// następuje m.in. pobranie klipu dźwiękowego i jego odtwarzanie

onceClip = soundList.getClip(chosenFile); //
loopClip = soundList.getClip(chosenFile);
...
onceClip.play();

// Jednokrotne odtwarzanie

...
loopClip.loop();

// Pętla odtwarzania

...
loopClip.stop();

// Zatrzymaj odtwarzanie w pętli

.

..

}

W metodach

start

i

stop

apletu nast

ę

puje wznawianie i zatrzymanie

odtwarzania pliku:

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 26

public void stop() {
onceClip.stop();

// Zatrzymanie

if (looping) {
loopClip.stop();

// Zatrzymanie

}
}
public void start() {
if (looping) {
loopClip.loop();

// Wznawianie

}
}

Pliki d

ź

wi

ę

kowe ładowane b

ę

d

ą

w w

ą

tku pobocznym, w metodzie

run()

obiektu klasy pomocniczej

SoundLoader

zamiast w metodzie

init()

apletu. Dzi

ę

ki temu ładowanie pliku nie b

ę

dzie blokowało samego

apletu.

// W pierwszej klasie pomocniczej nast

ę

puje utworzenie obiektu w

ą

tku

// dla ka

ż

dego, przez u

ż

ytkownika wybranego pliku d

ź

wi

ę

kowego:

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 27

class AppletSoundList extends java.util.Hashtable {

...

// W metodzie

startLoading

wołanej w konstruktorze obiektu klasy

// pomocniczej inicjowana jest lista obiektów klipów dźwiękowych

public void startLoading(String relativeURL) {
new AppletSoundLoader(applet, this, baseURL, relativeURL);

// Załaduje klipy i przekaże je do obiektu typu AppletSoundList

}
}

// Definicja drugiej klasy – dla w

ą

tków realizuj

ą

cych ładowanie plików

import javax.swing.*;
import java.applet.*;
import java.net.URL;
class AppletSoundLoader extends Thread {
JApplet applet;
AppletSoundList soundList;
URL baseURL;

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 28

String relativeURL;
public AppletSoundLoader(JApplet applet,

// Obiekt – aplet SoundApplet

AppletSoundList soundList,

// Obiekt - lista klipów

URL baseURL,
String relativeURL) {
this.applet = applet;
this.soundList = soundList;
this.baseURL = baseURL;
this.relativeURL = relativeURL;
setPriority(MIN_PRIORITY);
start();

// Aktywuj wątek

}
public void run() {

// Metoda run() klasy wątku AppletSoundLoader

AudioClip audioClip = applet.getAudioClip(baseURL, relativeURL);
soundList.putClip(audioClip, relativeURL);

// Dołączy plik do listy

}
}

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 29

2) Odtwarzanie d

ź

wi

ę

ku w aplikacji (

newAudioClip()

)

Aplikacje mog

ą

ładowa

ć

klipy audio z dowolnego miejsca

URL,

dzi

ę

ki

metodzie statycznej

newAudioClip

w klasie

java.applet.Applet

:

public static final AudioClip newAudioClip(URL r);


Po utworzeniu obiektu klasy implementuj

ą

cej

AudioClip

metod

ą

Applet.newAudioClip

, aplikacja korzysta z metod interfejsu

AudioClip

:

play, loop, stop

;

w celu kontroli odtwarzania d

ź

wi

ę

ku.

Przykład.

Aplikacja

SoundApplication

– posiada prawie ten sam kod co

poprzedni aplet. Jedyn

ą

zasadnicz

ą

ż

nic

ą

jest zast

ą

pienie wywołania

metody

getAudioClip

przez

Applet.newAudioClip

w celu załadowania

d

ź

wi

ę

ków z

URL

.

AudioClip audioClip = Applet.newAudioClip(new URL(adresPliku));

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 30

8.4 Klasa

Graphics

Gdy ikony w AWT lub Swing-u nie wystarczaj

ą

nam dla prezentacji

grafiki mo

ż

emy skorzysta

ć

z klas

Graphics2D

lub

Graphics

.

1) Kształty

Klasa

Graphics

posiada metody dla rysowania nast

ę

puj

ą

cych

kształtów:



linia (drawLine)



prostokąt (drawRect, fillRect)



podwyższony lub obniżony prostokąt (draw3DRect, fill3DRect)



prostokąt o zaokraglonych rogach (drawRoundRect, fillRoundRect)



krzywa zamknięta (drawOval, fillOval)



łuki (drawArc, fillArc)



wielokąt (drawPolygon, drawPolyline, fillPolygon)

Np. narysowanie prostokąta:

g.drawRect(x, y, rectWidth - 1, rectHeight - 1);

Narysowanie wypełnionego obszaru prostokąta:

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 31

g.fillRect(x, y, rectWidth, rectHeight);

Uwaga: w metodzie drawRect podaje się o 1 piksel mniejszą szerokość i
wysokość, gdyż system rysuje linie pod podanym prostokątem a nie w jego
ramach.

Przykład 8.7

.

Program rysuje wypełniony

ż

ółtym kolorem prostok

ą

t w

miejscu klikni

ę

cia mysz

ą

przez u

ż

ytkownika.

GUI zawiera dwa komponenty: górny komponent jest klasy
u

ż

ytkownika RectangleArea – zawiera brzeg o dwóch stanach, tło i

ż

ółty prostok

ą

t; dolny komponent jest etykiet

ą

monitoruj

ą

c

ą

stan

programu.

Kod rysowania dla górnego komponentu:

class RectangleArea extends JPanel {
...

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 32

int rectWidth = 50;
int rectHeight = 50;
...
public RectangleArea(...) {
...

// Definiowanie brzegu dla panelu

Border raisedBevel = BorderFactory.createRaisedBevelBorder();
Border loweredBevel = BorderFactory.createLoweredBevelBorder();
Border compound = BorderFactory.createCompoundBorder

(raisedBevel, loweredBevel);

setBorder(compound);
...
}
...
public void paintComponent(Graphics g) {
super.paintComponent(g);

// Maluj tło

// Maluj wypełniony prostokąt w miejscu wybranym przez użytkownika.

if (point != null) {

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 33

g.drawRect(point.x, point.y, rectWidth - 1, rectHeight - 1);
g.setColor(Color.yellow);
g.fillRect(point.x + 1, point.y + 1, rectWidth - 2, rectHeight - 2);
controller.updateLabel(point);
}
}
}


W metodzie paintComponent wołane są metody drawRect i fillRect w celu
narysowania prostokąta o obramowaniu 50 x 50 pikseli wypełnionego żółtym
prostokątem o rozmiarze 48 x 48 pikseli.

Uwaga: ujemne dane dla szeroko

ś

ci lub wysoko

ś

ci, albo punkt

odniesienia poło

ż

ony poza obszarem, albo zbyt du

ż

e rozmiary

prostok

ą

ta s

ą

dozwolone, ale prowadz

ą

do narysowania niepełnego

prostok

ą

ta lub całkowicie niewidocznego.

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 34

Przykład 8.8

.

Program ilustruje wszystkie kształty.

Fragment kodu rysujący podane kształty:


zmienne rectHeight i rectWidth podają rozmiar prostokąta obejmującego dla
każdego kształtu,



zmienne x i y są różne dla każdego kształtu, aby kształty nie pokrywały się;



zmienne bg i fg są typu Color – wyznaczają one kolor tła i pióra.

Color fg3D = Color.lightGray;
...

// Metoda: drawLine(x1, y1, x2, y2)

g.drawLine(x, y+rectHeight-1, x + rectWidth, y);
...

// Metoda: drawRect(x, y, w, h)

g.drawRect(x, y, rectWidth, rectHeight);
...

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 35

// Metoda: draw3DRect(x, y, w, h, raised)

g.setColor(fg3D);
g.draw3DRect(x, y, rectWidth, rectHeight, true);
g.setColor(fg);
...

// Metoda: drawRoundRect(x, y, w, h, arcw, arch)

g.drawRoundRect(x, y, rectWidth, rectHeight, 10, 10);
...

// Metoda: drawOval(x, y, w, h)

g.drawOval(x, y, rectWidth, rectHeight);
...

// Metoda: drawArc(x, y, w, h, startAngle, arcAngle)

g.drawArc(x, y, rectWidth, rectHeight, 90, 135);
...

// Metoda: drawPolygon(xPoints, yPoints, numPoints)
// Rysuje krzywą zamkniętą

int x1Points[] = {x, x+rectWidth, x, x+rectWidth};
int y1Points[] = {y, y+rectHeight, y+rectHeight, y};

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 36

g.drawPolygon(x1Points, y1Points, x1Points.length);
...

// Metoda: drawPolyline(xPoints, yPoints, numPoints)
// Rysuje krzywą otwartą

int x2Points[] = {x, x+rectWidth, x, x+rectWidth};
int y2Points[] = {y, y+rectHeight, y+rectHeight, y};
g.drawPolyline(x2Points, y2Points, x2Points.length);
...

// Metoda: fillRect(x, y, w, h)

g.fillRect(x, y, rectWidth, rectHeight);
...

// Metoda: fill3DRect(x, y, w, h, raised)

g.setColor(fg3D);
g.fill3DRect(x, y, rectWidth, rectHeight, true);
g.setColor(fg);
...

// Metoda: fillRoundRect(x, y, w, h, arcw, arch)

g.fillRoundRect(x, y, rectWidth, rectHeight, 10, 10);

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 37

...

// Metoda: fillOval(x, y, w, h)

g.fillOval(x, y, rectWidth, rectHeight);
...

// Metoda: fillArc(x, y, w, h, startAngle, arcAngle)

g.fillArc(x, y, rectWidth, rectHeight, 90, 135);
...

// Metoda: fillPolygon(xPoints, yPoints, numPoints)

int x3Points[] = {x, x+rectWidth, x, x+rectWidth};
int y3Points[] = {y, y+rectHeight, y+rectHeight, y};
g.fillPolygon(x3Points, y3Points, x3Points.length);
...

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 38

2) Rysowanie tekstu

Funkcjonalno

ść

dla rysowanie tekstu w AWT zapewniaj

ą

klasy

Graphics, Font, FontMetrics

.

W miar

ę

mo

ż

liwo

ś

ci nale

ż

y korzysta

ć

z komponentów stworzonych dla

reprezentacji informacji tekstowej.

W klasie

Graphics

zdefiniowano trzy metody rysowania tekstu:

drawBytes, drawChars, drawString.

Np.

g.drawString("Hello World!", x, y);

Argumenty (liczby całkowite) x, y – pozycja lewego dolnego rogu tekstu
(y wyznacza bazow

ą

lini

ę

tekstu).

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 39

Klasa FontMetrics -

umożliwia zmianę domyślnej czcionki.

Przykład 8.9

. Program jest modyfikacją poprzedniego programu (8.8)-

wykorzystano obiekt klasy FontMetrics dla zmiany rozmiaru czcionki tak,
aby najdłuższy napis („drawRoundRect”) zmieścił się w obszarze dla
pojedynczego kształtu.

boolean fontFits = false;
Font currentFont = biggestFont;
FontMetrics currentMetrics = getFontMetrics(currentFont);
int size = currentFont.getSize();
String name = currentFont.getName();
int style = currentFont.getStyle();

while (!fontFits) {

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 40

if ( (currentMetrics.getHeight() <= maxCharHeight)
&& (currentMetrics.stringWidth(longString) <= xSpace)) {
fontFits = true;
} else {
if (size <= minFontSize) {
fontFits = true;
} else { currentFont = new Font(name, style, --size);
currentMetrics = getFontMetrics(currentFont);
}
}

Obiekt klasy FontMetrics udostępnia następującą informację o rozmiarach
danej czcionki:

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 41

Metody klasy FontMetrics

informujące o pionowych rozmiarach:

int getAscent()
int getMaxAscent()

Pierwsza metoda podaje liczbę pikseli pomiędzy linią górną a bazową. Druga
- maksymalną odległość dla najwyższych znaków.

int getDescent()
int getMaxDescent()

Pierwsza metoda podaje liczbą pikseli pomiędzy linią bazową a linią dolną.
Druga – maksymalna odległość dla najwyższych znaków.

int getHeight();

Metoda podaje liczbą pikseli pomiędzy linią bazową wiersza

tekstu a linią bazową następnego wiersza tekstu.

int getLeading()

; Metoda podaje liczbą pikseli odstępu pomiędzy sąsiednimi

wierszami tekstu – pomiędzy linią dolną jednego wiersza a linią dolną
nastepnego. Do oznaczenia wysokości czcionki stosuje się miarę „punktową”
– 1 punkt to ok. 1/72 cala.

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 42

Metody klasy

FontMetrics

informujące o rozmiarach w poziomie dla czcionki

(podają one szerokość czcionki z uwzględnieniem odstępu):

int getMaxAdvance()

Pełna szerokość (w pikselach) najszerszego znaku czcionki.

int bytesWidth(byte[], int, int)

Pełna szerokość tekstu - wycinka tablicy (1-szy argument) od podanego
indeksu (2-gi argument) i o podanej liczbie bajtów (3-ci argument).

int charWidth(int)
int charWidth(char)

; Pełna szerokość podanego znaku.

int charsWidth(char[], int, int)

Pełna szerokość napisu – wycinka tablicy znaków.

int stringWidth(String)

; Pełna szerokość podanego napisu.

int[] getWidths()

Pełna szerokość każdego z pierwszych 256 znaków czcionki.

background image

8. Multimedia.

W. Kasprzak: Programowanie zdarzeniowe

8 - 43

3) Klasa

Graphics2D

Jest to znacznie bogatsza w kształty geometryczne klasa graficzna
wprowadzona w Java 2. Umożliwia ona:



rysowanie linii o dowolnej grubości;



wypełnianie kształtów gradientami i teksturami;



przesuwanie, obracanie i skalowanie oraz łączenie tekstu i grafiki;



komponowanie przesłaniania tekstu i grafiki;



zapamiętywanie obrazów i operacje na obrazach.

Np.


Wyszukiwarka

Podobne podstrony:
Proz S2 id 402992 Nieznany
Proz S12 id 402989 Nieznany
Proz S9 id 402999 Nieznany
Proz S13 id 402990 Nieznany
Proz S4 id 402994 Nieznany
Proz S3 id 402993 Nieznany
Proz S14 id 402991 Nieznany
Proz S7 id 402997 Nieznany
Proz S10 id 402987 Nieznany
Proz S5 id 402995 Nieznany
Proz S2 id 402992 Nieznany
Proz S12 id 402989 Nieznany
chemia proz maj 2011 cke id 112 Nieznany
Abolicja podatkowa id 50334 Nieznany (2)
4 LIDER MENEDZER id 37733 Nieznany (2)
katechezy MB id 233498 Nieznany
metro sciaga id 296943 Nieznany
perf id 354744 Nieznany
interbase id 92028 Nieznany

więcej podobnych podstron