Sunteți pe pagina 1din 41

112

Alte controale Windows

JPasswordField

Controlul de tip JPasswordField este folosit pentru preluarea parolelor.


ProprietăŃile sale sunt similare controlului de tip JTextField. Practic, într-o aplicaŃie
care accesează o bază de date se preia o parolă care este folosită ulterior la stabilirea
nivelului de acces al utilizatorului aplicaŃiei. Astfel dacă parola este a unui simplu
operator care culege date o parte din elementele de control ale aplicaŃiei (opŃiuni din
meniuri, butoane de pe barele cu instrumente sau conŃinute în formulare) devin
inactive. Ele vor fi desigur activate dacă parola introdusă este cea a inginerului de
baze de date care întreŃine aplicŃia. Între cele două extreme pot fi definite diverse
nivele de prioritate, fiecare cu caracteristicile sale.

JTextArea

Controlul de tip JTextArea se utilizează pentru introducerea şirurilor de


caractere lungi, pe mai multe linii. ProprietăŃile folosite pentru accesarea conŃinutului
sunt aceleaşi ca şi în cazul controlul de tip JTextField.

JCheckBox

Un control de tip casetă de validare (JCheckBox) poate avea două stări: selectat
sau neselectat. Starea de selectare poate fi stabilită în momentul realizării interfeŃei
grafice sau în timpul execuŃiei aplicaŃiei, prin apelul metodei setChecked(). Testarea stării
controlului se realizează prin apelul metodei isSelected().
Ca şi în cazul controalelor de tip JButton, controlului de tip JCheckBox i se poate
asocia o secvenŃă de tratare a evenimentului declanşat la selectarea acestuia cu mouse-
ul.
113

JRadioButton

Cotroalele de tip JRadioButton (butoane radio) servesc la selectarea unei valori


dintr-un set de valori posibile. Pentru a impune acest comportament înaintea adăugării
butoanelor de tip JRadioButton care vor compune un grup de butoane se va adăuga
interfeŃei un control de tip ButtonGroup. Pentru a realiza gruparea, se selectează
succesiv, cu tasta Control apăsată, butoanele radio care compun grupul şi apoi, în
fereastra de proprietăŃi, se selectează pentru proprietatea buttonGroup numele obiectului
de tip ButtonGroup adăugat anterior.

Uneori metoda de tratare a evenimentului declanşat la selectarea unuia dintre


butoane trebuie să fie aceeaşi pentru toate butoanele care formează grupul.. Pentru a
impune acest lucru se scrie metoda folosind unul dintre butoane, după care se selectează
succesiv butoanele şi se editează numele dat implicit metodei de tratare a evenimentului
actionPerformed.
114

Starea iniŃială a butoanelor, respectiv butonul care apare selectat la afişarea


interfeŃei se impune folosind proprietatea selected a butoanelor. Evident, numai un buton
din grup poate avea starea selectat. Ca şi în cazul controalelor de tip JCheckBox, se
poate modifica prin program starea de selectare a unuia dintre butoanele care formează
grupul apelând metoda setSelected() şi se poate testa starea unuia dintre butoane prin
apelul metodei isSelected().

Controale Windows cu listă

Componentele Swing folosite limbajul Java începând cu versiunea 1.2


implementează arhitectura Model-View-Controller (MVC). Modelul MVC constă în esenŃă
în separarea datelor de reperezentarea lor. Datele sunt conŃinute într-un obiect (model)
asociat unui control Windows care realizează reprezentarea lor (view). Cea de-a treia
componentă, Controller realizează interceptarea şi procesarea evenimentelor.

Controller

View Model

Această abordare stă de altfel la baza independenŃei aplicaŃiilor Java de platforma


pe care se execută aplicaŃia.
Dacă pentru controale simple obiectul care conŃine datele este realizat automat
pentru controale complexe, care pot conŃine un număr mare şi variat de obiecte
(JComboBox, JList, JTable, JTree), programatorul poate opta între folosirea unui obiect
aparŃinând unei clase implicite (DefaultListModel, DefaultTableModel, DefaultTreeModel)
şi definirea unei clase proprii, derivată dintr-o clasă abstractă predefinită sau nederivată.
Evident complextitatea programării creşte dacă nu se foloseşte clasa implicită, dar în cazul
unor reprezentări mai deosebite este singura soluŃie.
115

JComboBox

Controlul de tip JComboBox permite selectarea unei valori dintr-o listă predefinită.
Definirea listei se realizează de obicei în etapa de proiectare a aplicaŃiei, conŃinutul
acesteia fiind accesibil prin intermediul proprietăŃii model, Lista poate fi construită şi
editată şi dinamic, în timpul execuŃiei, folosind metodele:

Tip
Metoda AcŃiune
returnat
void addItem(Object obj) Adaugă un element în listă
void insertItemAt(Object obj, int index) Inserează un element în listă
Object getSelectedItem() Returnează ob. selectat
int getSelectedIndex() Returnează poz. elem. selectat
void removeAllItems() Goleşte lista
void removeItem(Object obj) Suprimă prima apariŃie a obj.
void removeItemAt(int index) Suprimă el.. de la poziŃia index
int getItemCount() Returnează nr. de elemente
void setEditable() În funcŃie de argument
caseta de text va fi editabilă
sau needitabilă

În aplicaŃiile destinate realizării interfeŃei cu baze de date prezintă un mare


interes popularea listei prin preluarea valorilor dintr-o mulŃime de selecŃie, ca în
exemplul următor:

