Proz S10 id 402987 Nieznany

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 1

10. Swing – układanie i malowanie

10.1 Zarz

ą

dzenie układem i malowanie kontenera

10.2 Klasa

JComponent

i malowanie komponentu

10.3 Wzorce projektowe

Composite

i

Decorator

10.4 W

ą

tek rozdziału zdarze

ń

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 2

10.1 Zarz

ą

dzanie układem i malowanie kontenera

1) Zarz

ą

dzanie układem komponentów w kontenerze

Poni

ż

ej podano 5 ró

ż

nych układów komponentów. W czasie realizacji

kontenera okre

ś

lane s

ą

rozmiary i poło

ż

enia komponentów. 6-ty

menad

ż

er układu to

CardLayout

układ o charakterze zakładek.

Menad

ż

erowie

(zarz

ą

dcy) układu:

BorderLayout,

GridLayout,

FlowLayout,

BoxLayout,

GridBagLayout,

CardLayout

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 3

Ka

ż

dy kontener posiada

domy

ś

lnego

menad

ż

era układu :



dla obiektów klasy

JPanel

jest nim

FlowLayout

;



dla paneli zawarto

ś

ci (głównych kontenerów w obiektach

JApplet

,

JDialog

i

JFrame

) jest nim

BorderLayout

.


O zastosowanym menad

ż

erze układu powinni

ś

my decydowa

ć

w chwili

tworzenia obiektu klasy

JPanel

lub podczas dodawania komponentów do

panelu zawarto

ś

ci.

Zmian

ę

menad

ż

era umo

ż

liwia metoda kontenera

setLayout

. Np.

fragment kodu ustawiaj

ą

cy menad

ż

era

BorderLayout

:

JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());



BorderLayout

Posiada

5

obszarów

przeznaczonych

dla

komponentów:

North, South, East, West, Center

.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 4

BoxLayout

Komponenty rozmieszczane s

ą

w kolumnie lub

wierszu.

Zachowane

s

ą

maksymalne

rozmiary

komponentu i mo

ż

liwe jest przyleganie komponentów.

FlowLayout

Wypełnia komponentami wiersze od lewej do prawej i kontynuje w razie
potrzeby w dalszym wierszu.

GridLayout

Normalizuje rozmiary komponetów i wy

ś

wietla

je w zadanej liczbie wierszy i kolumn.

GridBagLayout

Umo

ż

liwia

elastyczny

dobór

rozmiarów

wierszy i kolumn.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 5

Preferowany rozmiar komponentu

Na rzecz komponentu mo

ż

liwe s

ą

wywołania metod:

setMinimumSize, setPreferredSize, setMaximumSize

lub nadpisanie metod

getMinimumSize, getPreferredSize, getMaximumSize.

Jedynie menad

ż

er

BoxLayout

zwraca uwag

ę

na wymagany przez

komponent maksymalny rozmiar.

Preferowane poło

ż

enie komponentu

Wywołania metod komponentu:

setAlignmentX , setAlignmentY

lub nadpisanie metod

getAlignmentX , getAlignmentY .

Jedynie menad

ż

er

BoxLayout

zwraca uwag

ę

na wymagane przez

komponent poło

ż

enie.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 6

Przebieg ustalania rozmiaru i poło

ż

enia ramki

JFrame

Metoda

pack()

sprawia,

ż

e komponent klasy

JFrame

posiada

preferowany

rozmiar.

1. Preferowany rozmiar ramki wynika z dodania rozmiarów

brzegu

ramki

do

preferowanego rozmiaru komponentów

bezpo

ś

rednio

zawartych w ramce, czyli równa si

ę

sumie preferowanych rozmiarów

panelu zawarto

ś

ci ramki

("content pane") i

paska menu

.

2. Zarz

ą

dca układu dla "content pane" (zwykle jest nim

BorderLayout

)

okre

ś

la

preferowany rozmiar

tego "ukrytego" kontenera. Zale

ż

y on od:

rozmiarów brzegu

panelu zawarto

ś

ci i od

preferowanych rozmiarów komponentów

, zawartych w tym panelu.

Np. zarz

ą

dca

GridLayout

stara si

ę

dopasowa

ć

szeroko

ść

i wysoko

ść

ka

ż

dego zarz

ą

dzanego komponentu do najszerszego i najwy

ż

szego z

nich.

3. Ka

ż

dy

komponent

podaje zarz

ą

dcy układu swoje

preferowane

rozmiary

lub zwraca rozmiar wynikaj

ą

cy ze

ś

rodowiska "

look and feel

".

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 7

4. Po wyznaczeniu rozmiarów komponentów, ustalany jest rozmiar ich
kontenera i ten wynik

propagowany jest w gór

ę

hierarchii

komponentów.

2) Malowanie komponentów kontenera

Zasady malowania komponentu

1. Proces wykre

ś

lania rozpoczyna si

