You are on page 1of 16

Forrs: http://www.doksi.

hu

Adatbzis kliens alkalmazs NetBeans-ben


Szksges programok:
NetBeans
PostgreSQL
PostgreSQL JDBC Driver

Az adatbzis
Az adatbzis nem bonyolult, de a clnak megfelel.

Adatbzis tulajdonos felhasznl ltrehozsa


CREATE ROLE citizen LOGIN
ENCRYPTED PASSWORD 'md5406dff156756e03e214f3c52c5dec68c'
NOSUPERUSER INHERIT CREATEDB CREATEROLE;
A jelsz citizen.

Adatbzis ltrehozsa
CREATE DATABASE
WITH OWNER
ENCODING =
TABLESPACE

citizensdb
= citizen
'UTF8'
= pg_default;

Tblk ltrehozsa
A cities tbla

CREATE TABLE cities


(
city_id serial NOT NULL,
city_name character varying(64) NOT NULL,
CONSTRAINT cities_pkey PRIMARY KEY (city_id),
CONSTRAINT cities_ukey UNIQUE (city_name)
) WITHOUT OIDS;
ALTER TABLE cities OWNER TO citizen;

A citizens tbla
CREATE TABLE citizens
(
citizen_id serial NOT NULL,
citizen_name character varying(64) NOT NULL,
citizen_city_id integer NOT NULL,
CONSTRAINT citizens_pkey PRIMARY KEY (citizen_id),

Forrs: http://www.doksi.hu

CONSTRAINT citizens_cities_fkey FOREIGN KEY (citizen_city_id)


REFERENCES cities (city_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
) WITHOUT OIDS;
ALTER TABLE citizens OWNER TO citizen;

A projektek ltrehozsa
A programhoz kt projektet hozunk ltre: a f alkalmazst, s az adatbzishoz kttt vezrlinket
tartalmaz programknyvtrat. Ezeket azrt tesszk kln programknyvtrba, hogy
jrafelhasznlhatak legyenek ms projektekben is.

A f projekt
File->New Project. Categories listadobozban kijelljk a General-t, a Projects listadobozban a Java
Application-t. Next. A Project Name szvegdobozba berjuk hogy Citizens, kikapcsoljuk a Create
Main Class-t, s Finish.
Elsknt a PostgreSQL JDBC Driver-t kell beletenni a projektnkbe. Menjnk be a DB project
Properties-be, Libraries, Add JAR/Folder. Keressk meg a postgresql-jdbc.jar-t, s adjuk hozz. (Ez
nlam Fedora 8-on a /usr/share/java mappban volt.) OK. Innentl a DB projektnk kpes
kapcsoldni postgresql adatbzishoz.
A Source Packages-be hozzunk ltre egy j csomagot, a neve citizens. A csomagba hozzunk ltre
kt JFrame Class-t, az egyiknek a neve CitizensFrame, a msiknak CitiesFrame.
Most mst nem fogunk csinlni, a tbbihez mr szksg van az j vezrlinkre.

A programknyvtr ltrehozsa
File->New Project. Categories listadobozban kijelljk a General-t, a Projects listadobozban a Java
Class Library-t. Next. A Project Name szvegdobozba berjuk hogy DB, s Finish.
Ezutn mg mindig a Citizens projekt marat az aktv, ez nem baj, berakjuk hozz fggsgnek a
DB-t. A Citizens projekten jobbgomb->Properties. A Categories listadobozban vlasszuk ki a
Librariest. Jobboldalt Add Project, vlasszuk ki a DB projektnk fknyvtrt, s OK. Mostantl a
Citizens projektnk fgg a DB-tl, ha valamit vltoztatunk a DB-ben, jra fogja fordtani a DB-t is,
s a Citizens-t is. Ezrt maradhat nyugodtan a Citizens f projektnek.
Ehhez a projekthez is adjuk hozz a PostgreSQL JDBC Drivert.
A DB projektben a Source Packages-hez hozzunk ltre egy db nev Java Package-t.
Ezzel a kt alap projektnket el is ksztettk.

Az adatbzishoz kttt osztlyok ltrehozsa


A DBConnection osztly
Ez az osztly fogja trolni az adatbzis kapcsolatunkat. Minden egyes vezrlnk ehhez az
osztlyhoz lesz ktve, ezen keresztl tudjk frissteni a megjelentett adatokat.
A DB csomagba hozzunk ltre egy DBConnection nev Java Class-t. Az osztlyben t fle adatot
fogunk trolni:

host

Forrs: http://www.doksi.hu

felhasznlnv

jelsz

adatbzisnv

kapcsolat

Csinljunk ngy String tpus vltozt, rgtn az osztly fejlc utn, valamint egy Connection
tpust (java.sql.Connection).
public class DBConnection {
private
private
private
private
private

String host;
String username;
String password;
String dbName;
Connection connection;

A Connection-t els krben valsznleg alhzza pirossal, ez azrt van, mert mg nem
importltuk. A Connection-n hobbgomb->Fix Imports, s ksz.
Ksztsk el a kapcsolds/jrakapcsolds/bonts metdusainkat.
public void connect() {
if(host != null && dbName != null && username != null && password != null)
{
disconnect();
try {
Class.forName("org.postgresql.Driver");
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
try {
String url = "jdbc:postgresql://" + host + "/" + dbName;
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
connection = DriverManager.getConnection(url, props);
} catch(SQLException e) {
e.printStackTrace();
}
}
}
public void reconnect() {
disconnect();
connect();
}
public void disconnect() {
try {
if(connection != null && !connection.isClosed()) {
connection.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
}

Kellenek mg a get/set metdusok a vltozkhoz:

Forrs: http://www.doksi.hu

public String getHost() {


return host;
}
public void setHost(String aHost) {
host = aHost;
reconnect();
}
public String getDatabase() {
return dbName;
}
public void setDatabase(String aDbName) {
dbName = aDbName;
reconnect();
}
public String getUsername() {
return username;
}
public void setUsername(String aUsername) {
username = aUsername;
reconnect();
}
public String getPassword() {
return password;
}
public void setPassword(String aPassword) {
password = aPassword;
reconnect();
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection aConnection) {
connection = aConnection;
}

Elvileg ha lenyitogatjtok a Projects ablakban a DBConnection osztlyt, ott van Bean Patterns, s
hozz lehet adni ezeket a tulajdonsgokat, megcsinlja a get/set metdusokat is alapbl, de lltlag
NetBeans 6-bl ki fogjk szedni ezt a Bean dolgot, hogy ttervezzk, mert rgi, meg nemj, ezrt
csinltuk inkbb kzzel.
Csinlunk egy isOpen metdust, ezzel vizsgljuk a DBResultSet-ben, hogy nyitott-e a kapcsolat.
public boolean isOpen() {
try {
if(connection != null && !connection.isClosed()) {
return true;
}
} catch (SQLException ex) {
ex.printStackTrace();
}
return false;
}

Most nhny sz arrl, mrt csinltuk ilyen automata csatlakozsosra az egszet. A connect

Forrs: http://www.doksi.hu

metdusban megnzi hogy minden be van-e lltva, ha igen, akkor megprbl csatlakozni. A set
metdusokban is mindig jracsatlakozunk automatikusan. Ez azrt kell, mert a DBConnection
osztlyunkat ki szeretnnk tenni form-ra, s ott grafikus felletbl tudjuk ilyen tulajdonsgok
prbeszdablakban lltgatni ezeket a dolgokat, a get/set metdusokon keresztl. Ezzel a mdszerrel
rgtn kapcsoldni is fog az osztlyunk, ha minden adatot megadtunk.
DBConnection.java-n jobbgomb->Tools->Add to palette, s adjuk hozz a Beans szekcihoz, vagy
ahova akarjuk. Innentl az osztlyunkat rhzhatjuk a form-okra, mint a gombot, stb. A
DBConnection osztlyunk egy lthatatlan bean lesz, az Other Components-nl fog megjelenni a
formon. Ha a palettrl rhzzuk a form-ra, kell hogy csinljon egy dBConnection1 nev pldnyt
belle, s a properties ablakban tudjuk lltgatni a tulajdonsgokat. Emiatt kellett a get/set
metdusokba beletenni a connect()-et, stb hogy ilyenkor is kapcsoldjon, ha itt lltgatjuk. Ki is
lehet prblni: ha mindent belltunk, csatlakozik.
Egyelre a DBConnection-el nem foglalkozunk tbbet, megcsinljuk a DBResultSet osztlyunkat.

A DBResultSet osztly
Ebben az osztlyban fogjuk trolni a lekrdezsek eredmnyeit. Ebbl fognak tpllkozni a
vezrlink is.
A db csomagban hozzunk lrte egy DBResultSet Java Class-t. Ehhet is kell a Serializable interfsz,
hogy tudjuk bean knt hasznlni.
public class DBResultSet implements Serializable {

Ide is ngy vltoz kell:

a kapcsolat

az sql parancs

az eredmnyhalmaz

a statement (elkpzelsem nincs, mi lehet magyarul)

private
private
private
private

DBConnection connection;
String command;
ResultSet resultSet;
Statement statement;

Kellenek open/close/reopen metdusok, hasonlan a DBConnection connect-ekhez.


Az open metdusban megcsinljuk a lekrdezst, s eltroljuk a resultSet vlaozba.
public void open() {
if(connection != null && connection.isOpen() && command != null) {
try {
statement = connection.getConnection().createStatement();
resultSet = statement.executeQuery(command);
resultSet.next();
} catch(SQLException e) {
e.printStackTrace();
}
}
}

A zrs egyrtelm.
private void close() {
try {
if(resultSet != null) {

Forrs: http://www.doksi.hu

resultSet.close();
resultSet = null;
}
if(statement != null) {
statement.close();
statement = null;
}
} catch(SQLException e) {
e.printStackTrace();
}
}

Ez is:
private void reopen() {
close();
open();
}

Ide is tesznk isOpen metdust:


public boolean isOpen() {
if(resultSet != null) {
return true;
}
return false;
}

Kellenek mg a get/set metdusok:


public DBConnection getConnection() {
return connection;
}
public void setConnection(DBConnection aConnection) {
connection = aConnection;
reopen();
}
public String getCommand() {
return command;
}
public void setCommand(String aCommand) {
command = aCommand;
reopen();
}
public ResultSet getResultSet() {
return resultSet;
}
public void setResultSet(ResultSet aResultSet) {
resultSet = aResultSet;
}

Megrjuk mg a destuktort, amiben szpen lezrjuk a dolgokat:


protected void finalize() throws Throwable {
close();
super.finalize();
}

Ezzel a nagy rsz meg is van. A kvetkezkben az zenetkldst csinljuk meg a kt osztly kztt.

Forrs: http://www.doksi.hu

Ugye ha a kapcsolat ltrejn, szlni kell az eredmnyhalmaz objektumoknak, hogy megcsinlhatjk


a lekrdezst stb. Ehhez visszatrnk elszr a DBConnection osztlyhoz.

A DBConnection osztly zenetei


Hozzunk ltre a db Java Package-en bell egy event Java Package-t. Az event csomagba 3 j
osztlyt csinlunk:

DBConnectionOpenedEvent

DBConnectionChangedEvent

DBConnectionClosedEvent

Ezek az zenetek fognak menni a DBResultSet-eknek. Termszetesen ha Opened eventet kap a


DBResultSet, megtudja hogy van kapcsolat, megcsinlja a lekrdezst. A Changed eventre ugyanez.
Ha Closed, akkor a DBResultSet is lezr.
Mindhrom osztly az ActionEvent osztlybl lesz szrmaztatva, a konstruktorok paramterei a
kld objektum, s az zenet azonost.
public class DBConnectionOpenedEvent extends ActionEvent {
public DBConnectionOpenedEvent(Object aSender, int aId) {
super(aSender, aId, "DBCONNECTION_OPENED");
}
}
public class DBConnectionChangedEvent extends ActionEvent {
public DBConnectionChangedEvent(Object aSender, int aId) {
super(aSender, aId, "DBCONNECTION_CHANGED");
}
}
public class DBConnectionClosedEvent extends ActionEvent {
public DBConnectionClosedEvent(Object aSource, int aId) {
super(aSource, aId, "DBCONNECTION_CLOSED");
}
}

Ezutn tesznk a DBConnection-be egy EventListenerList vltozt, ebbe fogjuk trolni azokat a
DBResultSet-eket, amik kapcsolatban vannak a DBConnection-en, teht akiket rtesteni kell, ha
vmi vltozs trtnik.
private EventListenerList eventListenerList = new EventListenerList();

Megcsinljuk a metdusokat, amivel tudunk hozzadni s elvenni listenert.


public void addActionListener(ActionListener aListener) {
eventListenerList.add(ActionListener.class, aListener);
}
public void removeActionListener(ActionListener aListener) {
eventListenerList.remove(ActionListener.class, aListener);
}

Htravannak mg az zenetkld metdusok. Egy, ami minden listenernek kld egy bizonyos
zenetet, valamint mindhrom zenetre kln egy-egy.

Forrs: http://www.doksi.hu

public void fireActionEvent(ActionEvent aEvent) {


ActionListener listeners[] =
eventListenerList.getListeners(ActionListener.class);
for(int i = 0; i < listeners.length; i++) {
listeners[i].actionPerformed(aEvent);
}
}
public void fireDBConnectionOpenedEvent() {
fireActionEvent(new DBConnectionOpenedEvent(this,
ActionEvent.ACTION_PERFORMED));
}
public void fireDBConnectionChangedEvent() {
fireActionEvent(new DBConnectionChangedEvent(this,
ActionEvent.ACTION_PERFORMED));
}
public void fireDBConnectionClosedEvent() {
fireActionEvent(new DBConnectionClosedEvent(this,
ActionEvent.ACTION_PERFORMED));
}

Mr csak annyi van htra, hogy belerakjuk az zenetkldseket a megfelel helyekre.


Elszr az connect metdusba, a sikeres kapcsolds utn.
fireDBConnectionOpenedEvent();

Majd a close metdusba.


fireDBConnectionClosedEvent();

A vgn a setConnection metdusba.


fireDBConnectionChangedEvent();

A DBConnection osztlyunk ezzel ksz is van, rtrhetnk a DBResultSet zeneteire.

A DBResultSet osztly zenetei


Az elzekben ltott mdon ltrehozunk a db.event csomagban ngy zenetet:

DBResultSetOpened

DBResultSetChanged

DBResultSetDataChanged

DBResultSetClosed

A DBResultSetDataChanged zenetet ksbb fogjuk hasznlni, majd ha mr vltoztatni is tudunk


az adatokon, egyelre az a cl, hogy megjelentsk az adatbzisban lv adatokat.
Itt trnk ki arra, hogy egy teljesen ltalnos DBResultSet esetben, a DBConnectionOpenedEvent
s DBConnectionChangedEvent event utn nem csak jra le kellene krni az adatokat, ahogy n
csinlom, hanem ilyenkor lehetne leellenrizni, hogy a kapott j kapcsolatban megvan-e minden
tbla, amire a DBResultSet-ben megadott parancs hivatkozik stb. Ezzel n most nem foglalkozok,
ugyis dobja a kivtelt ha gond van, de teljesen korrektre gy kellene megrni.
A DBResultSet osztlyunkat az ActionListener-bl is szrmaztatjuk.
public class DBResultSet implements Serializable, ActionListener {

Forrs: http://www.doksi.hu

Ezutn mr bele tudjuk rakni a DBConnection EventListener listjba.


Kell mg egy actionPerformed metdus, ez fog meghvdni, ha a DBConnection kld valami
zenetet.
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("DBCONNECTION_OPENED")) {
reopen();
}
if(e.getActionCommand().equals("DBCONNECTION_CHANGED")) {
reopen();
}
if(e.getActionCommand().equals("DBCONNECTION_CLOSED")) {
close();
connection = null;
}
}

Ugyangy, itt is kell EventListener lista, mert a DBResultSet is fog zeneteket kldeni a hozz
kapcsolt vezrlkhz.
private EventListenerList eventListenerList = new EventListenerList();

Az tbbi metdus ugyanaz, vagy hasonl mint a DBConnection esetben, csak itt ngy fle zenetet
kldnk.
public void addActionListener(ActionListener aListener) {
eventListenerList.add(ActionListener.class, aListener);
}
public void removeActionListener(ActionListener aListener) {
eventListenerList.remove(ActionListener.class, aListener);
}
public void fireActionEvent(ActionEvent aEvent) {
ActionListener listeners[] =
eventListenerList.getListeners(ActionListener.class);
for(int i = 0; i < listeners.length; i++) {
listeners[i].actionPerformed(aEvent);
}
}
public void fireDBResultSetOpenedEvent() {
fireActionEvent(new DBResultSetOpenedEvent(this,
ActionEvent.ACTION_PERFORMED));
}
public void fireDBResultSetChangedEvent() {
fireActionEvent(new DBResultSetChangedEvent(this,
ActionEvent.ACTION_PERFORMED));
}
public void fireDBResultSetDataChangedEvent() {
fireActionEvent(new DBResultSetDataChangedEvent(this,
ActionEvent.ACTION_PERFORMED));
}
public void fireDBResultSetClosedEvent() {
fireActionEvent(new DBResultSetClosedEvent(this,
ActionEvent.ACTION_PERFORMED));

Forrs: http://www.doksi.hu

Most be kell rakni a klnbz zenetek kldst a megfelel helyekre.


Az open metdusba.
fireDBResultSetOpenedEvent();

A close metdusba.
fireDBResultSetClosedEvent();

A setConnection metdus picit nagyobb trst ignyel. Ha mr volt kapcsolat eltte, abbl ki kell
venni, hogy tbbet ne zengessen, ha mr nem is hozz tartozik a DBResultSet.
if(connection != null) {
connection.removeActionListener(this);
}

Ha belltunk egy j kapcsolatot, az j kapcsolat EventListener listjba be kell tennnk a


DBResultSet-et, hogy kapja tle az zeneteket.
connection.addActionListener(this);

Ezzel vgeztnk is az unalmas rszekkel, kvetkeznek a modellek, amik mr a vezrlink adatait


fogjk szolgltatni.

A modellek
Ebben a lersban kt modellt fogok adatbzishoz ktni:

PlainDocument (a JTextField modellje)

DefaultComboBoxModel (a JComboBox modellje)

Kell pr szt szlnunk a java vezrlkrl, s modellekrl. A vezrlket, s a bennk trolt adatot
sztszedtk kt rszre, a vezrl csak megjelent, az adatot valjban a modell trolja. Egyszer
plda: csinlok kt szvegmezt, mindegyiknek ugyanazt a modellt adom meg (ugyanazt a
pldnyt). Ha a modellben tlltom a szveget, mindkt szvegmezben meg fog vlzotni. Minden
tpus vezrlnek meg van a sajt modellje. Ebbl kvetkezik, hogy neknk a megfelel modellt
kell sszektni az adatbzissal, a vezrl akkor mr onnan fogja kapni az adatot.

A DBDocument osztly
Ez az osztlyunk lesz az adatbzishoz kttt szvegmezk forrsa. Az osztly helye a db
csomagban lesz. Ahogy a DBResultSet, a PlainDocument-bl lesz szrmaztatva, s esemnyeket is
fogadhat.
public class DBDocument extends PlainDocument implements ActionListener {

Csinlunk kt vltozt:

a DBResultSet, amibl a modell veszi az adatot

az adatbsis mez neve, amit meg akarunk jelenteni

private DBResultSet resultSet;


private String column;

Kell egy refresh metdus, ami a DBResultSet alapjn frissti az adatot. A fireInsertUpdate a
modellhez csatolt vezrlknek kld zenetet, hogy vltozott a megjelentend adat, ez alapbl

Forrs: http://www.doksi.hu

megvan, gy mkdik a modell/view architektra. Neknk csak az adatbzis zeneteket kell kln
megrni.
public void refresh() {
if(resultSet != null && resultSet.isOpen()) {
ResultSet rs = resultSet.getResultSet();
try {
String value = rs.getString(column);
try {
remove(0, getLength());
insertString(0, value, null);
fireInsertUpdate(new DefaultDocumentEvent(0,
value.length(), DocumentEvent.EventType.CHANGE));
} catch(BadLocationException e) {
e.printStackTrace();
}
} catch(SQLException e) {
e.printStackTrace();
}
}
}

Termszetesen itt is lesznek get/set metdusok a kt vltozhoz.


public DBResultSet getResultSet() {
return resultSet;
}
public void setResultSet(DBResultSet aResultSet) {
if(resultSet != null) {
resultSet.removeActionListener(this);
}
resultSet = aResultSet;
resultSet.addActionListener(this);
refresh();
}
public String getColumn() {
return column;
}
public void setColumn(String aColumn) {
column = aColumn;
refresh();
}

A setResultSet metdusban, ahogy a DBResultSet setConnection-ben, itt is kivesszk a rgi


DBResultSet listjbl, s beletesszk az jba.
Htravan mg az actionEvent metdus, ugyangy, ahogy a DBResultSet-nl, ez fog vgrehajtdni,
ha a DBResultSet valamilyen zenetet kld.
public void actionPerformed(ActionEvent event) {
if(event.getActionCommand().equals("DBRESULTSET_OPENED")) {
refresh();
}
if(event.getActionCommand().equals("DBRESULTSET_CHANGED")) {

Forrs: http://www.doksi.hu

refresh();
}
if(event.getActionCommand().equals("DBRESULTSET_DATACHANGED")) {
refresh();
}
if(event.getActionCommand().equals("DBRESULTSET_CLOSED")) {
try {
insertString(0, "", null);
} catch(BadLocationException e) {
e.printStackTrace();
}
}
}

Ide mr belevettk a DBResultSetDataChanged zenetet is, ha valamilyen msik vezrl


vltoztatott az adatokot, akkor frisstnk (ezt az esemnyt a DBResultSet mg nem kldi, ksbb
lesz rla sz).
Ezzel ksz is vagyunk, ki lehet prblni amit eddig csinltunk. A DBResultSet s a DBDocument
vezrlt is tegyk r a palettra a Beans szekciba, ahogy a DBConnection-t.

A prbaalkalmazs
Elszr tegynk adatokat az adatbzisba, legalbb egy vrost, s egy embert. Ez mindenkppen
kell, mivel a DBResultSet megnyitsnl bentvan egy next(), automatikusan lp az els rekordra,
hogy legyen mit megjelenteni. Ezt majd ksbb kivesszk, egyelre gy knyelmes.
Nyissuk meg a Citizens projekt CitizensFrame fjljt, tervez nzetben. A palettrl tegynk a
form-ra egy DBConnection, egy DBResultSet ,egy DBDocument s egy JTextField vezrlt. A
JTextField-et helyezzk el ahogy akarjuk, a msik hrom DB osztly az Instpector-ban az Other
Components-nl lesz, mivel nem lthat komponensek. A pldnyok nevei dBConnection1,
dBResultSet1 stb, automatikusan adja, t lehet utna nevezni.
lltgassuk be a komponensek tulajdonsgait.
DBConnection:

database = citizens

host = ht ez pp ami

username = citizen

password = citizen

DBResultSet:

command = SELECT * FROM citizens

connection = vlasszuk ki a Bean-t, s dBConnection1

DBDocument:

column = citizen_name

resultSet = dBResultSet1

JTextField:

document = dBDocument1

Ha minden jl megy, akkor a tervez nzetben mr meg is jelent az els polgrunk neve.

Forrs: http://www.doksi.hu

Rekordmveletek hozzadsa
Mozgs mveletek
Ehhez kell ngy metdus a DBResultSet osztlyba.
public void first() {
try {
resultSet.first();
} catch(SQLException e) {
e.printStackTrace();
}
fireDBResultSetDataChangedEvent();
}
public void prev() {
try {
resultSet.previous();
} catch(SQLException e) {
e.printStackTrace();
}
fireDBResultSetDataChangedEvent();
}
public void next() {
try {
resultSet.next();
} catch(SQLException e) {
e.printStackTrace();
}
fireDBResultSetDataChangedEvent();
}
public void last() {
try {
resultSet.last();
} catch(SQLException e) {
e.printStackTrace();
}
fireDBResultSetDataChangedEvent();
}

A mkdsk elg egyrtelm: mozognak az eredmnyhalmazban, s zennek a vezrlknek, hogy


vltozs trtnt. Ezzel egytt vegyk ki a DBResultSet.open metdusbl a next-et, amivel alapbl
az els rekordra lptnk, hogy res tblnl ne kavarjon be. A problma ezzel annyi, hogy alapbl
a rekordok eltt van a mutat, s szpen kapunk egy kivtelt, mikor a programunk indul. Ezt azzal
tudjuk orvosolni, hogy a DBDocument osztlyban megvizsgljuk, hogy vals rekordon llunk-e, s
csak abban az esetben frisstjk az adatokat. Betesznk egy felttelt az refresh metdusba.
if(!rs.isBeforeFirst() && !rs.isAfterLast()) {
...
}

Hogy hasznlni is tudjuk ket, tegynk egy JToolBar-t a CitizensFrame-re. Tegynk r ngy
JButtont, nevezzk t ket firstButton, prevButton, nextButton, lastButton-ra. A gombokon
jobbgomb->Events->Action->actionPerformed, ez hozzadja a forrshoz a gombhoz tartoz
metdust, ami vgrehajtdik, ha megnyomjuk. A ngy metdusba termszetesen a mozgs

Forrs: http://www.doksi.hu

mveleteket hvjuk meg.


private void lastButtonActionPerformed(java.awt.event.ActionEvent evt) {
dBResultSet1.last();
}
private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {
dBResultSet1.next();
}
private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) {
dBResultSet1.prev();
}
private void firstButtonActionPerformed(java.awt.event.ActionEvent evt) {
dBResultSet1.first();
}

Ha tesznk be tbb adatot a citizens tblba, s kiprbljuk, tudunk mozogni a rekordok kztt.

j, Frisst s Trl mveletek


Adjunk hozz az eszkztrunkhoz mg hrom elemet:

egy JToggleButton-t, ami az j rekord gomb lesz

egy JButton-t, ami a frissts

s mgegy JButton-t, ami a trls

A gombok mkdse a kvetkez lesz:

A hozzads gombunk a togglebutton: ha megnyomjuk, tvltunk j rekord mdba,


berhatjuk az j rekord adatait, s a frissts gombbal felvehetjk az j rekordot. Ha j
rekord mdban megnyomjuk mgegyszer a hozzads gombot (kikapcsoljuk), az lesz a
mgse, ilyenkor nem veszi fel az j rekordot.

A frissts gomb nem j rekord mdban az aktulis adatokat fogja felrni az adatbzisba
(vltoztats).

A trls gomb egyrtelm, trlni fogja az aktulis rekordot.

Nevezzk t a hrom gombot addToggleButton, updateButton, s delButton-ra.


Hozzunk ltre egy DBResultSetDataUpdate esemnyt, a szoksos mdon.
public class DBResultSetDataUpdateEvent extends ActionEvent {
public DBResultSetDataUpdateEvent(Object aSender, int aId) {
super(aSender, aId, "DBRESULTSET_DATAUPDATE");
}
}

rjuk meg hozz a kld metdust a DBResultSet-ben.


public void fireDBResultSetDataUpdateEvent() {
fireActionEvent(new DBResultSetDataUpdateEvent(this,
ActionEvent.ACTION_PERFORMED));
}

A DBDocument osztlyba tegynk egy update metdust, ez fogja a szvegmezben lv adatot


visszarni a DBResultSet-be.
public void update() {
if(resultSet != null) {

Forrs: http://www.doksi.hu

ResultSet rs = resultSet.getResultSet();
try {
if(!rs.isBeforeFirst() && !rs.isAfterLast()) {
try {
rs.updateString(column, getText(0, getLength()));
} catch(BadLocationException e) {
e.printStackTrace();
}
}
} catch(SQLException e) {
e.printStackTrace();
}
}
}

A DBDocument actionPerformed metdusba rjuk bele az j zenet kezelst is.


if(event.getActionCommand().equals("DBRESULTSET_DATAUPDATE")) {
update();
}

Ezutn a DBResultSet osztly update metdust kell megrni, ami elkldi az zenetet minden
vezrlnek, s az j adatokat visszarja az adatbzisba.
public void update() {
fireDBResultSetDataUpdateEvent();
try {
resultSet.updateRow();
} catch (SQLException ex) {
ex.printStackTrace();
}
}

Most az updateButton actionPerformed metdust kell magrni, hogy hvja az update-et.


private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {
if(addToggleButton.getModel().isSelected()) {
dBResultSet1.insertRow();
addToggleButton.getModel().setSelected(false);
} else {
dBResultSet1.update();
}
}

Ki lehet prblni, ha trjuk a polgrunk nevt, s megnyomjuk az update gombot, frisslni fog az
adatbzisban. Az if els fele az j rekord, felveszi az adatbzisba, majd kikapcsolja a toggleButtont.
Most csinljuk meg a trlst, ez a legegyszerbb. A DBResultSet-be kell egy delete metdus.
public void delete() {
try {
resultSet.deleteRow();
} catch(SQLException e) {
e.printStackTrace();
}
fireDBResultSetDataChangedEvent();
}

Ezutn a delButton actionPerformed metdusa. Ebbe ugye illene egy rkrdezs hogy tnyleg
akarjuk-e trlni, most kimarad.

Forrs: http://www.doksi.hu

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


dBResultSet1.delete();
}

Kvetkezik a bonyolultabb rsz: az j rekord felvtele.


Ehhez hrom j metdust kell csinlnunk a DBResultSet-be. Az insertMode tvlt az j rekord
mdba, az insertRow felveszi az j rekordot, a cancelInsertRow visszatr norml mdba, a rekord
felvtele nlkl.
public void insertMode() {
try {
resultSet.afterLast();
fireDBResultSetDataChangedEvent();
resultSet.moveToInsertRow();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void insertRow() {
try {
fireDBResultSetDataUpdateEvent();
resultSet.updateInt("citizen_city_id", 1);
resultSet.insertRow();
fireDBResultSetDataChangedEvent();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void cancelInsertRow() {
try {
resultSet.moveToCurrentRow();
fireDBResultSetDataChangedEvent();
} catch (SQLException ex) {
ex.printStackTrace();
}
}

Az insertMode-ban azrt megynk az afterLast-ra, hogy a vezrlink tartalma trldjn, s res


lappal kezdje a felhasznl a rekord felvtelt. gy nem kell kzzel kitrlgetni ket eltte. Az
insertRow-ban a resultSet.updateInt(citizen_citi_id, 1) azrt van, mert a vroshoz a combobox
mg nincs ksz, s nem engedne null rtket. gy ki tudjuk prblni a rekordfelvtelt, br mindenki
az 1-es vrosban fog lakni. Ezt a sort ksbb majd ki kell venni.
Most mg az j rekord gomb vannak htra a CitizensFrame-ben.
private void addToggleButtonItemStateChanged(java.awt.event.ItemEvent evt) {
if(addToggleButton.getModel().isSelected()) {
dBResultSet1.insertMode();
} else {
dBResultSet1.cancelInsertRow();
}
}

Ezzel ksz is a rekord felvtele.

You might also like