Dezvoltarea Unei Aplicatii de Banking Folosind Limbajul Java
=== Dezvoltarea unei aplicatii de banking folosind limbajul Java ===
FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT “IOAN SLAVICI” TIMIȘOARA
UNIVERSITATEA “IOAN SLAVICI” TIMIȘOARA
FACULTATEA DE INGINERIE
DOMENIUL CALCULATOARE ȘI TEHNOLOGIA INFORMAȚIEI
FORMA DE ÎNVĂȚĂMÂNT – ZI
PROIECT DE DIPLOMĂ
CONDUCĂTOR ȘTIINȚIFIC
prof.dr.ing. Vladuțiu Mircea
ABSOLVENT
SĂVESCU DANIEL
– 2016 –
FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT “IOAN SLAVICI” TIMIȘOARA
UNIVERSITATEA “IOAN SLAVICI” TIMIȘOARA
FACULTATEA DE INGINERIE
DOMENIUL CALCULATOARE ȘI TEHNOLOGIA INFORMAȚIEI
FORMA DE ÎNVĂȚĂMÂNT – ZI
Dezvoltarea unei aplicații de banking folosind limbajul Java
CONDUCĂTOR ȘTIINȚIFIC
prof.dr.ing. Vladuțiu Mircea
ABSOLVENT
SĂVESCU DANIEL
2016
UNIVERSITATEA DIN ORADEA
FACULTATEA de Inginerie Electrică și Tehnologia Informației
DEPARTAMENTUL Calculatoare și tehnologia informației
TEMA _________________
Lucrare de Finalizare a studiilor a studentului: Săvescu Daniel
1). Tema lucrării de finalizare a studiilor: Dezvoltarea unei aplicații de banking folosind limbajul Java
2). Termenul pentru predarea lucrării: 07.06.2016
3). Elemente inițiale pentru elaborarea lucrării de finalizare a studiilor: Documentația aferentă aplicațiilor de internet banking.
4). Conținutul lucrării de finalizare a studiilor: Tratarea succintă a noțiunilor teoretice legate de internet banking.Prezentarea în detaliu a aplicației dezvoltate, precum și a rezultatelor experimentale.
5). Material grafic: Ordinograme și reprezentari grafice corespunzatoare rezultatelor experimentale.
6). Locul de documentare pentru elaborarea lucrării: Biblioteca Universității Politehnica Timișoara și Biblioteca Universității de Vest Timisoara
7). Data emiterii temei: 20.10.2015
Coordonatori științifici
prof.dr.ing. Vladuțiu Mircea
REFERAT
PRIVIND LUCRAREA DE LICENȚĂ
A
ABSOLVENTULUI: Săvescu Daniel
DOMENIUL Calculatoare și tehnologia informației
SPECIALIZAREA Tehnologia informației
PROMOȚIA 2016
Titlul lucrării: Dezvoltarea unei aplicatii de banking folosind limbajul Java
Structura lucrării: Introducere
Elemente de factură teoretică utilizate la dezvoltarea aplicației
Șabloane de proiectare
Implementarea aplicației
Bibliografie
Anexe
Aprecieri asupra conținutului lucrării de LICENȚĂ (finalizare a studiilor), mod de abordare, complexitate, actualitate, deficiențe:
Lucrarea conține o parte aplicativă deosebit de consistentă implicând soluții cu caracter de originalitate .Autorul tratează în mod corect elemente teoretice esențiale inserandu-le în lucrare doar în măsura în care contribuie la ințelegerea părții aplicative.
Lucrarea tratează o problematică de strictă actualitate luând în considerație importanța domeniului aplicațiilor de internet banking.
Structura lucrării aparține absolvetului, aceasta alocand o pondere de 25% elementelor fundamentării teoretice, restul fiind atribuit dezvoltării aplicației.Cele două parți de esență ale lucrării sunt flancate de succinte capitole introductive și de concluzii, precum și de bibliografie.
Aprecieri asupra lucrării (se va menționa: numărul titlurilor bibliografice consultate, frecvența notelor de subsol, calitatea și diversitatea surselor consultate; modul în care absolventul a prelucrat informațiile din surse teoretice):
Sursele bilbliografice sunt alese in mod corespuzator.
Considerăm tematica dată spre rezolvare ca fiind integral soluționată.
Materialul grafic este executat in mod îngrijit, fiind complementar părții redactate.
(se va menționa: opțional locul de documentare și modul în care absolventul a realizat cercetarea menționându-se contribuția autorului):
Informațiile preluate din surse teoretice sunt citate în mod corespunzator fiind inserate în lucrare doar pe masură ce sunt utilizate pentru înlesnirea urmăriri părții aplicative.
Concluzii (coordonatorul lucrării trebuie să aprecieze valoarea lucrării întocmite, relevanța studiului întreprins, competențele absolventului, rigurozitatea pe parcursul elaborării lucrării, consecvența și seriozitatea de care a dat dovadă absolventul pe parcurs):
In baza celor mai sus menționate, lucrarea elaborată de absolvent este valoroasă, fiind bazată pe un amplu studiu de literatură specializată, absolventul dovedind reale competențe în domeniul aplicațiilor de banking.
Redactarea lucrării respect întocmai cerințele academice de redactare (părți, capitole, subcapitole, note de subsol și bibliografie).
Consider că lucrarea îndeplinește/ nu îndeplinește condițiile pentru susținere în sesiunea de Examen de LICENȚĂ (finalizare a studiilor) din IULIE 2016 și propun acordarea notei ………………
Oradea,
Data
20.06.2016 Conducător științific
prof.dr.ing.Vladuțiu Mircea
Cuprins
Pagina
Capitolul I Introducere…………………………………………………..7
Contextul……………………………………………………………7
Structura lucrării…………………………………………………….7
Capitolul II Elemente de factură teoretică utilizate la
dezvoltarea aplicației…………………………………………………….8
2.1 Variabile…………………………………………………………….8
2.2 Domeniul de aplicare și durata de execuție a unei variabile……….8
2.3 Clase…………………………………………………………………9
2.4 Metode……………………………………………………………….9
2.5 Încapuslarea…………………………………………………………10
2.6 Moștenirea…………………………………………………………..10
2.7 Componenta Swing…………………………………………………11
2.8 Java Fundation Classes……………………………………………….12
2.9 Ierarhia Clasei Swing…………………………………………………12
Capitolul III Șabloane de proiectare …………………………………….16
3.1 Structura unui șablon de proiectare…………………………………17
3.2 Descrierea șabloanelor de proiectare………………………………..17
3.3 Organizarea șabloanelor de proiectare ……………………………..20
3.4 Rezolvarea problemelor de design…………………………………..21
3.5 Arhitectura Model View Controller…………………………………26
Capitolul IV Implementarea aplicației…………………………………..29
Concluzii………………………………………………………………….41
Bibliografie……………………………………………………………….42
Anexe……………………………………………………………………..43
1.Introducere
Contextul
Lucrarea de diplomă are în vedere studierea metodelor în construcția unei aplicații de banking folosind limbajul de programare Java. Vor fi discutate metodele de implementare cum ar fi clasele, obiectele, interfețele cu utilizatorul și nu în ultimul rând șabloanele de proiectare pentru realizarea acesteia.
Încă de la începuturile calculatoarelor, acestea au fost programate fără ajutorul limbajelor de programare, acestea fiind programate doar folosind limbajul mașină. Limbajele de mașina absolute am fost denumite mai târziu “limbaje de programare de primă generație”.
Urmatorul pas către dezvoltarea limbajelor de programare a fost construția limbajelor de asamblare. Acestea au fost mai ușor de utilizat de către programatori, ținând cont că ele erau mai strans legate de arhitectura seturilor de instrucțiuni a mașinii respective. La inceputul anilor 1950 au fost create primele limbaje de nivel înalt. Aceste limbaje sunt mai ușor de folosit pentru programatori deoarece sintaxa lor este mai apropiată de termeni umani de întelegere.
Ca o concluzie, un limbaj de programare este un limbaj formal construit pentru a specifica instrucțiuni unei mașini (calculator). Limbajele de programare sunt folosite pentru a crea programe, pentru a controla comportamenul unei mașini sau pentru a exprima algoritmi. Descrierea unui limbaj de programare este împărțită în două categorii, una este sintaxa (forma) , iar cealaltă este semantica (sensul).
Programarea orientată pe obiecte este o paradigmă de programare care se bazează pe “obiecte”. Aceste obiecte conțin date,ele sunt stocate sub forma de field-uri, adesea cunoscute și sub forma de atribute, și comportamentul obiectelor, adesea cunoscut și sub forma de metode. În majoritatea programelor construite cu acest tip de limbaje de programare, obiectele interacționează între ele. Există o mare diversitate de limbaje de programare orientate pe obiecte, dar cele mai populare sunt cele care se bazează pe clase, acest lucru însemnând că, obiectele sunt instanțele claselor.
1.2 Structura lucrării
Structura lucrării de diplomă este împărțită pe patru capitole legate între ele pe baza conceptelor folosite care se regasesc atât în partea teoretică dar și în partea practică a lucrării. În capitolul al doilea denumint “Elemente de factură teoretică utilizate la dezvoltarea aplicației” am tratat elementele generale legate de limbajul de programare, unele dintre elemente constând în descrierea variabilelor, domeniul de aplicare a acestora și durata lor de execuție, s-au mai explicat și principile de moștenire de încapsulare a datelor și nu în ultimul rând am dezbatut și folosirea claselor. Tot in acest capitol s-a discutat și despre interfețele cu utilizatorul unde s-a realizat o descriere a acestora.
În continuarea lucrării de diplomă, mai exact în capitoul trei denumit “Șabloane de proiectare” s-a abordat tema folosirii șabloanelor de proiectare în aplicațiile software acestea ușurând munca programatorilor și s-a facut cate o descriere pentru fiecare șablon in parte.
În finalul lucrarii de diplomă s-a tratat capitoul de “Implementarea aplicației”, acesta cuprinzand pas cu pas fiecare instrucțiune pentru crearea aplicației de banking pentru acest proiect de diplomă.
7
2. Elemente de factură teoretică utilizate la dezvoltarea aplicației
De la bun început trebuie precizat un lucru: învățarea unui limbaj de programare deschide nenumărate oportunități și în același timp există nenumărate beneficii. Există multe limbaje de programare din care să alegem, deși nu există nici o competiție între ele. Fiecare limbaj de programare a fost creat pentru un motiv specific, și prin evoluția lor au contribuit la avansul tehnologic al zilelor noastre.
Comparându-le între ele, fiecare limbaj are punctele lui slabe, dar si puncte forte. În opinia mea un limbaj bun de programare care merită învățat este Java. Singura propoziție care îl poate descrie cel mai bine este: “Java este un limbaj matur.” .Am spus asta deoarece există anumite motive. Există multe informații legate de Java,datorită faptului că există de mult timp,aproape orice întrebare pe care ne-o putem imagina legată în legatură cu limbajul i s-a găsit un raspuns pe Internet. Folosind un motor de căutare putem găsi diferite coduri sursă, care dezbat mai multe probleme. Java are o sursă bogată de API-uri (Application Programming Interface) și are un suport incredibil de open-source. Există o sumedenie de unelte de programare pentru absolut orice dorim să construim. Pe langă acest lucru mai există și o largă comunitate de programatori dispuși să vină în ajutorul unui începător sau chiar în chestiuni mai avansate. Java este un limbaj de programare orientat pe obiecte.El cuprinde în interior cele mai bune practici de proiectare pe obiecte și sugerează puternic că trebuie învațate și urmate. De asemenea promovează puternic utilizarea corectă a documentației despre design patterne (sabloane de proiectare). Înțelegerea sabloanelor de proiectare poate duce la un cod mult mai bine întreținut. Compilatoarele de Java sunt extrem de bine proiectate. Datorită faptului că Java este un limbaj puternic tipizat, nu doar vă vor fi notificate erorile dar, pot apărarea sugesti pentru reformarea și reformatarea codului cu explicații clare și extrem de înteles. Înca un lucru ce îl putem spune este trecerea ușoră de la Java la programarea pentru dispozitivele ce conțin Adroid, deoarece toate aplicațiile pentru Adroid sunt dezvoltate folosind Java. Pentru începatori învățarea acestui limbaj pare a fi puțin descurajantă. Odată învățate noțiunile de bază ale limbajului, se poate trece cu ușurință la învățarea subiectelor mai avansate deoarece codul este foarte explicit, plus că există o sursă imensă de cursuri, care, cu ușurință vă pot iniția în acest limbaj puternic. [1]
2.1 Variabile
Variabila este unitatea de bază pentru stocare într-un program Java. O variabilă este definită prin combinația unui identificator, un tip și o inițializare optională. În Java toate variabilele trebuie declarare înainte de a fi folosite. Forma de bază în declararea unei variabile este arată mai jos :
tip identificator = valoare.
Tipul unei variabile poate să difere, deoarece în Java există opt tipuri de date primitive, ele sunt : byte, short, int, long, float, double, boolean și char. Identificatorul este numele variabilei. Pentru a inițializa o variabilă trebuie să adăugăm semnul egal (“=“) și apoi să îi atribuim o valoare. De reținut este faptul că valoarea variabilei trebuie să corespundă cu tipului acesteia. [2]
2.2 Domeniul de aplicare și durata de execuție a unei variabile
[2] Java permite variabilelor să fie declarate în cadrul oricărui bloc.Un bloc începe cu o acoladă de deschidere și se închide tot cu o acoladă de închidere. Un bloc definește un domeniu de aplicare.
8
Astfel,de fiecare dată când începem un bloc nou, se crează un nou domeniu de aplicare.Un domeniu de aplicare determină ce obiecte sunt vizibile pentru alte părți ale programului. De asemenea, acesta determină, durata de execuție a acestor obiecte. Multe alte limbaje de programare, definesc două categorii de, domenii de aplicare : locale și globale. Cu toate acestea, aceste domenii tradiționale nu se protrivesc bine cu modelul Java strict orientat pe obiecte. În Java cele două domenii majore sunt cele definite de o clasă și cele definite de o metodă. Chiar și această distincție este oarecum artificială. Domeniul de aplicare definit la o metodă începe cu deschiderea unei acolade și se termină cu închiderea ei tot prin intermediul unei acolade. Cu toate acestea,în cazul în care metoda are parametrii și ei sunt incluși în domeniul de aplicare a metodei.
Ca regulă generală, variabilele declarate în interiorul unui domeniu de aplicare nu sunt vizibile (adică accesibile) pentru codul care este definit în afara acestui domeniu de aplicare. Astfel, atunci când declarați o variabilă într-un domeniu de aplicare,vă localizați acea variabilă și o protejați de acces sau modificări neautorizate. Într-adevăr, regulile domeniului de aplicare oferă fundamenul pentru încapsulare.
2.3 Clase
[2] Clasele stau la baza programării in Java. Este construcția logică pe care este construit tot limbajul Java, deoarece clasele definesc forma și natura unui obiect. Orice concept pe care doriți să îl impuneți în aplicare într-un program Java, trebuie să fie încapsulat într-o clasă. Poate cel mai important lucru de ințeles despre clase este că ele definesc un nou tip de date. Odată definită o clasă, acest nou tip poate fi folosit pentru a crea obiecte de acest tip.Astfel, o clasă este un șablon pentru un obiect, iar un obiect este o instanță a unei clase. Pentru că un obiect este o instanță a unei clase, veți vedea de multe ori două cuvinte: obiect și instanță, utilizate interschimbabil. Atunci când definiți o clasă, declarați forma exactă și natura ei. Puteți face acest lucru prin specificarea datelor pe care le conține și codul care functionează pe datele respective. În timp ce clasele mai simpliste conțin doar cod sau numai date, clasele de nivel mai complex le conțin pe amândouă.Datele sau variabilele, definite în cadrul unei clase sunt numite variabile de instanță. Codul ce conține comportamenul unei clase se numește metodă. În mod colectiv, metodele și variabilele definite într-o clasă sunt numite membri ai clasei. În cele mai multe clase, variabilele de instanță sunt prelucrate cu ajutorul metodelor. Variabilele definite în cadrul unei clase sunt numite variabile de instanță, pentru că fiecare instanță a clasei (adică, fiecare obiect al clasei) conține propria copie a acestor variabile. Astfel, datele pentru un singur obiect sunt unice și separate.
2.4 Metode
Clasele de obicei sunt formate din două lucruri: variabile de instanță și metode. Forma generală a unei metode este următoarea :
Tipul Numele(lista parametrii){
//corpul metodei
}
[2] Aici, tipul specifică tipul de date returnat de metodă. Acesta poate fi orice tip valid, inclusiv tipurile de clasă pe care le creați. Dacă metoda nu returnează nici o valoare atunci tipul este “void”. Numele metodei poate fi orice identificator legal, care nu include un cuvânt rezervat în Java, și nu poate conține numele altor elemente din cadrul domeniului de aplicare curentă. Parametrii sunt, in esență variabile care primesc valoarea argumentelor, atunci când o metodă este apelată. Dacă o metodă nu are parametrii, atunci lista de parametrii trebuie să fie goală.
9
Metodele care au un tipul de returnare,altul în afară de “void”, returnează o valoare la rutina de așteptare folosind următoarea formă :
return valore;
Aici valoare, este valoarea returnată.
2.5 Încapsularea
[2] Întreaga idee din spatele încapsulării este de a ascunde detaliile de implementare față de utilizatori. În cazul în care un membru de date este privat, înseamnă că poate fi accesat numai în cadrul aceleași clase. Nici o altă clasă din exterior nu poate avea acces la datele private (variabile) a unei alte clase. Pentru a avea acces la datele private ale unei clasa va trebui să declarăm metodele publice de “set()” și get()”.Metoda “set()” are rolul de a inițializa variabilele private dintr-o clasă, iar metoda “get()” returnează valoarea variabilei private.De accea încapsularea se mai numește și ascundere de date. Încapsularea are următoarele avantaje : datele nu mai sunt separate de prelucrări, obiectele apar ca niste cutii negre care ascund detaliile de implementare, asigură securitatea datelor stocate de un obiect împotriva modificarilor neautorizati sau accidentali.
2.6 Moștenirea
[2] Moștenirea este una dintre pietrele de temelie a programării orientate pe obiecte deoarece permite crearea unor clasificări ierarhice.Cu ajutorul moștenirii, se poate crea o clasă generală care definește trasături comune la un set de elemente similare. Această clasă generală poate fi moștenită și de alte clase, mai specific, fiecare la rândul ei adăugând elemente noi. În terminologia Java, o clasă care este moștenită se numește superclasa. Clasa care o moștenește se numește subclasă. Prin urmare, o subclasă este o versiune specializată a unei superclase. Ea moștenește toate variabilele de instanță și metodele, la rândul său adăugând elemente unice.
Figura 1 : Moștenire single level
O subclasă nu poate moșteni variabilele de instanță private ale unei superclase. Limbajul Java nu suportă moștenirea multiplă, doar cea multilevel. În cazul moștenirii se mai pot folosi și termeni precum clasă de bază și clasă derivată, așa cum se prezintă și în figura de mai sus.
10
Un alt lucru important în moștenire, este suprascrierea metodelor, acest lucru însemnând că putem avea două metode cu același nume și aceași listă de parametrii, dar în subclasă una
dintre metode să se comporte diferit, față de metoda din superclasă, chiar dacă ambele metode sunt la fel.
Figura 2 : Suprascrierea metodelor
Figura 3 : Moștenire multilevel
2.7 Componenta Swing
[3] Swing este următoarea generație de seturi de instrumente GUI (Graphic User Interface) care Sun Microsystems le-a creat pentru a permite dezvoltarea de noi aplicații enterprise.
11
Programatorii pot folosi Swing-ul pentru dezvoltarea de aplicații de scară largă cu o gamă largă de componente puternice. În plus, se pot extinde cu ușurință sau se pot modifica aceste componente pentru a controla aspectul și comportamentul lor. Swing nu este un acronim. Numele reprezintă alegerea de colaborare a designerilor săi, atunci când proiectul a fost demarat la sfarșitul anului 1996. Swing face parte dintr-o familie mai mare de produse Java, cunoscute sub numele de Java Fundation Classes (JFC) .
2.8 Java Fundation Classes (JFC)
[3] Java Fundation Classes (JFC) este o suită de biblioteci concepute pentru a sprinjini programatorii în crearea de aplicații enterprise în Java. Swing API-ul (Application Programming Interface) este doar una dintre cele cinci biblioteci care alcătuiesc JFC.De asemenea JFC-ul este format și din Abstract Window Toolkit (AWT), Accessibility API, 2D API, și suportul îmbunătățit pentru capabilitațile de Drag and Drop.
Figura 4 : Cele cinci API-uri ale JFC
2.9 Ierarhia Clasei Swing
[3] La prima vedere, ierarhia clasei arată foarte similar cu cea a AWT-ului.Fiecare componentă Swing cu un AWT echivalent, împart același nume, cu excepția faptului că, clasă Swing este precedată de majuscula “J”.
Figura 5 : Ierarhia componentelor Swing
12
Cu toate acestea, la o examinare mai atentă, veți descoperi că există diferențe între componentele Swing si cele AWT. De exemplu, componentele de meniu, inclusiv JMenuBar acum sunt deșcendente a aceeași component de bază ca și celălalte : JComponent. Această este o schimbare din vechile clase de meniu AWT.De asemenea, Swing a reproiectat ierarhia butoanelor. Aceasta include o clasă “JToggleButton” folosită în dublă stare a componentelor.
Posibil de observat, există și o creștere a numărului de cadre (frames) și a panourilor (panes) în Swing. Un exemplu de luat în considerare sunt cadrele interne (internal frames).Swing suportă plasarea de cadre în interiorul altor cadre. Acest lucru este denumit în mod obișnuit ca o interfață de, documentație multiplă (MDI) .
Clasa JComponent
[3] JComponent este o clasă abstractă pe care majoritatea componentelor Swing o moștenesc.La fel cum și clasa java.awt.Component servește ghidarea framework-urilor a componentelor AWT, la fel și clasa JComponent servește același rol pentru componentele Swing. Trebuie spus că, clasă JComponent moștenește clasa java.awt.Container putem spune că, componentele Swing au o mare funcționalitate precum cele AWT. Deoarece clasa JComponent moștenește clasa Container, multe componente Swing pot servi drept containere pentru componentele AWT și Swing. Aceste componente pot fi adăugate utilizând metoda add(), metodă care se află în clasa Container.
Clasa JFrame
[3] Cel mai frecvent container Swing folosit pentru aplicații in Java este clasa JFrame. Clasa JFrame asigură o fereastră de titlu, marginile frame-ului, precum și butoanele de minimizare, maximizare și butonul de închidere al ferestrei. Pentru amplasare JFrame-ului trebuie apelată metoda getContentPane().add().
Clasa JWindow
.[3] JWindow este o extensie a clasei java.awt.Window, care folosește clasa JRootPane ca singura componentă. Pe lângă toate aceste distincții JWindow nu schimbă nimic ce este deja definit în clasa Window. În AWT, cel mai frecvent motiv pentru folosirea clasei Window, este crearea meniurilor pop-up. Fiindcă Swing oferă o clasă specială pentru meniurile pop-up, aceasta numindu-se JPopupMenu, nu este necesară moștenirea clasei JWindow pentru acest motiv. Singurul scop pentru folosirea clasei JWindow este acela când trebuie să afișăm ceva în propria fereastră fară a apela la folosirea clasei JFrame.
Clasa JApplet
JApplet este o extensie simplă a clasei java.applet. Applet este utilizată la crearea programelor Swing concepute pentru a fi utilizate într-un web browser. [3] Ca o subclasă directă a Applet, clasa JApplet este folosită în același fel cu metodele init(), start() și stop() care joacă un rol foarte important. Principalul lucru pe care JApplet îl prevede este că, clasa Applet nu folosește clasa JRootPane ca și singura componentă de afișare.
Clasa JDialog
JDialog este versiunea Swing de superclasă a java.awt.Dialog.[3] Clasa JDialog folosește clasa JRootPane ca și recipient și asigură comportamentul standard pentru închiderea ferestrelor.
13
Figura 6 : Ierarhia clasei JDialog
Clasa JComboBox
JComboBox, combină un buton sau un câmp editabil și nu în ultimul rând o listă drop-down. Această clasă este una foarte similară cu, componenta AWT Choice la rândul ei implementând interfața ItemSelectable pentru compatibilitate. În mod regulat, componenta JComboBox oferă un singur câmp de editare text, această componentă mai incluzând și un buton cu o săgeată în jos. Atunci când butonul este apăsat va apărea o listă de selecție unde utilizatorul are dreptul să aleagă.[3] Dacă se va face o selecție atunci, alegerea este copiată în câmpul textului editabil, iar fereastra curentă se va închide automat. Câmpul de text din componenta JComboBox poate fi editabil sau needitabil. Această stare este controlată de proprietatea de editare. Dacă câmpul de text este editabil atunci utilizatorul poate introduce informații în caseta de text, precum și posibilitatea de a face selecții din listă. Dacă componenta este needitabilă, utilizatorul poate face doar selecții din listă. Pentru a adăuga elemente noi în lista de selecție,se va folosi metoda addItem(), în sens contrar pentru ștergerea de elemente din listă se vor folosi metodele removeItem() și removeItemAt(). De asemenea se pot adăuga elemente la o anumită poziție în lista de selecție folosind metoda insertItemAt(), iar pentru returnarea numărului total de elemente din listă se va folosi metoda getItemCount().
Clasa JLabel
Swing permite crearea de etichete care pot include text, imagini sau ambele. [3] Clasa JLabel permite adăugarea de etichete standard neinteractive pentru interfața cu utilizatorul, iar această clasă este una foarte similară cu, clasa java.awt.Label.
Figura 7 : Diagrama clasei JLabel
14
Clasa JMenuBar
Clasa JMenuBar înlocuiește clasa AWT MenuBar. Această clasă crează pe orizontală o bară de meniu, care poate cuprinde între zero sau mai multe meniuri ce se pot atașa la această componentă. [3] JMenuBar folosește DefaultSingleSelectionModel, ca și model de date deoarece utilizatorul poate activa doar unul dintre meniurile sale. Odată ce, cursorul mouse-ului părăsește meniul, aceasta dispare în mod automat de pe ecran.
Figura 8 : Diagrama clasei JMenuBar
Pentru adaugărea de obiecte în meniu se va folosi metoda add(). Clasa JMenuBar, atribuie un index fiecărui obiect adăugat în bara de meniu. Bara de meniuri afișează meniurile de la stânga la dreapta, respectând ordinea indexurilor atribuite.
Clasa JTable
Luând în considerare tabelele în Swing, unitatea lor de bază nu este o celulă individuală, ci o coloană. În cazurile din lumea reală, cele mai multe coloane ale tabelelor reprezintă un anumit tip de informație care este consecventă pentru toate înregistrările. De exemplu ,numele unei persoane, poate fi un șir de caractere (String) acesta fiind poziționat ca prima coloană a tabelului. Pentru oricare alt rând, prima celulă este întotdeauna un șir de caractere. În cazul coloanelor, nu este obligatoriu ca acestea să aibă același tip de date. Coloanele mai pot conține și valori booleane, nu numai șiruri de caractere. [3] Deoarece tabelul are capacitatea de a stoca diferite tipuri de date, acest lucru afectează și modul în care tabelul plasează datele. Din cauză că, clasa JTable este într-o continuă evoluție s-ar putea găsi alte modalități pentru care tabelul să nu se bazeze atât de mult pe coloane. Această clasă oferă controlul asupra aspectului și comportamentul tabelului. Se poate modifica distanța dintre coloane, redimensionarea coloanelor, culoarea lor, etc. Prin modul de, delagare se pot adăuga sau șterge rânduri și coloane folosind direct obiectul JTable.
15
Figura 9 : Diagrama clasei JTable
3. Șabloane de proiectare
În ingineria software, un șablon de proiectare (design pattern) software este o soluție reutilizabilă generală a unei probleme care apare frecvent într-un anumit context în proiectarea de software. Șabloanele de proiectare sunt strategii independente de limbaj care sunt folosite pentru rezolvarea problemelor comune pentru proiectele care folosesc programarea orientată pe obiecte. Atunci cand se face un șablon de proiectare, ar trebuii știute numele unor soluții comune. Șabloanele de proiectare orientate pe obiecte arată în mod tipic relații și interacțiuni între clase sau obiecte, fară a se specifica claselor de aplicații finale sau obiectele care sunt implicate. Șabloanele de proiectare pot fi privite ca o abordare structurată folosite în programarea calculatoarelor intermediare între nivelurile unui paradigm de programare și un algoritm concret.[4]
În general, un șablon are patru elemente generale:
1.Numele șablonului, este o întrebuințare care se folosește pentru a descrie o problemă de proiectare, soluția ei dar și consecințele. Atribuirea unui nume șablonului, influențează prin creșterea vocabularului de, design. El ne va permite să proiectăm la un nivel mai înalt de abstractizare. Având un vocabular pentru șabloane, acesta ne va perminte să vorbim cu ușurință despre ele cu, colegii, în documentația noastră și chiar cu noi înșine. Căutarea de nume potrivite, este cea mai grea parte pentru dezvoltarea de cataloage.
2.Problema, descrie când trebuie aplicat șablonul. Ea explică problema și contextual ei. Ea poate descrie probleme specifice de modelare cum ar fi reprezentarea algoritmilor ca obiecte. Uneori problema va include o listă de condiții care trebuie să fie îndeplinite înainte să capete sens pentru aplicarea șablonului.
16
3.Solutia, descrie elementele care formează modelul, responsabilitățile, relațiile și colaborările. Soluția nu descrie un model concret sau punerea acestuia în aplicare, deoarece un model este ca un șablon care poate fi aplicat în mai multe situații diferite. Astfel, șablonul furnizează o descriere abstractă a unui model de problemă și cum un aranjament general de elemente ce le poate rezolva.
4.Consecințele, sunt rezultatul a unui schimb de aplicări a șabloanelor.Cu toate că, consecințele sunt adesea neexprimate când sunt descrise decizile de modelare, acestea sunt critice pentru evaluarea alternativelor de proiectare și pentru întelegerea costurilor și beneficiilor în aplicarea șabloanelor. Consecințele pentru software adeseori se referă la îngrijorarea pentru spațiul și timpul comerțurilor. Ele pot aborda probleme de limbaj precum și de punere în aplicare.
Un șablon de proiectare numește, abstractizează și identifică aspectele cheie a unei structuri de modelare comune care le face utile pentru crearea unui design reutilizabil strict orientat pe obiecte. Un șablon de proiectare identifică clasele participante și cazurile, rolurile lor, colaborările precum și distribuirea responsabilităților. Fiecare șablon de proiectare se axează pe o anumită problemă de modelare orientată pe obiecte precum și pe alte probleme.
3.1 Structura unui șablon de proiectare
Șabloanele de proiectare sunt compuse din mai multe secțiuni. De un interes deosebit sunt următoarele secțiuni: Structure (Structura), Participants (Participanti) și Collaboration (Colaborare). Aceste secțiuni descriu un prototip micro-arhitectural pe care dezvoltatorii de aplicații le copiază și le adaptează la design-urile, lor special pentru a rezolva problemele curente descries de modelele de design. O micro-arhitectură este un set de elemente constructive si relațiile lor. Dezvoltatorii de aplicații folosesc șabloanele de proiectare prin introducerea lor în prototipul de micro-arhitectură, ceea ce înseamnă că micro-arhitecturile au o structură și o organizare similară cu șablon de proiectare ales.
3.2 Descrierea șabloanelor de proiectare
Șabloanele de proiectare, pur și simplu includ produsul final al unui proces de design și nu în ultimul rând includ și relațiile dintre clase și obiecte. Pentru a putea reutiliza șabloanele trebuie înregistrate decizile, alternativele și nu în ultimul rând schimburile de informații care au adus la refolosirea lor. Exemplele concrete sunt importante, deoarece ele permit a vedea funcționabilitatea șabloanelor.[4]
Putem descrie șabloanele de proiectare folosind un format consistent. Fiecare șablon este împarțit pe secțiuni, făcându-le mai ușor de învațat, de comparat și de folosit. În total există douăzeci și trei de șabloane de proiectare, numele lor și o scurtă descriere a fiecăruia se afla în lista ce urmează :[4]
Abstract Factory :
Oferă o interfață pentru crearea de legături legate sau dependente de obiecte fară a specifica clasele lor concrete.
Adapter :
Convertește interfața unei clase în altă interfață pe care, clientul o dorește. Tot acest tip de șablon permite claselor să lucreze împreună care nu puteau altfel, din cauza unor interfețe incompatibile.
17
Bridge :
Disociază o abstracție de la implementarea acesteia, astfel încât cele două pot varia în mod independent.
Builder :
Separă construirea unui obiect complex de reprezentarea sa, astfel încat același proces de construcție poate crea diferite reprezentări.
Chain of Responsibility :
Evită cuplarea expeditorului a unei cereri către receptor prin faptul oferirii mai mult decât un obiect oferindu-i o șansă de a gestiona solicitarea. Se înlănțuiesc obiectele primite și se transmite cererea de-a lungul înlănțuirii până când obiectul se poate manipula.
Command :
Încapsuleaza o cerere ca un obiect permițându-vă astfel parametrizarea clienților, cu diferite cereri și oferind un suport pentru a spirijini diferite operații.
Composite :
Compune obiecte în structuri de arbori pentru a reprezenta o parte întreagă de ierarhii. Tot acest lucru va permite clienților să trateze obiectele individual și formează o compoziție de obiecte uniforme.
Decorator :
Atașează responsabilități suplimentare la un obiect dinamic. Acest tip de șablon mai oferă și o alternativă flexibilă la sublclasare pentru extinderea functionalității.
Facade :
Furnizează o interfață unificată pentru un set de interfețe într-un subsistem. Tot acest șablon definește o interfață de nivel superior, care face subsistemul mai ușor de utilizat.
Factory Method :
Definește o interfață pentru crearea unui obiect, dar lasă ca subclasele să decidă care clasă să o instanțieze.
Flyweight :
Utilizează partajarea pentru a sprijinii un număr mare de obiecte bine definite în mod efficient.
18
Interpreter :
Având în vedere un limbaj, se definește o reprezentare pentru sintaxa lui, împreună cu un interpretor care folosește o reprezentație de a interpreta declarații în acest limbaj.
Iterator :
Oferă o modalitate de a accesa elementele unui obiect agregat secvențial fără a expune reprezentarea sa de bază.
Mediator :
Definește un obiect care încapsulează modul în care un set de obiecte interacționează. Acest șablon promovează cuplajul slab prin păstrarea obiectelor fără a se referi unele la celălalte în mod explicit și permite ca interacțiunea lor să varieze în mod independent.
Memento :
Fără a încălca principiul de încapsulare, acest tip de șablon captează și exteriorizează starea internă a unui obiect, astfel încât obiectul poate fi readus la starea sa actuală mai târziu.
Observer :
Definește una sau mai multe dependențe între obiecte, astfel încâ atunci când un obiect își schimbă starea, toate funcțiile ce depind de el sunt notificate și actualizate automat.
Prototype :
Precizează tipurile de obiecte pentru a fi create folosind o instanță de prototipare și de a crea noi obiecte prin copierea acestui prototip.
Proxy :
Furnizează un substituent pentru un alt obiect, pentru a controla accesul său.
Singleton :
Asigură că o clasă are doar o singură instanță, și se furnizează un punct global de acces pentru aceasta.
State :
Perminte unui obiect să își modifice comportamentul atunci când modificările interne se schimbă. În acest caz obiectul va apărea pentru a își schimba clasa.
Strategy :
Definește o familie de algoritmi, le încapsulează pe fiecare dintre ele și le face interschimbările. Acest șablon permite algoritmului să varieze în mod independent de clienții care îl folosesc.
19
Template Method :
Definește scheletul unui algoritm într-o operație, diferindu-se de unii pași dintr-o subclasă. Lasă subclasele să redefinească anumite etape ale unui algoritm, fără a schimba structura algoritmului.
Visitor :
Reprezintă o operație care trebuie efectuată pe elementele unui obiect structurat. Acest șablon permite să, se definească o nouă operație fără a schimba clasele de elemente pe care se lucrează.
3.3 Organizarea șabloanelor de proiectare
Șabloanele de proiectare variază în granularitate și în nivelul de abstractizare al acestora. Unele șabloane sunt adesea folosite împreună. [4] De exemplu, șablonul Composite este adesea folosit cu Interator sau Visitor. Unele modele sunt alternative: Prototype este adesea o alternativă a șablonului Abstract Factory. Unele șabloane au ca rezultatat modele similare, chiar dacă șabloanele au diferite intenții.De exemplu,diagramele de structură a șabloanelor Composite și Decorator sunt similare.
Figura 10 : Relatiile dintre sabloanele de proiectare
20
3.4 Rezolvarea problemelor de degisn
Șabloanele de proiectare rezolvă multe dintre problemele de zi cu zi, probleme pe care designeri specializați pe, programarea orientată pe obiecte le au de confruntat în multe moduri diferite. Aici găsiți prezentate mai multe dintre aceste probleme și modul în care șabloanele de proiectare sunt folosite pentru rezolvarea lor .[4]
Găsirea obiectelor adecvate
Programele orientate pe obiecte sunt formate din obiecte. Atât pachetele de obiecte cât și pachetele de date și procedurile toate lucrează asupra datelor. Procedurile sunt numite de obicei metode sau operații. Un obiect efectuează o operație atunci când primește o cerere sau un mesaj de la un client.
Cererile sunt singura modalitate pentru a face ca un obiect să execute o operație. Operațiile sunt singura modalitate de a schimba datele interne ale unui obiect. Din cauza acestor restricții, starea interna a obiectelor este încapsulată. Aceasta nu poate fi accesată în mod direct, iar reprezentarea ei este invizibilă din afara obiectului.
[4] Partea cea mai grea despre design-ul orientării pe obiecte este descompunerea unui sistem în obiecte. Această sarcină este dificilă deoarece mulți factori intră în joc: încapsularea, granularitatea, dependența, flexibilitatea, performanța, evoluția, reutilizarea,etc.Ele influentează procesul de, descompunere, de multe ori în moduri conflictuale.
Metodologiile de design ale orientării pe obiecte favorizează multe abordări diferite .Se poate scrie problema unei declarații împarțită în verbe și substantive, apoi se pot crea, clasele corespunzătoare la fel și metodele aferente, sau se poate axa, asupra colaborărilor și responsabilităților din sistem. Vor exista întotdeauna contradicții cu privire la care metodă este mai bună de folosit.
Multe obiecte dintr-un șablon provin din modelul de analiză. Dar de multe ori modelele orientate pe obiecte sfâtșesc ulterior cu, clase care nu corespund cu lumea reală. Unele dintre acestea sunt clase de nivel scăzut cum ar fi matricile. Unele sunt la nivele mult mai mari. De exemplu, șablonul Composite care introduce o abstracție pentru tratarea obiectelor în mod uniform,care nu au un corespondent fizic. Modelarea strictă a lumii reale, conduce la un sistem care să reflecte realitățile de astăzi, dar nu neapărat și de mâine. Abstracțiile care apar în timpul proiectării sunt esențiale pentru a face un design flexibil.
Șabloanele de proiectare ajută la identificarea abstracțiilor mai puțin evidente și obiecte pe care le poate captura. De exemplu, obiectele care reprezintă un proces sau un algoritm nu apar în natura lor, dar acestea sunt o parte esențială a șabloanelor de proiectare flexibile. Șablonul de proiectare Strategy descrie modul în care se pune în aplicare familii interschimbabile de algoritmi. Șablonul State reprezintă fiecare stare a unei entități ca obiect. Aceste obiecte sunt rareori găsite în timpul analizei sau chiar în stadiile de proiectare. Acestea sunt descoperite mai târziu în cursul de a face un design mai flexibil și mai reutilizabil.
Determinarea obiectelor
Obiectele pot varia foarte mult în dimensiune și număr. Ele pot reprezenta inclusiv hardware-ul, până la aplicații întregi. [4] De aici reiese și întrebarea : Cum decidem ce ar trebui sa fie un obiect? Această problemă este abordată la fel și de șabloanele de proiectare. Șablonul Facade descrie cum se pot reprezenta subsisteme complete ca obiecte,șablonul Flyweight descrie modul în care se pot susține un număr mare de obiecte. Alte șabloane de proiectare descriu metode specifice de, descompunere a unui obiect în secțiuni mai mici.
21
Șabloanele: Abstract Factory și Builder conțin obiecte de randament ale căror responsabilități sunt crearea de alte obiecte. Șabloanele Visitor și Command conțin obiecte de randament ale căror responsabilități sunt doar să pună în aplicare o solicitare pe un alt obiect sau grupuri de obiecte.
Specificarea de interfețe pentru obiecte
Fiecare operațiune declarată de un obiect, specifică numele operațiunii, obiectele sunt luate drept parametri, iar aceste operațiuni returnează valori. Acest lucru este cunoscut sub numele de semnătura operațiuni. Setul tuturor semnăturilor definite de operatiunile unui obiect se numește interfața obiectului. Interfața unui obiect caracterizează un set complet de solicitări, care pot fi transmise la obiect. Orice solicitare care se potrivește cu o semnătură în interfața obiectului aceasta poate fi transmisă la un obiect.[4]
Un tip este un nume folosit pentru a desemna o interfață particulară. Un obiect poate avea mai multe tipuri ,iar la o scară mai largă obiectele pot, partaja același tip. O parte a interfeței unui obiect poate fi caracterizată prin un singur tip,iar celălalte părți de alte tipuri.Două obiecte de același tip au nevoie de părți comune ale interfețelor acestora. Interfețele pot conține și alte interfețe ca subseturi.Uneori putem spune de un subtip că moștenește interfața acestuia.
Interfețele sunt fundamentale în sistemele orientate pe obiecte. Obiectele sunt cunoscute doar prin intermediul interfețelor .Nu există nici o altă modalitate de a ști detalii despre un obiect, sau că acesta sa facă o acțiune, fără a trece prin interfața acestuia. Interfața unui obiect nu oferă detalii despre implementarea sa, diferite obiecte sunt libere să implementeze diferite cereri. Asta înseamnă că două obiecte cu implementări diferite pot avea aceași interfață.
Atunci când o cerere este trimisă la un obiect, operațiunea care este efectuată depinde atât de cerere cât și de obiectul de primire. Obiectele diferite care sprijină cereri identice pot avea diferite implementări ale operațiilor care îndeplinesc aceste cereri. Asociată de execuție în timp real a unei cereri de către un obiect și una dintre operațiile sale este cunoscută sub numele de legare dinamică.[4]
Legarea dinamică înseamnă rezolvarea unei cereri care este pusă în aplicare doar în timpul de execuție. În consecință se pot scrie programe care așteaptă un obiect cu o anumită interfață, știind că orice obiect care are o interfață corectă, el va accepta această cerere. Mai mult decât atât, legarea dinamică permite substituirea obiectelor care au interfețe identice pentru fiecare dintre ele doar în timpul de execuție. Această substituire mai este cunoscută și sub numele de polimorfism care este un elemente cheie în programarea orientată pe obiecte. Polimorfismul permite unui obiect client de a face câteva presupuneri despre alte obiecte dincolo de o interfață specială. Polimorfismul simplifică definițiile clienților, decuplează obiectele unele față de celălalte și permite ca relațiile lor să varieze în timpul execuției.
Șabloanele de proiectare ajută la definirea interfețelor prin identificarea elementelor cheie, cât și prin tipurile de date care se transmit peste o interfață. Un șablon de proiectare ar putea de asemenea să spună ceea ce sa nu includă o interfață. Șablonul Memento este un bun exemplu. Acesta descrie modul de a încapsula și de a salva starea internă a unui obiect, astfel încât obiectul poate fi readus la acea stare mai târziu.
Șabloanele de proiectare pot specifica, de asemenea și relațiile dintre interfețe. În mod special ele necesită adesea ca unele clase să aibă interfețe similare, sau să aibă loc constrângeri privind interfețele unor clase. De exemplu, interfața șablonului Visitor trebuie să reflecte toate clasele de obiecte pe care utilizatorii o pot vizita.
Specificarea implementării de obiecte
Punerea în aplicare a unui obiect este definit de clasa sa. Clasa specifică datele interne ale obiectului și definește operațiile pe care obiectul le poate efectua. Orice date definite într-o clasă, se execută la rândul lor în ordinea operațiilor.
22
Tipurile de returnare și variabilele de instanță sunt opționale, din moment ce nu ne asumăm o implementare statică a limbajului de programare. Obiectele sunt create prin instanțarea unei clase. Se mai poate spune că un obiect este o instanță a unei clase. Procesul de instanțiare a unei clase alocă spațiu pentru datele interne ale obiectului și asociază aceste operații cu datele alocate obiectului. De regulă, se pot instanția mai multe obiecte prin instanțierea aceleași clase. Se pot definii noi clase în termenii unei clase existente folosind procesul de moștenire a unei clase. Atunci când o subclasă moștenește datele unei clase parinte, aceasta include defințiile tuturor datelor și operațiunile pe care clasa parinte le are definite. [4] Obiectele care sunt instanțiate dintr-o subclasă vor conține toate datele definite de subclasă și de clasa părinte sau superclasă, aceste obiecte fiind în măsură să efectueze toate operațiile definite în subclasă și în clasa părinte.
O clasă abstractă este una a cărui scop principal este de a defini o interfață comună pentru subclasele sale. Ca regulă principală, o clasă abstractă nu poate fi instanțiată. Operațiile declarate într-o clasă abstractă, dar care nu sunt implementate sunt numite operații abstracte. Clasele care nu sunt abstracte sunt numite clase concrete.
Subclasele pot redefini comportamentul claselor părinte. Mai precis, o subclasă poate suprascrie operațiile din clasa pe care o moștenește. Suprascrierea operațiilor oferă o șansă sublclaselor pentru gestionarea cererilor în locul claselor de tip părinte. Moștenirea claselor permite definirea claselor, prin extinderea altor clase, facandu-le ușor faptul de a definii familii de obiecte care au functionabilități similare. O clasă mixtă este o clasă al cărui scop este de a oferi o interfață opțională sau funcționalitate altor clase. Este similară cu o clasă abstractă care la rândul ei nu poate fi instanțiată.
Clase contra interfețe de moștenire
Este important să înțelegem diferența dintre clasa unui obiect și tipul acesteia. Clasa unui obiect definește modul în care obiectul este implementat. Clasa definește starea internă a obiectului și punerea în aplicare a operaților sale. Tipul unui obiect se referă doar la interfața sa, iar acesta se mai poate referi și la setul de solicitări la care poate să raspundă. Un obiect poate avea mai multe tipuri, și obiectele din clase diferite pot avea același tip.
Desigur, există o relație stransă între clasa unui obiect și tipul acesteia. Deoarece o clasă definește operațiunile pe care un obiect le poate efectua, de asemenea definește tipul obiectului. Când spunem că un obiect este o instanță a unei clase, presupunem că obiectul sprijină interfața definită de clasă.
Este de asemenea important să înțelegem diferența dintre moștenirea unei clase și moștenirea unei interfețe. Moștenirea de clasă definește punerea în aplicare a unui obiect în ceea ce privește implementarea altui obiect. Pe scurt, este un mecanism de partajare de cod și de reprezentare.În al doilea rând, moștenirea de interfață descrie când un obiect poate fi folosit în locul altui obiect. Este foarte ușor de a confunda aceste două concepte,deoarece multe limbaje de programare nu fac această distincție explicită. Deși cele mai multe limbaj de programare,nu oferă suport pentru distincția între interfață și implementarea moștenirii,programatorii fac distincția în practică.
[4] Multe dintre șabloanele de proiectare depind, de această distincție.De exemplu, obiectele din șablonul de proiectare Chain of Responsibility trebuie să aibă un tip comun,dar deobicei nu împărtășesc o implementare comună. În șablonul Composite,Component definește o interfață comună. Șabloanele Command, Observer, State și Strategy sunt adesea puse în aplicare folosind clase abstracte, care sunt interfețe pure.
Programarea unei interfețe
Moștenirea claselor este practic un mecanism de extindere a functionabilității unei aplicații prin reutilizarea unor functionalități din clasa parinte.
23
Aceasta va permite să definiți un nou obiect în ceea ce privește înlocuirea unuia vechi. Aceasta va permite să obțineți noi implementări, moștenind ceea ce este necesar din clasele deja existente. Abilitatea moștenirii de a definii familii de obiecte, este de asemenea importantă, deoarece polimorfismul depinde de ea.
Atunci când moștenirea este folosită cu atenție, toate clasele derivate dintr-o clasă abstractă vor împărtășii aceași interfață. Acest lucru implică faptul că o subclasă pur și simplu adaugă sau suprascrie operațiile, dar nu ascunde operațiile clasei părinte. Toate subclasele pot raspunde la solicitările din interfața clasei abstracte, ceea ce le face pe toate subtipurile clasei abstracte.
Există două avantaje pentru manipularea obiectelor din punct de vedere al interfeței definite prin clase abstracte :
1.Clienții rămân conștienți de anumite tipuri de obiecte pe care le folosesc,atâta timp cât obiectele să adere la interfața pe care, clienții o așteaptă.
2.Clienții rămân conștienți de clasele, care implementează aceste obiecte.Clienții știu doar despre clasa(clasele) abstracte care definesc interfața.
A nu se declara variabile care să fie instanțe ale claselor concrete. În schimb, se pot folosi la definirea unei interfețe printr-o clasă abstractă. Trebuie instanțiate clase concrete undeva în sistem, desigur șabloanele: Abstract Factory, Builder, Factory Method, Prototype și Singleton vă permit să faceți acest lucru. Prin abstractizarea procesului de creare a unui obiect, aceste șabloane oferă modalități diferite de a asocia o interfață prin punerea sa în aplicare în mod transparent la instanțiere. Șaboanele asigură ca sistemul să fie scris în termeni de interfețe și nu de implementări.
Moștenirea contra procesului de compozitie
Cele două tehnici comune pentru reutilizarea funcționabilității în sistemele orientate pe obiecte sunt moștenirea claselor și compoziția obiectelor. Așa cum a mai fost explicat, moștenirea claselor permite definirea și implementarea unei clase. Refolosirea subclaselor este adesea menționată ca reutilizare transparentă. Cu ajutorul moștenirii, datele claselor de tip părinte sunt adesea vizibile subclaselor. Procesul de compoziție al obiectelor este o alternativă pentru moștenirea claselor. Noi funcționabilități sunt obținute prin asamblarea și construcția de obiecte în scopul obținerii de funcții mai complexe. Compoziția obiectelor necesită ca obiectele să fie compuse din interfețe bine definite. Acest stil de reutilizare este numit invizibil deoarece nici un detaliu intern al obictelor nu este vizibil.
Atât moștenirea cât și compoziția au, avantaje și dezavantaje. Procesul de moștenire este definit ca fiind unul static în momentul compilării, și este simplu de utilizat din moment ce este susținut direct, de limbajul de programare. De asemenea, procesul de moștenire a claselor este ușor de modificat pentru, punerea în aplicare a reutilizării lui. Atunci când o subclasă, suprascrie unele dintre operații, acestea pot afecta operațiile pe care le moștenește, presupunând că ele apelează operațiile suprascrise.
Dar, procesul de moștenirea are și unele dezavantaje. În primul rând, nu se pot schimba implementarile moștenite din clasele de tip părinte în timpul execuției programului, deoarece procesul de moștenire este definit doar la momentul compilării. În al doilea rând, și în cel mai rău caz clasele de tip părinte definesc adesea cel puțin o parte a reprezentării fizice a subclaselor. Deoarece moștenirea expune o subclasă și detaliile implementării clasei părinte, adesea se spune că moștenirea rupe procesul de încapsulare a datelor.
Punerea în aplicare a unei subclase devine atât de strâns legată de punerea în aplicare a clasei sale părinte ca orice schimbare în implementarea clasei părinte va forța subclasa să se schimbe. Dependența de implementare poate cauza uneori probleme atunci când se încercă să se reutilizeze o subclasă.
24
În cazul în care orice aspect al implementării procesului de moștenire nu este adecvat pentru noi domenii problematice, atunci clasa părinte trebuie rescrisă sau înlocuită cu alte aspecte asemănătoare. Această dependență limitează flexibilitatea și nu în ultimul rând procesul de reutilizare. O singură soluție pentru acest lucru este moștenirea claselor abstracte, deoarece acestea deobicei oferă puține date sau nu pot fi implementate.
Compoziția de obiecte este definită în mod dinamic, aceasta având loc în timpul de execuție prin obiecte care preiau trimiteri la alte obiecte. Compozitia cere ca obiectele să își respecte reciproc interfețele, acest lucru necesitând la rândul său proiectarea de interfețe atent proiectate, acest lucru oferind un câștig, deoarece obiectele sunt accesate prin intermediul interfețelor, lor, acest lucru neputând să rupă procesul de încapsulare .Un obiect poate fi înlocuit de un alt obiect doar în timpul execuției, atâta timp cât ele sunt de același tip. Mai mult decât atât, pentru ca implementarile obiectelor vor fi scrise în termeni de interfețe de obiecte, în mod substanțial vor exista mai puține dependențe de implementare.
Compoziția de obiecte are un alt efect asupra sistemului de proiectare. Favorizarea compoziției de obiecte în locul procesului de moștenire, ajută la păstrarea fiecărei clase ca fiind încapsulată, aceasta concentrându-se pe o singură sarcină. Clasele și ierarhiile de clase vor rămane de, dimensiuni reduse și este puțin, probabil ca ele să crească în mărime fiind mai greu de gestionat. Pe de altă parte, un design bazat pe compoziția de obiecte va avea mai multe obiecte, iar comportamentul sistemului va depinde, de interdependența lor, în loc să fie definite într-o singură clasă.
În mod ideal, nu trebuie create noi componente pentru a realiza procesul de reutilizare. Ar trebui să obțineti toate funcționabilitățile de care aveți nevoie doar prin asamblarea componentelor existente prin, procesul de compoziție al obiectelor. Dar, cazul acesta se întamplă rareori, deoarece setul de componente disponibile nu este niciodată suficient de bogat în practică. Procesul de refolosire a moștenirii face mai ușor cazul creări de noi componente, care pot fi compunse cu ajutorul unor componente mai vechi. Concluzia este că, procesul de moștenire și cel de compoziție al obiectelor pot lucra în paralel.
Delegarea obiectelor
Delegarea este o modalitate de a face compoziția obiectelor la fel de puternică precum este reutilizarea procesului de moștenire. În procesul de, delegare două obiecte sunt implicate în manipularea unei cereri: un obiect receptor deleagă operațiuni către delegatul său. Acest lucru, este un lucru analogic deoarece subclasele pot amâna cererile catre clasele de tip părinte. Dar folosind procesul de moștenire, o operație moștenită se poate referi întotdeauna la un obiect destinatar prin intermediul variabilelor membre. Pentru a obține același efect folosind procesul de, delegare receptorul trece la delegat permițând funcționarea operației delegatului către receptor.
[4] Principalul avantaj al procesului de, delegare este că se pot obține ușor comportamente comune în timpul execuției și se poate schimba modul prin care acestea sunt compuse. Pe de altă parte procesul de, delegare are și un dezavantaj, el fiind împărțit cu alte tehnici care fac software-ul mai flexibil prin, procesul de compoziție al obiectelor: software-ul dinamic foarte parametrizat este mai greu de înțeles decât software-ul static.De asemenea există și ineficiențe în timpul execuției, dar ineficiențele umane sunt mai importante pe termen lung. Delegarea este o alegere bună de, design numai atunci când metodele ei simplifică modul de lucru în loc sa îl complice. Nu este ușor ca cineva să poată da reguli atunci când trebuie folosită delegarea, deoarece cât va fi ea de eficientă depinde doar de context și cât de multă experiență are un programator pentru a o putea folosi. Procesul de, delegare funcționează cel mai bine când este utilizat într-un mod extrem de stilizat cum ar fi șabloanele de proiectare standard.
25
Mai multe tipuri de șabloane de proiectare folosesc procesul de, delegare.Ele ar fi următoarele: State, Strategy și Visitor, aceste șabloane depind de acest proces. În șablonul State un obiect de tip delegație cere unui obiect de tip State starea sa actuală. În șablonul Strategy, un obiect deleagă o cerere specifică unui obiect care reprezintă o strategie pentru realizarea cererii. Un obiect poate avea doar o singură stare, dar poate avea mai multe strategii pentru diferite cereri. Scopul ambelor șabloane este de a schimba comportamentul unui obiect prin schimbarea obiectelor la care procesul de, delagare are anumite cereri. Pentru șablonul Visitor operația care se realizează pe fiecare element al unei structuri de obiecte este întotdeauna delegată obiectului de tip Visitor.
Alte șabloane folosesc procesul de, delegare mai puțin.Șablonul Mediator introduce un obiect să medieze comunicarea între alte obiecte. Uneori obiectul de tip Mediator implementează operațiuni pur și simplu prin transmiterea lor la alte obiecte. Uneori trece cu ajutorul unei referințe propii și, prin urmare folosește adevăratul proces de, delegare. Șablonul Chain of Responsibility gestionează solicitările prin transmiterea lor de la un obiect la altul printr-o înlanțuire de obiecte. Uneori, această cerere poartă cu ea o referință la obiectul original, primind cererea, în cazul în care șablonul folosește procesul de, delegare. Șablonul Bridge disociază o abstracție de la punerea sa în aplicare. În cazul în care abstracția și implementarea particulare sunt potrivite, atunci abstractizarea poate delega pur și simplu operațiuni pentru, punerea sa în aplicare. Procesul de, delegare este un exemplu, extrem al compoziției obiectelor. Acesta arată că se poate înlocui întotdeauna procesul de moștenire cu, compoziția obiectelor, ca un mecanism de reutilizare a codului.
Moștenire contra tipurile parametrizate
O altă tehnică pentru refolosirea funcționabilității prin tipuri parametrizate este cunoscută sub numele de generic. Această tehnică vă permite să definiți un tip fară a specifica toate celălalte tipuri pe care le utilizează. Tipurile nespecificate sunt furnizate ca parametri de la punctul de utilizare. De exemplu o clasă de tip listă poate fi parametrizată prin tipul de elemente pe care ea le conține. Pentru a declara o listă de numere întregi,trebuie furnizat tipul integer ca parametru pentru tipul parametrizat de tip listă. Pentru a declara o listă de obiecte de tip String, se furnizează tipul String ca și parametru. Tipurile parametrizate ne ofera un al treilea mod de a crea un comportament în sistemele orientate pe obiecte. Multe șabloane pot fi implementate folosind oricare dintre aceste trei tehnici. Aceste tehnici sunt urmatoarele :
1. O operație implementată de o subclasa
2. Responsabilitatea unui obiect care a trecut la rutina de sortare
3. Un argument care specifică numele funcției pentru a fi apelată pentru a compara elementele.
Există diferențe importante între aceste tehnici. Compoziția obiectelor permite schimbarea comportamentelor obiectelor, compunse în timpul execuției programului, dar necesită indirectare care poate fi mai puțin eficientă. Moștenirea oferă implementări implicite pentru anumite operații și permite subclaselor să le suprascrie. Tipurile parametrizate permit schimbarea tipurilor pe care o clasă le poate utiliza. Nici procesul de moștenire și nici tipurile parametrizate nu se pot schimba în timpul execuției.
3.5 Arhitectura Model View Controller
Swing folosește arhitectura model view controller (MVC) ca design fundamental din spatele fiecărei componente.În esență, arhitectura model view controller împarte componentele GUI (Graphic User Interface) în trei elemente.Aceste elemente joacă un rol crucial în modul de comporate a, acestor componente.[3]
26
Model (Modelul). Acesta cuprinde starea datelor pentru fiecare componentă în parte. Există diferite modele, pentru diferite tipuri de componente. De exemplu, modelul unei componente scrollbar poate conține informații despre poziția curentă a acestuia și a valorilor minime și maxime. Pe de altă parte, un meniu poate conține o listă de elemente de meniu din care utilizatorul poate să aleagă. Această informație rămâne la fel indiferent cum , componenta este proiectată pe ecran. Datele modelului sunt întotdeauna independente de reprezentarea vizuală a componentelor.
View (Vizualizare). Vizualizarea se referă la cum sunt văzute componentele pe ecran. Un exemplu bun despre cum vederile pot diferi, putem privi fereastra unei aplicații pe două platforme GUI (Graphic User Interface) diferite. Aproape toate cadrele ferestrelor au o bară de titlu care se întinde deasupra ferestrei.
În orice caz, bara de titlu poate avea casuța de inchidere fie pe partea stângă cum de regulă se poate găsi pe, platformele Mac OS, fie pe partea dreaptă cum de regulă sunt pe platformele Windows. Acestea sunt exemple de, diferite tipuri de vizualizări pentru aceleași obiecte de ferestre.
Controller (Regulator). Este partea interfeței cu utilizatorul care dictează modul în care componenta interacționează cu evenimentele. Evenimentele vin în mai multe forme (ex : apăsarea unui click de mouse , o apăsare a tastei care declanșează o anumintă comandă). Controller-ul decide reacția fiecărei componente.
Model View Controller-ul decuplează vizualizarea și modelele prin stabilirea unui protocol între ele. Vizualizarea trebuie să asigure ca aspectul său reflectă starea modelului. Oricând datele modelului se, schimbă modelul notifică vizualizări care depind de el. Ca și răspuns, fiecare vizualizare are oportunitatea de a se actualiza. Această abordare permite atașarea de multiple vizualizari modelului pentru a oferi diferite prezentări. De asemenea se pot crea noi vizualizări pentru un model fără al rescrie.
Figura 11 : Diagrama MVC
[3] O altă caracteristică a MVC-ului este faptul că vizualizarile pot fi îmbricate. De exemplu, un panou de control de butoane, ar putea fi implementate ca o vizualizare complexă, care, conține vizualizari îmbricate de butoane. MVC-ul suportă vizualizări îmbricate cu ajutorul clasei CompositeView, o subclasă a clasei View. Obiectele CompositeView se comportă ca și obiectele View. O vizualizare de compoziție, poate fi folosită ori de cate ori o vizualizare este utilizată dar,de asemenea conține și gestionează vizualizări îmbricate.
27
De asemenea, MVC-ul vă permite să, schimbați modul în care o vizualizare răspunde la datele introduse de utilizator fără a schimba prezentarea vizuală a acesteia. MVC-ul încapsulează mecanismul de răspuns într-un obiect de tip Controller. Există o clasă ierarhică de controllere, facând mai ușoară crearea unui nou controller ca o variație a unuia deja existent.
O vizualizare utilizează o instanță a subclasei Controller pentru a implementa un anumit răspuns strategic. Pentru a implementa o strategie diferită,trebuie reînolcuită instanța cu un controller diferit. Este chiar posibil să, se schimbe vizualizarea controller-ului în timpul execuției pentru a permite schimbarea vizualizării la modul în care datele sunt introduse de către utilizator. De exemplu, o vizualizare poate fi dezactivată, astfel încât aceasta să nu accepte nici o introducere de date, pur și simplu dându-i controller-ului un eveniment care ignoră datele de intrare.
Relatia între vizualizare și controller este un exemplu de șablon de proiectare asemenea celui Strategy. Strategy este un obiect care reprezintă un algoritm. Aceasta este folositor când se dorește a înlocui algoritmul fie el static sau dinamic, când există mai multe variante ale algoritmului, sau când algoritmul are structuri de date complexe pe care dorim să le încapsulăm.
28
4. Implementarea aplicației
Partea practică a lucrării de licență constă într-o aplicație de banking construită în limbajul de nivel înalt Java. Mediul de programare în care a fost programată aplicația este compilatorul NetBeans, acest mediu oferind toate elementele pentru implementarea unei astfel de aplicație. NetBeans este o platforma de dezvoltare software scrisa in Java. Aceasta platforma este un instrument pentru programatori pentru scrierea, compilarea, testarea si depanarea de proiecte. Acest mediu de dezvoltare suporta Java, dar si alte limbaje de programare. Am ales acest compilator deoarece funcțiile de programare pentru mediul SWING sunt mai ușor de folosit față de alte complilatoare de exemplu: Eclipse. Utilizând acest compilator am folosit pentru dezvolatarea aplicației optiunea standard de “Java application” pentru realizarea claselor principale, iar pentru interfața grafică am folosit funcționalitatea de “Swing”, această funcționalitate fiind integrată in compilatorul NeatBeans.
Pentru dezolvarea acestei aplicații se va folosi principiul de moștenire, tipul de moștenire folosit pentru dezvoltarea acestei aplicații este numit “single level inheritance”, am folosit acest tip de moștenire deoarece limbajul Java nu suportă moștenirea multiplă (multiple inheritance). În general principiul de moștenire este folosit de limbajele de programare orientate pe obiecte. Pentru început am construit urmatoarele clase : “Bank”, „Customer”, „Account”, „Checking” și o clasă „Savings”. Clasa „Checking” și „Savings” moștenesc clasa „Account”.
În clasa “Account” vom adăuga următoarele variabile de instanță : “private double balance”, “private double interest”, ”private int accountNumber”. Pentru variabilele “balance” și “interest” se vor folosi metode de get() și set(). Metoda “set()” este folosită pentru inițializarea variabilelor de instanță care au modificatorul “private”, iar metoda “get()” este folosită pentru a returna valoarea variabilelor de instanță care au fost inițializate cu ajutorul metodei “set()”, ca o concluzie se va folosi principiul de encapsulare pentru inițializarea lor. Variabila “accountNumber” va trebui ințializată de fiecare dată cand un obiect de tip Account va fi inițializat.
Pentru aceasta se va declara încă o variabilă de tip „private static int numberOfAccount” care va fi inițializată cu valoarea de 1000000 și vom mai avea nevoie și de un constructor default de tip “Account” în care valoarea variabilei „accountNumber” va fi incrementată de la 1000000 la 1000001.
În clasa “Checking” vom adăuga o variabilă de tip „private static String accountType” pe care o vom inițializa cu valorea „Checking”, iar în clasa „Savings” vom avea același tip de variabilă cu același nume dar, valoarea variabilei va fi „Savings”. Revenind la clasa „Checking” vom avea nevoie sa declarăm un constructor care va avea un parametru de tip double denumit „initialDeposit”. În acest constructor vom folosit cuvantul cheie “super()” , care va apela constructorul clasei „Account” pentru incrementarea variabilei „accountNumber”. Tot în acest constructor se va apela si metoda „setBalance(initialDeposit)”,această metodă este in primul rând moștenită din clasa „Account”,iar cu ajutorul acestei metode se va inițializa variabila de instanță „balance”(sold).Acesta metodă va lua ca parametru variabila „initialDeposit”. Apoi se va folosi o instrucțiune if unde vom verifica dacă variabila “initialDeposit” este mai mare decat 10000, dacă expresia este adevărată vom inițializa variabila “interest” cu valoarea 0.05 (5%).
Dacă expresia este falsă, iar, variabila “initialDeposit” este mai mică, atunci variabila va fi inițializată cu valoarea 0.02 (%2).
La finalul acestei clase “Checking” vom suprascrie metoda “toString()”. Metoda “toString()” returnează un obiect sub forma unui String care va afișa tipul contului bancar (Account Type), numărul de cont (Account Number), soldul (Balance) și rata dobânzii (Interest Rate).Clasa “Savings” este identică cu, clasa “Checking”, singura modificare fiind numele constructorului care va avea numele “Savings”.
29
Revenind la clasa “Account” , va trebui sa mai adăugăm două metode. Una numită “public void withdraw”, această metodă va fi folosită atunci când dorim sa retragem bani din cont iar cealaltă va avea numele de “public void deposit”, iar această metodă va fi folosită atunci când dorim să depozităm bani in cont. Ambele metode vor avea ca și parametru o variabilă de tip double numită “amount” , deoarece atunci cand dorim sa retragem sau să adaugăm bani în cont, va trebui sa plătim o anumită sumă de bani.
În metoda “withdraw” se va folosi o instrucțiune if care va , verifica dacă suma pe care vrem să o retragem din cont , plus procentul de 5% este mai mare decât soldul contului, atunci ea va afișa un mesaj prin care vom fi atenționați că suma pe care vrem să o retragem depășește soldul actual. Dacă suma nu depașește soldul contului din care vrem să retragem banii, atunci vom reinițializa variabila “balace” din care vom scădea suma pe care vrem să o retragem, adică variabila “amount”, plus procentajul de 5%, mai precis valoarea 0.05. La finalul metodei ea va printa pe ecran soldul curent al contului. În metoda „deposit” se va folosi o instrucțiune if care va, verifica dacă suma pe care o dorim sa o depozităm este mai mică decât 0 atunci se va printa un mesaj de eroare în care vom fi atenționați că nu putem sa adăugam sume (valori) negative. Dacă suma nu este negativă atunci vom reinițializa variabila „amount” cu valoarea ei, multiplicată cu valoarea variabilei „interest” (dobândă), totul adăugandu-se variabilei „balance” (sold) , la finalul metodei se va afișa soldul curent după depozitare. Tot în aceaste metode se va apela metoda „checkInterest()”, această metodă adaugă o anumita dobandă bazându-se pe sumele depozitate în cont. În această metodă se va folosi tot o instrucțiune if care va, verifica dacă variabila “balance” (sold) este mai mare decat 10000 atunci variabila “interest” (dobandă) va avea valoarea de 0.05 ( 5%) , iar dacă este mai mică decat 10000 atunci ea va avea valoarea de 0.02 (2%).
În clasa “Customer” am construit patru variabile de tip private final : “private final String firstName”, „private final String lastName”, „private final String ssn”, „private final Account account”.După declararea variabilelor va trebui sa declarăm și un constructor de tip „Customer” unde vom inițializa variabilele declarate în această clasă.La finalul acestei clase se va suprascrie metoda “toString()”, după cum am precizat anterior metoda „toString()” returnează datele obiectului sub forma unui String, am suprascris această metodă deoarece am dorit să returneze informațiile despre client. Metoda va printa :numele, prenumele, social security number, și tipul contului.
În clasa „Bank” se va importa clasa „java.util.ArrayList”, această clasă ne va lăsa sa utilizăm vectorii de tip listă,dacă nu importam această clasă acest lucru nu era posibil ,pe urmă am construit un vector de tipul ArrayList numit „customers”, care va conține clienții băncii.
Tot în clasa “Bank” se va implementa o metodă de tip void numită „void addCustomer”, acestă metodă când va fi apelată va adăuga un client nou băncii, iar ea va avea ca și parametru un obiect de tip Customer. În această metodă vom adăuga clienții folosind intrucțiunea “customers.add(customer)”. O altă metodă pe care o vom avea în această clasă va fi „Customer getCustomer(int account)”, această metodă va returna poziția clientului, apoi vom mai avea nevoie ca vectorul de tipul ArrayList să fie returnabil, pentru acest lucru vom construi o metodă de tipul „ArrayList<Customer> getCustomers()”, această metodă va returna poziția clienților, în această metodă se va folosi instrucțiunea “return customers”.
După construirea claselor descrise mai sus, acuma este timpul pentru a implementa interfața grafică a acestei aplicații. Pentru realizarea acestui lucru vom folosi un proiect de tip SWING. Java SWING este folosit pentru prelucrarea interfețelor grafice (GUI). SWING-ul face parte din Java Fundation Classes(JFC) și include mai multe pachete pentru dezvoltarea de aplicații desktop. SWING-ul include în modul sau nativ, butoane, toolbar-uri, zone pentru afișarea textului, etc. Primul lucru pe care trebuie să îl facem este să dăm click dreapta pe package, apoi selectăm „New” și vom selecta form-ul pe care vrem să îl construim. Din lista disponibilă vom selecta JFrame Form pe care îl vom numi „MainMenu”. În figura ce va urma, vă este prezentat form-ul final al aplicației.
30
Pentru început, ceva ce au toate programele în general este un toolbar unde se poate selecta File, Edit și așa mai departe. Așa că pentru a face acest lucru posibil se va scrie in metoda “private void initComponents()” , următoarele secvențe de cod : “menuBar = new javax.swing.JMenuBar();” , această linie va construi efectiv toolbar-ul, apoi pentru optiunea “File” se va scrie : “fileMenu = new javax.swing.JMenu();”. Pentru setarea corectă a textului din taskbar, referindu-mă direct la optiune “File” urmatoarea linie de cod trebuie implementata :
“fileMenu.setText("File")”, după care vom avea nevoie de “menuBar.add(fileMenu);” pentru ca optiunea “File” să fie atașată taskbar-ului. În final se va folosi “setJMenuBar(menuBar);” pentru ca taskbar-ul sa fie atașat JFrame-ului.
Figura 12 : Interfața aplicației
Pentru această aplicație avem de luat în considerare următoarele lucruri pe care ea trebuie să le facă: posibilitatea de construire a noi conturi bancare, posibilitatea de, depozitare, retragere de numerar și nu în ultimul rând posibilitatea de afișare a listei de conturi, cu detaliile necesare. Spre finalul acestui proiect se va implementa si opțiunea de Open si Save.
Următorul lucru pentru dezvolarea acestei aplicații este “javax.swing.GroupLayout contentPanelLayout = new javax.swing.GroupLayout(contentPanel);”.
Acest cod adaugă la JFrame un panou (Panel). Pentru adăugarea lui se va folosi “contentPanel.setLayout(contentPanelLayout);”. Odată adăugat panoul, el se va redimensiona cu marimea ferestrei principale a aplicației.Tot în metodă “private void initComponents()” se vor adauga si butoanele :
– “addAccountButton = new javax.swing.JButton();” ,
– “depositButton = new javax.swing.JButton();”
– “removeAccountButton = new javax.swing.JButton();”
– “withdrawButton = new javax.swing.JButton();”
Apoi vom folosi metoda “.setText()” pentru a le schimba eticheta :
“addAccountButton.setText("Add Account");
“removeAccountButton.setText("Remove Account");”
31
“depositButton.setText("Deposit");”
“withdrawButton.setText("Withdrawl");”
În metoda “initComponents()” se vor genera toate funcționabilitățile construite în frame prin modul de utilizare “drag and drop”. Pentru setarea corespunzătoare a numelor de butoane am folosit metoda “.setText()”. Această metodă va luat ca și parametru un String, adică în cazul actual numele dorit pentru setarea butoanelor ,generate anterior.
În continuare se va adăuga un tabel JFrame-ului. Se va folosi un tabel deoarece vom avea nevoie de mai multe coloane pentru salvarea de date. Se va folosi “accountTable = new javax.swing.JTable();” pentru construirea unui obiect de tip tabel. Coloanele lui vor fi modificate.
“accountTable.setModel(new javax.swing. table. Default Table Model” în care vom avea “new String [] {"First Name", "Last Name", "Account Number", "Balance"}”.Numărul de rânduri va fi zero.
Următorul lucru de implementat este un “MenuItem” pentru toolbar-ul existent pentru aceasta se va folosi instrucțiunea : “exitMenuItem = new javax.swing.JMenuItem();” care va genera un obiect de tipul “JMenuItem”, apoi se va folosi metoda “.setText(“Exit”) pentru redenumirea etichetei, iar la final pentru a fi adăugat meniul in toolbar se va folosi metoda “.add()” , care va luat ca și argument pe “exitMenuItem”. Metoda “.add()” este folosită atunci când se dorește ca obiectul generat (buton, menu item, etc) să fie atașat frame-ului actual. Pentru ca opțiunea “Exit” sa funcționeze vom avea nevoie de un EventHandler. Aceasta este urmatorul : “private void exit Menu Item Action Performed (java.awt.event.ActionEvent evt)”. În interiorul lui se va folosi cuvantul de referinta “this()” urmat de metoda “.dispose()”. Metoda “.dispose()” este folosită atunci când vrem să închidem(eliminăm) fereastra actuală.
În continuare am implementat funcționalitatea butonului “Add Account”. Pentru început când se va da click pe acest buton, se va deschide un alt form, mai precis un JDialog Form. Am ales acest tip de form deoarece , el trebuie în mod neapărat completat pentru a se putea continua cu alte facilități ale aplicației. Pentru început se va adăuga un “Event Handler” butonului “Add Account” din formul “MainMenu” , de tipul “private void addAccountButtonActionPerformed” care va lua ca și parametru “java.awt.event.ActionEvent evt”. În interiorul acestui event se va construi un obiect cu numele de instanță “menu” de tipul “new AddAccountMenu”, care la rândul lui are ca parametri pe “this” adică părintele principal în cazul nostru form-ul “MainMenu” și pe “true” deoarece este o fereastra modală. Tot in acest event, trebuie să facem fereastra vizibilă, pentru acest lucru se va folosi metoda “.setVisible(true)”. Metoda “.setVisible()” este folosită atunci când dorim ca fereastra să fie afișată pe ecran.
Atunci când aplicația principală rulează, ea se va deschide în colțul din stânga a ecranului, pentru ca ea să apară în centrul ecranului va trebui să îi setăm locația, pentru acest lucru ne trebuie urmatoărea comandă, care va fi scrisă in metoda “public MainMenu()” , declarația este următoarea : “setLocationRelativeTo(null)”.
Metoda “MainMenu()” conține toate declarațile și instrucțiunile ce fac parte din frame-ul principal al aplicației. Pentru ca frame-ul JDialog să apară mereu suprapus peste frame-ul “MainMenu” atunci în metoda “public AddAccountMenu()” vom avea următoarea declarație : “setLocationRelativeTo(parent)”. Se va folosi parametrul “parent” deoarece el este părintele frame-ului “MainMenu”.Metoda “AddAccountMenu()” conține la rândul ei toate declarațile și instrucțiunile pentru funcționabilitatea frame-ului “AddAccountMenu()”.
32
Frame-ul “AddAcountMenu” va include numele și prenumele clientului, social-security-number(cnp-ul), depozitul inițial și tipul de cont pe care dorim să îl facem. Pentru început frame-ului trebuie să îi adăugăm un grid layout, pentru a face asta trebuie să implementăm urmatoarea linie de cod : “getContentPane().setLayout(new java.awt.GridLayout())” , în care vom avea ca și parametrii valorile 6, 2, 5, 5 . Aceste numere reprezintă numărul de rânduri, numărul de coloane , decalajul pe verticală și decalajul pe orizontală.
După implementarea layout-ului se vor adăuga cinci etichete pentru “First Name” (nume), “Last Name” (prenume), “Social Security Number” (cnp), “Initial Deposit” (depozit inițial) și “Account Type” (tipul de cont). Pentru realizarea acestui lucru se vor declara cinci variabile denumite “firstNameLabel”, “lastNameLabel”, “ssnLabel”, “depositLabel” și “typeLabel”, acestea fiind inițializate cu un obiect de tip “new javax.swing.JLabel()”. Pentru redenumirea lor se va folosi metoda “.setText()” al cărui parametru este șirul de caractere dorit pentru redenumirea etichetei. După cum am precizat anterior metoda “.setText()” are ca parametru un String. Această metodă este folosită pentru setarea corespunzatoare a numelor text-field-urilor , butoanelor, etc. Pentru amplasarea lor în frame-ul “AddAccountMenu” se va folosi metoda “.add()” al cărui parametru este variabila “jLabel”. La fel cum am mai precizat, metoda “.add()” este folosită atunci când dorim să atașăm frame-ului butoane, tool-bar-uri,etc.
În dreptul primelor patru etichete se va amplasa câte un text field, pentru realizarea lor este nevoie de patru variabile :” firstNameField” ,” lastNameField”, “ssnField”, “depositField”. Ele vor fi inițializate cu un obiect de tip “new javax.swing.JTextField”. Pentru amplasarea lor in frame-ul “AddAccountMenu” se va folosi metoda “.add()” al cărei parametru vor fi variabilele însuși. În dreptul ultimei etichete se va folosi un “ComboBox” care va avea două valori : “Checking” și “Savings”. Pentru realizarea lui se va declara o variabila “typeField” care va lua valorea de “new javax.swing.JComboBox<>()”. După cum am precizat va avea doua valori, pentru asta am se va folosi metoda “.setModel()” , al carei parametru va fi un vector de tip String[] inițializat cu valorile “Checking” și Savings”. Metoda “.setModel()” este folosită atunci când dorim să adăugăm valori unui ComboBox sau a unui tabel. Ultimul lucru ce va mai fi adaugat acestui frame sunt două butoane “Ok” și “Cancel” pentru confirmare sau anulare. Pentru acest lucru am declarat două variabile “okButton” și “cancelButton” care sunt inițializate cu “new javax.swing.JButton();”. Pentru butonul de “Cancel” vom adăuga un event handler , this.dispose() pentru ca atunci când se va apăsa fereastra actuală să, se închidă. După cum am precizat mai sus metoda “.dispose()” este folosită atunci când se dorește a se închidă fereastra actuală.Pentru butonul “OK” se va implementa tot un event. În acest event trebuie verificat numele , prenumele , ssn-ul , depozitul inițial și nu il ultimul rând pentru construirea unui tip de cont.
33
Figura 13 : Interfața frame-ului “AddAccountMenu”
Pentru verificarea numelui , a prenumelui și a social security number-ului se vor declara trei instructiuni if() ale căror expresii sunt: “firstNameField.getText().isEmpty()”, “lastNameField.getText().isEmpty()” și ““ssnField. getText().isEmpty()”. Dacă câmpurile de text sunt lăsate libere atunci se va printa un mesaj de eroare. Pentru a construi mesajele de eroare se va implementa un StringBuilder “warnings” și pentru fiecare mesaj se va folosi metoda “.append()” această metodă luând ca și parametru mesajul de avertisment pentru fiecare câmp lăsat liber, în cazul de față pentru nume va printa “First name must not be empty”, pentru prenume “Second name must not be empty”, pentru ssn “SSN must be 9 digits, dashes are acceptable.”.
Atunci cand se va verifica ssn-ul se va folosi metoda “.matches()” al cărui parametru este o expresie regulată "(\\d{3}-?){2}\\d{4})” . Această expresie ne va lăsa sa folosim următorul format de cifre pentru ssn (xxx-xxx-xxxx).
Pasul următor este declararea variabilelor de tip String “firstName”, ”lastName”, “ssn”, “depositString” și o variabilă de tip double “amount”. Aceste variabile se vor inițializa dacă câmpurile anterioare nu sunt lasate libere folosind metoda “.getText()”. Metoda “.getText()” este folosită atunci când dorim să extragem String-ul amplsat într-un text-filed. Pentru inițializarea depozitului inițial prima dată se va, verifica dacă campul este lăsat gol, acest lucru îl vom face folosind o instructiunea “if (depositField .getText(). isEmpty()) ”, dacă expresia este adevarată atunci se va printa un mesaj de eroare folosind metoda “.append()” a StringBuilder-ului, în caz contrar se va executa o instructiune “try” in care vom inițializa variabila “amount” cu o valoare convertită de tip double a câmpului “depositField”.
În cazul în care nu se vor semnala erori în instrucțiunea “else” prima dată se va declara o variabilă de tip “Account” denumită “account” care va fi initializată cu valoarea “null”. După această declarație se va folosi o instrucțiune “if (typeField. getSelectedItem(). toString() == "Checking") în care se verifică dacă tipul contului selectat din “ComboBox” este egal cu valoare
34
“Checking” atunci variabila “account” va fi inițializată cu un obiect de tip “Checking()” al cărui parametru este variabila “amount”. ”. Înaintea inițializarii variabilei “account” se va folosi o instrucțiune de decizie “if(amount >= 100)”,adică suma minimă depusă pentru deschiderea un tip de cont “Checking” este de 100$.
Pe urmă se va continua cu o instrucțiune “else if (typeField.getSelectedItem().toString() == "Savings")” în care se va, verifica dacă contul este de tip “Savings”, iar atunci variabila “account” va fi inițializată cu un obiect de tip “Savings()” al cărui parametru este variabila “amount”. Tot ca în cazul de mai sus, înaintea inițializării variabile se va folosi tot o instrucțiune “if(amount >=50)”,adică suma minimă pe care trebuie să o depunem este de 50$ pentru deschiderea unui cont de tip “Savings”.
În continuarea aplicației se va prezenta cum sunt adăugate conturile noi construite în tabelul din frame-ul “MainMenu”. În eventhandler-ul “addAccountButtonActionPerformed” se va folosi o instrucțiune if unde se va verifica dacă “menu.getCustomer()” este diferită decât valoare “null” atunci se va apela metoda “add Customer To Table (menu.getCustomer())”, deoarece metoda getCustomer() nu există, în interiorul frame-ului “AddAccountMenu” va fi amplasată metoda “Customer getCustomer()” aceasta metodă va returna un obiect de tip “customer”. În continuare se va implementa metoda “add Customer ToTable(Customer customer)”,această metodă când va fi apelată ea va adăuga un nou client în tabelul din frame-ul principal “MainMenu”. În interiorul acestei metode se va declara o variabilă de tip “DefaultTableModel” numită “model” care va fi inițializată cu valoarea “accountTable.getModel()”. Tot in această metodă se va folosi metoda “.addRow()”,această metodă va adaugă un rând nou tabelului, ea va lua ca și parametru un vector de obiecte ,cum ar fi “customer.getFirstName()”, “customer.getLastName()”, ”customer.getAccount().getAccountNumber()” și “customer . getAccount().getBalance()”.
Figura 14 : Adăugare cont in table
În continuare vom implementa funcționalitatea butonului “Remove Account”. Pentru ca butonul să fie funcționabil vom avea nevoie de o metodă “private Customer
35
getSelectedCustomer()”, această metodă va selecta din tabel, clientul pe care dorim să îl selectăm. În această metodă se va declara un obiect de tip Customer numit “customer” care va fi inițializat cu valoarea “null”. Apoi, vom reține numărul rândului selectat din tabel, pentru realizarea acestui lucru vom avea nevoie de o variabilă de tip intreg “int selectedRow” care va fi inițializată cu valoarea variabilei “accountTable.getSelectedRow()”. Următorul pas ce trebuie făcut este folosirea unei instrucțiuni if al cărei expresie este “selectedRow >= 0”, atunci am inițializat o variabila locală de tip intreg “int accountNumber” cu valoarea rândului selectat.Această metodă va returna un obiect de tip “customer”.
În continuare se va construi altă metodă de tip “private void removeCustomerFromTable()”, această metodă va sterge clientul pe care îl selectăm din tabelul cu clienții băncii , metoda va avea un parametru de tip “int row”. În această metodă este nevoie de modelul tabelului așa că se va inițializa o variabilă de tip “DefaultTableModel” cu valoarea “accountTable .getModel()”. Tot în interiorul acestei metode se va folosi “model.removeRow(row)” , metoda “.removeRow()” va șterge rândul selectat din tabel, ea va avea ca parametru numărul rândului selectat.Tot ce mai trebuie făcut ca butonul “Remove Account” să funcționeze este implementarea unui event.În acest event se vor apela metodele construite anterior.
În continuare vom implementa funcționalitatea butonului “Deposit”.Pentru început am construit un frame de tip JDialog cu numele “DepositMenu”. După generarea lui , am aplicat un “Grid Layout”, acest layout va avea două coloane, decalajele verticale și orizontale vor avea o valoare de cinci, iar numărul de rânduri vor fi două. După configurarea layout-ului se va adăuga un label , un text field și două butoane. Textul label-ului va fi schimbat în “Deposit” folosind metoda “.setText()”,iar butoanele se vor numi “Deposit” și “Cancel” , folosind tot metoda “.setText()”.
Butonului “Cancel” i se va adăuga un event “private void cancelButtonActionPerformed” în care se va adăuga “this.dispose()”. Atunci când se va da click pe butonul “Cancel” el va închide frame-ul. În continuare am adăugat funcționabilitatea butonului “Deposit”, pentru ca acesta să fie funcționabil trebuie să adăugam un event “private void depositButtonActionPerformed” . Înainte să putem face un deposit în cont trebuie să verificăm dacă text field-ul nu este gol, trebuie să mai verificăm dacă suma depusă este un număr pozitiv, iar la final se va putea face depozitul.
Pentru verificarea text field-ului se va folosi o instrucțiune if al cărei expresie verifică dacă “amountField.getText().isEmpty()” atunci se va printa un mesaj de eroare folosind un string builder “warnings”,acest mesaj de eroare este “Deposit amount is required”. În instrucțiunea “else” se va declara o variabilă locală “double amount”, în interiorul instrucțiunii “else” se va folosi o instrucțiune de try și catch. În instrucțiunea try,variabila “amount” va fi inițializată cu “Bank. Round (Double. parseDouble (amountField.getText()), 2);” , metoda “round” face parte din clasa “Bank”, această metodă rotunjește primele două zecimale a variabilei “amount”.
Pentru ca butonul să fie funcționabil am adăugat un event în codul sursă al frame-ului principal, adică “MainMenu”. În eventul “private void depositButtonActionPerformed” vom construi un client de tip “Customer” numit “customer” care va fi inițializat cu rândul selectat din tabel, adică “accountTable.getSelectedRow()”. Tot în acest event se va folosi o instrucțiune if în care se verifică daca “customer != null” atunci se va instanția un meniu de tip “DepositMenu” care va avea trei parametri adică pe “this, true,customer”.
36
Următoarea instrucțiune va face ca frame-ul “DepositMenu” să fie vizibil folosid “menu.setVisible(true)”. Tot în instrucțiunea if se va apela și metoda “reloadCustomerRowData”, această metodă va reîncărca datele tabelului cu, clienti, ea va avea doi parametri : “selectedRow” și “customer”. Această metodă va fi construită tot în codul frame-ului “MainMenu”. În această metodă vom avea nevoie de modelul tabelului, adică o variabilă de tip “DefaultTableModel” numită “model” care va fi inițializată cu valoarea lui “accountTabel.getModel()”. Variabila “menu” va fi folosită de trei ori utilizând metoda “.setValueAt()”, această metodă setează valoarea în celulă de la indexul coloanei și indexul rândului ea va lua trei parametri “customer .getFirstName()”, “selectedRow” și numărul rândului.
Exact aceleași principii folosite mai sus pentru butonul “Deposit” sunt folosite și pentru funcționabilitatea butonulu “Withdrawal”, singura modificare care va fi facută este implementarea unui comision de tranzacție care va avea valoarea de 5$.
Figura 15 : Frame-ul “DepositMenu”
Figura 16 : Frame-ul „WithdrawalMenu”
37
O altă funcție a aplicației pe care am implementat-o este dezactivarea butoanelor “Remove Account”, “Deposit” și “Withdrawal”, ele fiind disponibile doar atunci când se va genera un rând in tabel. Pentru acest lucru trebuie am selectat tabelul din frame-ul “MainMenu” , să deselectăm opțiunea “enabled” pentru fiecare buton în parte. Vom selecta din proprietățile tabelului un event de click, în acest event vom avea o metodă numită “setAccountButtonsActive()”, această metodă va fi apelată doar atunci când în tabel va exista un client nou și se va da click pe acel client, atunci metoda va activa butoanele “Remove Account”, “Deposit” și “Withdrawal”. Această metodă are un parametru de tip boolean numit “active”. În această metodă se vor folosi variabilele butoanelor urmate de metoda“.setEnable(active)”.“depositButton.setEnabled(active)”,“withdrawButton.setEnabled(active)”, “removeAccountButton.setEnabled(active).Metoda “setEnable()” activează butoanele care au fost dezactivate anterior.
Următoarea funcționalitate a aplicației este afișarea detaliilor clientului, atunci când se va da, dublu click pe rândul pe care se află. Pentru început în metoda “accountTableMouseClicked”, această metodă se va apela atunci când se va da click pe un client din tabelul din frame-ul “MainMenu”. Tot in această metodă se va folosi o instrucțiune if care va, verifica dacă s-a dat dublu click, pentru aceasta este nevoie de “evt.getClickedCount() == 2” , dacă expresia este adevărata atunci se vor afișa detaliile contului respectiv.
Următorul lucru este construcția frame-ului pentru afișarea detaliilor. Se va folosi un JDialog Frame, care se va numi “AccountDetailsPage”. Acestui frame i-am adăugat un “grid layout” pe care l-am configurat să aibă nouă rânduri și două coloane. În continuare acestui frame se vor adăuga șaisprezece label-uri, opt dintre ele se vor redenumi cu : “First Name”, “Last Name”, “Social Security Number”, “Account Type”, “Account Number”, “Balance”, “Interest Rate” , “Transaction Fee”, iar restul label-urilor vor fi setate cu valorile contului respectiv.
În metoda “public AccountDetailsPage()” am adăugat un parametru de tip Customer, deoarece vom avea nevoie de detaliile clientului pentru setarea valorilor label-urilor lăsate libere. Această metodă conține construcția frame-ului “AccountDetailsPage”, în această metodă se gasesc toate declarațiile și instrucțiunile pentru acest frame. Pentru setarea label-urilor se va folosi metoda “.setText()” pentru adăugarea textului cu valoarile propriu-zise. Descrisă anterior, metoda “.setText()" setează valorile dorite pentru numele labe-uri-lor. După setarea valorilor de text pentru fiecare label în parte, se va reveni la metoda “accountTableMouseClicked” din frame-ul “MainMenu”. Această metodă este apelată atunci cand se va da click pe un client din tabelul construit în frame-ul principal al aplicației. În interiorul metodei se va folosi o instrucțiune if , in interiorul ei se va declara o variabilă pentru a afla rândul selectat numita “selectedRow” care este inițializată cu “accountTable.getSelectedRow()”, apoi se va construi un client de tip “Customer” numit “customer” acesta fiind inițializat cu “getSelectedCustomer(selectedRow)”, pe urmă se va folosi tot o instrucțiune de decizie if a cărei expresie verifică dacă clientul diferă de valoarea “null” atunci se va construi o pagină de tipul frame-ului “AccountDetailsPage” , această pagină fiind vizibilă folosind metoda “.setVisible(true)”. Această metodă va face vizibil frame-ul “AccountDetailsPage”.
38
Figura 17 : Frame-ul “Account Details Page”
Ultima implementare în această aplicație sunt funcțiile de “Open” și “Save”, pentru a putea salvarea conturilor și pentru încărcarea lor. Pentru început trebuie adăugate două menu iteme în toolbar-ul “File” din frame-ul principal adică “MainMenu”. Acestea vor fi redenumite în “Save” și “Open”. Pentru opțiunea de “Save” se va implementa o scurtătură prin apăsarea tastelor “CTRL + S”, iar pentru opțiunea de “Open” se va apăsa scurtătura de “CTRL + O”. În continuare se va adăuga funcționabilitatea opțiunii “Save” , pentru acest lucru se va construi un event pe nume “saveAsMenuItemActionPerformed”. În acest event se va declara o variabilă de tip “JFileChooser” numită “chooser” care va fi inițializată cu “new JFileChooser()”. Chooser-ului îi i se va adăuga un filtru de fișiere de tipul “new BofFilter()” folosind metoda “.setFileFilter”. Metoda “.setFileFilter” filtrează tipul de fișiere dorit. Odată construit filtrul va trebui construită și o nouă clasă pe nume “BofFilter” care va moșteni clasa “FileFilter”. Clasa “FileFilter” este o clasă abstractă pentru filtrarea setului de fișiere afișate pentru utilizatori. În această clasă vom avea două metode “public String getDescription” această metodă va returna numele fișierului "Bank Object File". Cea de-a doua metodă este “public boolean accept” această metodă alege dacă rezultatul trebuie să apară în directorul curent cu extensia fișierului “.bof”.
În această metodă se va folosi o instrucțiune if a cărei expresie verifică dacă un director sau numele fișierului se termină cu extensia “.bof” atunci va returna valoarea “true”, dacă nu atunci va returna “false”. Momentan în meniul “Save” există opțiunea de a selecta “All Files”, dar se vrea împiedicarea acestui lucru, așa că în metoda “saveAsMenuItemActionPerformed” mai exact variabila “chooser” se va folosi metoda “.setAcceptAllFileFilterUsed()” cu parametrul “false”. Această metodă afișează utilizatorului la salvare diferite formate de a salva fișierul. În continuare se va folosi o instrucțiune if a cărei expresie verifică dacă s-a selectat un fișier atunci se va construi o variabila “file” de tipul “File” care va fi inițializată cu variabila
39
“chooser.getSelectedFile()”. Tot în instrucțiunea if se va declara o variabilă de tipul “String” numită “fileName” care va fi inițializată cu valoarea “file.toString()”. Se va folosi încă o instrucțiune if care verifică dacă fișierul nu are la sfarșit extensia “.bof” dacă expresia este adevarată atunci fișierului i se va adăuga extensia “.bof”. Acuma se va implementa opțiunea “Open”. Pentru acest lucru vom construi un event pe nume “openMenuItemActionPerformed” în acest event se va declara ca în opțiunea precedentă o variabilă de tip JFileChooser numită tot “chooser”, acestei variabile i se va adaugă tot un filtru de tipul “BofFilter”, și iarăși se va folosi metoda “.setAcceptAllFileFilterUsed” cu paramentrul “false” pentru ca atunci când vom incărca fișierul în aplicație să nu apară opțiunea de “All Files”. Tot în acest event se va folosi o instrucțiune if care verfică dacă fișierul pe care vrem să îl deschidem nu are extensia “.bof” atunci va afișa un mesaj de eroare în mod constrat atunci va trebui sa declarăm o variabilă de tipul “FileInputStream” numită “fIn” care va fi initializată cu “new File Input Stream (chooser.getSelectedFile())”, următoarea instrucțiune este declararea unei variabile de tipul “ObjectInputStream” numită “objIn” care va fi inițializată cu “new ObjectInputStream(fIn)”,următoul lucru trebuie ca fișierul să fie citit, pentru lucrul aceasta trebuie o variabilă de tip “Object” numită “bankData” care este inițializată cu “objIn.readObject()”.
40
5.Concluzii
Lucrarea prezentată se referă la modul în care se poate dezvolta o aplicație de tip banking.Pe parcursul lucrării am proiectat o aplicație, realizând partea de software, necesară implementării aplicației.Această aplicație poate fi folosită cu ușurintă de personalul autorizat a unei instituții bancare.
Aplicația ar mai putea fi dezvoltată prin folosirea unei baze de date mai complexe și prin editarea informațiilor legate de fiecare client în parte și nu în ultimul rând pentru securizarea acesteia.Ca și scop de viitor, această aplicație ar putea fi dată in folosință unei instituții bancare, după unele modificări mai riguroase.
41
Bibliografie
[1] http://blog.teamtreehouse.com/learn-java
[2] Herbert Schildt.The Complete Reference Java 7th Edition,2007
[3] OReilly. Java Swing 2nd Edition,2002
[4] Erich Gamma,Richard Helm,Ralph Jonsopn,John Vlissides. Design Patterns : Elements of Reusable Object Oriented Software,1995
[5] OReilly. HeadFirst Design Patterns,2004
[6] Bruce Eckel.Thinking in Java 4th Edition,2006
[7] Y.Daniel Liang.Introduction To Java Programming 10th Edition,2013
[8] Ivor Horton`s.Beginning Java 7th Edition,2011
[9] Joshua Bloch.Effective Java 2nd Edition,2008
42
Anexe
package bankapp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
public class MainMenu extends javax.swing.JFrame {
private Bank bank;
private String saveLocation = null;
public MainMenu() {
initComponents();
setLocationRelativeTo(null);
43
bank = new Bank();
}
private void initComponents() {
contentPanel = new javax.swing.JPanel();
addAccountButton = new javax.swing.JButton();
removeAccountButton = new javax.swing.JButton();
depositButton = new javax.swing.JButton();
withdrawButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
accountTable = new javax.swing.JTable();
menuBar = new javax.swing.JMenuBar();
fileMenu = new javax.swing.JMenu();
saveMenuItem = new javax.swing.JMenuItem();
saveAsMenuItem = new javax.swing.JMenuItem();
openMenuItem = new javax.swing.JMenuItem();
exitMenuItem = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Bank Application");
addAccountButton.setText("Add Account");
addAccountButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addAccountButtonActionPerformed(evt);
}
44
removeAccountButton.setText("Remove Account");
removeAccountButton.setEnabled(false);
removeAccountButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
removeAccountButtonActionPerformed(evt);
}
});
depositButton.setText("Deposit");
depositButton.setEnabled(false);
depositButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
depositButtonActionPerformed(evt);
}
});
withdrawButton.setText("Withdrawal");
withdrawButton.setEnabled(false);
withdrawButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
withdrawButtonActionPerformed(evt);
}
});
accountTable.setAutoCreateRowSorter(true);
accountTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
45
},
new String [] {
"First Name", "Last Name", "Account Number", "Balance"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Integer.class, java.lang.String.class
};
boolean[] canEdit = new boolean [] {
false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
accountTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
accountTable.getTableHeader().setReorderingAllowed(false);
accountTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
accountTableMouseClicked(evt);
}
});
jScrollPane1.setViewportView(accountTable);
46
if (accountTable.getColumnModel().getColumnCount() > 0) {
accountTable.getColumnModel().getColumn(0).setResizable(false);
accountTable.getColumnModel().getColumn(1).setResizable(false);
accountTable.getColumnModel().getColumn(2).setResizable(false);
accountTable.getColumnModel().getColumn(3).setResizable(false);
}
javax.swing.GroupLayout contentPanelLayout = new javax.swing.GroupLayout(contentPanel);
contentPanel.setLayout(contentPanelLayout);
contentPanelLayout.setHorizontalGroup(
contentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(contentPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(contentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(contentPanelLayout.createSequentialGroup()
.addComponent(addAccountButton)
.addGap(18, 18, 18)
.addComponent(removeAccountButton)
.addGap(18, 18, 18)
.addComponent(depositButton)
.addGap(18, 18, 18)
.addComponent(withdrawButton)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
47
contentPanelLayout.setVerticalGroup(
contentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(contentPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(contentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(addAccountButton)
.addComponent(removeAccountButton)
.addComponent(depositButton)
.addComponent(withdrawButton))
.addGap(18, 18, 18)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
.addContainerGap())
);
fileMenu.setText("File");
saveMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
saveMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/bankapp/save.png")));
saveMenuItem.setText("Save");
saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveMenuItemActionPerformed(evt);
}
48
fileMenu.add(saveMenuItem);
saveAsMenuItem.setText("Save As…");
saveAsMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveAsMenuItemActionPerformed(evt);
}
});
fileMenu.add(saveAsMenuItem);
openMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
openMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/bankapp/open.png")));
openMenuItem.setText("Open");
openMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
openMenuItemActionPerformed(evt);
}
});
fileMenu.add(openMenuItem);
exitMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/bankapp/delete.png")));
exitMenuItem.setText("Exit");
exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
exitMenuItemActionPerformed(evt);
49
DECLARAȚIE DE AUTENTICITATE
A
LUCRĂRII DE FINALIZARE A STUDIILOR
Titlul lucrării ________________________________________________________
___________________________________________________________________
___________________________________________________________________
Autorul lucrării _____________________________________________
Lucrarea de finalizare a studiilor este elaborată în vederea susținerii examenului de finalizare a studiilor organizat de către Facultatea _________________________________________ din cadrul Universității din Oradea, sesiunea_______________________ a anului universitar ______________.
Prin prezenta, subsemnatul (nume, prenume, CNP)_____________________
___________________________________________________________________
___________________________________________________________________,
declar pe proprie răspundere că această lucrare a fost scrisă de către mine, fără nici un ajutor neautorizat și că nici o parte a lucrării nu conține aplicații sau studii de caz publicate de alți autori.
Declar, de asemenea, că în lucrare nu există idei, tabele, grafice, hărți sau alte surse folosite fără respectarea legii române și a convențiilor internaționale privind drepturile de autor.
Oradea,
Data Semnătura
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Dezvoltarea Unei Aplicatii de Banking Folosind Limbajul Java (ID: 114017)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