ę

od

najwy

ż

szego komponentu

w

hierarchii, który ma by

ć

malowany (po raz pierwszy lub od

ś

wie

ż

ony).

2. Komponenty Swing-a

domy

ś

lnie od

ś

wie

ż

aj

ą

swój wygl

ą

d po

modyfikacji. Np. w wyniku wywołania metody

setText

()

komponent

zostanie zmodyfikowany i ewentualnie zmieni

ą

si

ę

jego rozmiary.

3. Je

ś

li zmiana poło

ż

enia lub rozmiaru komponentu nie nast

ę

puje

automatycznie to mo

ż

na j

ą

wymusi

ć

metod

ą

revalidate()

a potem nale

ż

y

wywoła

ć

repaint()

.

4. Kod malowania wykonuje si

ę

w

w

ą

tku rozdziału zdarze

ń

.

5. Malowanie jest

podwójnie buforowane

- najpierw wypełniany jest

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 8

"wirtualny bufor ekranu" i dopiero po zako

ń

czeniu malowania odbywa si

ę

opró

ż

nienie tego bufora i przesłanie jego zawarto

ś

ci do bufora ekranu.

Metoda

setOpaque

Mo

ż

na przekaza

ć

do zarz

ą

dcy malowania informacj

ę

o tym,

ż

e

komponent

jest nieprzezroczysty

- metod

ą

setOpaque(true)

- co zwi

ę

kszy

efektywno

ść

procesu rysowania.

Wprawdzie komponentom odpowiadaj

ą

zawsze

prostok

ą

tne obszary

to

jednak przezroczyste komponenty mog

ą

mie

ć

dowolny kształt,

odsłaniaj

ą

c fragmenty przykrywanego komponentu.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 9

Przykład.

Dany jest interfejs u

ż

ytkownika i tworz

ą

ca go hierarchia

kontenerów.

Proces malowania powy

ż

szego graficznego interfejsu:

1.

Kontener główny

typu

JFrame

maluje si

ę

samodzielnie jako pierwszy.

2.

Kontener "content pane

" najpierw maluje tło - szary, jednorodny

czworok

ą

t. Nast

ę

pnie wzywa on zawarty w nim obiekt typu

JPanel

do

malowania si

ę

.

Zwró

ć

my uwag

ę

na fakt,

ż

e panel zawarto

ś

ci powinien by

ć

nieprzezroczysty

. Poniewa

ż

JPanel

jest nieprzezroczysty mo

ż

na by go

wykorzysta

ć

w roli "content pane", tzn. zamiast

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 10

content=frame

.

getContentPanel()

i

content.add(panel)

// dodania naszego panelu do „content pane”

mogliby

ś

my ustawi

ć

„content pane” na nasz panel dzi

ę

ki:

setContentPane(panel)

.

3.

Kontener typu

JPanel

zawarty w „content pane” maluje najpierw

swoje tło - szary, jednorodny prostok

ą

t. Nast

ę

pnie maluje swój brzeg -

jest on w tym przypadku typu

EmptyBorder

– brzeg zwi

ę

ksza

preferowany rozmiar panelu. Na koniec panel wzywa "swoje"
komponenty aby po kolei same "malowały si

ę

".

4.

Komponent

JButton

maluje prostok

ą

tne tło (je

ś

li wyst

ę

puje) i

nast

ę

pnie maluje swój tekst. Je

ś

li przycisk posiada aktualnie kontekst

klawiatury to jego wygl

ą

d jest zmieniany zgodnie z przyj

ę

tym

ś

rodowiskiem "look-and-feel".

5.

Komponent

JLabel

maluje swoje tło i swój tekst.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 11

10.2 Klasa

JComponent

i malowanie komponentu

Bazowa klasa komponentów Swing-a to klasa

JComponent

, która

dziedziczy z klasy

Container,

a ta z kolei dziedziczy z klasy

Component

.

Klasa

Component

– zapewnia wszystkie podstawowe funkcje

komponentu od ustawiania ich wygl

ą

du po malowanie i zdarzenia.

Klasa

Container

– wspomaga dodawanie komponentów do kontenera i

zarz

ą

dzanie rozkładem komponentów.

1) Cechy klasy

JComponent



Ustawianie wygl

ą

du komponentu

Metoda

setBorder

umo

ż

liwia okre

ś

lenie brzegu komponentu.

Inne metody pozwalaj

ą

na ustawianie kolorów (

setForeground,

setBackground

), czcionki (

setFont

), przezroczysto

ś

ci (

setOpaque

) i

kursora (

setCursor

).



Malowanie komponentu

Metoda główna

paint

nie jest jawnie wywoływana i nie mo

ż

e by

ć

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 12

przesłaniana. Wywołuje ona metody

paintComponent

,

paintBorder

i

paintChildren

. Z nich jedynie metoda

paintComponent

mo

ż

e by

ć