rezultat = comanda.executeQuery("SELECT * FROM edituri order by


nume");
while (rezultat.next()) // Trec pe urmatoarea linie
{ // preiau numele
String nm = rezultat.getString("nume");
listaed.addItem(nm); // listaed este un JComboBox
}

Pentru a însera o funcŃie de tratare a evenimentului produs la selectarea unui


element folosind un control de tip JComboBox se procedează ca şi în cazurile deja
prezentate, respectiv se selectează controlul cu butonul drept al mouse-ului şi în
meniul contextual se selectează Events / Action:
116

private void listaedActionPerformed(java.awt.event.ActionEvent evt)


{
// TODO add your handling code here:
// Copiez din combo in variabila numeed de tip String
numeed = (String)listaed.getSelectedItem();
}

Există situaŃii în care caseta de text a controlului trebuie să primească doar o


parte din şirul conŃinut în linia selectată. În exemplul următor s-a reŃinut în caseta de
text doar primul element din şirul de caractere conŃinut în linia selectată:

private void listacitActionPerformed(java.awt.event.ActionEvent evt)


{
// TODO add your handling code here:
// Preiau sirul de car. din lista
String nm = (String)listaed.getSelectedItem();
// Separ subsirurile din sir
String[] sir = nm.split(" ");
listaed.setEditable(true); // caseta combo devine editabilă
listaed.setSelectedItem(sir[0]); // preiau numai primul element
listaed.setEditable(false); // caseta combo devine needitabilă
. . . // In continuare urmeaza utilizarea valorii selectate
}

Metoda split() a clasei String permite separarea unui şir de caractere într-un
număr de subşiruri, separatorii permişi fiind daŃi într-un şir (al doilea argument). În
exemplul prezentat şirul folosit ca argument conŃine un spaŃiu.
Pentru a impune valoarea din caseta de text a controlului combinat trebuie
modificat tipul acestuia, din needitabil în editabil. După impunerea valorii se revine la
starea iniŃială. Modificarea acestei proprietăŃi se realizează folosind metoda
setEditable().

Exemplu : Se cere să se realizeze un formular pentru introducerea cititorilor


bibliotecii în tabelul Cititori având structura :
117

Câmpul COD_CIT fiind de tip autoincrement, este comod să se creeze pentru


iniŃializarea lui cu valori corecte un obiect de tip sequence (secvenŃă). Declararea în
Oracle XE a unui obiect de tip sequence se realizează selectând Object Browser /
Create / Sequence :

În noua fereastră se va defini numele obiectului (citi_seq), valoarea de start şi


incrementul.

EvidenŃierea funcŃionării noului obiect se poate realiza tastând o comandă SQL


SELECT.
118

FuncŃia NEXTVAL incrementează secvenŃa cu o unitate iar funcŃia CURRVAL


returnează valoarea curentă a acesteia.

Tot ca element ajutător s-a definit tabelul Judete. Acesta are două câmpuri şi
va fi folosit pentru popularea cu date a unui control JComboBox care va servi la
alegerea judeŃului. În tabelul Cititori va fi introdusă valoarea numerică ID_JUD
aferentă judeŃului selectat.

Ca şi în cazul primului formular realizat, se va adăuga clasei principale un


obiect din clasa JDialog căruia îi vor fi apoi adăugate controalele necesare, ca în
figură.

cit_nume, cit_prenume
cit_cnp
cit_jud
cit_loc

cit_adr

cit_tel, cit_email

cit_adauga, cit_imprima, cit_gata

Numele ferestrei de dialog este cititori iar în stânga imaginii noii ferestre sunt
scrise numele obiectelor pe care le conŃine. Pentru a putea imprima conŃinutul
formularului cititori, partea utilă a acestuia (zona de deasupra butoanelor de
comandă) a fost dispusă pe un control de tip JPanel (denumit cit_imprim).
119

Pentru afişarea formularului se va adăuga încă o opŃiune meniului derulant


Formulare , metoda de tratare a evenimentului declanşat la selectarea acestuia fiind
asemănătoare cu cea scrisă pentru primul formular:

Tot ca în cazul primului formular metoda declanşată de selectarea butonului


Gata (obiectul cit_gata) realizează ascunderea ferestrei.

Pentru a pregăti formularul în vederea culegerii de date trebuie populată lista


controlului cit_jud. Pentru aceasta vor fi adăugate clasei principale două noi obiecte,
cit_cmd de tip Statement şi cit_rs de tip ResultSet. Cele două noi variabile vor fi
iniŃializate în metodele asociate evenimentelor windowActivated şi windowDeactivated
(CititoriWindowActivated respectiv CititoriWindowDeactivated).
120

În continuare se pot scrie metodele apelate la acŃionarea butoanelor Adauga


şi Imprimă.
Pentru primul buton, secvenŃa de cod care trebuie scrisă va realiza construirea
unei comenzi INSERT folosind valorile din câmpurile formularului. Exemplu:

INSERT into Cititori VALUES (citi_seq.NEXTVAL, '0987654321123', 'Pop',


'Vasile',
'Drobeta', 12, 'Str. Mica Nr. 14, Bl. B4 Ap. 6', '0258123456','')

Pentru a construi valorile necesare introducerii cheii primare s-a utilizat


secvenŃa citi_seq declarată împreună cu tabelul Cititori.
Deoarece în comanda SQL şirurile de caractere sunt plasate între apostroafe,
este convenabilă adăugarea unei metode care să returneze un şir format prin
încardarea între apostroafe a şirului primit ca argument.
Metoda adăugată a fost denumită apostrof() şi are următoarea definiŃie:

Metoda cit_adaugaActionPerformed() apelată la apăsarea butonului Adauga


este următoarea:

private void cit_adaugaActionPerformed(java.awt.event.ActionEvent evt) {


try {
// Preiau valorile din controale
String cnp, nume, prenume, localitatea, adresa, telefon, email;
int jud;
cnp = cit_cnp.getText();
nume = cit_nume.getText();
prenume = cit_prenume.getText();
localitatea = cit_loc.getText();
// Preiau judetul din multimea de selectie
int poz = cit_jud.getSelectedIndex(); // Poz. in lista
// Caut in cit_rs poz. indicata
cit_rs.absolute(poz+1); // mut? cursorul pe a linia poz+1 din cit_rs
jud = cit_rs.getInt("ID_JUD");
adresa = cit_adr.getText();
telefon = cit_tel.getText();
email = cit_email.getText();
// Formulez comanda INSERT
String frazaSQL = "INSERT into Cititori VALUES (citi_seq.NEXTVAL";
frazaSQL += "," + apostrof(cnp);
frazaSQL += "," + apostrof(nume);
frazaSQL += "," + apostrof(prenume);
frazaSQL += "," + apostrof(localitatea);
frazaSQL += "," + jud;
frazaSQL += "," + apostrof(adresa);
121

frazaSQL += "," + apostrof(telefon);


frazaSQL += "," + apostrof(email)+ ")";
// Creez un Statement
Statement stm = cnx.createStatement();
// Apelez metoda executeUpdate() pt. a trimite comanda INSERT
//System.out.println(frazaSQL);
stm.executeUpdate(frazaSQL);
stm.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
Metoda cit_imprimaActionPerformed() apelată la apăsarea butonului Imprima
realizează imprimarea conŃinutului panoului (JPanel) cit_imprim pe imprimanta
implicită :

private void cit_adaugaActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
PrintUtilities.printComponent(cit_imprim);
}

Dacă se testează aplicaŃia, un rezultat posibil ar fi :

Preluarea datei calendaristice


Tabelul IMPRUMUT al utilizatorului BIBLIO conŃine două câmpuri de tip DATE.
122

Pentru inserarea unei înregistrări în acest tabel s-a realizat formularul


Imprumuturi.

nume_cititor titlu_carte

data_imp

data_rest

După crearea interfeŃei şi impunerea numelor variabilelor ca în figură, s-a


scris metoda aferentă evenimentului windowActivated. Aceasta va popula cu date
cele două controale cu listă, nume_cititor şi titlu_carte. Înaintea începerii programării
s-au adăugat clasei principale variabilele impstat şi impstatc din clasa Statement
respectiv imprs şi imprsc din clasa ResultSet.

private void ImprumuturiWindowActivated(java.awt.event.WindowEvent evt) {


// TODO add your handling code here:
try {
// Populez cele doua liste. Pentru ambele, multimile de selectie
// trebuie sa ramana active pana la terminare.
// Populez prima lista
impstat = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
imprs = impstat.executeQuery("SELECT * from Cititori order by Nume");
nume_cititor.removeAllItems();
while (imprs.next()) {
String n = imprs.getString("nume")+" "+imprs.getString("prenume");
nume_cititor.addItem(n);
}
// Populez a doua lista
impstatc = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
imprsc = impstatc.executeQuery("SELECT * from Carti order by Titlu");
titlu_carte.removeAllItems();
while (imprsc.next()) {
String n = imprsc.getString("Titlu");
titlu_carte.addItem(n);
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
123

După selectarea unei cărŃi va fi înregistrată data împrumutului în caseta de


text data_imp. SecvenŃa de cod corespunzătoare va constitui corpul metodei asociată
evenimentului actionPerformed declanşat de selectarea unei cărŃi folosind controlul
titlu_carte (JComboBox).
Caseta de text data_imp este iniŃializată cu data calendaristică furnizată de
sistemul de operare. Pentru aceasta s-a creat variabila locală azi din clasa Calendar
apelând metoda statică getInstance(). În continuare s-a definit variabila fmt din
clasa SimpleDateFormat destinată impunerii formatului dorit de afişare a datei
calendaristice.
Şirul de caractere care va conŃine data calendaristică în formatul impus se
obŃine prin apelul fmt.format(azi.getTime())). El va fi memorat în caseta de text
data_imp.
Metoda se încheie prin transferul controlului intrărilor spre data_rest (metoda
requestFocus()).

private void titlu_carteActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
Calendar azi = Calendar.getInstance();
SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
data_imp.setText(fmt.format(azi.getTime()));
data_rest.requestFocus();
}
Crearea unei noi înregistrări în tabelul IMPRUMUT se realizează printr-o
comandă INSERT creată în metoda asociată evenimentului actionPerformed declanşat
de apăsarea butonului "Inregistrare". Corpul acesteia este prezentat în continuare,
singura remarcă fiind aceea că numărarea elementelor unei mulŃimi de selecŃie începe
de la 1 iar poziŃia primului element din lista unei casete combinate este 0. De aceea
trecerea într-o mulŃime de selecŃie la o linie corespunzând unei poziŃii poz din lista
asociată unui control JComboBox se va realiza apelând multime.absolute(poz+1).

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
try {
// Inserez o linie in tabelul IMPRUMUT
// Preiau codul cititorului
int poz = nume_cititor.getSelectedIndex();
imprs.absolute(poz + 1); // Merg pe linia selectata
int codcit = imprs.getInt("cod_cit");
// Preiau codul cartii
poz = titlu_carte.getSelectedIndex();
imprsc.absolute(poz + 1); // Merg pe linia selectata
int codcarte = imprsc.getInt("cod_carte");
// Creez fraza INSERT
String frazaSQL = "INSERT into Imprumut VALUES (";
frazaSQL += String.valueOf(codcarte) + "," + String.valueOf(codcit);
frazaSQL += "," + apostrof(data_imp.getText());
frazaSQL += "," + apostrof(data_rest.getText());
frazaSQL += "," + 0 +")"; // 0 = FALSE, 1 = TRUE
// Creez un Statement
Statement stm = cnx.createStatement();
124

// Apelez metoda executeUpdate() pt. a trimite comanda INSERT


System.out.println(frazaSQL);
stm.executeUpdate(frazaSQL);
stm.close();
} catch (SQLException ex) {
ex.printStackTrace();
}

JTable

Obiectele din clasa JTable sunt controale Windows destinate afişării datelor sub
formă tabelară. Deoarece comanda SQL SELECT destinată interogării serverului de baze
de date furnizează datele în formă tabelară, este evident că interfaŃa grafică a aplicaŃiei va
conŃine astfel de controale. Controlul de tip JTable este însă unul deosebit de complex.
Pentru păstrarea claselor şi a interfeŃelor necesare construirii şi utilizării acestor controale,
în Swing există un un pachet special, javax.swing.table.
Ca şi în cazul celorlalte controale Windows, JTable are la bază arhitectura MVC
(Model - View - Controller).
View este componenta destinată afişării datelor şi este integral implementată în
clasa JTable, deci nu necesită atenŃie.
Model este practic un obiect care va conŃine datele de reprezentat. El va aparŃine
unei clase a aplicaŃiei derivată din clasa AbstractTableModel. Constructorul acestei clase
realizează memorarea într-un tablou bidimensional a datelor care vor fi conŃinute în tabel.
Controller este ansamblul de metode implementate pentru manipularea datelor
conŃinute în tabel şi tratarea evenimentelor utilizator. Metodele aparŃin interfeŃei
TableModel pe care clasa AbstractTableModel o implementează.

Exemplu fundamental:
Pentru evidenŃierea cărŃilor provenind de la diferite edituri se doreşte
realizarea unui formular care să permită navigarea în tabelul Edituri şi afişarea într-un
tabel a înregistrărilor din tabelul Carti asociate înregistrării curente din tabelul Edituri.
Rezolvare. Datele din tabel pot fi obŃinute prin executarea interogării

SELECT titlu, an_apar from Carti where cod_edit = coded

Parametrul coded este de tip int şi va avea valoarea cheii primare din tabelul
Edituri, cod_edit. Practic la trecerea în mulŃimea de selecŃie care conŃine datele din
125

tabelul edituri de pe o linie pe alta, coded va prelua din linia curentă a mulŃimii de
selecŃie valoarea câmpului cod_edit.
Pentru a-i asocia tabelului un obiect care să conŃină datele, model, se va
adăuga aplicaŃiei o nouă clasă, denumită TbModel derivată din AbstractTableModel.

Deoarece după adăugarea cuvintelor extends AbstractTableModel necesare


indicării derivării declaraŃia clasei apare ca eronată, se selectează ca în cazurile deja
întâlnite Fix Imports. De data aceasta evidenŃierea declaraŃiei clasei ca eronată nu
dispare. Aceasta deoarece clasa AbstractTableModel conŃine câteva metode abstracte
pe care orice clasă derivată trebuie în mod obligatoriu să le implementeze. Pentru
evidenŃierea acestora mediul NetBeans oferă următoarea cale:
• Se selectează în meniul aplicaŃiei Source / Override and Implements
Methods (sau se apasă Ctrl + I) pentru a se afişa fereastra Override
and Implement Methods.
126

• În fereastra Override and Implement Methods se selectează caseta


Show Abstract methods Only şi se selecteză cu Ctrl apăsat toate
metodele afişate :

• Se selectează Ok
NetBeans adaugă clasei TbModel cele trei metode selectate. Acestea vor
trebui ulterior editate.
În continuare este dat fişierul TbModel.java conŃinând clasa realizată.

package biblioteca;

import java.sql.ResultSet;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

public class TbModel extends AbstractTableModel {


private String[] colNume={"Titlu","Anul aparitiei"};
private ArrayList dateContinute; // va fi ArrayList de ArrayList

public TbModel(ResultSet rs) {


dateContinute = new ArrayList();
try{
while(rs.next()){
ArrayList linie = new ArrayList();
String titlu = rs.getString("TITLU");
int an_apar = rs.getInt("AN_APAR");
linie.add(titlu);
linie.add(an_apar);
dateContinute.add(linie);
}
} catch(Exception e){
System.out.println("Exceptie in TbModel");
}
}
127

public int getColumnCount() {


return colNume.length;
}

public Object getValueAt(int linie, int col) {


// Preiau linia rowIndex
ArrayList rand_cautat = (ArrayList) dateContinute.get(linie);
return rand_cautat.get(col);
}

public String getColumnName(int column) {


return colNume[column];
}

public int getRowCount() {


return dateContinute.size();
}
}

După realizarea acestor completări se poate începe construirea formularului


EditCarti. Dispunerea şi denumirile controalelor acestuia sunt cele din figura
următoare.

ec_nume EditCarti

ec_gata

ec_prec

ec_urm
ec_tabel

Celorlalte controale (JLabel şi JScrollPane) nu li s-au schimbat numele.


După adăugarea controlului ec_tabel din clasa JTable se realizează adaptările
necesare pentru a-i asocia obiectul care va deŃine datele (model), aparŃinând clasei
TbModel definită anterior.
Se selectează controlul ec_tabel (JTable) şi se apasă butonul din dreptul
proprietăŃii model:
128

În fereastra care se afişează se impun următoarele:


• numărul de linii care se va afişa,
• numărul de coloane,
• titlul fiecărei coloane şi
• tipul de dată afişat în fiecare coloană.
129

Pentru afişarea formularului realizat se va adăuga meniului derulant


Formulare o intrare suplimentară, metoda asociată selectării acesteia realizând
afişarea ferestrei EditCarti.

AplicaŃia mai trebuie completată cu câteva metode asociate unor evenimente:


activarea sau dezactivarea ferestrei EditCarti sau acŃionarea butoanelor din fereastră.
Deoarece repopularea tabelului ca urmare a reconstruirii mulŃimii de selecŃie
corespunzătoare unei valori a cheii primare din tabelul Edituri, cod_edit se realizează
repetat, în trei metode ale clasei (la afişarea formularului şi la apăsarea butoanelor
Precedenta şi Urmatoarea), este bine să se programeze o metodă ajutătoare. Metoda
realizată a fost denumită populareTablou() şi conŃinutul ei este prezentat în
continuare.

public void populareTablou(int coded) {


Statement carti_stmt = null;
ResultSet rs = null;
try {
carti_stmt = cnx.createStatement();
rs = carti_stmt.executeQuery
( "SELECT titlu, an_apar FROM Carti WHERE cod_edit = "
+ String.valueOf(coded));
ec_tabel.setModel(new TbModel(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn column = null;
column = ec_tabel.getColumnModel().getColumn(0);
column.setPreferredWidth(300);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
După impunerea conŃinutului tabelului prin apelul metodei setModel() se
realizează redimensionarea primei coloane a tabelului. Această operaŃie este
necesară deoarece în mod normal coloanele sunt create de lăŃimi egale. Fiecare
coloană dintr-un JTable are asociat un obiect din clasa TableColumn. Clasa
TableColumn conŃine metode pentru preluarea sau impunerea lăŃimii unei coloane. În
exemplul dat obŃinerea obiectului TableColumn asociat primei coloane ("Titlu") se
realizează scriind ec_tabel.getColumnModel().getColumn(0). LăŃimea acesteia este
ulterior modificată prin apelul metodei setPreferredWidth().

SecvenŃa de program care trebuie să se execute la activarea ferestrei


realizează crearea mulŃimii de selecŃie necesară navigării în tabelul Edituri şi, după
preluarea codului primei edituri, apelează metoda populareTablou(). Obiectul
130

comanda din clasa Statement, va rămâne deschis pe toată durata afişării formularului
EditCarti.

private void EditCartiWindowActivated(java.awt.event.WindowEvent evt) {


// TODO add your handling code here:
try {
comanda = cnx.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rezultat = comanda.executeQuery("SELECT * FROM edituri order by nume");
// carti_stmt = cnx.createStatement();
if (rezultat.next()) // Trec pe prima linie
{
String nm = rezultat.getString("nume");
ec_nume.setText(nm);
int coded = rezultat.getInt("cod_edit");
populareTablou(coded);
}
} catch ( SQLException sqlException ) {
System.out.println("Conectare imposibila.");
System.exit( 1 );
}
}

La închiderea formularului va fi închis obiectul Statement comanda .

Metodele asociate butoanelor "Precedenta" respectiv "Urmatoarea" realizează


deplasarea în mulŃimea de selecŃie conŃinând înregistrările din tabelul Edituri. La
trecerea pe o nouă linie a mulŃimii de selecŃie se preia numele editurii şi se
reconstruieşte tabelul cu cărŃi prin apelul metodei setModel().

private void ec_urmActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
try {
if(!rezultat.isLast()) // nu este pe ultima linie
{
ec_prec.setEnabled(true);
if (rezultat.next()) // Trec pe urmatoarea linie
{ // preiau numele
String nm = rezultat.getString("nume");
ec_nume.setText(nm);
int coded = rezultat.getInt("cod_edit");
populareTablou(coded);
131

}
} else {
ec_urm.setEnabled(false);
}
} catch (SQLException esq) {}
}

private void ec_precActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
try {
if(!rezultat.isFirst()) // nu este pe prima linie
{
ec_urm.setEnabled(true);
if (rezultat.previous()) // Trec pe linia anterioara
{ // preiau numele
String nm = rezultat.getString("nume");
ec_nume.setText(nm);
int coded = rezultat.getInt("cod_edit");
populareTablou(coded);
}
} else {
ec_prec.setEnabled(false);
}
} catch (SQLException esq) {}
}

Butonul Iesire realizează ascunderes ferestrei EditCarti:

private void ec_gataActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
EditCarti.setVisible(false);
}

Rezultat posibil:
132

ObservaŃie
Foemularul realizat oferă o soluŃie pentru afişarea informaŃiilor din două
tabele aflate în relaŃie 1 la n. De obicei însă selectarea în primul tabel se realizează
folosind o casetă combinată (JComboBox). Selectarea unei valori în caseta combinată
provoacă repopularea controlului din clasa JTable în care sunt afişate datele din al
doilea tabel. Exemplul precedent poate fi uşor modificat asfel încât editura să fie
selectată într-un control JComboBox. O variantă posibilă este fereastra de dialog
CitEdCombo prezentată în continuare.

cited_Editura

cited_Carti

CitEdCombo

După adăugarea controalelor şi schimbarea numelor acestora ca în figură,


proprietăŃile controlului de tip JTable sunt modificate ca în exemplul precedent
(numărul de coloane, titlurite) şi apoi sunt generate şi editate patru metode
1. WindowActivated:

private void CitEdComboWindowActivated(java.awt.event.WindowEvent evt) {


// TODO add your handling code here:
try {
cited_comanda = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
cited_rs = cited_comanda.executeQuery("SELECT * from Edituri order by Nume");
cited_Editura.removeAllItems();
while (cited_rs.next()) {
String n = cited_rs.getString("nume");
cited_Editura.addItem(n);
}
// Preiau codul primei edituri din lista
cited_rs.first();
int coded = cited_rs.getInt("Cod_Edit");
133

// Populez tabelul
populareTablou1(coded);
} catch (SQLException ex) {
ex.printStackTrace();
}
}

Variabilele folosite la popularea cu date a controlului de tip JComboBox ,


cited_comanda (Statement) şi cited_rs (ResultSet) au fost în prealabil adăugate
variabilelor clasei principale.
Metoda populareTablou1() este similară metodei populareTablou(). DiferenŃa
constă în numele controlului din clasa JTable referit.

2. WindowDeactivated
La închiderea formularului trebuie apelate metodele close aferente obiectelor
de tip Statement şi ResultSet folosite.

private void CitEdComboWindowDeactivated(java.awt.event.WindowEvent evt) {


// TODO add your handling code here:
try {
cited_comanda.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}

3. ActionPerformed (declanşat de JComboBox)


Selectarea unei edituri în caseta combinată declanşează un eveniment
ActionPerformed. Metoda aferentă trebuie generată şi editată astfel:

private void cited_EdituraActionPerformed(java.awt.event.ActionEvent evt) {


try {
// TODO add your handling code here:
// Se selecteaza codul noii edituri
int linie = cited_Editura.getSelectedIndex();
cited_rs.absolute(linie+1); // mut cursorul in cited_rs pe linie
int coded = cited_rs.getInt("Cod_Edit");
// Repopulez tabelul
populareTablou1(coded);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
134

4. ActionPerformed (declanşat de butonul Iesire)


Apăsarea butonului Iesire provoacă ascunderea ferestrei de dialog
CitEdCombo.

Inserarea in JTable a altor tipuri de obiecte

Celulele de pe o coloană a unui tabel pot conŃine în principiu orice tip de


obiect, mai frecvent folosite fiind pictogramele şi controale de tip JComboBox.
Crearea unui tabel conŃinând astfel de obiecte necesită însă adăugarea de noi
clase şi secvenŃe de cod care asigură afişarea corectă şi tratarea evenimentelor
specifice.

Exemplu: Se consideră un formular care afişează cititorii unei biblioteci:

Pentru a da posibilitate operatorului să iniŃieze corectarea datelor unui cititor


prin simpla selectare cu mouse-ul a pictogramei din prima coloană corespunzând liniei
eronate se va proceda astfel:
135

1. Se adaugă aplicaŃiei o clasă nouă care va prelua afişarea noului tip de


dată:

package biblioteca;
public class Afisez {

/** Creates a new instance of Afisez */


public Afisez() {
}
}

Se corectează declaraŃia clasei astfel încât să fie derivată din


DefaultTableCellRenderer.
public class Afisez extends DefaultTableCellRenderer {
...
Se elimină eroarea evidenŃiată de editor prin completarea listei de pachete
incluse folosind opŃiunea Fix imports a mediului de programare.
Se suprascrie metoda getTableCellRendererComponent() moştenită de la clasa
de bază. Pentru aceasta se selectează în meniul derulant Source opŃiunea Override
Methods:

Metoda adăugată este apoi editată. Corpul acesteia va conŃine crearea unui
obiect din clasa ImageIcon. Acesta va fi impus ca şi conŃinut al celulei din tabel prin
apelul metodei setIcon().

public Component getTableCellRendererComponent(JTable table,


136

Object value, boolean isSelected, boolean hasFocus, int row, int column) {
ImageIcon icon=new ImageIcon( getClass().getResource("img/edit_big.gif"));
setIcon(icon);
return this;
}
2. Ca şi în exemplele precedente se adaugă aplicaŃiei o clasă nouă
(denumită TbModelCiti) care va servi la păstrarea datelor tabelului. ConŃinutul
acesteia este similar celor deja realizate.

package biblioteca;

import java.sql.ResultSet;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

public class TbModelCiti extends AbstractTableModel {

private String[] colNume={"Edit","Nume", "Prenume", "CNP"};


private ArrayList dateContinute; // va fi ArrayList de ArrayList

/** Creates a new instance of TbModelCiti */


public TbModelCiti(ResultSet rs) {
dateContinute = new ArrayList();
try{
while(rs.next()){
ArrayList linie = new ArrayList();

String nume = rs.getString("NUME");


String prenume = rs.getString("PRENUME");
String cnp = rs.getString("CNP");
linie.add(null); // aici va fi pictograma
linie.add(nume);
linie.add(prenume);
linie.add(cnp);
dateContinute.add(linie);
}
} catch(Exception e){
System.out.println("Exceptie in TbModel");
}
}

public Object getValueAt(int linie, int col) {


// Preiau linia rowIndex
ArrayList rand_cautat = (ArrayList) dateContinute.get(linie);
return rand_cautat.get(col);
}

public int getRowCount() {


return colNume.length;
}

public int getColumnCount() {


return dateContinute.size();
}

public String getColumnName(int column) {


137

return colNume[column];
}
}

3. Înaintea creării tabelului pentru afişarea cititorilor se vor adăuga clasei


principale perechea de variabile comanda_citi (Statement) şi rs_citi (ResultSet)
precum şi metoda getCiti() care construieşte un obiect din clasa ResultSet conŃinând
cititorii din baza de date.

public ResultSet getCiti() {


rs_citi=null;
try {
comanda_citi = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs_citi=comanda_citi.executeQuery("Select * from Cititori");
} catch (SQLException ex) {
ex.printStackTrace();
}
return rs_citi;
}

4. Crearea tabelului conŃinând cititorii se va face prin inserarea lui folosind


mediul de dezvoltare. După inserare se va accesa proprietatea model:

În fereastra de definire a modelului se va selecta pentru Select Mode:


valoarea Form Connection:

Apoi se va apăsa butonul Advanced şi vor fi impuse secvenŃele de cod care


vor fi executate înaintea respectiv după crearea tabelului tabelCiti:
138

SecvenŃa Post-initialization impune clasa Afişez realizată anterior ca delegată


pentru afişarea primei coloane a tabelului.
După selectarea butonului Ok se revine în fereastra de editare a modelului, se
selectează butonul User Code şi se adaugă apelul constructorului clasei TbModelCiti.

Cele 3 secvenŃe de cod incluse în fereastra de configurare a modelului pot fi


identificate în corpul metodei initComponents(), generată automat de către mediul de
dezvoltare.

...
139

De altfel această procedură poate fi urmată în toate cazurile în care se doreşte


impunerea unui anumit mod de creare a unei componente a interfeŃei.

Pentru a realiza afişarea unei ferestre de editare la selectarea cu mouse-ul a


unei pictograme din prima coloană a tabelului, în metoda executată la activarea
ferestrei se va creea un obiect aparŃinând unei clase anonime care va implementa
interfaŃa ListSelectionListener, ca mai jos.

private void AfisareCititoriWindowActivated(java.awt.event.WindowEvent evt) {


// TODO add your handling code here:
tabelCiti.setRowHeight(32);
tabelCiti.clearSelection();
TableColumn column = null;
column = tabelCiti.getColumnModel().getColumn(0);
column.setPreferredWidth(0);
column = tabelCiti.getColumnModel().getColumn(1);
column.setPreferredWidth(130);
tabelCiti.setCellSelectionEnabled(false);
column = tabelCiti.getColumnModel().getColumn(2);
column.setPreferredWidth(130);
ListSelectionModel rowSM = tabelCiti.getSelectionModel();
rowSM.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
//Ignore extra messages.
if (e.getValueIsAdjusting()) return;
ListSelectionModel lsm =
(ListSelectionModel)e.getSource();
if (!lsm.isSelectionEmpty()) {
int selectedRow = lsm.getMinSelectionIndex();
//selectedRow is selected
int coloana =

tabelCiti.getColumnModel().getSelectionModel().getAnchorSelectionIndex();
if(coloana == 0) {
String s = "Celula " + selectedRow + ", " + coloana + " e selectata.";
JOptionPane.showMessageDialog(null,s); // Se inlocuieste
}
tabelCiti.clearSelection();
}
}
});

Calendar azi = Calendar.getInstance();


SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
dataRaport.setText(fmt.format(azi.getTime()));
}

Apelul JOptionPane.showMessageDialog(null,s); va fi înlocuit cu apelul


metodei SetVisible(true) pentru fereastra de dialog care trebuie afişată (fereastra de
editare a cititorului).
140

Laborator nr. 9

InterfaŃa aplicaŃiei. Controale Windows. Adăugarea datelor în baza de date.

1. PorniŃi aplicaŃia NetBeans.


2. CreaŃi un formular pentru adăugarea autorilor în baza de date

Obs.
• adăugaŃi meniului aplicaŃiei biblio o nouă intrare în meniul Formulare, Adăugare – de tip
JMenu, cu o opŃiune, Autori (JMenuItem).
• ataşaŃi opŃiunii din meniu adâugate o funcŃie de tratare (actionPerformed) conŃinând
secvenŃa de cod:
AAutori.setLocation(120,170);
AAutori.setVisible(true);
AAutori.pack();

• creaŃi în Oracle un obiect de tip sequence (secvenŃă) necesar introducerii codului autorului.
Numele noului obiect va fi autoaut.
Pentru aceasta selectaŃi în interfaŃa grafică a serverului Oracle XE Object Browser / Create /
Sequence şi daŃi secvenŃei numele autoaut, cu valoarea de pornire 1 şi valoarea incrementului
1.
• CreaŃi un formular pentru adăugarea cititorilor în baza de date, astfel:
 selectaŃi succesiv fereastra principală şi controlul JDialog din fereastra Palette;
 selectaŃi cu dublu clic intrarea în arborele din fereastra Inspector identificatorul noii
ferestre;
 adăugaŃi cele trei controale de tip JLabel (pentru titlu şi etichetele formularului), două
controale de tip JTextField şi cele două controale de tip JButton;
 schimbaŃi textele corespunzătoare acestor controale;
141

 schimbaŃi numele controalelor (clic dreapta pe control în fereastra Inspector -> Change
Variable Name) astfel:

Obs. Deoarece în comanda SQL insert care va fi construită în cadrul funcŃiei apelate la acŃionarea
butonului Introducere şirurile de caractere sunt plasate între apostroafe, este convenabilă adăugarea
în cadrul clasei principale a unei metode care să returneze un şir format prin încardarea între
apostroafe a şirului primit ca argument.

Metoda adăugată a fost denumită apostrof() şi are următoarea definiŃie:

public String apostrof(String p)


{
String c = "'" + p + "'";
return c;
}

• codul necesar preluării conŃinuturilor din controale şi apoi scrierii în baza de date este :
try
{
String nume, prenume;
nume = numaut.getText();
prenume = prenumaut.getText();

String frazaSQL = "INSERT into autori VALUES (autoaut.NEXTVAL";


frazaSQL += "," + apostrof(nume);
frazaSQL += "," + apostrof(prenume)+ ")";
// Creez un Statement*/
Statement stm = cnx.createStatement();
// Apelez metoda executeUpdate() pt. a trimite comanda INSERT
stm.executeUpdate(frazaSQL);
stm.close();
142

}
catch (SQLException ex) {
ex.printStackTrace();
}
numaut.setText("");
prenumaut.setText("");
}

• adăugaŃi codul necesar închiderii formularului AAutori


AAutori.setVisible(false);

3. AdăugaŃi proiectului biblio o altă intrare în submeniul Formulare/ Adăugare – Cititori.


(JMenuItem).

4. AdăugaŃi intrării acititori ( = adăugare cititori) evenimentului actionPerformed codul:


ACititori.setLocation(120,170);
ACititori.setVisible(true);
ACititori.pack();

5. CreaŃi în baza de date biblio, un nou tabel, judet, cu 3 câmpuri, cod_jud (number(2,0)), judeŃ
(varchar2(50)) şi acronim (char(2) şi introduceŃi câteva judeŃe.
6. ModificaŃi în baza de date tabelul cititori , înlocuind câmpul judetul cu noul câmp, cod_jud,
cheie străină.
7. ModificaŃi deopotrivă felul câmpului cod_cit, transformându-l în câmp de tip autoincrement.
Pentru asta declaraŃi un obiect de tip secvenŃă (Object Browser / Create / Sequence) cu numele de
autocit, cu valoarea de pornire 1 şi valoarea incrementului 1:
8. CreaŃi un formular pentru adăugarea cititorilor în baza de date, astfel:
• selectaŃi succesiv fereastra principală şi controlul JDialog din fereastra Palette;
143

• selectaŃi cu dublu clic intrarea în arborele din fereastra Inspector identificatorul noii
ferestre;
• adăugaŃi cele nouă controale de tip JLabel (pentru titlu şi etichetele formularului), şase
controale de tip JTextField, un control de tip JTextArea , un control de tip JComboBox şi
cele două controale de tip JButton;
• schimbaŃi textele corespunzătoare acestor controale;
• schimbaŃi numele controalelor (clic dreapta pe control în fereastra Inspector -> Change
Variable Name) astfel:

• adăugaŃi clasei principale două noi obiecte, unul adcitrez, din clasa Statement ( iniŃializat la
deschiderea formularului şi închis la ieşirea din acesta), şi un al doilea, interogare1, din
clasa ResultSet (acesta va conŃine comenzi SQL individuale care vor fi apoi trimise
serverului Oracle XE ) respectând ordinea: Biblio -> Source Packages -> Biblioteca ->
Biblio.java
->Biblio -> Fields -> Add Field;

• ataşaŃi evenimentului windowActivated ( în fereastra Inspector : Form Biblio ->


Other Components -> ACititori) metoda AutoriWindowActivated care va conŃine:
- iniŃializarea celor două obiecte (adcitrez şi interogare1);
144

- popularea cu date a listei controlului jud de tip combobox;

try {
adcitrez = cnx.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
interogare1 = adcitrez.executeQuery("SELECT * FROM judet order by judet");
jud.removeAllItems();
while (interogare1.next()) {
String nm = interogare1.getString("judet");
jud.addItem(nm);
}
} catch ( SQLException ex ) {
ex.printStackTrace();
System.exit( 1 );
}

• ataşaŃi evenimentului windowDeactivated metoda ACititoriWindowDeactivated


try {
adcitrez.close();
interogare1.close();
} catch (SQLException ex) {
ex.printStackTrace();
}

• codul necesar preluării conŃinuturilor din controale şi apoi scrierii în baza de date este :
try
{
String cenepe, nume, prenume, localitatea, adresa, telefon, mail;
int jude;
cenepe = cnp.getText();
nume = num.getText();
prenume = pren.getText();
localitatea = loc.getText();

int poz = jud.getSelectedIndex(); // Poz. in lista


interogare1.absolute(poz+1); // mut cursorul pe linia poz+1
jude = interogare1.getInt("cod_jud");

adresa = adr.getText();
telefon = tel.getText();
mail = email.getText();

String frazaSQL = "INSERT into cititori VALUES (autocit.NEXTVAL";


frazaSQL += "," + apostrof(cenepe);
frazaSQL += "," + apostrof(nume);
frazaSQL += "," + apostrof(prenume);
frazaSQL += "," + apostrof(localitatea);
145

frazaSQL += "," + jude;


frazaSQL += "," + apostrof(adresa);
frazaSQL += "," + apostrof(telefon);
frazaSQL += "," + apostrof(mail)+ ")";
// Creez un Statement*/
Statement stm = cnx.createStatement();
// Apelez metoda executeUpdate() pt. a trimite comanda INSERT
System.out.println(frazaSQL);
stm.executeUpdate(frazaSQL);
stm.close();
}
catch (SQLException ex) {
ex.printStackTrace();
}

• adăugaŃi codul necesar închiderii formularului ACititori


ACititori.setVisible(false);

9. CreaŃi un formular pentru adăugarea editurilor în baza de date


146

Laborator nr. 10

InterfaŃa aplicaŃiei. Controale Windows. JTable.

10. PorniŃi aplicaŃia NetBeans.


11. AdăugaŃi proiectului biblio o altă intrare în meniul Formulare, Situatii – de tip JMenu, cu o
intrare de tip JMenuItem, Cartile unui autor.

12. AdăugaŃi pentru intrarea cartiaut ( = cartile unui autor) metoda de tratare a evenimentului
actionPerformed care va conŃine codul:
CartiAut.setLocation(120,170);
CartiAut.setVisible(true);
CartiAut.pack();
13. CreaŃi un formular pentru vizualizarea cărŃilor unui autor, astfel:

pentru funcŃionarea corectă a formularului trebuie să procedaŃi astfel :


• adăugaŃi aplicaŃiei o nouă clasă, TbModel derivată din AbstractTableModel
147

După adăugarea noii clase corectaŃi-i declaraŃia astfel încât să reiasă derivarea dorită:

public class TbModel extends AbstractTableModel {

• adăugaŃi clasei TbModel două variabile:


private String[] colNume={"Cartea","Anul aparitiei"};
private ArrayList dateContinute; // va fi ArrayList de ArrayList

• adăugaŃi clasei TbModel trei metode - getColumnCount(), getRowCount() şi


getValueAt(int,int) - alegând Source -> Override Methods -> Show abstract Methods
Only. Odată cu adăugarea clasei TbModel s-a creat fişierul TbModel.java. Aici editaŃi
codul celor trei metode astfel:

public int getColumnCount() {


return colNume.length;
}

public int getRowCount() {


return dateContinute.size();
}

public Object getValueAt(int linie, int col) {


// Preiau linia rowIndex
ArrayList rand_cautat = (ArrayList) dateContinute.get(linie);
return rand_cautat.get(col);
}

• AdăugaŃi noii clase metoda getColumnName() :

public String getColumnName(int column) {


return colNume[column];
}

• EditaŃi constructorul clasei TbModel astfel încât să adauge în variabila dateContinute


din clasa ArrayList datele primite în momentul apelării constructorului conŃinute într-un
obiect din clasa ResultSet.
public class TbModel extends AbstractTableModel{
private String[] colNume={"Cartea","Anul aparitiei"};
private ArrayList dateContinute; // va fi ArrayList de ArrayList
148

/** Creates a new instance of TbModel */


public TbModel(ResultSet rs) {
dateContinute = new ArrayList();
try{
while(rs.next()){
ArrayList linie = new ArrayList();
String cartea = rs.getString("titlu");
int an_apar = rs.getInt("an_apar");
linie.add(cartea);
linie.add(an_apar);
dateContinute.add(linie);
}
} catch(Exception e){
System.out.println("Exceptie in TbModel");
}

• reveniŃi la clasa principală şi adăugaŃi-i două variabile globale , una de tip Statement şi
una de tip ResultSet:
Statement aut_comanda ;
ResultSet aut_rs ;
• la deschiderea formularului trebuie rulată o secvenŃă de cod care populează controalele
aut (JComboBox) şi autcarti (JTable):
private void CartiAutWindowActivated(java.awt.event.WindowEvent evt) {
// TODO add your handling code here:

try {
aut_comanda =
cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
aut_rs = aut_comanda.executeQuery("SELECT * from autori order by
nume");
aut.removeAllItems();
while (aut_rs.next()) {
String n = aut_rs.getString("nume");
aut.addItem(n);
}
// Preiau codul primului autor din lista
aut_rs.first();
int codaut = aut_rs.getInt("cod_aut");

// Populez tabelul din grid

Statement carti_stmt = null;


ResultSet rs = null;
try {
149

carti_stmt = cnx.createStatement();
rs = carti_stmt.executeQuery
("SELECT carti.titlu, carti.an_apar FROM carti, autori, autcarti
WHERE autori.cod_aut = autcarti.cod_aut and carti.cod_carte = autcarti.cod_carte
and autori.cod_aut = "
+ String.valueOf(codaut));
autcarti.setModel(new TbModel(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn column = null;
column = autcarti.getColumnModel().getColumn(0);
column.setPreferredWidth(300);

} catch (SQLException ex) {


ex.printStackTrace();
}

} catch (SQLException ex) {


ex.printStackTrace();
}

• la închiderea formularului trebuie apelată metoda close pentru obiectul de tip Statement
folosit:
private void CartiAutWindowDeactivated(java.awt.event.WindowEvent evt) {
// TODO add your handling code here:
try {
aut_comanda.close();
} catch (SQLException ex) {
ex.printStackTrace();
}

• AtaşaŃi o metodă de tratare a evenimentului produs la selectarea unui nou autor în


controlul aut (JComboBox) . În această metodă se va prelua codul autorului selectat de
utilizator şi se va repopula controlul autcarti (JTable).

private void autActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
try {
// Se selecteaza codul autorului
int linie = aut.getSelectedIndex();
150

if (linie>=0){
aut_rs.absolute(linie+1);
int codaut = aut_rs.getInt("Cod_aut");
// Repopulez tabelul
Statement carti_stmt = null;
ResultSet rs = null;
try {
carti_stmt = cnx.createStatement();

rs = carti_stmt.executeQuery

("SELECT carti.titlu, carti.an_apar FROM carti, autori, autcarti WHERE


autori.cod_aut = autcarti.cod_aut and carti.cod_carte = autcarti.cod_carte
and autori.cod_aut = "
+ String.valueOf(codaut));
// Repopulare JTable
autcarti.setModel(new TbModel(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn column = null;
column = autcarti.getColumnModel().getColumn(0);
column.setPreferredWidth(300);

} catch (SQLException ex) {


ex.printStackTrace();
}

}
} catch (SQLException ex) {
ex.printStackTrace();

• Metoda executată la apăsarea butonului "Iesire"


private void ies3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
CartiAut.setVisible(false);
}

14. Respectând aceeaşi procedură ca şi la formularul anterior, creaŃi un formular pentru


vizualizarea cărŃilor apărute la o editură, astfel:
151

ObservaŃii:
• fraza SELECT pentru popularea controlului de tip JComboBox va fi:
SELECT * from edituri order by nume

• fraza SELECT pentru popularea controlului de tip JTable va fi:


SELECT carti.titlu, autori.nume, carti.an_apar FROM carti, autori, autcarti, edituri WHERE
autori.cod_aut = autcarti.cod_aut and carti.cod_carte = autcarti.cod_carte and carti.cod_edit =
edituri.cod_edit and edituri.cod_edit = String.valueOf(codedit)

• dacă fraza SELECT este prea lungă, puteŃi adopta următorul mod de scriere:
String fraza;

fraza = "SELECT carti.titlu, autori.nume, carti.an_apar ";


fraza += "FROM carti, autori, autcarti, edituri ";
fraza += "WHERE autori.cod_aut = autcarti.cod_aut and ";
fraza += "carti.cod_carte = autcarti.cod_carte and ";
fraza += "carti.cod_edit = edituri.cod_edit and ";
fraza += "edituri.cod_edit = " + String.valueOf(codedit);

rs = carti_stmt.executeQuery(fraza);

• clasa declarată :

public class TbModel_1 extends AbstractTableModel {

private String[] colNume={"Titlul cartii","Autorul", "Anul aparitiei"};


private ArrayList dateContinute; // va fi ArrayList de ArrayList

public TbModel_1(ResultSet rs) {


dateContinute = new ArrayList();
152

try{
while(rs.next()){
ArrayList linie = new ArrayList();

String cartea = rs.getString("titlu");


String autorul = rs.getString("nume");
int an_apar = rs.getInt("an_apar");

linie.add(cartea);
linie.add(autorul);
linie.add(an_apar);

dateContinute.add(linie);
}

} catch(Exception e){
System.out.println("Exceptie in TbModel_1");
}

}
• cele patru metode ale noii clase vor fi identice cu metodele clasei TbModel de la
exemplul anterior
• declaraŃi două variabile globale , una de tip Statement şi una de tip ResultSet:
Statement edi_comanda ;
ResultSet edi_rs ;

15. CreaŃi un formular pentru vizualizarea cărŃilor împrumutate de către un cititor, astfel:

S-ar putea să vă placă și