capitolul 5 poo

Upload: nickerloden

Post on 09-Mar-2016

27 views

Category:

Documents


0 download

DESCRIPTION

Capitolul 5 POO

TRANSCRIPT

  • CUPRINS

    CAPITOLUL 5 3

    UTILIZAREA PLATFORMEI JAVA PENTRU DEZVOLTAREA APLICAIILOR CU INTERFA GRAFIC 3

    5.1 PROPUNERE ARHITECTURAL PENTRU APLICAIILE DE BUSINESS 4 5.1.1 ARHITECTUR GENERAL MULTI-STRATIFICAT LOGIC 5 5.1.2 MVC MODEL VIEW CONTROLLER 7 5.2 APLICAIE CU INTERFA GRAFIC SWING N NETBEANS 8 5.2.1 CONSTRUIREA N SWING A FORMULARELOR SIMPLE PENTRU NOMENCLATOARE 9 5.2.2 CONSTRUIREA N SWING A FORMULARELOR MASTER-DETAIL 24 5.3 APLICAIE CU INTERFA GRAFIC JAVASERVERFACES I ECLIPSE 41 5.3.1 ORGANIZAREA PROIECTELOR N ECLIPSE N CONTEXT JAVASERVER FACES 42 5.3.1 CONSTRUIREA FORMULARELOR WEB PENTRU NOMENCLATOARE 51 5.3.2 CONSTRUIREA FORMULARELOR MASTER-DETAIL N CONTEXT JAVASERVER FACES 74 5.3.2 PREGTIREA I LANSAREA APLICAIEI 90

    BIBLIOGRAFIE 93

    ANEXA 1: MODELUL CONTABIL. CLASELE CU PERSISTEN JPA 95 CLASELE ENTITI 95 REGISTRE 116 SERVICII ALE AFACERII 120 ANEXA 2: APLICAIA JSF. COD SURS FORMULARE WEB 124 MAINFORM.JAVA 124 FORMCONTURI.JAVA 124 FORMOPERATIUNI.JAVA 128 MAINFORM.XHTML 136 FORMCONTURI.XHTML 137 FORMOPERATIUNI.XHTML 139

  • 2 Dezvoltarea aplicaiilor orientate obiect pe platforma Java

  • CAPITOLUL 5

    Utilizarea platformei Java pentru dezvoltarea aplicaiilor cu interfa grafic

    Capitolul de fa urmrete cu precdere ntregirea, ntr-o anumit

    msur, a procesului de dezvoltare a unei aplicaii, a crei sub-strat privind logica afacerii a constituit subiectul capitolului 4. Prin urmare, descrierea modului de realizare a unei interfee grafice pentru prezentarea sau expunerea entitilor afacerii ctre utilizatorii finali (actorii de business propriu-zii) reprezint tema principal, ns nu ntr-o abordare exhaustiv. Obiectivul de baz const n stabilirea unor principii i repere metodologice de baz, dar care s fie i validate prin intermediul unor componente software realizabile sau implementabile folosind platforma Java

    1.

    1 O abordare mai detaliat, mai nuanat i mai complet constituie subiectul unor

    cursuri specifice abordate n contextul masterului de Sisteme Informaionale pentru Afaceri, de exemplu Medii integrate de dezvoltare a afacerilor sau Aplicaii client/server i Web.

  • 4 Capitolul 5

    5.1 Propunere arhitectural pentru aplicaiile de business

    n continuare, vom ncerca s prezentm modul de realizare att al

    aplicaiilor de tip desktop, ct i al aplicaiilor web, ntr-o manier simplificat, dar coerent i pornind de la aceeai baz: stratul entitilor persistente i serviciilor afacerii investigat n capitolul anterior. De altfel, acesta este i avantajul major al izolrii n aceast manier al modelului afacerii: posibilitatea reutilizrii acestuia n ambele tipuri de aplicaii: desktop i web.

    Aplicaiile desktop au un istoric consistent n spate, le-am putea considera veteranele aplicaiilor pentru afaceri. Acest fapt le confer un nivel apreciabil de maturizare exprimat prin suportul conceptual evoluat: vorbim de evenimente, controale grafice, formulare, aciuni, modele de date i binding, MVC2 etc., precum i de un grad de componentizare ridicat: referindu-ne aici n special la maniera de a construi noi componente grafice complexe pe baza celor existente. Aplicaiile Web au ajuns i ele la un grad de maturizare satisfctor tocmai prin edificarea unui suport conceptual aproximativ la paritate cu cel al aplicaiilor desktop tradiionale. Cu alte cuvinte, vom ncerca prezentarea modului de elaborare a unei aplicaii web ntr-o manier, pe ct posibil, similar cu cea a unei aplicaii desktop: vom construi tot formulare bazate pe componente grafice comune prin care vom expune aceleai entiti ale afacerii i ale cror aciuni vor rspunde la evenimente-utilizator.

    Indiferent de tipul aplicaiei, arhitectura propus trebuie s promoveze

    o cale prin care entitile afacerii vor fi expuse prin intermediul unei interfee grafice. Fie c este vorba de o aplicaie desktop sau Web, bazat pe un nivel al afacerii construit anterior (vezi abordarea MDD) sau legat direct la o baz de date SQL, scopurile (i exigenele) rmn neschimbate, cel puin n urmtoarele privine:

    construire formulare simple, pentru actualizarea nomenclatoarelor;

    construire formulare complexe master-detail, n special pentru tranzacii-operaionale implicnd entitile;

    integrare cu suport sau servicii de rapoarte (bazate, spre exemplu, pe un motor-generator gen JasperReport).

    2 Model-View-Controller.

  • Dezvoltarea aplicaiilor cu interfa grafic 5

    5.1.1 Arhitectur general multi-stratificat logic

    Simplificnd, arhitectura aplicaiei, a crei implementare va fi exemplificat n continuare att n contextul cadrului de lucru JavaSwing, ct i n contextul JavaServer Faces, poate fi descris astfel:

    un nivel de prezentare: format din componentele grafice specifice

    (Swing sau JSF) i structurile de legtur (binding) la coleciile cu entitile din modelul afacerii;

    un nivel al gestiunii comportamentului interfeelor grafice, ca urmare a aciunii utilizatorilor finali;

    un nivel al modelului afacerii: format din definiiile entitilor afacerii

    plus modelul de mapare obiectual-relaional (JavaPersistence API) n structurile specifice suportului de persisten;

    un nivel al structurilor de date implicate n gestiunea entitilor

    persistente ale afacerii, gestiunea tranzaciilor asupra entitilor afacerii, tranzacii responsabile cu sincronizarea strii entitilor cu baza de date, aciunile tranzacionale invocnd registrele MDD bazate pe instanele EntiyManager ale JPA.

    Dac n privina arhitecturii logice am delimitat mai multe niveluri de

    organizare, din punct de vedere fizic vom delimita, practic, dou straturi, att n privina aplicaiilor tradiionale de tip desktop, ct i n privina aplicaiilor Web:

    un strat care va gzdui aplicaia propriu-zis, cu nivelurile de

    prezentare, inclusiv gestiunea aciunilor utilizatorilor, i cel al entitilor afacerii;

    un strat care va gzdui baza de date suport pentru persistena entitilor afacerii.

  • 6 Capitolul 5

    Figura 5.1 Perspectiv simplificat asupra unei aplicaii de business legat la o

    baz de date

    n cazul aplicaiilor Web, s-ar putea reclama un amendament bazat pe

    faptul c browserul Web ar putea fi considerat un substrat fizic autonom: aplicaia propriu-zis rezid pe stratul fizic corespunztor serverului Web, ns o parte a contextului de execuie se desfoar n cadrul strict al browserului. Pe de alt parte, de regul, cnd se face referire la aplicaii organizate fizic pe trei straturi, se are n vedere existena autonom a unui strat-middleware autonom, al serviciilor afacerii, prin intermediul cruia sunt accesate entitile afacerii, care, prin urmare, sunt separate, astfel, i fizic, fa de componentele de prezentare.

    Aceast modalitate de abordare arhitectural a aplicaiilor pentru

    afaceri este inspirat dintr-un ablon de proiectare numit MVC, prezentat, foarte pe scurt, n paragraful imediat urmtor, care a pus problema separrii responsabilitilor diverselor componente implicate n construirea aplicaiilor cu interfa grafic.

  • Dezvoltarea aplicaiilor cu interfa grafic 7

    5.1.2 MVC Model View Controller

    ablonul de proiectare MVC are implicaii arhitecturale datorit

    faptului c se refer, din start, la separarea responsabilitii obiectelor implicate ntr-o aplicaie ce manevreaz structuri de date ce urmeaz a fi expuse utilizatorilor. n acest context deosebim urmtoarele tipuri de componente: componente model obiecte-structuri de date, n general, se

    recomand ca aceste obiecte s fie eliberate de vreo constrngere contextual (nu trebuie obligate s implementeze o interfa specific);

    componente view obiectele care vor determina modul n care vor fi prezentate componentele model;

    componente controller obiectele care vor controla interaciunile (desfurarea fluxului de interaciuni) cu componentele model, adic, n primul rnd, vor actualiza modelul pe baza modificrilor iniiate de utilizatori asupra componentelor view.

    Change

    Observe

    Model

    View

    Controller

    Figura 5.2 Perspectiv simplificat asupra ablonului de proiectare MVC

    Adaptarea arhitectural a ablonului MVC a fost posbil pe baza

    transformrii componentei controller (C) n, s zicem, prezenter (P), prelund inclusiv responsabilitatea iniializrii i sincronizrii componentelor view pe baza strii modelului.

  • 8 Capitolul 5

    5.2 Aplicaie cu interfa grafic Swing n NetBeans Cadrul de lucru Swing rmne, nc, pentru platforma Java

    instrumentul cel mai la ndemn pentru construirea aplicaiilor desktop3, care, dup cum am menionat deja, au ca principal caracteristic faptul c sunt instalate, ruleaz i i formeaz starea pe suportul de calcul al utilizatorului final. Interfeele grafice Swing pot constitui, fr probleme, i un front-end pentru aplicaii Java a cror componente de logic a afacerii sunt amplasate ntr-un spaiu de tip middleware (adic pe un server de aplicaii propriu-zis), ns, tradiional, partea de server din arhitectura acestor aplicaii de tip Java-desktop este constituit de un SGBD cu care se comunic prin intermediul unui driver JDBC.

    (Cum obiectivul nostru n acest capitol are n vedere prezentarea unui mod de realizare ct mai rapid i mai coerent a unei aplicaii de business, nu ne propunem i nici nu vom zbovi asupra principiilor generale ale componentelor Swing, lucruri pentru care ar trebui dedicat o carte tehnic separat, concentrat numai asupra interfeelor grafice i nu asupra conceptelor de programare sau arhitecturii aplicaiilor.)

    Cadrul de lucru Swing poate fi utilizat n mod direct n construirea interfeelor grafice specifice aplicaiilor de business, consumatoare de date prin definiie. O astfel de ntreprindere s-ar putea dovedi, ns, destul de anevoioas pentru un programator mai novice, de aceea au fost realizate n jurul Swing o serie de alte cadre de lucru, concentrate asupra unor sarcini precise i, n general, consumatoare de productivitate, cadre care s completeze i s fac mai agreabil experiena JavaSwing n lumea aplicaiilor de business.

    n acest sens puteam aminti Bean Binding API care i propune s

    realizeze o legare ct mai declarativ (printr-un sublimbaj specific de expresii) i mai flexibil (legarea componentelor grafice la structuri de date neconvenionale sau necompatibile nativ cu modelele de date ale acestor componente) ntre controalele grafice Swing i structurile de date fondate pe baza coleciilor de entiti JPA. Mediul de lucru NetBeans are meritul de a transforma caracteristica declarativ a cadrului de lucru BeansBinding (JSR 295) n reducerea la maximum a efortului de programare, prin urmare obiectivul fiind: ct mai declarativ, nsemnnd mai puin cod implicat n legarea componentelor vizuale la datele suport.

    3 Crcotaii nu vor fi chiar de acord, amintind de SWT, mai puin popular ns n

    contextul enterprise, i JavaFx, prea nou nc i cam necopt.

  • Dezvoltarea aplicaiilor cu interfa grafic 9

    Suportul pentru componentele grafice Swing legate la date comport dou paliere:

    un palier programatic, prin combinarea cadrului de lucru pentru

    interfee grafice Java Swing API (javax.swing) cu cadrul de lucru pentru legarea declarativ a componentelor simple JavaBeans prin sincronizarea valorilor proprietilor lor (org.jdesktop.beansbinding);

    suportul vizual sau asistena oferit de mediul de lucru NetBeans, prin instrumentul FormBuilder de proiectare a interfeelor, care permite construirea expresiilor de legare declarativ prin selectarea vizual a elementelor implicate. Un astfel de context de lucru va fi utilizat n continuare, mai nti

    pentru construirea formularelor simple, de tip nomenclator, i apoi a formularelor mai complexe, operaionale, de tip master-detail.

    5.2.1 Construirea n Swing a formularelor simple pentru nomenclatoare

    Chiar i pentru construirea celui mai simplu formular, ar trebui s se

    aib n vedere cel puin urmtoarele seciuni: o seciune care s asigure aciuni de navigare, adic s permit

    selectarea datelor ce urmeaz a fi vizualizate-modificate-tranzacionate;

    o seciune care s permit accesul la elementele de detaliu (de interes) ale datelor vizate a fi vizualizate-modificate-tranzacionate;

    o seciune care s permit iniierea operaiunilor tranzacionale asupra datelor curente sau alte aciuni cu privire la starea general a formularului curent (de exemplu prsirea lui).

    Figura 5.3 Structur formular simplu

  • 10 Capitolul 5

    De exemplu un formular de acest gen ar putea arta ca cel din figura 5.3. Structura acestuia este extrem de simpl, asigurnd totui o funcionalitate de cutare-selecie-navigare bazat pe o list (JList), detaliile fiecrui obiect persistent fiind prezentate prin componente simple (JTextField). Funcionalitatea tranzacional va fi invocat prin butoanele de adugare, tergere i salvare.

    Modelul sau structura de date a formularului nainte de a proiecta grafica formularului folosind componente

    vizuale individuale, fiind un formular legat la o surs de date persistente provenind dintr-o baz de date, trebuie create structurile sau modelul de date al formularului: de regul o colecie tipizat (Collection, List, Set, Map etc.) de entiti obinute prin invocarea unor operaii specifice unui registru (cu entiti ale afacerii) care s interogheze corespunztor baza de date.

    Prin urmare, utiliznd drept surs de date un registru (repository

    MDD vezi capitolul 4) vom evita modul clasic de invocare a suportului de persisten ce implic folosirea componentelor Query i EntityManager din categoria Java Persistence a barei de instrumente Palette (activat de ctre modul Design specific instrumentului FormBuilder pentru obiectele de tip JFrame sau JPanel create n mediul NetBeans). Avantajul unei asemenea abordri, bazat pe registre JPA, const n izolarea componentelor stratului de prezentare fa de mediul efectiv de furnizare a serviciilor de persisten, ceea ce va conferi o flexibilitate sporit dac natura acestor servicii se va modifica: de exemplu la trecerea de la o arhitectur cu 2 la una cu 3 straturi, care ascunde practic detaliile substratului de persisten, n primul rnd din motive de ordin fizic.

  • Dezvoltarea aplicaiilor cu interfa grafic 11

    Figura 5.4 Paleta Java Persistence

    Crearea structurii de date a formularului folosind suportul JPA se

    desfoar printr-o procedur ce const n urmtorii pai:

    1. Asigurarea sursei de date pentru formular. Acest lucru se va face exclusiv din cod. Astfel, se declar o nou

    variabil de instan de tip RegistruClienti, pe care o vom numi simplu registruClienti, iniializarea acesteia fcndu-se n constructorul formularului.

    // Listing 5.1 Initializare regsitru de entitati

    public class FormConturi extends javax.swing.JFrame {

    private RegistruConturi registruConturi;

    public FormConturi() {

    // creare entity manager

    EntityManagerFactory emf = Persistence.

    createEntityManagerFactory("EntitatiContabilitate");

    EntityManager em = emf.createEntityManager();

    // initializare registru

    registruConturi = new RegistruConturi(em);

    initComponents();

    }

    ... ... ...

    }

  • 12 Capitolul 5

    2. Crearea unui model de date pentru formular. Cel mai simplu astfel de model const n crearea i popularea n

    cadrul formularului a unei colecii de entiti ale afacerii, instane app.model.contabilitate.Cont, n cazul exemplului curent, provenite din

    registruConturi. Colecia de entiti se va materializa concret printr-o list care poate fi obinut vizual din instanierea componentei Query Result din paleta de componente, i pe care o vom numi simplu conturi. Pentru aceasta trebuie avute n vedere proprietile:

    a. Type parameters din categoria Code, care va meniona tipul entitilor gestionate, n cazul nostru ;

    b. Custom Creation Code, tot din categoria Code, care va meniona materializarea concret a listei, adic prin instanierea java.util.ArrayList.

    Figura 5.5 Iniializarea coleciei de entiti din modelul de date

    Ca urmare, la nivelul fiierului Java care va genera formularul-

    component al stratului de prezentare (FormConturi.java), va fi generat urmtoarea linie de cod, care desemneaz prima structur din modelul de date ce se va forma astfel: List conturi;

  • Dezvoltarea aplicaiilor cu interfa grafic 13

    Modelul de date va fi completat cu o nou structur, similar listei de conturi de mai sus, dar care va gestiona o list de clase de conturi, mai exact de instane app.model.contabilitate.conturi.ClasaConturi: List claseConturi;

    n fine, ultima component a modelului de date al formularului va

    consta dintr-un atribut (expus ca o proprietate, adic prin intermediul unui cuplu de operaii get/set) ce va stoca referina entitii Cont curente, adic a elementului considerat selectat din colecia conturi descris mai sus. app.model.contabilitate.conturi.Cont cont;

    Pentru a exploata cel mai elegant sistemul de legare-sincronizare a

    componentelor grafice de prezentare (listele de elemente JList sau JComboBox, csuele de text JTextField sau JFormattedTextField sau grupurile de opiuni JRadioButton sau JCheckBox) cu modelul de prezentare, constituit acum prin atributele conturi, claseConturi i cont ale clasei-support a formularului n lucru, vom expune aceste structuri ca i proprieti JavaBean obinuite.

    // Listing 5.2 Expunerea modelului de date al formularului

    public List< ClasaConturi> getClaseConturi() {

    return claseConturi;

    }

    public void setClaseConturi(List claseConturi) {

    this.claseConturi = claseConturi;

    }

    public List< Cont> getConturi() {

    return conturi;

    }

    public void setConturi(List conturi) {

    this.conturi = conturi;

    }

    public Cont getCont() {

    return cont;

    }

    public void setCont(Cont cont) {

    this.cont = cont;

    }

    Instruciunile efective, prin care o component grafic poate fi legat

    la o structur din modelul de date, ar putea arta (pentru o component de tip JList cu rol de selecie-navigare) ca n listingul urmtor.

    // Listing 5.3 Legarea unei liste de navigare

  • 14 Capitolul 5

    // la modelul de date al formularului

    private javax.swing.JList lstConturi;

    lstConturi = new javax.swing.JList();

    // conturi desemneaz aici numele proprietii

    // din modelul de date al formularului

    ELProperty eLProperty = ELProperty.create("${conturi}");

    // Instana JlistBinding reprezint legtura n sine ntre

    // proprietatea din model(invocat ca instan ELProperty)

    // i componenta grafic (lstConturi)

    JListBinding jListBinding = SwingBindings.createJListBinding(

    AutoBinding.UpdateStrategy.READ_WRITE,

    this, eLProperty,

    lstConturi

    );

    Clasele ELProperty, JListBinding, SwingBindings i AutoBinding fac

    parte din pachetul org.jdesktop.beansbinding care gzduiete suportul BeanBindings pentru Swing. Din fericire, mediul de dezvoltare NetBeans ofer un nivel de asisten destul de convenabil care genereaz implicit instruciunile de mai sus.

    La nivelul unui formular, gestiunea tuturor legturilor necesare pentru sincronizarea componentelor grafice cu structurile modelului de date se face folosind o strategie de grupare ce implic o instan BindingGroup. Ca urmare, atunci cnd se dorete re-sincronizarea valorilor afiate curent de ctre componentele grafice se pot invoca urmtoarele instruciuni: this.bindingGroup.unbind();

    this.bindingGroup.bind();

    Acest lucru ar trebui s fie neaparat necesar numai atunci cnd asupra modelului survin anumite modificri sau reiniializri care nu provin, n mod direct, de la nivelul componentelor grafice.

    Navigabilitatea Am menionat mai sus c una dintre seciunile eseniale ale unui astfel

    de formular se refer la asigurarea unei modaliti de cutare-navigare-selecie pe sursa de date. Cel mai simplu mod se poate concretiza prin oferirea posibilitii utilizatorului final de a selecta dintr-o list de entiti i, eventual, de a itera sau rsfoi secvenial lista respectiv prin butoane de navigare gen anterior, urmtor, primul, ultimul. O astfel de funcionalitate se poate obine utiliznd componentele Swing urmtoare:

    JList, JComboBox sau JTable pentru lista de entiti selectabile;

    JButton pentru aciunile de navigare secveniale.

  • Dezvoltarea aplicaiilor cu interfa grafic 15

    Figura 5.6 Zona de cutare-selecie-navigare a formularului

    n figura de mai sus am folosit o component JList nsoit de dou

    butoane etichetate astfel nct s sugereze direcia de navigare. Pentru alimentarea cu elemente selectabile (instane app.model.contabilitate.conturi.Cont) a componentei JList, pe care am denumit-o simplu lstConturi, se apeleaz opiunea Bind Elements din meniul contextual

    4 asociat componentei JList n modul Design al

    NetBeabs, care deschide un asistent de configurare n care ar trebui completate cteva rubrici, astfel:

    la rubrica Binding Source se va alege elementul Form, nelegnd astfel c structura de date la care va fi legat lista aparine sau reprezint o proprietate a formularului curent;

    la rubrica Binding Expression se va desemna, prin expresia ${conturi}, specific limbajului de binding, proprietatea conturi a elementului specificat anterior la rubrica Binding Source, adic a formularului curent;

    dac rubrica Display Expression nu este completat, atunci conturile vor fi afiate n list prin raportare la evaluarea metodei toString(), motenit sau suprascris n clasa app.model.contabilitate.conturi.Cont;

    n rubrica Display Expression poate fi completat o expresie care s desemneze numele proprietii instanelor Cont a crei valoare va fi afiat n list.

    4 Activat la click-dreapta.

  • 16 Capitolul 5

    Figura 5.7 Legarea listei la colecia de conturi din modelul de date

    Cum selectarea unui element din list se va materializa n valoarea

    corespunztoare a atributului cont din structura modelului de date al formularului, va trebui s legm elementul curent selectat al listei la respectiva proprietate din modelul de date, invocnd asistentul Bind SelectedElement i completnd rubricile dup cum se sugereaz n figura urmtoare.

  • Dezvoltarea aplicaiilor cu interfa grafic 17

    Figura 5.8 Legarea elementului curent al listei la proprietatea corespunztoare

    din modelul de date al formularului

    n listingul urmtor este prezentat codul generat.

    // Listing 5.4 Legarea listei la modelul de date

    ELProperty eLProperty = ELProperty.create("${conturi}");

    JlistBinding jListBinding = SwingBindings.createJListBinding(

    AutoBinding.UpdateStrategy.READ_WRITE,

    this, eLProperty, lstConturi);

    jListBinding.setDetailBinding(

    ELProperty.create("${denumire}")

    );

  • 18 Capitolul 5

    // Legarea elementului curent al listei

    //la proprietatea coresp. din model

    Binding binding=Bindings.createAutoBinding(

    AutoBinding.UpdateStrategy.READ_WRITE, this,

    ELProperty.create("${cont}"), lstConturi,

    BeanProperty.create("selectedElement"));

    // Gestiunea acestor legturi se face centralizat

    // printr-un grup corespunztor iniializat anterior

    bindingGroup.addBinding(jListBinding);

    bindingGroup.addBinding(binding);

    Butoanele de navigare au rolul de a induce o navigare secvenial,

    nainte i napoi, pentru modelul grafic al formularului propus anterior. Strategia de realizare a unui astfel de comportament se bazeaz pe manipularea programatic a componentei lstConturi, adic prin selectarea elementului anterior sau urmtor fa de elementul curent selectat n list, element curent sincronizat cu atributul cont din modelul de date al formularului. Prin urmare, modificarea elementului curent al listei va avea ca efect imediat actualizarea modelului de date, mai exact a contului curent. Navigarea programatic ntr-o list se poate face fie prin selecia indexului elementului, fie prin desemnarea direct a valorii. Ceea ce nseamn c aciunile din spatele butoanelor de navigare ar putea fi codificate n dou moduri alternative.

    Mai nti, n modul Design, dup selectarea butonului de comand, se acceseaz din meniul contextual opiunea Event Action ActionPerformed, opiune care va activa modul Source, ancornd cursorul de scriere n metoda asociat evenimentului de acionare a componentei JButton avut n vedere. Dup care, implementarea aciunilor de navigare poate fi fcut:

    relativ la proprietatea index, mai exact operaia setSelectedIndex specific componentelor JList;

    // Listing 5.5 Prima variant a aciunilor de navigare

    private void btnPreviousContActionPerformed(

    java.awt.event.ActionEvent evt) {

    int currentIdx = this.lstConturi.getSelectedIndex();

    if ((currentIdx - 1) >= 0){

    this.lstConturi.setSelectedIndex(currentIdx - 1);

    lstConturi.scrollRectToVisible(

    lstConturi.getCellBounds(lst.getSelectedIndex(),

    lstConturi.getSelectedIndex())

    );

    }

    }

  • Dezvoltarea aplicaiilor cu interfa grafic 19

    private void btnNextContActionPerformed(

    java.awt.event.ActionEvent evt) {

    int currentIdx = this.lstConturi.getSelectedIndex();

    if ((currentIdx + 1) < this.lstConturi.getMaxSelectionIndex()){

    this.lstConturi.setSelectedIndex(currentIdx + 1);

    lstConturi.scrollRectToVisible(

    lstConturi.getCellBounds(lst.getSelectedIndex(),

    lstConturi.getSelectedIndex()));

    }

    }

    relativ la proprietatea value, mai exact operaia

    setSelectedValue specific componentelor JList.

    // Listing 5.6 A doua variant a aciunilor de navigare

    private void btnPreviousContActionPerformed(

    java.awt.event.ActionEvent evt) {

    int currentIdx = this.conturi.indexOf(this.cont);

    if (currentIdx > 0){

    Cont previousCont = this.conturi.get(currentIdx - 1);

    this.lstConturi.setSelectedValue(

    previousCont.getDenumire(), true);

    }

    }

    private void btnNextContActionPerformed(

    java.awt.event.ActionEvent evt) {

    int currentIdx = this.conturi.indexOf(this.cont);

    if ((currentIdx + 1) < this.conturi.size()){

    Cont nextCont = this.conturi.get(currentIdx + 1);

    this.lstConturi.setSelectedValue(

    nextCont.getDenumire(), true);

    }

    }

    n prima variant, la selectarea sau desemnarea unei noi poziii drept

    element curent al formularului, se are n vedere pstrarea noii poziii n interiorul intervalului eligibil al indexului listei, iar elementul nou selectat s fie adus n raza vizibil a listei. Aceast variant are i avantajul c nu este implicat n mod direct nici o structur a modelului de date al formularului, prin urmare este posibil o eventual separare chiar n clase diferite a mecanismelor de implementare a comportamentului fa de structurile modelului de date. A doua variant implic modelul prin faptul c indexul elementului este identificat pornind de la sursa de date a listei

  • 20 Capitolul 5

    de conturi, ns are avantajul unei mai elegante strategii pentru pstrarea elementului nou selectat vizibil n interiorul listei, nefiind necesar invocarea operaiei scrollRectToVisible a listei vizuale, ci doar de specificarea valorii true pentru cel de-al doilea argument al operaiei setSelectedValue.

    Elementele de detaliu rubricile formularului Aceast zon i propune s prezinte utilizatorului final descrierea

    sau, mai exact, proprietile entitii curente a formularului, ntr-o manier vizual, printr-un set de rubrici alctuite dintr-o pereche de componente:

    o etichet JLabel pentru a specifica numele rubricii sau detaliului a crui valoare va fi prezentat,

    printr-o component specific Swing, care s prezinte sugestiv din punct de vedere vizual domeniul specific al valorii reale a proprietii entitii.

    Cel mai simplu mod de a prezenta o valoare ar fi folosind un text-box

    (JTextField, JFormattedTextField), ns exist cazuri cnd valoarea efectiv nu reprezint un simplu text sau valoare numeric ce poate fi introdus direct de utilizatorul final, ci trebuie selectat dintr-un set de valori sau opiuni predefinite ce pot fi prezentate printr-o list simpl (JList) sau combinat (JComboBox) sau chiar un grup de butoane radio.

    n exemplul nostru, rubricile formularului se refer la codul contului (txtCod), denumirea sau numele acestuia (txtDenumire), precum i clasa din care face parte (cboSubClasaCont). n cazul primelor dou rubrici, acestea vor fi implementate astfel:

    component grafic folosit va fi JTextField sau JFormattedTextField (n special atunci cnd este vorba de valori numerice sau date calendaristice);

    legarea la modelul de date (binding) se va face prin proprietatea text folosind ca intermediar lista (lstConturi), mai exact proprietatea selectedElement a acesteia care, la rndul ei, este legat la atributul cont din structura formularului.

  • Dezvoltarea aplicaiilor cu interfa grafic 21

    Figura 5.9 Legarea rubricilor de tip text ale formularului

    De asemenea, pentru afiarea listei vizuale cu datele ncrcate (prin

    binding) din colecia-model de date a formularului, constructorul iniial trebuie modificat dup cum se arat n listingul urmtor. // Listing 5.7 Iniializarea final a formularului

    public FormConturi() {

    // creare entity manager

    EntityManagerFactory emf = Persistence.

    createEntityManagerFactory("EntitatiContabilitate");

    EntityManager em = emf.createEntityManager();

    // initializare registru

    registruConturi = new RegistruConturi(em);

    // metod generat de mediul NetBeans pe baza

    // manipulrii vizuale a structurii grafice a formularului

    // n modul design

    initComponents();

    // initializare model

    initDataModel();

  • 22 Capitolul 5

    // refresh pe formular

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    // selectarea primului element din lista vizual

    this.lstConturi.setSelectedIndex(0);

    }

    private void initDataModel(){

    this.conturi =

    new ArrayList(registruConturi.getConturi());

    this.claseConturi =

    new ArrayList(

    registruConturi.getClaseConturi());

    }

    Se remarc, n listingul de mai sus, invocarea n constructor a metodei

    de iniializare a modelului de date, precum i refresh-ul forat al formularului prin refacerea grupului de legturi a crui referin este accesibil prin atributul bindingGroup.

    Aciunile tranzacionale n fine, ultima seciune a formularului se concentraz n a oferi

    utilizatorului final posibilitatea de a (vezi butoanele corespunztoare din figura 5.8):

    aduga noi entiti n formular aciune ce poate fi invocat din

    evenimentul actionPerformed al unui buton etichetat adugare i care vizeaz instanierea clasei-entitate Cont, stabilirea unor valori implicite proprietilor eseniale (cel puin a celor care sunt implicate n stabilirea identitii), adugarea acestei noi entiti n structura de date a formularului (adic n lista conturi), re-legarea structurilor vizuale ale formularului la modelul de date i selectarea programatic a noii entiti, adic desemnarea acesteia drept selectedElement n lista vizual.

    salva modificrile efectuate asupra entitii curente aciune asociat

    unui buton de salvare i care implic invocarea metodei de salvare-sincronizare cu suportul de persisten a instanei registruConturi;

    terge entitatea curent aciune tranzacional asociat unui buton de

    tergere, care implic apelul operaiei de tergere ctre

  • Dezvoltarea aplicaiilor cu interfa grafic 23

    registruConturi, ndeprtarea entitii din structura de date conturi a formularului, dar i refresh-ul componentelor vizuale;

    Figura 5.10 Butoanele pentru aciunile aa-zise tranzacionale

    resetarea strii curente a formularului, abadonnd modificrile

    curente implic re-alimentarea modelului de date cu entiti refcute de pe suportul de persisten (practic se ncepe o alt trazacie, abandonnd-o pe cea precedent).

    // Listing 5.8 Implementarea aciunilor tranzacionale

    private void cmdAdaugaActionPerformed(

    java.awt.event.ActionEvent evt) {

    this.cont = new Cont();

    this.cont.setCod("999.999");

    this.cont.setDenumire("Cont nou 999.999");

    this.cont.setSubClasaCont(this.claseConturi.get(0));

    this.conturi.add(this.cont);

    // refresh pe formular

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    lstConturi.setSelectedValue("Cont nou 999.999", true);

    }

    private void cmdSalvareActionPerformed(

    java.awt.event.ActionEvent evt) {

    this.registruConturi.addCont(this.cont);

    }

    private void cmdStergeActionPerformed(

    java.awt.event.ActionEvent evt) {

    this.conturi.remove(this.cont);

  • 24 Capitolul 5

    this.registruConturi.removeCont(this.cont);

    // refresh pe formular

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    if (!this.conturi.isEmpty()){

    this.lstConturi.setSelectedIndex(0);

    }

    }

    private void cmdAbandonActionPerformed(

    java.awt.event.ActionEvent evt) {

    this.registruConturi.refreshCont(this.cont);

    // refresh pe formular

    String elementCurent = this.cont.getDenumire();

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    this.lstConturi.setSelectedValue(elementCurent, true);

    }

    5.2.2 Construirea n Swing a formularelor master-detail Din punct de vedere structural, formularele operaionale la care vom

    face referire n continuare reprezint o rafinare a formularelor simple dezbtute mai sus, n sensul c structura formularelor simple va constitui, n acest caz, partea master care, din punctul de vedere al utilizatorului final, va fi explicitat printr-o zon detail ce va fi format de regul pe baza unui grid ale crui linii individuale vor prezenta entiti-detalii legate de entitatea-master.

    Prin urmare, se recomand ca baza coordonrii master-detail ntre cele

    dou zone s o constituie o relaie 1M (adic o entitate master la mai multe entiti detail) deja recunoscut i marcat corespunztor n modelul afacerii i suportul de persisten JPA. Formularul din exemplul curent se bazeaz pe relaia (dintre o instan) OperaieContabil (i mai multe instane) nregistrareContabil. Regula natural din domeniul afacerii pe care s-a construit aceast legtur era exprimat prin faptul c o operaie contabil este constituit de mai multe nregistrri debitoare sau creditoare. De asemenea, vom ncerca s acoperim prin interfaa grafic i precizarea specific a tipologiei nregistrrii contabile tipologia care a fost reflectat n modelul afacerii prin specializarea clasei nregistrareContabil (declarat apoi abstract) n subclasele nregistrareDebit i nregistrareCredit. Varianta final de formular M/D la care dorim s ajungem ar trebui s arate aproximativ ca n figura urmtoare.

  • Dezvoltarea aplicaiilor cu interfa grafic 25

    Figure 5.11 Formular master-detail pentru operaiuni contabile

    Stucturile modelului de date master-detail n cazul de fa, construirea modelului de date al formularului va

    cuprinde mai multe colecii de entiti distincte, eventual provenind de la mai multe registre (sau de la un registru mai complex, care ar putea gestiona n comun entitile de tip OperaiuneContabil, nregistrareContabil i Cont). Modul de constituire a acestor registre i a structurilor-colecii din modelul de date al formularului este identic ca n cazul formularelor simple. n final, ar trebui s rezulte, n cadrul formularului FormOperaiuniContabile, grupul de atribute (cu metodele get/set aferente expunerii lor ca proprieti) prezentat n tabelul urmtor.

  • 26 Capitolul 5

    Tabelul 5.1 Modelul de date al formularului pentru operaiuni contabile

    Variabila pentru registru

    Structurile de date

    registruOperaiuni List operatiuni List conturi OperatiuneContabila operatiuneContabila InregistrareContabila inregistrareContabila Cele dou colecii (de tip List, dar materializate ca ArrayList) vor fi introduse exact ca i colecia de conturi din cazul formularului simplu, iar constructorul FormOperaiuniContabile va fi modificat dup cum se arat n listingul de mai jos. // Listing 5.9 Iniializarea modelului de date M/D

    public class FormOperatiuniContabile extends javax.swing.JFrame {

    private RegistruOperatiuni registruOperatiuni;

    private List operatiuni =

    new ArrayList();

    private List conturi = new ArrayList();

    private OperatiuneContabila operatiuneContabila;

    private InregistrareContabila inregistrareContabila;

    public FormOperatiuniContabile() {

    // creare entity manager

    EntityManagerFactory emf = Persistence.

    createEntityManagerFactory("EntitatiContabilitate");

    EntityManager em = emf.createEntityManager();

    // initializare registru

    registruOperatiuni = new RegistruOperatiuni(em);

    initComponents();

    initFormDataModel();

    ... ... ...

    }

    private void initFormDataModel(){

    this.operatiuni.addAll(

    this.registruOperatiuni.getOperatiuni());

    if (!this.operatiuni.isEmpty()){

    this.operatiuneContabila = this.operatiuni.get(0);

    }

    this.conturi.addAll(this.registruOperatiuni.getConturi());

    } ... ... ...

    }

  • Dezvoltarea aplicaiilor cu interfa grafic 27

    Construirea zonei master Componenta grafic directoare, adic cea a crui element curent va

    sincroniza rubricile formularului, este o list, pe care o vom denumi lstOperatiuni, iar elementul curent va fi desemnat prin proprietatea selectedElement.

    Tabelul 5.2 Tabloul general de configurare al comp. grafice din zona master

    Componenta

    (numele

    variabilei)

    Tip comp. Legare la modelul de date - Binding

    Proprietate Source Expression

    lstOperatiuni JList elements formular Bindding:

    ${operatiuni}

    Display:

    ${idOperatiune}

    lstOperatiuni JList selectedElement formular ${operatiune

    Contabila}

    txtID JTextField text lstOperaiuni ${selectedItem.id}

    txtData

    Contabilizare

    JFormatted

    TextField

    value lstOperaiuni ${selectedItem.data

    Contabilizare}

    n legtur cu componenta txtDataContabilizare, descris n tabelul

    de mai sus, mai trebuie fcute cteva precizri, legate de strategia utilizrii unei componente mai sofisticate (JFormattedTextField) dect simplele csue de text (JTextField) pentru prezentarea valorilor de tip dat calendaristic (java.util.Date). Spre deosebire de componentele JTextField, cele de tip JFormattedTextField sunt asociate cu un obiect de tip Formatter care asigur transformarea-formatarea textului simplu (valorile proprietii text de tip String) ntr-un tip de date int ale crui valori sunt accesibile prin proprietatea value. Acesta este motivul pentru care proprietatea legat(bounded) nu este text, ci value.

    Instrumentul de formatare a datelor calendaristice necesar componentei txtDataContabilizare poate fi creat i iniializat ca un simplu atribut membru al clasei-formular. private java.text.SimpleDateFormat dateFormat =

    new java.text.SimpleDateFormat("dd/MM/yyyy");

    Se observ c, de fapt, la iniializarea lui este specificat printr-un ir

    de caractere formatul de dat dorit, n cazul de fa dd/MM/yyyy. Este important de menionat c acest ir de caractere este case-sensitive, spre exemplu nlocuirea subformatului pentru luna calendaristic cu mm va

  • 28 Capitolul 5

    avea ca efect afiarea minutelor din componenta Time a datei calendaristice.

    Asocierea formatului la componenta vizual txtDataContabilizrii trebuie fcut la iniializarea acesteia din urm. Cel mai comod mod de a realiza acest lucru const n activarea ferestrei Customized Code din meniul contextual asociat componentei grafice n modul design al mediului NetBeans.

    Figura 12. Iniializarea componentei txtDataContabilizare cu formatul de dat

    dorit

    Construirea zonei detail Structura principal a modelului de date referitor la aceast zon va

    consta dintr-o list instane de tip nregistrareContabil, accesibile prin proprietatea nregistrri a clasei OperatiuneContabil. Popularea acestei liste se face n mod automat, n substraturile de persisten, la fiecare reconstituire a unei entiti OperaiuneContabil selectabil n zona master. Aceast proprietate va constitui sursa de date pentru gridul,

  • Dezvoltarea aplicaiilor cu interfa grafic 29

    componenta JTable tblInregistrari, ale crui legturi cu modelul de date sunt configurate destul de asemntor cu o component de tip JList.

    Tabelul 5.2 Tabloul general de configurare al comp. grafice din zona master

    Componenta/

    Numele

    variabilei

    Tip

    comp.

    Binding

    Proprietate Source Expression

    tblInregistrri JTable elements lstOperatiuni ${selectedElement

    .liniifactura}

    Selected

    Element

    Form ${inregistrareContabila}

    Asistentul de legare, activat din opiunea Table Contents a meniului contextual din modul Design al mediului NetBeans, a componentei grid de tip JTable la structurile corespunztoare din modelul de date al formularului, ofer posibilitatea alegerii proprietilor entitilor-detalii care vor afiate drept coloane, ordinea acestora, precum i desemnarea antetelor acestora.

    Figura 5.13 Iniializarea gridului tblInregistrri componenta JTable pentru

    detalii

    Un prim aspect mai deosebit, legat de componenta tblInregistrri

    descris mai sus, se refer la faptul c definiia acesteia implic o coloan necesar pentru afiarea (dar i editarea) valorilor de tip Cont ale entitilor InregistrareContabila. Problema pornete de la modul implicit

  • 30 Capitolul 5

    de prezentare a valorilor n celulele gridului: adic drept iruri de caractere expuse prin intermediul instanelor JTextField. Cum un Cont nu este nici ir de caractere (String), nici dat calendaristic sau valoare numeric convenional convertibil n ir, transformarea acestor instane n iruri de caractere se face prin invocarea metodei toString() motenit din clasa Object. Din acest motiv, clasa Cont trebuie s suprascrie aceast metod, rezultatul ei constituind forma de prezentare n grid. Aadar, dac vom dori s prezentm conturile prin denumirile lor, ca i n cazul listei formularului simplu, metoda toString() ar trebui s arate astfel:

    @Override

    public String toString() {

    return denumire;

    }

    Un al doilea aspect, poate mai critic dect cel dinainte, se refer la

    modul de editare-modificare a valorilor din grid. Urmtoarele cerine ar putea fi absolut rezonabile: valorile coloanei Cont s fie selectabile dintr-o list de elemente; valorile coloanei Suma s nu aib mai mult de 2 poziii zecimale (fiind

    exprimate n RON, subdiviziunea acestuia este banul, adic a suta parte). Pentru a rspunde solicitrilor de mai sus, putem apela la dou

    strategii:

    prima implic numai elementele dezvoltate specifice formularelor prezentate pn la acest moment, i se refer la pstrarea gridului iniial doar ca i component de prezentare-selecie care ar urma s deserveasc un al doilea subformular simplu (primul fiind cel considerat master) ale crui rubrici efective ar urma s permit accesul la entitile selectabile din componenta JTable de navigare;

    a doua, mai dificil, dar mai potrivit pentru ergonomia formularului, const n editarea acestor valori direct n grid, prin urmare, n celulele coloanelor din grid ar urma s fie incluse componente grafice corespunztoare de tip JComboBox, pentru selectarea unor valori-opiuni dintr-o list de elemente posibile, pentru conturi n cazul nostru, i de tip JFormattedTextField pentru editarea valorilor numerice dup un format care s restricioneze numrul de zecimale posibile. Strategia includerii componentelor de editare direct n grid comport 2

    etape:

  • Dezvoltarea aplicaiilor cu interfa grafic 31

    prima se refer pur i simplu la construirea acestora i legarea la modelul de date n modul asistat, ca i pn acum, cu precizarea c, imediat dup configurarea lor, vor trebui ascunse, cel mai simplu prin ne-includerea lor n container-ul vizual al formularului;

    a doua este pur programatic i se refer la includerea unei clase speciale n proiectul care gzduiete formularul, plus invocarea acesteia n cteva instruciuni ce au ca scop configurarea efectiv a coloanelor ce vor expune respectivele componente n regimul de editare al valorilor din celule.

    n prima faz, se instaniaz grafic cele dou componente (modul

    Design al mediului NetBeans) undeva pe o zon neutr din formular i se configureaz dup cum se specific n tabelul urmtor.

    Tabelul 5.3 Tabloul general de configurare al comp. grafice din zona master

    Componenta

    (numele

    variabilei)

    Tip comp. Legare la modelul de date - Binding

    Proprietate Source Expresie

    cboCont JComboBox elements formular ${conturi}

    Selected

    Element

    tblInregistrari ${selected

    Element.cont}

    txtSuma

    JFormatted

    TextField

    value tblInregistrari ${selected

    Element.suma}

    De asemenea, componenta txtSuma va fi formatat prin intermediul

    urmtorului format: private DecimalFormat decimalFormat = new DecimalFormat("0.000");

    la fel ca i componenta txtDataContabilizare prezentat deja.

  • 32 Capitolul 5

    Figura 5.14 Iniializarea componentei txtSuma cu formatul numeric dorit

    Excluderea lor din container-ul vizual al formularului (ele vor fi

    incluse programatic direct n grid) se poate face printr-o operaiune Drag&Drop n fereastra Inspector din modul Design, astfel nct acestea s fie incluse n categoria Other Components (vezi figura 14).

  • Dezvoltarea aplicaiilor cu interfa grafic 33

    Figura 5.15 Fereastra Inspector din modul Design

    n etapa de configurare programatic, componenta JTable este

    instruit s foloseasc cele dou componente drept suport de editare a valorilor celor dou coloane (cont i suma). Pentru a uura i simplifica totodat acest efort, avem nevoie de clasa TableColumnEditor prezentat n listingul urmtor. // Listing 5.10 Clas suport pentru componenta JTable

    class TableColumnEditor

    extends AbstractCellEditor implements TableCellEditor {

    private JComponent component;

    public TableColumnEditor(JComponent component) {

    this.component = component;

    }

    public JComponent getComponent() {

    return component;

    }

    public void setComponent(JComponent component) {

    this.component = component;

  • 34 Capitolul 5

    }

    // metod invocat de grid atunci

    // cnd utilizatorul selecteaz valorea unei celule

    // dintr-una din coloanele specifice

    public Component getTableCellEditorComponent(JTable table,

    Object value,boolean isSelected,

    int rowIndex, int vColIndex) {

    component.setVisible(true);

    return component;

    }

    // metod invocat de grid atunci

    // cnd utilizatorul ncheie editarea

    // celulei curente cu acea component activat prin invocarea

    // metodei getTableCellEditorComponent

    public Object getCellEditorValue() {

    if (component instanceof JComboBox){

    return ((JComboBox)getComponent()).getSelectedItem();

    }

    if (component instanceof JFormattedTextField){

    return ((JFormattedTextField)getComponent())

    .getValue();

    }

    return null;

    }

    }

    Rolul instanelor acestei clase este de a mpacheta componenta grafic propriu-zis pentru a fi livrat corespunztor gridului tblInregistrri, lucru care se realizeaz programatic dup cum se arat n listingul urmtor. // Listing 5.11 Includerea componentelor grafice n grid

    private void initTableCellEditors(){

    // coloana cont are indexul 1 n structura gridului

    TableColumnEditor contCellEditor =

    new TableColumnEditor(cboCont);

    tblInregistrari.getColumnModel()

    .getColumn(1).setCellEditor(contCellEditor);

    // coloana suma are indexul 2 n structura gridului

    TableColumnEditor sumaCellEditor =

    new TableColumnEditor(txtSuma);

    tblInregistrari.getColumnModel()

    .getColumn(2).setCellEditor(sumaCellEditor);

    }

  • Dezvoltarea aplicaiilor cu interfa grafic 35

    Metoda initTableCellEditors va trebui invocat apoi din contructorul formularului. // Listing 5.12 Forma final de iniializare a formularului M/D

    public FormOperatiuniContabile() {

    // creare entity manager

    EntityManagerFactory emf = Persistence.

    createEntityManagerFactory("EntitatiContabilitate");

    EntityManager em = emf.createEntityManager();

    // initializare registru

    registruOperatiuni = new RegistruOperatiuni(em);

    initComponents();

    initFormDataModel();

    // refresh pe formular

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    this.lstOperatiuni.setSelectedIndex(0);

    initTableCellEditors();

    }

    Ca urmare, la selecia unei valori numerice din coloana, s spunem suma, componenta de editare corespunztoare va trebui s se activeze:

  • 36 Capitolul 5

    Figura 5.16 Activarea componentei txtSuma direct n grid

    (pentru activarea componentei cboCont vezi figura 10)

    Aciuni tranzacionale master-detail nainte de a trece efectiv la descrierea aciunilor tranzacionale, mai

    trebuie comentate anumite responsibiliti care, n opinia noastr, in mai mult de model dect de interfaa grafic.

    Salvarea oricrei linii, noi sau modificate, trebuie fcut mpreun cu

    agregatul din care face parte; n acest sens, n clasa OperatiuneContabil ar putea fi adugat o directiv specific de cascadare n legtur cu atributul ce implementeaz legturile cu clasa InregistrareContabila:

    @OneToMany(mappedBy = "operatiune", cascade=CascadeType.ALL)

    @MapKey(name = "nrOrdine")

    private Map inregistrari =

    new HashMap();

  • Dezvoltarea aplicaiilor cu interfa grafic 37

    Aciunea de adugare a unei noi linii va fi invocat din evenimentul actionPerformed al unui buton de adugare linii. n cazul nostru concret, adugarea unei noi nregistrri se poate face att pe debit, ct i pe credit, apelnd de fapt la subclasele InregistrareDebit i InregistrareCredit ale clasei InregistrareContabila. Din acest motiv, formularul pentru operaiuni contabile are dou butoane implicare n adaugarea de linii-detalii:

    // Listing 5.13 Aciunile de adugare nregistrri-detaliu

    private void btnAdaugareDebitActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    // actualizare model

    this.inregistrareContabila =

    new InregistrareDebit(this.conturi.get(0), 0.0);

    this.operatiuneContabila.addInregistrareContabila(

    this.inregistrareContabila);

    // refresh grid

    this.bindingGroup

    .getBinding("tblInregistrariElements").unbind();

    this.bindingGroup

    .getBinding("tblInregistrariElements").bind();

    }

    private void btnAdaugareCreditActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    // actualizare model

    this.inregistrareContabila =

    new InregistrareCredit(this.conturi.get(0), 0.0);

    this.operatiuneContabila.addInregistrareContabila(

    this.inregistrareContabila);

    // refresh grid

    this.bindingGroup

    .getBinding("tblInregistrariElements").unbind();

    this.bindingGroup

    .getBinding("tblInregistrariElements").bind();

    }

  • 38 Capitolul 5

    Se observ c, pentru reflectarea noii nregistrri la nivelul gridului, a fost necesar un refresh al componentei JTable pentru a o resincroniza cu modelul de date al formularului. n acest scop am apelat la refacerea doar a legturii referitoare strict la componenta tblInregistrari, evitnd refacerea ntregului grup de legturi al formularului. Orice legtur poate fi identificat printr-un nume precizat n fereastra Advanced a asistentului Binding.

    Figura 5.17 Identificarea legturii cu modelul de date al componentei

    tblInregistrri

  • Dezvoltarea aplicaiilor cu interfa grafic 39

    ndeprtarea unei linii din gridul detail se traduce prin ndeprtarea acesteia din structura de date inregistrari a operaiunii curente n formular. ndeprtarea efectiv din baza de date se va face la salvarea facturii curente. Acest aciune va fi asociat unui buton de tergere.

    // Listing 5.14 Aciunea de stergere nregistrri-detaliu

    private void btnStergeInregistrareActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    if (this.inregistrareContabila == null)

    return;

    // actualizare model

    this.operatiuneContabila.removeInregistrareContabila(

    this.inregistrareContabila);

    this.bindingGroup

    .getBinding("tblInregistrariElements").unbind();

    this.bindingGroup

    .getBinding("tblInregistrariElements").bind();

    }

    La nivelul zonei master se gsesc i aciunile efectiv tranzacionale cu suportul de persisten:

    un buton de adugare operaiune nou; un buton de salvare a operaiunii curente (inclusiv a nregistrrilor

    modificate sau adugate); un buton de tergere a operaiunii curente (inclusiv a nregistrrilor

    asociate i prezentate n grid). // Listing 5.15 Aciunile tranzactionale la nivelul master

    private void btnSalveazaActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    // tranzactia cu suportul de persistenta

    this.registruOperatiuni.addOperatiuneContabila(

    this.operatiuneContabila);

    }

  • 40 Capitolul 5

    private void btnOpNouaActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    // tranzactia cu suportul de persistenta

    this.registruOperatiuni.addOperatiuneContabila(

    this.operatiuneContabila);

    }

    private void btnStergeOpActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    // tranzactia cu suportul de persistenta

    this.registruOperatiuni.removeOperatiuneContabila(

    this.operatiuneContabila);

    // actualizare model

    this.operatiuni.remove(this.operatiuneContabila);

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    if (!this.operatiuni.isEmpty()){

    this.lstOperatiuni.setSelectedIndex(0);

    }

    }

    n plus mai poate fi adugat i un buton de refacere a structurilor de date ale formularului (etichetat abandon), care s rencarce din suportul de persisten entitile-operaiuni contabile. // Listing 5.16 Abandonul a strii curente a formularului

    private void btnAbandonActionPerformed(

    java.awt.event.ActionEvent evt) {

    // preconditii

    if (this.operatiuneContabila == null)

    return;

    this.registruOperatiuni.

    refreshOperatiune(this.operatiuneContabila);

    // refresh pe formular

    String elementCurent = this.operatiuneContabila

    .getIdOperatiune().toString();

    this.bindingGroup.unbind();

    this.bindingGroup.bind();

    this.lstOperatiuni.setSelectedValue(elementCurent, true);

    }

  • Dezvoltarea aplicaiilor cu interfa grafic 41

    5.3 Aplicaie cu interfa grafic JavaServerFaces i Eclipse

    Aplicaiile Web, construite folosind sau nu cadrul de lucru JSF, se

    bazeaz pe formulare HTML capabile s fie materializate sau concretizate n contextul unui browser Web. Prin urmare, utilizatorii finali interacioneaz n mod direct cu formularele HTML din browser, urmnd ca aciunile acestora, n special cele tranzacionale, s se concretizeze n cereri HTTP ctre serverul Web. n acest fel, sunt iniiate diverse procesri care au loc la nivelul serverului, inclusiv tranzacii cu bazele de date sau alte componente middleware. Generarea i transmiterea formularelor HTML ctre utilizatorii finali nu sunt considerate operaiuni costisitoare, logica esenial a aplicaiei rmnnd la nivelul serverului. Ca urmare, instalarea i livrarea unei aplicaii web este considerat mult mai simpl i mai puin constisitoare dect n cazul aplicaiilor desktop ce trebuie instalate pe fiecare sistem de calcul-client n parte. n cazul aplicaiilor Web cerina de baz pentru accesarea lor de pe client se refer la existena unui browser. Cum astzi nu putem concepe un computer fr conexiune la internet i browser web, aceast condiie iniial este, practic, implicit satisfcut.

    Modul n care diversele tipuri de tehnologii i cadre de lucru pentru

    aplicaiile web neleg s proceseze formularele HTML i cererile HTTP asociate acestora este extrem de variat. n cazul JavaServer Faces, o component a unei interfee grafice Web are dou laturi: expunerea ei n format HTML i reflectarea acesteia ntr-o component JavaBean rezident i procesat pe server. Cu alte cuvinte, componentele interfeelor grafice ale aplicaiilor JSF sunt responsabile pentru:

    1. livrarea codului HTML (ca i cum rezultatul procesrii strii lor la

    nivelul serverului ar fi compilat, de fapt convertit, n cod HTML) ctre browser, ca urmare: cererile HTML, de la componentele UI5 proprii browserului

    sau provenind din scriptingul JavaScript, sunt recepionate de un servlet-controller Java pe partea de server, care le traduce n componente Java-JSF gzduite i procesate pe JVM6-ul serverului;

    ca rspuns la cererile client, componentele JSF sunt invocate i interacioneaz pe baza infrastructurii orientate pe evenimente a mediului JSF, iar apoi starea acestor componente este re-

    5 Componente UI, adic componente ale interfeei grafice, n mod concret ale

    formularelor. 6 Motorul de execuie a proceselor Java.

  • 42 Capitolul 5

    tradus, convertit sau compilat n codul HTML specific a crui interpretare pe clientul-browser va nlocui parial sau total (ceea ce echivaleaz un gen de refresh) partea de prezentare efectiv expus utilizatorului final;

    2. susinerea infrastructurii bazat pe evenimente i sincronizarea (JSF

    binding) strii lor la structurile de date rezidente pe serverul Web.

    5.3.1 Organizarea proiectelor n Eclipse n context JavaServer Faces

    Ceea ce ne propunem n continuare const, practic, n rencarnarea

    aplicaiei Swing Desktop referitoare la conturi, operaiuni i nregistrri contabile, ntr-un mediu pur web, sprijinindu-ne n aceast aventur pe cadrul de lucru JSF pentru aplicaiile Web standardizat pentru platforma Java Enterprise. Toate elementele ulterioare de design i implementare, cu explicaiile aferente, au legtur cu ultima versiune a specificaiilor JSF, i anume cea marcat cu indicativul 2.0.

    Vom cuta, pe ct posibil, s folosim aceeai manier i experien

    MVC pe care am exemplificat-o n paragrafele referitoare la cadrul de lucru Swing. De asemenea, designul final al formularelor web va respecta, n linii foarte generale, designul sau aezarea grafic a formularelor aplicaiei Swing. Ca urmare, vom ncerca s folosim aceleai principii de delimitare a unui formular ntr-o zon de cutare-selecie-navigare, o zon coninnd rubrici de prezentare-editare a entitilor din modelul de date i o zon cu butoanele de aciune specifice operaiilor tranzacionale.

    De asemenea, vom folosi acelai model al afacerii i acelai strat de

    persisten (JPA) pregtit n capitolul 4. Motiv pentru care vom folosi aceeai organizare bazat pe dou proiecte, mediul de dezvoltare integrat va fi, ns, de aceast dat, Eclipse7:

    Un proiect de tip JPA va gzdui modelul (contabil) afacerii.

    Vom utiliza aceeai implementare JPA ca i n cazul aplicaiei desktop, i anume EclipseLink 2.1.

    Un proiect de tip Dynamic Web Module va gzdui

    componentele de prezentare care se vor materializa sau, mai bine spus, vor genera, n cele din urm, n paginile Web

    7 n mod concret, a fost folosit distribuia OEPE-Helios de la Oracle.

  • Dezvoltarea aplicaiilor cu interfa grafic 43

    coninnd formularele ce vor expune entitile afacerii ctre utilizatorii finali.

    Configurarea proiectului JPA are n vedere, n primul rnd, instalarea

    bibliotecilor de implementare a cadrului de lucru JPA-EclipseLink. Acestea pot fi instalate on-line la iniializarea proiectului (vezi figura de mai jos) sau ulterior, dup crearea proiectului, cu ajutorul unui asistent care va fi invocat din fereastra (Properties) de configurare a proiectului, seciunea Java Persistence.

    Figura 5.18 Descrcarea bibliotecii suport pentru EclipseLink

    Un alt element esenial n configurarea proiectului JPA se refer la

    definirea driverului JDBC necesar conexiunilor cu baza de date int, PostgreSQL n cazul exemplului de fa. n acest sens, se va invoca dialogul Add Library din meniul contextual asociat proiectului, atunci cnd perspectiva

    8 activ a mediului Eclipse este Java. Din pcate,

    majoritatea driverelor nu pot fi descrcate online direct din mediul 8 n Eclipse, fiecare tip de proiect este asociat cu o anumit perspectiv specific

    care se refer la un anumit set de ferestre, precum i la dispunerea lor n cadrul ferestrei principale a mediului de dezvoltare.

  • 44 Capitolul 5

    Eclipse, prin urmare ele trebuie mai nti descrcate separat, de pe site-ul productorului, i apoi trebuie specificate n ultimul pas al procedurii de configurare (vezi figura urmtoare).

    Figura 5.19 Configurarea driverului PostgreSQL

    Configurarea proiectului aplicaiei Web are n vedere, n primul rnd,

    instalarea bibliotecilor suport pentru cadrul de lucru JSF, corespunztoare implementrii ApacheMyFaces, n cazul exemplului nostru. Acest lucru poate fi realizat la iniializarea proiectului (vezi figura de mai jos) sau ulterior, cu ajutorul unui asistent ce poate fi invocat din fereastra

  • Dezvoltarea aplicaiilor cu interfa grafic 45

    (Properties) de configurare a proiectului, seciunea Project Facet, opiunile JavaServerFaces i JSTL.

    Figura 5.20 Configurarea implementrii ApacheMyFaces pentru cadrul de

    lucru JSF 2.0

    Instalarea unei biblioteci-suport care s conin o implementare JSTL se poate face on-line, la fel ca i implementarea n cazul implementrii JSF-MyFaces. Astfel c, dup bifarea rubricii JSTL din seciunea ProjectFacets a ferestrei de proprieti a proiectului web, vei observa apariia unui mesaj-link n partea de jos Further configuration required. Acionnd acest link va aprea un dialog din care putei selecta opiunea de descrcare on-line a bibliotecii n discuie.

  • 46 Capitolul 5

    Dup cum se observ i din figura precedent, am optat pentru implementarea ApacheMyFaces pentru specificaia JSF. Pentru a putea instala aplicaia Web, pe care ne propunem s o construim n continuare, ntr-un mediu de execuie corespunztor testrii, vom avea nevoie de un server Web care s furnizeze mediul de execuie (mediul runtime) al acesteia. Serverul Web pe care l vom folosi va fi ApacheTomcat v.6.0. Acesta trebuie mai nti descrcat de pe site-ul http://tomcat.apache.org/ i apoi instalat de sine-stttor ntr-o locaie proprie. Aducerea acestuia n mediul Eclipse, pentru ca apoi s poat fi asociat cu proiectul aplicaiei Web, se poate face n mai multe moduri. Cel mai simplu const n invocarea opiunii New Server din meniul contextual asociat ferestrei Servers ce face parte din perspectiva Web a mediului Eclipse, perspectiv care se activeaz, de regul, la crearea sau deschiderea unui proiect Web.

    Figura 5.20 Configurarea serverului Apache Tomcat

    n fine, un ultim pas n configurarea proiectului aplicaiei web se

    refer la crearea unor referine ctre proiectul JPA. Acestea sunt necesare, pe de o parte, pentru a putea invoca entitile afacerii la constituirea modelelor de date ale formularelor Web, i, pe de alt parte, pentru a

  • Dezvoltarea aplicaiilor cu interfa grafic 47

    putea instala pe serverul Tomcat, odat cu aplicaia Web propriu-zis, i a arhivelor JAR care conin implemetrile modelului de persisten. Mai nti, se adaug proiectul JPA n pagina Projects a seciunii Java Build Path din fereastra de proprieti a proiectului Web (vezi figura de mai jos).

    Figura 5.21 Specificarea proiectului JPA n configuraia de compilare a

    proiectului Web

    n fine, mai este necesar i adugarea aceluiai proiect JPA i n

    configuraia de instalare a aplicaiei Web descris prin seciunea Web Deployment Assembly a ferestrei de proprieti a proiectului Web.

  • 48 Capitolul 5

    Figura 5.22 Specificarea proiectului JPA n configuraia de instalare a

    proiectului Web

    Alte biblioteci suport care s-ar putea dovedi necesare proiectului Web

    pot fi descrcate i incluse n proiect folosind opiunea Configure Build Path din meniul contextual asociat proiectului specific ferestrei Package Explorer din perspectiva Java a mediului Eclipse sau din seciunea Java Build Path a ferestrei de proprieti a proiectului. n pagina Libraries a acestei seciuni exist disponibile mai multe aciuni prin care pot fi asociate cu proiectul curent, fie direct arhivele, descrcate n prealabil, coninnd funcionalitile suport necesare (Add Jar sau Add External Jar), fie asocierea acestora prin intermediul sistemului de management al bibliotecilor specific mediului Eclipse. O bibliotec poate grupa mai multe arhive JAR, cum este cazul bibliotecilor MyFaces, JSTL sau EclipseLink al cror coninut poate fi vizualizat i din fereastra Preferences a meniului Window din Eclipse, sub-seciunea Java Build Path User Libraries (vezi figura urmtoare).

  • Dezvoltarea aplicaiilor cu interfa grafic 49

    Figura 5.23 Coninutul bibiotecilor suport necesare proiectelor JPA i Web

    Principalele structuri fizice ale proiectului Web pe care l vom obine

    ca urmare a invocrii ablonului Dynamic Web Module, dar i a configurrilor descrise mai sus, constau n:

    folderul src care va gzdui clasele Java ce vor implementa

    componentele bean responsabile de implementarea funcionalitilor legate de modelele de date i de aciunile sau comportamentul asociat formularelor Web;

    folderul WebContent care va conine fiierele de configurare

    (web.xml i faces-conFiguraxml din sub-folderul WEB-INF), precum i fiirele xhtml ce vor descrie, prin elemente-tag specifice JSF, modul de constituire a formularelor Web propriu-zise.

    Fiierul web.xml este esenial pentru c: pe de o parte, precizeaz servletul specific aplicaiilor JSF,

    servlet invocat de acele cereri ale cror ablon este precizat printr-o specificaie de mapare explicit;

  • 50 Capitolul 5

    // Listing 5.17 Specificaia servletului JSF n web.xml

    faces

    org.apache.myfaces.webapp.MyFacesServlet

    1

    faces

    *.jsf

    faces

    *.faces

    (prin urmare, adresele URL prin care vor fi invocate paginile coninnd formularele Web JSF vor trebui s se ncheie cu particula jsf sau faces).

    pe de alt parte specific pagina de pornire sau de start a

    aplicaiei Web, adic punctul de acces la contextul acesteia. // Listing 5.18 Specificaia paginilor de start n web.xml

    indListing html

    indListing htm

    indListing jsp

    default.html

    default.htm

    default.jsp

    De regul, fiierul web.xml nu este nevoie s fie editat n mod explicit.

    Cel mult, pagina de pornire indListing jsp, singura disponibil n proiect dintre opiunile welcome-file-list, poate fi modificat, astfel nct s fac o re-directare ctre o pagin de pornire dedicat aplicaiei JSF.

    De asemenea, nici n fiierul faces-conFiguraxml nu este nevoie s se

    fac modificri explicite, fiindc versiunea 2.0 a specificaiei JSF conine o serie de adnotri i mecanisme de configurare care ocolesc specificaiile explicite din acest fiier. Mediul Eclipse ofer i el o serie de asisteni care au rolul interpretrii i actualizrii informaiilor din acest fiier prin intermediul unor asisteni coninnd formulare grafice uor de utilizat chiar i pentru programatori mai puin experimentai.

  • Dezvoltarea aplicaiilor cu interfa grafic 51

    5.3.1 Construirea formularelor web pentru nomenclatoare La fel ca i n cazul formularelor desktop, vom ncerca s pstrm

    principalele seciuni referitoare la aciunile de cutare-selecie-navigare, rubricile-detalii i aciunile-tranzacionale. Acest lucru este evideniat n figura de mai jos unde este prezentat formularul pentru conturi, n versiunea Web. Dat fiind c scopul nostru este, mai degrab, arhitectural, nu ne vom concentra asupra posibilitilor de stilizare a paginii ce conine acest formular, ns, pentru o aplicaie real, destinat unui grup de utilizatori adevrai, tehnologiile CSS sunt obligatoriu a fi exploatate, eventual cu ajutorul unui designer-web cu mai mult experien.

    Figura 5.24 Versiunea Web a formularului pentru conturi

    De asemenea, principiile Model-View-Controller ne vor ghida, poate

    chiar ntr-o mai mare msur dect n cazul aplicaiilor desktop, i n procesul de elaborare a formularelor Web.

    Arhitectura logic a formularelor web, aa cum este structurat n

    cele dou fiiere pe care le vom folosi n implementarea lor, va arta astfel: Fiierul FormBean.java va fi responsabil de:

    structura modelui de date, adic

  • 52 Capitolul 5

    coleciile de date, mai exact de obiecte POJOs9, precum i a suportului de cutare-iteraie n aceste colecii, cel mai simplu mecanism fiind pstrarea referinelor elementelor considerate curente n formular, la fel ca i n cazul aplicaiilor desktop prezentate n paragrafele anterioare;

    legtur back-suport a modelui de date, cu alte cuvinte legtura cu sursele de date persistente sau, mai exact, referine ctre registrele JPA;

    structura controller, care se refer la suportul oferit: aciunilor de cutare-selecie-navigare, ce vor

    manipula, de fapt, modelul de date al formularului, urmnd ca, prin mecanismul implicit al servlet-controller-ului JSF, s fie re-actualizate sau re-sincronizate i componentele de prezentare instaniate, n cele din urm, n fereastra browserului utilizatorului final;

    aciunilor tranzacionale, care au n vedere modificarea strii obiectelor POJO din coleciile modelului de date, modificri ce, n final, vor trebui reflectate i n suportul de persisten cu ajutorul registrelor JPA.

    Fiierul Form.xhtml, ce asigur suportul necesar construirii structurilor finale de prezentare (nivelul view), avnd urmtoarele responsabiliti: descrierea aezrii n pagin, adic layout-ul sau modul

    de prezentare la nivelul clientului final al formularelor; mai exact, a modului de compunere i integrare a componentelor grafice utilizate;

    descrierea modului de legare-sincronizare (binding) a componentelor grafice la: structurile de date ale modelului - binding date; structurile comportamentale (structurile-suport

    controller) - binding aciuni Ajax.

    9 POJOs = Plain Old Java ObjectS se refer la obiecte Java obinuite, plate, fr

    obligativitatea implementrii vreunei interfee sau extinderei vreunei clase, abstracte sau nu, care s le confere un tip mai special.

  • Dezvoltarea aplicaiilor cu interfa grafic 53

    Crearea celor dou fiiere care descriu mpreun arhitectura unui formular JSF este totui o operaie care necesit o oarecare atenie. Astfel, crearea fiierului Java va fi realizat prin urmtoarea procedur:

    n primul rnd trebuie activat perspectiva Web a mediului de dezvoltare Eclipse, perspectiv care ofer, n fereastra Project Explorer, o viziune mult mai specializat a proiectului, dup cum se exemplific n figura de mai jos.

    Figura 5.25 Organizarea proiectului Web n Eclipse

  • 54 Capitolul 5

    apoi, din sub-categoria Managed Beans a Faces Configuration va fi invocat opiunea New Managed Bean a meniului contextual. Din prima fereastr a asistentului se alege opiunea Create a new Java Class care va lansa fereastra Java Class unde vor fi specificate pachetul i numele noii clase, pentru ca n urmtoarea fereastr s fie cerute informaii cu privire la aliasul obiectului-bean-suport i modul n care acesta va fi iniilalizat n contextul aplicaiei JSF. Deocamdat, strict pentru cerinele formularelor pe care le exemplificm, vom alege iniializarea la nivelul fiecrei noi sesiuni a aplicaiei, ceea ce nseamn c va fi iniializat o nou instan a formularului pentru fiecare utilizator n parte (vezi pasul 4 din figura de mai jos).

    Figura 5.26 Crearea unui nou fiier-formular JavaBean

    n fine, din meniul contextual asociat nodului WebContent n

    fereastra Project Explorer, este invocat opiunea New HTML file. n noua fereastr care se deschide astfel, se completeaz numele fiierului (a nu se uita extensia xhtml), iar n pasul urmtor se poate alege opiunea New Facelet Header (dup cum se exemplific n figura 5.27);

  • Dezvoltarea aplicaiilor cu interfa grafic 55

    Figura 5.27 Crearea unui nou fiier-formular JSF xhtml Ca urmare a pasului anterior, va rezulta un fiier simplu, doar cu

    cteva taguri HTML simple. n seciunea body a noului fiier, vor trebui adugate tagurile JSF specifice, i anume i , pentru nceput. Acestea pot fi aduse direct din paleta de componente, dup cum se exemplific n figura urmtoare.

  • 56 Capitolul 5

    Figura 5.28 Completarea fiierului-formular xhtml cu tagurile JSF de baz:

    view i formular

    Aducerea prin drag&drop, n contextul fiierului xhtml, a celor dou taguri specifice aplicaiilor JSF are drept consecin i completarea tagului general care descrie sursele de interpretare a tagurilor din document.

    Fr manipularea drag&drop din paleta de componente a tagurilor JSF, specificaiile de mai sus trebuie adugate explicit.

  • Dezvoltarea aplicaiilor cu interfa grafic 57

    Construirea structurii grafice a formularului Web

    Procedura de creare a fiierelor claselor Java - bean support i xhtml, descris mai sus, va trebui urmat implicit pentru orice nou formular al aplicaiei. n cazul concret al structurii formularului simplu, organizarea componentelor grafice care compun layout-ul acestuia va fi urmtoarea:

    zona de antet va conine informaii generale, cum ar fi numele

    formularului, nsoit de numele aplicaiei, care poate s constituie i un link ctre pagina sau formularul principal;

    zona de cutare/navigare/access entiti-POJOs din coleciile modelului de date, care vor fi expuse utilizatorului final, constituit astfel:

    un control grafic compozit: combo/list sau chiar tree/grid; o bar cu butoane de comand pentru invocarea aciunilor de

    navigare secvenial nainte/napoi/prim/ultim;

    zona de prezentare/editare entiti-POJOs cu rubrici pentru fiecare cmp sau proprietate de interes, rubrici formate din combinarea:

    unei etichete-nume cmp care va nsoi un control grafic de de prezentare-editare a valorii efective a

    proprietii int, control ce poate fi de tip textBox, dar i list de opiuni (list, combo, grup de butoane radio etc.).

    zona aciunilor tranzacionale format din:

    bara cu butoane de comand pentru adugare, tergere i bara cu butoane de comand salvare i abandon-refresh;

    zona de subsol cu eventuale informaii despre starea curent a

    aplicaiei sau formularului curent. Codificarea sau, mai bine zis, descrierea acestei structuri grafice n

    format xHTML se realizeaz folosind ns tagurile specifice JSF, i limitnd la maximum tagurile originale HTML, destul de greu controlabile n mod direct din context JSF.

    Pentru a realiza, n acest mod, un formular tranzacional, ntreg cadrul

    de prezentare va fi gestionat, n primul rnd, prin structuri tabelare combinate, structuri care vor fi reprezentate n JSF sub forma componentelor panelGrid. Acestea au urmtoarele caracteristici:

    ofer o structur tabelar orientat pe coloane, ale crei rnduri se

    completeaz secvenial, pe msur ce noi componente sunt adugate:

  • 58 Capitolul 5

    de exemplu un panelGrid definit pe 2 coloane va forma 3 rnduri complete atunci cnd este adugat a 6-a component;

    ofer posibilitatea adugrii unui antet i a unui subsol n mod

    independent de coloanele i rndurile care formeaz coninutul principal. n cazul concret al formularului pentru conturi, vom defini mai nti

    un panou (panelGrid) principal cu dou coloane, panou care va fi structurat astfel:

    n antet, definit prin tagul ,va fi inclus

    numele aplicaiei, printr-un comand link care s trimit la formularul principal;

    numele formularului specific printr-o csu de text ne-editabil;

    zona de cutare-navigare-selecie entiti-POJOs expuse va include

    urmtoarele dou elemente sau subdiviziuni ce vor forma prima linie din coninutul efectiv al panoului principal: un combo pentru navigare, desemnat prin tag-ul selectOneMenu,

    i care va conine un subtag selectedItems prin care se va descrie lista de elemente selectabile:

    o bar cu dou butoane navigare nainte i napoi desemnat

    printr-un panou distinct (panelGrid cu dou coloane i o singur linie):

    butonul napoi;

    butonul nainte;

    zona de prezentare/editare entiti/POJOs format din trei rubrici (i,

    prin urmare, trei linii n panoul principal), astfel: rubrica pentru prezentarea proprietii cod (a entitii Cont

    curente) etichet nume cmp;

  • Dezvoltarea aplicaiilor cu interfa grafic 59

    control de prezentare-editare valoare:

    rubrica pentru prezentarea proprietii denumire: etichet nume cmp;

    control de prezentare-editare valoare;

    rubrica pentru prezentarea proprietii subClasaCont: etichet nume cmp;

    control de prez.-editare valoare;

    zona de aciuni tranzacionale va forma ultima linie din panoul

    principal, format din dou elemente, fiecare, la rndul lui fiind un gen de toolbar: o bar (panou panelGrid cu 2 coloane i o singur linie) cu

    butoanele de comand pentru aciunile de adugare i tergere: butonul adaug;

    butonul sterge;

    o bar (panou panelGrid cu 2 coloane i o singur linie) cu butoanele de comand pentru aciunile de salvare i abandon

    butonul salveaz;

    butonul abandon;

    n subsol, , vor fi afiate informaii despre

    numrul de conturi ncrcate n formular printr-un text simplu, needitabil. Crearea i compunerea acestor seciuni i componente ale

    formularului se pot face direct n cod sau folosind paleta de componente oferite de mediul Eclipse, dup cum ncearc s sugereze i figura urmtoare.

  • 60 Capitolul 5

    Figura 5.29 Compunerea grafic a formularului cu manipularea drag&drop a

    componentelor grafice i generarea codului xHTML aferent

    Modelul sau structura de date a formularului Am artat deja, ntr-unul din paragrafele anterioare, modul n care va

    fi construit fiierul Java care va implementa logica obiectelor-bean-suport pentru modelul de date al formularului. Vom crea astfel, aa cum este descris n figura 26, bean-ul cu numele formClienti ce va fi iniializat pe baza clasei Java FormConturi.

    n interiorul acestei clase, modelul structurilor de date necesare

    componentelor interfeei grafice este implementat printr-un set de cmpuri, astfel:

  • Dezvoltarea aplicaiilor cu interfa grafic 61

    un cmp pentru colecia (List) de entiti de tip Cont, principalele obiecte POJO ale formularului; private List conturi = new ArrayList();

    un cmp pentru colecia de entiti de tip ClasaConturi, ce va alimenta

    lista de elemente dintre care va fi selectat valoarea proprietii subClasaCont a entitilor de tip Cont; private List claseConturi =

    new ArrayList();

    un cmp pentru stocarea referinei elementului, din colecia de

    conturi, considerat curent. private Cont cont = null;

    Modelul de date constituit din structurile de mai sus va fi expus prin

    intermediul unui set de proprieti (getteri cu sau fr setteri) aferente fiecrui cmp, astfel: // Listing 5.19 Modelul de date al formularului pentru conturi

    // numai getter pentru campul conturi

    // expunere ntr-o alt form de colecie dect cea original

    public Map getConturi() {

    Map conturiMap =

    new LinkedHashMap();

    if (this.conturi != null && !this.conturi.isEmpty()){

    for (Cont c : this.conturi){

    conturiMap.put(c.getDenumire(), c);

    }

    }

    return conturiMap;

    }

    // proprietate virtuala (nebazata efectiv pe un camp

    // cu nume similar) legata tot de campul conturi,

    // prin care vor fi expuse informatii ce sunt expuse i

    // in linia de stare a formularului

    public Integer getConturiCount(){

    return conturi.size();

    }

    // pentru campul claseConturi (numai getter)

    public Map getClaseConturi() {

    Map claseMap =

    new LinkedHashMap();

    if (this.claseConturi != null

  • 62 Capitolul 5

    && !this.claseConturi.isEmpty()){

    for (ClasaConturi c : this.claseConturi){

    claseMap.put(c.getDenumire(), c);

    }

    }

    return claseMap;

    }

    // pentru campul cont (pereche getter/setter)

    public Cont getCont() {

    return cont;

    }

    public void setCont(Cont cont) {

    this.cont = cont;

    }

    O prim observaie ce merit fcut n legtur cu modul de expunere a coleciilor de conturi i clase de conturi se refer la faptul c, dei implementate ca List-e convenionale, ele sunt exportate ca i colecii de tip Map, cheia acestora (bazat pe proprietatea denumire a instanelor Cont i ClasaConturi) constituind informaia ce va fi afiat n componentele grafice de tip list sau combo.

    Iniializarea i susinerea (n sensul persistenei) obiectelor din

    structurile de date ale modelului se face prin intermediul unui registru JPA instaniat n constructorul clasei. // Listing 5.20 Iniializarea modelul de date

    // al formularului pentru conturi

    private RegistruConturi registruConturi;

    public FormConturi() {

    // creare entity manager

    EntityManagerFactory emf = Persistence.

    createEntityManagerFactory("EntitatiContabilitate");

    EntityManager em = emf.createEntityManager();

    // initializare registru

    registruConturi = new RegistruConturi(em);

    initForm();

    }

    private void initForm(){

    this.conturi =

    new ArrayList(registruConturi.getConturi());

    if (this.conturi != null && !this.conturi.isEmpty()){

    // initializare cont curent implicit

    this.cont = this.conturi.get(0);

    }

  • Dezvoltarea aplicaiilor cu interfa grafic 63

    this.claseConturi =

    new ArrayList(

    registruConturi.getClaseConturi());

    }

    Metoda intern initForm, prezentat i ea n scriptul de mai sus, are rolul de a iniializa cmpurile care formeaz modelul de date al formularului, invocnd n acest sens registrul de conturi.

    Legarea(binding), sau sincronizarea modelului de date cu com-ponentele grafice din formular, este specificat n fiierul xhtml, printr-o serie de proprieti specifice tagurilor JSF (vezi tabelul urmtor).

    Tabelul 5.4 Legarea componentelor UI la modelul de date al formularului

    Component grafic/ tag JSF

    Proprietate Expresie JSF-EL10

    Binding

    Combo/ selectOneMenu

    value #{formConturi.cont}

    Combo/ selectedItems

    value #{formConturi.conturi}

    Csu de text/ inputText

    Value #{formConturi.cont.cod}

    Csu de text/ inputText

    Value #{formConturi.cont.denumire}

    Combo/ selectOneMenu

    value #{formConturi.cont.subClasaCont}

    Combo/ selectedItems

    value #{formConturi.claseConturi}

    10

    JSF-EL JavaServer Faces Expression Language.

  • 64 Capitolul 5

    Configurarea legturilor prezentate n tabelul de mai sus se poate face

    direct n cod sau folosind fereastra de proprieti asociat fiecrui element grafic sau tagului su (vezi figura urmtoare).

    Figura 5.30 Modificarea proprietilor componentelor JSF

    n legtur cu modul n care componentele grafice de tip list, de fapt

    comboBoxurile corespunztoare tagurilor selectOneMenu n cazul formularului pentru conturi, trebuie subliniate anumite specificaii:

    elementul curent selectat n list corespunde proprietii value a tag-

    ului selectMenu: acest lucru nseamn c valoarea care va rezulta din evaluarea expresiei consemnate prin limbajul specific de binding (JSF-EL Binding), mai precis valoarea proprietii cont (accesibil prin invocarea operaiei getCont) a formularului n cazul cboConturi,

  • Dezvoltarea aplicaiilor cu interfa grafic 65

    va determina elementul curent selectat, iar modificarea, n mod interactiv, de ctre utilizatorul final, a elementului curent, va modifica valoarea proprietii respective (se invoc operaia setCont);

    lista de elemente selectabile este specificat prin intermediul tagului

    selectItems, i va proveni din sursa de date specificat prin proprietatea value a acestuia. n cazul componentei cboConturi este vorba despre colecia desemnat prin proprietatea conturi a formularului. Elementele care sunt furnizate de sursa de date pot fi iruri simple de caractere sau pot fi perechi etichet-obiect POJO, unde eticheta va desemna un ir de caractere care va reprezenta grafic obiectul POJO n lista vizual.

    Navigabilitatea Dup cum s-a precizat deja, prima linie din panoul principal al

    formularului, deci imediat sub antet, va conine componentele grafice necesare aciunilor de cutare-selecie-navigare. Regsim n aceast zon, pe de o parte, comboBox-ul cboConturi i, pe de alt parte, un panou cu dou butoane de comand Next i Previos.

    De asemenea, tot ntr-unul din paragrafele precedente, a fost specificat

    deja modul cu