przesłaniana i wtedy wyznacza ona własny kod u

ż

ytkownika dla

rysowania komponentu.
Jawnie wywoływanymi metodami s

ą

te

ż

:

repaint

(wymusza, aby cało

ść

lub cz

ęść

w podanym prostok

ą

cie

obszaru komponentu została odmalowana)

,

revalidate (

wymusza ponowne obliczenie rozkładu dla kontenera

komponentu i prowadzi do odpowiedniego odmalowania).



“Look and feel”

Ka

ż

dy obiekt klasy

JComponent

posiada zwi

ą

zany z nim obiekt klasy

ComponentUI,

który realizuje jego rysowanie, obsług

ę

zdarze

ń

,

wyznacza rozmiary, itp. Rodzaj obiektu

ComponentUI

specyfikowany

jest niejawnie ustawieniem “look and feel” wynikaj

ą

cym z wykonania w

programie metody

UIManager.SetLookAndFeel

.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 13



Wspomaganie rozkładu komponentów

Klasa

Component

posiadała metody pobierania wymaga

ń

komponentu,

np.

getMinimumSize, getMaximumSize,

getPreferredSize

,

getAlignmentY

i

getAlignmentX

, a klasa

JComponent

dodaje do nich metody

umo

ż

liwiaj

ą

ce ustawianie tych własno

ś

ci –

setPreferredSize, setMinimumSize, setMaximumSize, setAlignmentX

i

setAlignmentY.

Istniej

ą

te

ż

metody do ustawiania i pobierania menad

ż

era układu

komponentu (

setLayout, getLayout

) oraz ustawienia kierunku -

zorientowania komponentu (

applyComponentOrientation

).



Zarz

ą

dzanie hierarchi

ą

komponentów zawartych w kontenerze

Metody dodaj

ą

ce komponent do kontenera (

add

) i usuwaj

ą

ce komponent

z kontenera (

remove

). Metody informuj

ą

ce o hierarchii w kontenerze:

getRootPane

– podaje kontener pełni

ą

cy rol

ę

“root pane” w kontenerze.

getComponentCount

- podaje liczb

ę

komponentów tego kontenera,

getComponent, getComponents

- pobiera jeden (o podanym indeksie)

lub wszystkie komponenty tego kontenera,

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 14

getParent

- podaje bezpo

ś

redni kontener tego komponentu;

getTopLevelAncestor

- pobiera główny kontener dla tego komponentu.



Własno

ś

ci ustawiane przez u

ż

ytkownika

U

ż

ytkownik mo

ż

e okre

ś

li

ć

własno

ś

ci (pary „nazwa/obiekt”) dla ka

ż

dego

obiektu klasy

JComponent.

Za ich pomoc

ą

mo

ż

e on sterowa

ć

przetwarzaniem danych swoich komponentów.
Metody

putClientProperty

i

getClientProperty

słu

żą

do nadawania

warto

ś

ci i pobierania warto

ś

ci własno

ś

ciom komponentu.



Wspomaganie dost

ę

pu do stanu komponentu

Szereg metod klasy

JComponent

umo

ż

liwia pobranie lub ustawianie

stanu komponentu. Np.

setName, getName, setEnabled, isEnabled,

setVisible, isVisible, isShowing

(sprawdza,

czy komponent i jego kontener

s

ą

namalowani na ekranie),

setToolTipText

.



Wspomaganie dost

ę

pu do rozmiaru i poło

ż

enia komponentu

Szereg metod pozwala na ustawianie i pobranie rozmiaru i poło

ż

enia:

getWidth, getHeight, getSize, setSize

(pobierz aktualn

ą

szeroko

ść

wzgl.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 15

wysoko

ść

komponentu w pikselach, pobierz wzgl. ustaw rozmiar

komponentu),

getX, getY, getBounds, setBounds

(pobierz aktualn

ą

współrz

ę

dn

ą

x wzgl.

y punktu odniesienia komponentu lub pobierz wzgl. ustaw poło

ż

enie

obejmuj

ą

cego prostok

ą

ta komponentu, wszystko wzgl

ę

dem górnego

lewego rogu przodka)

getLocation,

getLocationOnScreen,

setLocation

(pobierz

aktualne

poło

ż

enie komponentu wzgl

ę

dem górnego lewego rogu przodka wzgl.

ekranu lub ustaw to poło

ż

enie wzgl

ę

dne komponentu),

getInsets

(pobierz rozmiar brzegu komponentu).



Obsługa zdarze

ń

Metody pozwalaj

ą

ce zarejestrowa

ć

lub wyrejestrowa

ć

obiekt obsługi

zdarzenia komponentu:
dla przycisków myszy (

addMouseListener, removeMouseListener)

,

ruchu myszy (

addMouseMotionListener, removeMouseMotionListener

),

klawiatury (

addKeyListener, removeKeyListener

) i zdarzenia zwi

