05.01.2015 Views

Tehnici avansate de programare - Profs.info.uaic.ro

Tehnici avansate de programare - Profs.info.uaic.ro

Tehnici avansate de programare - Profs.info.uaic.ro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<st<strong>ro</strong>ng>Tehnici</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng><br />

Curs -<br />

Cristian Frăsinaru<br />

acf@<st<strong>ro</strong>ng>info</st<strong>ro</strong>ng>iasi.<strong>ro</strong><br />

Facultatea <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> Informatică<br />

Universitatea ”Al. I. Cuza” Iaşi


JavaBeans<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.1/1


Cuprins<br />

Specificatiile JavaBeans<br />

Tipuri <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> p<strong>ro</strong>prietati<br />

Crearea unui BeanInfo<br />

Crearea unui P<strong>ro</strong>pertyEditor<br />

Crearea unui Customizer<br />

Consi<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>raţii generale<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.2/1


Ce sunt componentele JavaBeans <br />

Componentele JavaBeans sunt:<br />

componente <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> sine stătătoare, reutilizabile,<br />

in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>pen<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>nte <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> platformă<br />

pot fi folosite pe orice platformă <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng><br />

se conformează cu o serie <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> specificaţii<br />

<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>finesc un mo<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>l pentru crearea <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> componente<br />

software.<br />

Un container reprezinta un context in care<br />

componentele pot fi grupate si cu care acestea pot<br />

interactiona.<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.3/1


Caracteristici<br />

Int<strong>ro</strong>specţie - pentru analizarea componentei <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng><br />

catre container<br />

Personalizare - pentru modificarea aspectului si<br />

functionalitatii<br />

P<strong>ro</strong>prietăţi - pentru individualizare si <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng><br />

Evenimente - pentru comunicare<br />

Persistenţă - salvare / restaurare p<strong>ro</strong>prietăţi<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.4/1


Exemplu <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> bean<br />

public class MyBean implements java.io.Serializable {<br />

private String value;<br />

public String getValue() {<br />

return value;<br />

}<br />

}<br />