ą

zane ze

zmian

ą

stanu komponentu – ukrycia widoczno

ś

ci, przywrócenia

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 16

widoczno

ś

ci,

przesuni

ę

cia

poło

ż

enia,

zmiany

rozmiarów,

itd.

(

addComponentListener, removeComponentListener

).



Wspomaganie mechanizmu ”drag and drop

Istniej

ą

metody wspomagaj

ą

ce wymian

ę

danych przez schowek

systemowy lub mechanizm przeci

ą

gania komponentu „drag and drop

(

setTransferHandler, getTransferHandler

) oraz sprawdzaj

ą

ce czy dany

punkt ekranu znajduje si

ę

wewn

ą

trz obszaru komponentu (

contains

) albo

jaki

komponent

najwy

ż

szego

poziomu

zawiera

ten

punkt

(

getComponentAt

).



Skróty klawiszy

Akcje

zdefiniowane

dla

komponentu

mog

ą

by

ć

aktywowane

przyci

ś

ni

ę

ciami klawiszy, np. je

ś

li przycisk posiada aktualny kontekst

klawiatury to naci

ś

ni

ę

cie klawisza „spacja” jest równowa

ż

ne z

klikni

ę

ciem

mysz

ą

.

Zwi

ą

zanie

akcji

z

klawiszami

nast

ę

puje

automatycznie dzi

ę

ki mechanizmowi „

look and feel

”.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 17

2) Malowanie komponentu

W celu wymalowania siebie samego obiekt klasy

JComponent

korzysta z

trzech metod, wywoływanych w nast

ę

puj

ą

cej kolejno

ś

ci:



paintComponent

– główna metoda malowania – domy

ś

lnie pierwsza

czynno

ść

to odtwarzanie tła je

ś

li komponent jest nieprzezroczysty –

nast

ę

pnie ewentualny kod malowania stworzony przez programist

ę

.



paintBorder

– nakazuje rysowanie siebie brzegowi komponentu (je

ś

li

istnieje) – ta metoda nie powinna by

ć

wywoływana lub przesłaniania.



paintChildren

- nakazuje rysowanie siebie komponentom-potomkom

zawartym w danym kontenerze (je

ś

li istniej

ą

) – ta metoda nie powinna

by

ć

wywoływana lub przesłaniania.


Powy

ż

sze trzy metody s

ą

wołane w metodzie klasy

JComponent

-

paint

,

która nie powinna by

ć

przesłaniana.


Standardowa realizacja malowania komponentu

Swinga

(ale nie dla

samej klasy

JComponent

) metod

ą

paintComponent

w

ś

rodowisku look-

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 18

and-feel

jest delegowana do pewnego obiektu (klasy

ComponentUI

),

który realizuje nast

ę

puj

ą

ce kroki:



sprawdza, czy komponent jest nieprzezroczysty,



je

ś

li tak, maluje tło całego obszaru komponentu,



ewentualnie maluje elementy wynikaj

ą

ce ze

ś

rodowiska look-and-feel.

Podwójne buforowanie

zapewnia płynne rysowanie GUI na ekranie.

Przykład.

Ilustracja kolejno

ś

ci rysowania w ka

ż

dym komponencie

dziedziczonym z klasy

JComponent

:

1. tło (je

ś

li

nieprzezroczyste)

2. rysowanie według

kodu u

ż

ytkownika

(je

ś

li wyst

ę

puje)

3. obramowanie
(je

ś

li wyst

ę

puje)

4. zawarte

komponenty

(je

ś

li wyst

ę

puj

ą

)

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 19

3) Metoda

paintComponent

Przykład 10.1

Wizualizacja obrazu, o normalnym rozmiarze i rozci

ą

gni

ę

tego wszerz.

class ImagePanel extends JPanel {
...
public void paintComponent(Graphics g) {
super.paintComponent(g);

// Rysuj tło

// Obraz o normalnym rozmiarze

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

// Rozmiar obrazu to 85 x 62

// Obraz rozci

ą

gni

ę

ty wszerz

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

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 20

W podanym przykładzie do

rysowania tła

wykorzystano

paintComponent

z nadklasy. Mo

ż

na te

ż

jawnie

w kodzie

paintComponent

poda

ć

na

pocz

ą

tku sekwencj

ę

instrukcji:

g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(getForeground());

Układ współrz

ę

dnych komponentu

– współrz

ę

dne całkowite z zakresu

(0, 0) do (szeroko

ść

- 1, wysoko

ść

- 1).

Ewentualne obramowanie zmniejsza obszar malowania komponentu.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 21

Informacj

ę

o komponencie uzyskujemy za pomoc

ą

metod:

getWidth, getHeight

i

getInsets

(dla informacji o brzegu).

Np.

public void paintComponent(Graphics g) {
...
Insets insets = getInsets();
int currentWidth = getWidth() - insets.left - insets.right;
int currentHeight = getHeight() - insets.top - insets.bottom;
...
}

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 22

4) Metoda

repaint

Argumenty metody

repaint

void repaint()

-

nakaz odmalowania całego obszaru komponentu.

void repaint(int, int, int, int)

– nakaz odmalowania jedynie podanego

obszaru prostok

ą

tnego w komponencie - X, Y, szeroko

ść

, wysoko

ść

.


Przykład 10.2

Program obliczaj

ą

cy obszar dla odmalowania.

class SelectionArea extends JLabel {
...
public SelectionArea(ImageIcon image, ...) {
super(image);

// Komponent wy

ś

wietla obraz.

...
}

...// W obsłudze zdarzenia „mouse-dragged”:

Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 23

repaint(totalRepaint.x, totalRepaint.y,
totalRepaint.width, totalRepaint.height);

...
public void paintComponent(Graphics g) {

super.paintComponent(g);

// Maluje tło i obraz

...

// Maluje prostok

ą

t na obrazie.

g.setColor(Color.white);
g.drawRect(rectToDraw.x, rectToDraw.y,
rectToDraw.width - 1, rectToDraw.height - 1);
...
}
...
}

Nad obrazem malowana jest ramka wybrana przez u

ż

ytkownika. Tylko

obszar komponentu odpowiadaj

ą

cy tej ramce jest odmalowywany.

Ten sam prostok

ą

t przekazany do metody

repaint

odzwierciedlony jest w

obiekcie

Graphics

przekazanym do metody

paintComponent.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 24

Metoda

getClipBounds

umo

ż

liwia pobranie malowanego obszaru:

public void paintComponent(Graphics g) {
Rectangle clipRect = g.getClipBounds();
if (clipRect != null) {

// punkt odniesienia

= (clipRect.x, clipRect.y)

// szeroko

ść

, wysoko

ść

= clipRect.width, clipRect.height

} else { ... }
}

Obiekt

Graphics

Obiekt

Graphics

zawiera informacje (stan kontekstu graficznego – kolor,

czcionk

ę

, obszar malowania) i metody potrzebne do malowania (np.

drawImage, drawString, drawRect, fillRect).

Ustawianie i pobieranie kontekstu, np.

getColor, getFont, setColor, setFont, setClip, getClipBounds.


Po zredukowanym malowaniu nale

ż

y odtworzy

ć

obszar malowania

komponentu jeszcze w metodzie

paintComponent

:

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 25

Rectangle oldClipBounds = g.getClipBounds();
Rectangle clipBounds = new Rectangle(...);
g.setClip(clipBounds);

...// Malowanie ...

g.setClip(oldClipBounds);

// Odtworzenie obszaru malowania


Powy

ż

sze wynika z faktu,

ż

e nie mamy pełnej kontroli nad obszarem

malowania w programie:

-

wiele kolejnych wywoła

ń

repaint

mo

ż

e by

ć

poł

ą

czonych w jedno

wywołanie

paintComponent;

-

metoda

paintComponent

mo

ż

e by

ć

wołana przez domy

ś

lny system

malowania, bez jawnego wołania w aplikacji

repaint

; np. pierwsza

prezentacja GUI, odsłoni

ę

cie okna komponentu przez zabranie

innego przesłaniaj

ą

cego okna.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 26

10.3 Wzorce projektowe

Composite

i

Decorator

1) Wzorzec struktury

Composite

Composite

jest wzorcem słu

żą

cym do reprezentacji

struktur drzewiastych typu

cało

ść

-cz

ęść

w taki sposób, aby sposób zarz

ą

dzania struktur

ą

nie zale

ż

ał od

jej zło

ż

ono

ś

ci. Ten wzorzec jest implementowany w

obiektowych bibliotekach

AWT i Swing

do realizacji struktury „komponent – kontener” i do zarz

ą

dzania jej

wizualizacj

ą

.


Z punktu widzenia obiektu-klienta wzorzec

Composite

umo

ż

liwia zarz

ą

dzanie

cało

ś

ci

ą

za pomoc

ą

wywołania operacji dla

jednego obiektu – korzenia drzewa

.

Niepotrzebna jest mu wiedza o rozmiarze drzewa, poniewa

ż

wywołanie

operacji (np. odmalowania kontenera) zostanie przekazane automatycznie do
wszystkich jego elementów.

Centralnym elementem wzorca jest

interfejs

Component

, który reprezentuje

dowolny obiekt w strukturze drzewiastej. Posiada on mo

ż

liwo

ś

ci dodawania i

usuwania swojego obiektu potomnego (oczywi

ś

cie, tak

ż

e typu

Component

)

oraz odwołania si

ę

do wybranego potomka. Zawiera on tak

ż

e

metod

ę

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 27

operation()

, któr

ą

nale

ż

y wykona

ć

na ka

ż

dym w

ęź

le struktury.

Interfejs

Component