public void setValue(String value) {<br />

this.value = value;<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.5/1


Tipuri <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> p<strong>ro</strong>prietăţi<br />

P<strong>ro</strong>prietatile unei componente JavaBean sunt elementele<br />

care <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>finesc caracterisiticile acelei componente.<br />

Concret, p<strong>ro</strong>prietatile sunt valorile accesate prin<br />

intermediul meto<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>lor publice <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip getter, setter. Pot fi<br />

<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> patru tipuri:<br />

simple<br />

legate<br />

constrânse<br />

in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>xate<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.6/1


P<strong>ro</strong>prietăţi simple<br />

Sunt p<strong>ro</strong>prietati care influenteaza aspectul sau<br />

functionalitatea unei componente dar a ca<strong>ro</strong>r schimbare<br />

nu implica nici un efect colateral.<br />

public class Component implements Serializable {<br />

private Font font;<br />

private boolean enabled;<br />

}<br />

public Font getFont() { return font; }<br />

public void setFont(String font) {<br />

this.font = font;<br />

}<br />

public boolean isEnabled() { return text; }<br />

public void setEnabled(boolean enabled) {<br />

this.enabled = enabled;<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.7/1


P<strong>ro</strong>prietăţi legate<br />

Sunt p<strong>ro</strong>prietati care, la modificarea lor, pot <st<strong>ro</strong>ng>info</st<strong>ro</strong>ng>rma<br />

obiectele interesate <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip listener, asupra modificarii<br />

aparute.<br />

O componenta ce contine p<strong>ro</strong>prietati legate trebuie sa<br />

ofere un mecanism prin care alte obiecte sa se<br />

inregistreze ca ascultatori ai acelor p<strong>ro</strong>prietati.<br />

Informarea ascultatorilor asupra schimbarii unei<br />

p<strong>ro</strong>prietati se face dupa ce schimbarea a avut loc prin<br />

intermediul unui obiect <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip P<strong>ro</strong>pertyChangeEvent.<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.8/1


Exemplu P<strong>ro</strong>pertyChange (1)<br />

public class MyBean {<br />

pricate String text;<br />

private P<strong>ro</strong>pertyChangeSupport changes=new P<strong>ro</strong>pertyChangeSupport(this);<br />

}<br />

public void addP<strong>ro</strong>pertyChangeListener(P<strong>ro</strong>pertyChangeListener l) {<br />

changes.addP<strong>ro</strong>pertyChangeListener(l);<br />

}<br />

public void removeP<strong>ro</strong>pertyChangeListener(P<strong>ro</strong>pertyChangeListener l) {<br />

changes.removeP<strong>ro</strong>pertyChangeListener(l);<br />

}<br />

public String getText() {<br />

return text;<br />

}<br />

public void setText(String newText) {<br />

String oldText = text;<br />

text = newText;<br />

changes.fireP<strong>ro</strong>pertyChange("text", oldText, newText);<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.9/1


Exemplu P<strong>ro</strong>pertyChange (2)<br />

Crearea unui listener<br />

public class MyBeanListener implements P<strong>ro</strong>pertyChangeListener {<br />

public void p<strong>ro</strong>pertyChange(P<strong>ro</strong>pertyChangeEvent e) {<br />

// reactioneaza la schimbarea textului<br />

}<br />

}<br />

public MyBeanListener(MyBean bean) {<br />

bean.addP<strong>ro</strong>pertyChangeListener(this);<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.10/1


P<strong>ro</strong>prietăţi constrânse<br />

O p<strong>ro</strong>prietate este constransa atunci cand schimbarea ei<br />

poate fi refuzata <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> catre un obiect (chiar <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> catre<br />

componenta insasi) care are drept <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> veto asupra<br />

acelei p<strong>ro</strong>prietati.<br />

Informarea ascultatorilor cu drept <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> veto asupra<br />

schimbarii unei p<strong>ro</strong>prietati se face înainte ca schimbarea<br />

sa aiba efectiv loc, prin intermediul unui eveniment <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip<br />

P<strong>ro</strong>pertyChangeEvent.<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.11/1


Exemplu VetoableChange (1)<br />

public class MyBean {<br />

private String text;<br />

private VetoableChangeSupport vetos=new VetoableChangeSupport(this);<br />

public void addVetoableChangeListener(VetoableChangeListener l) {<br />

vetos.addVetoableChangeListener(l);<br />

}<br />

public void removeVetoableChangeListener(VetoableChangeListener l) {<br />

vetos.removeVetoableChangeListener(l);<br />

}<br />

public void setText(String newText) th<strong>ro</strong>ws P<strong>ro</strong>pertyVetoException {<br />

String oldText = text;<br />

vetos.fireVetoableChange("text", oldText, newText);<br />

text = newText;<br />

changes.fireP<strong>ro</strong>pertyChange("text", oldText, newText);<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.12/1


Exemplu VetoableChange (2)<br />

Crearea unui listener<br />

public class MyBeanListener implements VetoableChangeListener {<br />

}<br />

public void vetoableChange(P<strong>ro</strong>pertyChangeEvent e)<br />

th<strong>ro</strong>ws P<strong>ro</strong>pertyVetoException {<br />

// drept <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> veto asupra schimbarii textului<br />

String p<strong>ro</strong>p = e.getP<strong>ro</strong>pertyName();<br />

if (p<strong>ro</strong>p.equals("text")) {<br />

String text = (String)e.getNewValue();<br />

if (text.length() == 0 ) {<br />

th<strong>ro</strong>w new P<strong>ro</strong>pertyVetoException("Textul este obligatoriu!", e);<br />

}<br />

}<br />

}<br />

public MyBeanListener(MyBean bean) {<br />

bean.addP<strong>ro</strong>pertyChangeListener(this);<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.13/1


P<strong>ro</strong>prietăţi in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>xate<br />

O p<strong>ro</strong>prietate in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>xata este o p<strong>ro</strong>prietate al carei<br />

domeniu <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> valori este reprezentat <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> o mulţime<br />

in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>xată (tablou).<br />

private String items[] = {"bean", "jsp", "servlet"};<br />

public String[] getItems() {<br />

return items;<br />

}<br />

public void setItems(String items[]) {<br />

this.items = items;<br />

}<br />

public String getItems(int in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>x) {<br />

return items[in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>x];<br />

}<br />

public void setItems(String items[], int in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>x) {<br />

this.items[in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>x] = items[in<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>x];<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.14/1


Int<strong>ro</strong>specţia<br />

Intrsopectia este p<strong>ro</strong>cesul prin care sunt <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>terminate<br />

p<strong>ro</strong>prietatile, meto<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>le si evenimentele unei componente<br />

Bean. Aceasta se face fie prin intermediul clasei<br />

Int<strong>ro</strong>spector, fie direct prin mecanismul <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> reflectare<br />

oferit <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> Java (Reflection API).<br />

Implicit, clasa Int<strong>ro</strong>spector foloseste ea insasi<br />

mecanismul <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> reflectare pentru inspectarea<br />

componentei, insa acest comportament poate fi<br />

schimbat prin construirea unei clase <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip BeanInfo.<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.15/1


Crearea unui BeanInfo<br />

Scopul unei clase BeanInfo este <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> a furniza<br />

int<strong>ro</strong>spectorului suficiente <st<strong>ro</strong>ng>info</st<strong>ro</strong>ng>rmatii pentru <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>scrierea si<br />

personalizarea componentei.<br />

Expunerea doar a unui subset specificat din<br />

p<strong>ro</strong>prietatile componentei.<br />

Specificarea unui nume mai <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>scriptiv pentru<br />

poprietati, altul <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>cat cel implicit.<br />

Despartirea p<strong>ro</strong>prietatilor in: normal si expert.<br />

Specificarea unei clase <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>dicate pentru<br />

personalizarea componentei (customizer)<br />

Asocierea unei imagini componentei, etc.<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.16/1


Crearea unui P<strong>ro</strong>pertyEditor<br />

Scopul unei clase P<strong>ro</strong>pertyEditor este <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> a oferi<br />

mecanismul necesare pentru editarea p<strong>ro</strong>prietăţilor unui<br />

bean în cadrul unui container.<br />

public class MyBeanTextEditor<br />

extends java.beans.P<strong>ro</strong>pertyEditorSupport {<br />

}<br />

public String getAsText() {<br />

//Valorea initiala<br />

return "Hello";<br />

}<br />

public void setAsText(String text) th<strong>ro</strong>ws IllegalArgumentException {<br />

if (text.length() > 10)<br />

th<strong>ro</strong>w new IllegalArgumentException("Text prea lung!");<br />

super.setAsText(text);<br />

}<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.17/1


Crearea unui Customizer<br />

Un Customizer oferă o interfaţă completă pentru<br />

editarea p<strong>ro</strong>prietăţilor unui bean. Aceasta trebuie să fie<br />

extinsă din clasa java.awt.Component pentru a putea<br />

fi instanţiată <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> container în cadrul unei ferestre<br />

specifice.<br />

Asocierea intre o componenta bean si o clasa <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> tip<br />

Customizer se face in metoda getBeanDescriptor a<br />

clasei BeanInfo<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.18/1


Consi<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>raţii generale<br />

Definesc un mo<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>l pentru crearea <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> componente<br />

Pot fi grupate în librării (.jar)<br />

Pot fi folosite în diferite contexte:<br />

GUI - <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> exemplu bean-uri Swing sau AWT<br />

Mo<st<strong>ro</strong>ng>de</st<strong>ro</strong>ng>l - reprezentarea datelor<br />

Sunt manevrate <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> un container, prin intermediul<br />

unui int<strong>ro</strong>spector<br />

Trebuie să fie agnostice <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> modul în care vor fi<br />

folosite<br />

Tehnologii <st<strong>ro</strong>ng>avansate</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>de</st<strong>ro</strong>ng> <st<strong>ro</strong>ng>p<strong>ro</strong>gramare</st<strong>ro</strong>ng> – p.19/1

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!