posiada dwie implementacje:

Leaf

oraz

Composite

.

Klasa

Leaf

reprezentuje obiekty, które nie posiadaj

ą

potomków (czyli li

ś

cie w

strukturze),

natomiast

Composite

jest dowolnym w

ę

złem po

ś

rednim.


Poniewa

ż

ka

ż

dy w

ę

zeł po

ś

redni zarz

ą

dza tak

ż

e poddrzewem, którego jest

korzeniem,

dlatego

metoda

operation()

,

poza

wykonaniem

operacji

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 28

specyficznych dla ka

ż

dego w

ę

zła, wywołuje swoje odpowiedniki w obiektach

potomnych, w ten sposób propaguj

ą

c wywołanie.

2) Wzorzec struktury

Decorator

Celem wzorca jest u

mo

ż

liwienie

dynamicznego

dodawania funkcjonalno

ś

ci do

obiektu. Stwarza on

elastyczn

ą

alternatyw

ę

dla mechanizmu dziedziczenia

klas.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 29

Klient

wysyła komunikat do obiektu

Decorator

, który przekazuje go obiektowi

ConcreteComponent

i wykonuje

dodatkowe operacje

(„dekoracje”).


Component

jest wspólnym interfejsem

dla wszystkich klas, które mo

ż

na

dekorowa

ć

. Implementuj

ą

go zarówno klasa

ConcreteComponent

, która jest

odpowiedzialna za podstawow

ą

funkcjonalno

ść

oferowan

ą

klientowi, jak i

dekoratory

.

Ka

ż

dy dekorator

posiada referencj

ę

(oznaczon

ą

jako kompozycj

ę

, aby

zaznaczy

ć

obowi

ą

zkowo

ść

i sił

ę

tej relacji) do innego obiektu

Component

,

którym mo

ż

e by

ć

ponownie dekorator lub

ConcreteComponent

. Otrzymuj

ą

c

żą

danie wykonania okre

ś

lonej operacji,

dekorator deleguje je

do swojego

„wewn

ę

trznego” obiektu

Component

, a nast

ę

pnie wykonuje

specyficzn

ą

dla

siebie dodatkow

ą

funkcjonalno

ść

.

Czyli dodanie do obiektu nowej funkcjonalno

ś

ci

polega na utworzeniu

dekoratora i przekazaniu mu tego obiektu.

Kiedy ka

ż

dy dekorator (klasy

ConcreteDecoratorA

i

ConcreteDecoratorB

)

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 30

dodaje do dekorowanego obiektu tylko jedn

ą

funkcj

ę

, wówczas dekoruj

ą

c

obiekt wielokrotnie uzyskujemy efekt osi

ą

gni

ę

cia

żą

danej sumarycznej

funkcjonalno

ś

ci.


Pod wzgl

ę

dem typu udekorowany obiekt nie ró

ż

ni si

ę

od obiektu

nieudekorowanego (klient widzi go przez interfejs

Component

), dlatego

zastosowanie tego wzorca nie wymaga istotnych zmian w kodzie klienta.

Obiekt

ConcreteComponent

, aby mógł uczestniczy

ć

w tym wzorcu, musi

definiowa

ć

interfejs

Component

, którego alternatywn

ą

implementacj

ą

s

ą

dekoratory.
Wa

ż

ne jest te

ż

, aby dekoratory odpowiednio delegowały swoje metody do

wewn

ę

trznych obiektów typu

Component

.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 31

10.4 W

ą

tek rozdziału zdarze

ń

1) "Event-dispatching thread"



Kod

obsługi zdarze

ń

wykonywany jest zawsze w jednym w

ą

tku, tzw.

w

ą

tku rozdziału zdarze

ń

("

event-dispatching thread

"). Dzi

ę

ki temu

ż

adna obsługa zdarzenia w programie nie mo

ż

e si

ę

rozpocz

ąć

zanim

nie zako

ń

czy si

ę

obsługa poprzedniego zdarzenia. Np. kod metody

actionPerformed

wykonuje si

ę

w w

ą

tku rozdziału zdarze

ń

.



Równie

ż

kod

malowania komponentów

na ekranie wykonuje si

ę

w tym

unikalnym

w

ą

tku rozdziału zdarze

ń

. Czyli od

ś

wie

ż

anie komponentu nie

mo

ż

e si

ę

odby

ć

dopóki wykonywana jest obsługa zdarzenia wcze

ś

niej

zainicjalizowana ni

ż

nakaz od

ś

wie

ż

enia wygl

ą

du komponentu GUI.

Zasady współpracy programu z GUI



Dla

apletu

nale

ż

y konstruowa

ć

GUI w metodzie

init

( )

.



Dla

aplikacji

bezpieczne jest stosowanie nast

ę

puj

ą

cego schematu:

public class MyApplication {

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 32

public static void main(String[] args) {
JFrame f = new JFrame(...);

...// Dodaj komponenty do ramki..

f.pack();

// Realizuj ramk

ę

f.setVisible(true);

// Wy

ś

wietl ramk

ę

// Teraz nie konstruuj ju

ż

ż

adnych elementów GUI.

}

// Wszystkie operacje na GUI - np.

setText, getText

, itd.

// wykonywane s

ą

podczas obsługi zdarze

ń

, np.

actionPerformed().

...
}

Stosuj zasad

ę

pojedynczego w

ą

tku

"Po realizacji komponentu Swing-a ka

ż

dy kod w programie, który zale

ż

y

od stanu komponentu lub wpływa na zmian

ę

stanu komponentu

powinien by

ć

wykonywany w w

ą

tku rozdziału zdarze

ń

."


Realizacja komponentu

oznacza,

ż

e jest on przygotowany do

namalowania go na ekranie.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 33



Realizacja głównego okna

nast

ą

pi na skutek wywołania dla niego

jednej z metod:

setVisible(true),
show(),
pack().



Po realizacji okna jego

komponenty s

ą

te

ż

zrealizowane

.



Je

ś

li

dodajemy komponent

do zrealizowanego kontenera to

automatycznie nast

ę

puje

realizacja tego komponentu

.

Pierwsza realizacja ramki zwykle polega na wywołaniu

pack

.

Nast

ę

pnie ramka jest wy

ś

wietlana wywołaniem

setVisible

(lub

show

).

Odst

ę

pstwa od zasady jednego w

ą

tku:



Pewne

metody w API

s

ą

zabezpieczone

przed w

ą

tkami – maj

ą

wbudowan

ą

synchronizacj

ę

dost

ę

pu.



GUI aplikacji

mo

ż

e by

ć

skonstruowany, zrealizowany i wy

ś

wietlony po

raz pierwszy w

głównym w

ą

tku

.

Przypomnijmy poprzedni przykład:

public static void main(String[] args) {

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 34

JFrame f = new JFrame(...);

...// Dodaj komponenty do ramki ...

f.pack();
f.setVisible(true);

// Dalej nie definiuj wi

ę

cej GUI .

}

W tym przykładzie GUI skonstruowano

w głównym w

ą

tku

. Mo

ż

liwe jest

bowiem skonstruowanie (ale nie wy

ś

wietlenie) GUI w dowolnym

w

ą

tku, je

ś

li tylko nie ma w nim odwoła

ń

do (lub modyfikacji) ju

ż

"zrealizowanych" komponentów.
Teoretycznie wywołanie

setVisible

nie jest zabezpieczone przed

w

ą

tkami

, gdy

ż

komponenty zostały wła

ś

nie zrealizowane wywołaniem

pack

. Jednak je

ś

li program nie posiada jeszcze widocznego GUI, jest

mało prawdopodobne, aby nast

ą

piło wywołanie

paint

zanim metoda

setVisible

powróci.




GUI apletu

mo

ż

e by

ć

skonstruowany i wy

ś

wietlony w

metodzie

init

.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 35

Przegl

ą

darki nie wołaj

ą

paint

dla apletu zanim nie wykonaj

ą

si

ę

metody

init

i

start

. Dlatego bezpieczne jest skonstruowanie GUI w metodzie

apletu

init

, je

ś

li tylko nie wywołuje si

ę

w niej

show()

lub

setVisible(true)

dla obiektu apletu.




Metody klasy

JComponent

-

repaint

i

revalidate

- mog

ą

by

ć

wołane z

ka

ż

dego w

ą

tku. Te metody przekazuj

ą

swoje wywołania do kolejki

obsług dla w

ą

tku rozdziału zdarze

ń

.



Listy z obserwatorami zdarze

ń

mog

ą

by

ć

modyfikowane przez ka

ż

dy

w

ą

tek - mo

ż

na wsz

ę

dzie wywoła

ć

metody

addListenerTypeListener

i

removeListenerTypeListener

– te operacje nie maj

ą

wpływu na aktualnie

realizowany rozdział zdarze

ń

.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 36

2) Jak nale

ż

y wykonywa

ć

kod w

w

ą

tku rozdziału zdarze

ń

?

Operacje na GUI po jego inicjalizacji prowadzone s

ą

przez w

ą

tek

rozdziału zdarze

ń

. Programy sterowane s

ą

zdarzeniami pochodz

ą

cymi

od widocznych komponentów takich jak przyciski lub operacje mysz

ą

.


Jednak s

ą

te

ż

sytuacje, gdy program wykonuje operacje na GUI, które

nie s

ą

inicjowane zdarzeniami. Oto przykłady takich sytuacji.

- Program wykonuje dłu

ż

sz

ą

inicjalizacj

ę

„na raty”

Taki program zwykle tworzy i pokazuje "zacz

ą

tki" swojego GUI podczas

inicjalizacji, a potem prowadzi zmian

ę

i modyfikacj

ę

swojego GUI.

Uzupełniaj

ą

ca inicjalizacja nie powinna mie

ć

miejsca w w

ą

tku rozdziału

zdarze

ń

, gdy

ż

blokowałaby przyjmowanie zdarze

ń

i od

ś

wie

ż

anie ekranu

dla programu.

- Programy, których GUI musi by

ć

zmodyfikowany w wyniku

niestandardowych zdarze

ń

.

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 37

Np. metoda programu serwera mo

ż

e zosta

ć

wywołana przez nieznany

w

ą

tek wykonywany na innej maszynie. Jednak w celu modyfikacji GUI

metoda ta powinna wywoła

ć

kod wykonywany w w

ą

tku rozdziału

zdarze

ń

.

3)

Asynchroniczne wywołania

metod w w

ą

tku rozdziału zdarze

ń

Klasa

SwingUtilities

posiada 2 metody przeznaczone

do współpracy

programu z w

ą

tkiem rozdziału zdarze

ń

:



invokeLater

Metoda spowoduje wykonanie zadanego kodu w w

ą

tku rozdziału

zdarze

ń

. Metoda nie czeka na wykonanie si

ę

tego kodu lecz powraca

natychmiast.



invokeAndWait

Działa podobnie jak metoda

invokeLater

ale czeka na wykonanie si

ę

zadanego kodu.

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 38

Deklaracja metody

invokeLater( )

public static void invokeLater(Runnable doRun)

Powoduje asynchroniczne wykonanie metody

doRun.run()

w w

ą

tku

rozdziału

zdarze

ń

,

po

wcze

ś

niejszym

wykonaniu

wszystkich

oczekuj

ą

cych w kolejce metod obsługi zdarze

ń

.

Ta metoda

mo

ż

e by

ć

te

ż

wołana

z samego w

ą

tku rozdziału zdarze

ń

.

Za obsług

ę

ewentualnych

wyj

ą

tków

zgłaszanych podczas wykonania

zleconego zadania

odpowiada w

ą

tek rozdziału zdarze

ń

.

Przykład

. Wywołanie zadania obiektu

doHelloWorld

i wydruk komunikatu:

Runnable doHelloWorld = new Runnable() {

public void run() {
System.out.println("Hello World w " + Thread.currentThread());
}

};

SwingUtilities.invokeLater(doHelloWorld);

// Wykonaj później

System.out.println("Ten komunikat może pojawić się wcześniej niż górny.");

background image

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 39

Deklaracja metody

invokeAndWait( )

public static void invokeAndWait(Runnable doRun)
throws InterruptedException, InvocationTargetException

Tak

ż

e ta metoda powoduje asynchroniczne wykonanie metody

doRun.run()

w w

ą

tku rozdziału zdarze

ń

, po wcze

ś

niejszym wykonaniu

wszystkich oczekuj

ą

cych w kolejce metod obsługi zdarze

ń

. Jednak

wołaj

ą

ca metoda

zostaje zablokowana

w oczekiwaniu na wykonanie si

ę

zleconego zadania.
Metody

invokeAndWait()

nie mo

ż

na

wywoła

ć

w w

ą

tku rozdziału zdarze

ń

.

Przykład.

Wywołanie metody

invokeAndWait()

z nowo tworzonego w

ą

tku

w aplikacji w celu wypisania napisu w w

ą

tku rozdziału zdarze

ń

, a

nast

ę

pnie po powrocie metody nast

ę

puje wypisanie pochodz

ą

ce z

nowego w

ą

tku aplikacji.

final Runnable doHelloWorld = new Runnable() {
public void run() {
System.out.println("Hello World w " + Thread.currentThread());
}
};

10. Swing – układanie i malowanie

W. Kasprzak: Programowanie zdarzeniowe

10 - 40

Thread appThread = new Thread() {
public void run() {
try { SwingUtilities.invokeAndWait(doHelloWorld);
}
catch (Exception e) { e.printStackTrace();
}
System.out.println("Koniec w " + Thread.currentThread());
}
};

appThread.start();

Je

ś

li metoda

run()

wołanego obiektu implementuj

ą

cego

Runnable

zgłasza wyj

ą

tek nieobsługiwany przez w

ą

tek rozdziału zdarze

ń

to jest on

zamieniany na wyj

ą

tek typu

InvocationTargetException

i przekazywany

do obsługi przez wołaj

ą

cy w

ą

tek.

Wyj

ą

tek typu

InterruptedException

zgłaszany jest wtedy, gdy

oczekiwanie naszego w

ą

tku na zako

ń

czenie si

ę

zleconego zadania

zostaje przerwane.


Wyszukiwarka

Podobne podstrony:
Proz S2 id 402992 Nieznany
Proz S12 id 402989 Nieznany
Proz S9 id 402999 Nieznany
Proz S8 id 402998 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 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