Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
EDAF20: Laboratory Assignments
Department of Computer Science
Lund Institute of Technology
January 25, 2016
Notice:
• The course contains three compulsory laboratory exercises.
• The labs are mostly homework. Before each lab session, you must have done all the
assignments in the lab, written and tested the programs, and so on. Contact your
teacher if you have problems solving the assignments.
• Smaller problems with the assignments, e.g., details that do not function correctly, can
be solved with the help of the teaching assistant during the lab session.
The labs are about:
1. Using SQL.
2. Designing and implementing a database.
3. Developing of a Java interface to the database in lab 2.
Also note:
• You are supposed to work in groups of two people. You should sign up for the labs
online. Follow the instructions on the course home page.
• You need a MySQL account to do the labs (one account per group). These are handed
out as mentioned during the first lecture.
• Exercise session 1 and 2 are devoted to preparations for lab 2, and the results will also
be used during lab 3. You have to prepare for lab 1 on your own.
• One extra lab occasion is organized only for students who are ill during a lab. Please
notify your teacher before the lab in case you are unable to attend the lab due to illness.
1
EDAF20
1
Labs
Lab Session 1
Objective: learn to write SQL queries and practice using the MySQL client.
1.1
Background
A database for registration of courses, students, and course results has been developed. The
purpose was not a new Ladok database (Swedish university student database), so everything
has been simplified as much as possible. A course has a course code (e.g., EDAF20), a name
(e.g., Database Technology), and a number of credits (e.g., 5). Students have a person
number (Swedish civic registration number) and a name. When a student has taken a
course his/her grade (3, 4 or 5) is registered in the database.
We started by developing an E/R model of the system (E/R stands for Entity-Relationship).
This model is developed in almost the same manner as the static model in object-oriented
modeling, and you make use of the same kind of UML diagrams. You may instead use traditional E/R notation, as in the course book. However, diagrams in the traditional notation
take more paper space, and the notation is not fully standardized, so we will only use the
UML notation. The model looks like this in the different notations (the UML diagram is at
the top):
Student
pNbr
firstName
lastName
0..*
0..*
TakenCourse
grade
courseCode
pNbr
Student
firstName
courseCode
courseName
credits
courseName
Course
TakenCourse
lastName
Course
grade
credits
The E/R model is then converted into a database schema in the relational model. We
will later show how the conversion is performed; for now we just show the final results. The
entity sets and the relationships have been converted into the following relations (the primary key of each relation is underlined):
Students(pNbr, firstName, lastName)
Courses(courseCode, courseName, credits)
TakenCourses(pNbr, courseCode, grade)
2
EDAF20
Labs
Examples of instances of the relations:
pNbr
790101–1234
770403–4321
791223–4443
courseCode
EDA016
EDA027
EDA250
firstName
Bo
Eva
Anna
lastName
Ek
Alm
Eriksson
courseName
Programmeringsteknik
Algoritmer och datastrukturer
Helhetsbild av datatekniken
pNbr
courseCode
770403–4321
EDA016
770403–4321
EDA027
760114–2952
EDA016
credits
5
5
6
grade
4
3
3
The tables have been created with the following SQL statements:
create table Students (
pNbr char(11),
firstName varchar(20) not null,
lastName varchar(20) not null,
primary key (pNbr)
);
create table Courses (
courseCode char(6),
courseName varchar(50) not null,
credits integer not null check (credits > 0),
primary key (courseCode)
);
create table TakenCourses (
pNbr char(11),
courseCode char(6),
grade integer not null check (grade >= 3 and grade <= 5),
primary key (pNbr, courseCode),
foreign key (pNbr) references Students(pNbr),
foreign key (courseCode) references Courses(courseCode)
);
All courses that were offered at the Computer Science and Engineering program at LTH
during the academic year 2002/03 are in the table Courses (the course names have in some
3
EDAF20
Labs
cases been abbreviated to make them shorter than 50 characters). Also, the database has
been filled with invented data regarding students and their taken courses. SQL statements
like the following have been used to insert the data:
insert into Students values(’790101-1234’, ’Bo’, ’Ek’);
insert into Courses values(’EDA016’, ’Programmeringsteknik’, 5);
insert into TakenCourses values(’770403-4321’, ’EDA016’, 4);
1.2
Assignments
1. Study the sections on SQL in the textbook (sections 7.1–7.19 and chapter 8 in [PMR05],
alternatively sections 6.1–6.4 and 6.7.1–6.7.3 in [UW02]). These sections contain more
than you will use during this exercise, so it may be a good idea to study assignment 3
in parallel.
2. Read the introduction to MySQL (see separate instructions).
3. Write SQL queries for the following tasks and store them in a text file. Format the SQL
code according to the rules (select on one line, from on one line, where on one line,
. . . ). Don’t use tabs to indent the SQL code, MySQL uses tabs for auto-completion of
table names and attribute names.
The tables Students, Courses and TakenCourses already exist in your database. If you
change the contents of the tables, you can always recreate them with the following
command (the script makeLab1.sql is available on the course homepage):
mysql> source makeLab1.sql
After most of the questions, there is a number in brackets. This is the number of rows
generated by the question. For instance, [72] after question a) means that there are 72
students in the database.
(a) What are the names (first name, last name) of all the students? [72]
(b) Same as question a) but produce a sorted listing. Sort first by last name and then
by first name.
(c) Which students were born in 1975? [2]
(d) What are the names of the female students, and which are their person numbers?
The next-to-last digit in the person number is even for females. The MySQL
function substr(str,m,n) gives n characters from the string str, starting at
character m, the function mod(m,n) gives the remainder when m is divided by n.
[26]
(e) How many students are registered in the database?
(f) Which courses are offered by the department of Mathematics
(course codes FMAxxx)? [24]
(g) Which courses give more than five credits? [21]
4
EDAF20
Labs
(h) Which courses (course codes only) have been taken by the student with person
number 790101-1234 ? [7]
(i) What are the names of these courses, and how many credits do they give?
(j) How many credits has the student taken?
(k) Which is the student’s grade average on the courses that he has taken?
(l) Same questions as in questions h)-k), but for the student Eva Alm. [5]
(m) Which students have taken 0 credits? [16]
(n) Which student has the highest grade average? Advice: define and use a view that
gives the person number and grade average for each student.
(o) List the person number and total number of credits for all students. Students
with no credits should be included in the list! [72]
(p) Same question as in question o) but with names instead of person numbers.
(q) Is there more than one student with the same name? If so, who are these students?
[7]
4. If you haven’t picked up your MySQL account before the lab, you will be given your
username and password at the lab, when you sign for it.
5. Log in to MySQL (see separate instructions). Change your MySQL password immediately.
6. Use mysql to execute the SQL queries that you wrote in assignment 3 and check that
the queries give the expected results. Advice: open the file containing the queries in
a text editor and copy and paste one query at a time, instead of writing the queries
directly in mysql.
5
EDAF20
2
Labs
Lab Session 2
Objective: learn to design and to implement a database. This involves creating an E/R
model for the application and converting the model into a relational model. You will also
learn to create SQL tables and to insert data into the tables. During lab 3 you will develop
a Java interface to the database.
Exercise sessions 1 and 2 (partially) are devoted to preparations for this lab.
2.1
Background
A database contains information regarding ticket reservations for movie shows. To make a
reservation you must be registered as a user of the system. In order to register you choose
a unique username and enter your name, address, and telephone number (the address is
optional). When you use the system later, you just have to enter your username.
In the system, a number of theaters show movies. Each theater has a name and a number
of (unnumbered) seats. A movie is described by its name only. (In a real system you would,
naturally, store more information: actor biographies, poster images, video clips, etc.)
A movie may be shown several times, but then during different days. This means that
each movie is shown at most once on any day.
A user can only reserve one ticket at a time to a movie show1 , and cannot reserve more
tickets than are available at a performance. When a user makes a reservation for a ticket he
receives a reservation number that he uses when he picks up the ticket.
2.2
Assignments
1. Study the sections on E/R modeling and conversion of the E/R model to relations in
the textbook (chapters 2 and 6 in [PMR05], or alternatively chapter 2 and sections
3.1–3.2 in [UW02]).
2. Develop an E/R model for the database that is described above. Start by finding
suitable entity sets in the system. For this, you may use any method that you wish,
e.g., start by finding nouns in the requirements specification and after that determine
which of the nouns that are suitable entity sets.
3. Find relationships between the entity sets. Indicate the multiplicities of the relationships.
4. Find attributes of the entity sets and (possibly) of the relationships. Consider which
of the attributes that may be used as keys for the entity sets. Draw a UML diagram
of your model.
5. Convert the E/R model to a relational model. Use the method that has been described
during the lectures and chapter 6 in [PMR05] (or sections 3.1–3.2 in [UW02]). Describe
your model on the form Relation1(attribute, . . . ), Relation2(attribute, . . . ). Identify
primary keys and foreign keys. About primary keys: a movie name and a date together
1
If the user wants several tickets for the same performance he must make several separate reservations.
6
EDAF20
Labs
suffice to identify a movie show, since each movie is shown at most once on one day.
This means that {movie name, date} is a key of the relation that describes movie
shows. If you convert the E/R model according to the rules, it may happen that the
key also contains the name of the theater. (That the name of the theater should not
be a part of the key is indicated by the functional dependency
movieName date → theaterName, which means that you can deduce the theater name
if you know the movie name and the date. We will discuss functional dependencies
later in the course.)
Additionally, relations must be normalized to avoid redundancy and anomalies in the
database. We omit normalization for now, since we haven’t discussed it yet. (Also,
relations usually are reasonably normalized if you start with a good E/R model.)
6. Study the sections in the textbook (7.21–7.23 in [PMR05] or 6.5–6.6 and 7.1–7.2 in
[UW02]) on SQL statements to modify, create tables and key constraints.
7. Write SQL statements for the following tasks, and execute the statements in mysql:
(a) Create the tables. Don’t forget primary keys and foreign keys. Insert data into
the tables. Invent you own data with real-world movie names and theater names.
Use the data type date for dates, entered and displayed in the form ’2006–12–24’.
Advice: write the SQL statements in a text file with the extension .sql. Execute
the statements with the mysql command
source filename
The file should have the following structure:
-- Delete the tables if they exist. To be able to drop
-- them in arbitrary order, disable foreign key checks.
set foreign_key_checks = 0;
drop table if exists Users;
...
set foreign_key_checks = 1;
-- create the tables
create table Users ( ... );
...
-- insert data into the tables
insert into Users values(...);
(b) List all movies that are shown, list dates when a movie is shown, list all data
concerning a movie show.
(c) Create a reservation. Advice: reservation numbers can be created automatically
by specifying the number column as an auto-increment column, like this:
create table Bookings (
nbr integer auto_increment,
... );
7
EDAF20
Labs
When you insert rows into the table and don’t give a value for the auto-increment
column nbr (or specify it as 0 or null), it will be assigned the values 1, 2, . . . When
a ticket is reserved a new row must be inserted into the reservation table, and the
number of available seats for the show must be updated. Before you do this you
have to check that there are seats available for the show. It is not easy to check
this in pure SQL, so we save this for lab 3, when you will code in Java and have
access to if-statements.
8. Check that the key constraints that you have stated work as intended: try to insert
two movie theaters with the same name, insert a movie show in a theater that is not
in the database,. . .
9. Consider the following problem: when you make a ticket reservation you first check that
seats are available for the show, then you create a reservation, then update the number
of available seats. Which problems can arise if several users do this simultaneously?
Draw a diagram which illustrates the problem.
10. What facilities must be offered by a database manager to make it possible to solve
problems of the kind described in task 9?
8
EDAF20
3
Labs
Lab Session 3
Objective: you will learn to use JDBC to communicate with a database from a Java program.
You will also learn something about designing a graphical user interface with the Java Swing
classes.
Exercise session 2 is devoted to preparations for this lab.
3.1
Background
A program which makes it possible to interactively make ticket reservations2 for movie
shows uses the database which you developed during lab 2. The program has a graphical
user interface.
The program is a stand-alone application, and the user must have the application installed
on his own computer. It would be preferable if the user could make ticket reservations over
the web. In lab 4, you will develop a servlet application which makes this possible.
The user interface for the program looks like this:
The window has two tabs: User login and Book ticket. The first tab is used when a user3
logs in to the system with his username, the second tab is used to make ticket reservations.
The reservation tab has two lists. In the left list are the names of movies currently
showing. When you select a movie, the show dates are shown in the right list. When you
select a date, information regarding the show is displayed in the text fields. When you click
the Book ticket button a reservation for the show is made, if there are available seats. You
receive an error message if there are no available seats.
When you make a reservation you receive a reservation number. The number of available
seats is updated on each reservation.
2
The program only handles new reservations. All other tasks concerning the database, e.g., creation of
new shows and creation of new users, are performed by other programs. In your case, you will use mysql to
perform such tasks.
3
Note: the ”user” here is the user of the ticket reservation system, who chose a username when he
registered in the system. Do not confuse this user with the database user, who must log in to the database
system with his MySQL username and password.
9
EDAF20
3.2
Labs
Assignments
1. Read about JDBC in the textbook [PMR05] section 20.8 (better covered in section
8.6 in [UW02]) and in the overhead slides. Further information on JDBC is available
through the course home-page links.
2. Large parts of the programs (classes) needed in the system are already written: a main
program (MovieBooking.java), and the user interface (MovieGUI.java and other files).
See appendix A.
The classes are in the file lab3Files.zip available from download from the course homepage. Change to an appropriate directory and unpack the file.
3. Your task is to complete the program by filling in the empty action-handling methods
in the listener classes.
The classes in the program are shown below, in a UML diagram. The diagram is
schematic and only shows the most important classes and associations. Study the
pictures of the user interface (under Background, above) and the Java code (appendix
A), and compare with the following description:
MovieBooking
1
1
MovieGUI
Database
1
1
1
1
JTabbedPane
1
CurrentUser
BasicPane
1
1
UserLoginPane
BookingPane
1
MovieBooking is the main program.
MovieGUI is the main class for the user interface.
JTabbedPane is one of the Swing standard classes. It describes a Swing component
that may contain several tabs.
BasicPane is a general description of a tab in the program.
UserLoginPane is the ”left tab”, which is used when a user logs in to the system.
BookingPane is the other tab, which is used when the user makes a reservation of a
ticket for a movie show.
Database handles all communication with the database system.
10
EDAF20
Labs
CurrentUser is a singleton class, which keeps track of the user that has logged in to
the system. It is used by the classes UserLoginPane and BookingPane.
An object of the class BasicPane divides the available window area into two areas: left
and right. The right part is further divided into three areas: top, middle, and bottom.
In the login tab the left area is empty. The top area contains the text ”Username” and
the text field where the user enters his username. The bottom area contains the login
button and a message line (called messageLabel in the program).
In the reservation tab the left area contains two lists: one for movie names, nameList,
and one for performance dates, dateList. The top area contains strings and text fields
used to display information regarding a movie show. The bottom area contains the
reservation button and a message line.
4. In the program, the following tasks shall be performed:
(a) When you click the Login button: log in with the specified username.
(b) When you enter the reservation panel: show movie names in the movie name list.
(c) When you select a movie name: show performance dates for the movie in the date
list.
(d) When you select a performance date: show all data concerning the performance
in the text fields.
(e) When you click Book ticket: make a ticket reservation.
Consider in detail what tasks have to be performed in the database for each of the
actions above.
JDBC calls are used for the communication between the program and the database
system. You should not have a tight coupling between the user interface and the
database communication, so you must collect all JDBC calls in a class Database.
Parts of this class are prewritten.
Specify more methods in the class Database to perform the tasks in 4a–4e. Do not
implement the methods yet. Advice: when you are to show information concerning
a performance (task 4d), you have to fetch the information from the database. Do
this by creating and returning an object of a class Performance, which has the same
attributes as the corresponding table in the database.
You will use the class Database (unchanged) also in lab 4.
5. When you select a movie name in the name list, the method valueChanged in the class
NameSelectionListener (in the class BookingPane) is called (task 4c):
public void valueChanged(ListSelectionEvent e) {
if (nameList.isSelectionEmpty())
return;
String movieName = (String) nameList.getSelectedValue();
/* --- insert own code here --- */
}
11
EDAF20
Labs
Replace the comment with the appropriate Java code. The code will call one of the
Database methods; implement this method.
6. Other methods, similar to valueChanged, must also be written. Do this, and implement the corresponding methods in the class Database.
To fetch a date column from a result set, use the method getString() (all you want
to do with the date is to display it).
7. To compile and test the program use either Eclipse4 or javac in a command shell5 .
Don’t forget to test the case when you try to reserve a ticket for a fully-booked performance; in that case you should receive an error message.
The program needs access to the MySQL JDBC driver (Connector/J, the class
com.mysql.jdbc.Driver, which is in the file mysql-connector-java-5.0.4-bin.jar, available for download from the course home-page). In Eclipse this .jar must be added to
the libraries using project Preferences/Java Build Path/LibrariesAdd External Jars. . .
When running the program from the command line:
java -cp .:downloadpath\mysql-connector-java-5.0.4-bin.jar MovieBooking
Alternatively, you can set CLASSPATH as shown below. Then, the program may be
executed with java MovieBooking:
set CLASSPATH=.:downloadpath\mysql-connector-java-5.0.4-bin.jar
References
[PMR05] T. Padron-McCarthy and T. Risch. Databasteknik. Studentlitteratur, 2005.
[UW02]
4
5
J. D. Ullman and J. Widom. A first course in database systems. Prentice Hall,
2002.
More about Eclipse IDE (Integrated Development Environment) during the labs.
Invoked in Windows by typing cmd in the Start/Run. . . dialog
12
EDAF20
Labs
Appendix A — Classes, Lab 3
MovieBooking.java
MovieGUI.java
BasicPane.java
UserLoginPane.java
BookingPane.java
ButtonAndMessagePanel.java
InputPanel.java
CurrentUser.java
Database.java
page
page
page
page
page
page
page
page
page
13
13
14
16
17
21
22
22
23
Listing 1: MovieBooking.java
/∗ ∗
∗ MovieBooking i s t h e main c l a s s f o r t h e movie t i c k e t b o o k i n g
∗ a p p l i c a t i o n . I t c r e a t e s a d a t a b a s e o b j e c t and t h e GUI t o
∗ i n t e r f a c e to the database .
∗/
public c l a s s MovieBooking {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
Database db = new Database ( ) ;
new MovieGUI ( db ) ;
}
}
Listing 2: MovieGUI.java
import j a v a x . swing . ∗ ;
import j a v a x . swing . e v e n t . ∗ ;
import j a v a . awt . ∗ ;
import j a v a . awt . e v e n t . ∗ ;
/∗ ∗
∗ MovieGUI i s t h e u s e r i n t e r f a c e t o t h e movie d a t a b a s e . I t s e t s up t h e
∗ main window and c o n n e c t s t o t h e d a t a b a s e .
∗/
public c l a s s MovieGUI {
/∗ ∗
∗ db i s t h e d a t a b a s e o b j e c t
∗/
private Database db ;
/∗ ∗
∗ tabbedPane i s t h e c o n t e n t s o f t h e window . I t c o n s i s t s o f two
∗ panes , User l o g i n and Book t i c k e t s .
∗/
private JTabbedPane tabbedPane ;
/∗ ∗
∗ C r e a t e a GUI o b j e c t and c o n n e c t t o t h e d a t a b a s e .
∗
∗ @param db The d a t a b a s e .
∗/
public MovieGUI ( Database db ) {
t h i s . db = db ;
JFrame frame = new JFrame ( ” MovieBooking ” ) ;
tabbedPane = new JTabbedPane ( ) ;
UserLoginPane u s e r L o g i n P a n e = new UserLoginPane ( db ) ;
13
EDAF20
Labs
tabbedPane . addTab ( ” User l o g i n ” , null , userLoginPane ,
” Log i n a s a new u s e r ” ) ;
BookingPane bookingPane = new BookingPane ( db ) ;
tabbedPane . addTab ( ”Book t i c k e t ” , null , bookingPane ,
”Book a t i c k e t ” ) ;
tabbedPane . s e t S e l e c t e d I n d e x ( 0 ) ;
frame . getContentPane ( ) . add ( tabbedPane , BorderLayout .CENTER) ;
tabbedPane . a d d C h a n g e L i s t e n e r (new ChangeHandler ( ) ) ;
frame . addWindowListener (new WindowHandler ( ) ) ;
frame . s e t S i z e ( 5 0 0 , 4 0 0 ) ;
frame . s e t V i s i b l e ( true ) ;
userLoginPane . displayMessage ( ” Connecting to database
. . . ”);
/∗ −−− change code h e r e −−− ∗/
/∗ −−− change x x x t o your u s e r name , yyy t o your password −−− ∗/
i f ( db . ope nConne ction ( ” xxx ” , ” yyy ” ) )
u s e r L o g i n P a n e . d i s p l a y M e s s a g e ( ” Connected t o d a t a b a s e ” ) ;
else
u s e r L o g i n P a n e . d i s p l a y M e s s a g e ( ” Could not c o n n e c t t o d a t a b a s e ” ) ;
}
/∗ ∗
∗ ChangeHandler i s a l i s t e n e r c l a s s , c a l l e d when t h e u s e r
∗ s w i t c h e s panes .
∗/
c l a s s ChangeHandler implements C h a n g e L i s t e n e r {
/∗ ∗
∗ C a l l e d when t h e u s e r s w i t c h e s panes . The e n t r y a c t i o n s
∗ o f t h e new pane a r e p erfor med .
∗
∗ @param e The change e v e n t ( n o t used ) .
∗/
public void s t a t e C h a n g e d ( ChangeEvent e ) {
BasicPane s e l e c t e d P a n e =
( BasicPane ) tabbedPane . g e t S e l e c t e d C o m p o n e n t ( ) ;
selectedPane . entryActions ( ) ;
}
}
/∗ ∗
∗ WindowHandler i s a l i s t e n e r c l a s s , c a l l e d when t h e u s e r
∗ e x i t s the application .
∗/
c l a s s WindowHandler extends WindowAdapter {
/∗ ∗
∗ C a l l e d when t h e u s e r e x i t s t h e a p p l i c a t i o n . C l o s e s t h e
∗ connection to the database .
∗
∗ @param e The window e v e n t ( n o t used ) .
∗/
public void windowClosing ( WindowEvent e ) {
db . c l o s e C o n n e c t i o n ( ) ;
System . e x i t ( 0 ) ;
}
}
}
Listing 3: BasicPane.java
import j a v a x . swing . ∗ ;
14
EDAF20
Labs
import j a v a x . swing . b o r d e r . ∗ ;
import j a v a . awt . ∗ ;
/∗ ∗
∗ BasicPane i s a pane i n t h e u s e r i n t e r f a c e . I t c o n s i s t s o f two s u b p a n e l s :
∗ t h e l e f t p a n e l and t h e r i g h t p a n e l . The r i g h t p a n e l i n t u r n c o n s i s t
∗ o f t h r e e p a n e l s on t o p o f each o t h e r : bottom , m i d d l e and t o p . S u b c l a s s e s
∗ can c h o o s e t o c o n f i g u r e t h e s e p a n e l s as t h e y w i s h .
∗ <p>
∗ The c l a s s c o n t a i n s a r e f e r e n c e t o t h e d a t a b a s e o b j e c t , so s u b c l a s s e s
∗ can communicate w i t h t h e d a t a b a s e .
∗/
public c l a s s BasicPane extends JPanel {
/∗ ∗
∗ The d a t a b a s e o b j e c t .
∗/
protected Database db ;
/∗ ∗
∗ A l a b e l which i s i n t e n d e d t o c o n t a i n a message t e x t .
∗/
protected J L a b e l m e s s a g e L a b e l ;
/∗ ∗
∗ C r e a t e a BasicPane o b j e c t .
∗
∗ @param db The d a t a b a s e o b j e c t .
∗/
public BasicPane ( Database db ) {
t h i s . db = db ;
m e s s a g e L a b e l = new J L a b e l ( ”
”);
s e t L a y o u t (new BorderLayout ( ) ) ;
JComponent l e f t P a n e l = c r e a t e L e f t P a n e l ( ) ;
add ( l e f t P a n e l , BorderLayout .WEST) ;
JPanel r i g h t P a n e l = new JPanel ( ) ;
r i g h t P a n e l . s e t L a y o u t (new BorderLayout ( ) ) ;
JComponent t o p P a n e l = c r e a t e T o p P a n e l ( ) ;
JComponent m i d d l e P a n e l = c r e a t e M i d d l e P a n e l ( ) ;
JComponent bottomPanel = c r e a t e B o t t o m P a n e l ( ) ;
bottomPanel . s e t B o r d e r
(new CompoundBorder (new S o f t B e v e l B o r d e r ( B e v e l B o r d e r . RAISED ) ,
bottomPanel . g e t B o r d e r ( ) ) ) ;
r i g h t P a n e l . add ( topPanel , BorderLayout .NORTH) ;
r i g h t P a n e l . add ( middlePanel , BorderLayout .CENTER) ;
r i g h t P a n e l . add ( bottomPanel , BorderLayout .SOUTH) ;
add ( r i g h t P a n e l , BorderLayout .CENTER) ;
}
/∗ ∗
∗ C r e a t e t h e l e f t p a n e l . S h o u l d be o v e r r i d d e n by s u b c l a s s e s .
∗
∗ @return An empty p a n e l .
∗/
public JComponent c r e a t e L e f t P a n e l ( ) {
return new JPanel ( ) ;
}
/∗ ∗
∗ C r e a t e t h e t o p p a n e l . S h o u l d be o v e r r i d d e n by s u b c l a s s e s .
∗
∗ @return An empty p a n e l .
∗/
public JComponent c r e a t e T o p P a n e l ( ) {
15
EDAF20
Labs
return new JPanel ( ) ;
}
/∗ ∗
∗ C r e a t e t h e m i d d l e p a n e l . S h o u l d be o v e r r i d d e n by s u b c l a s s e s .
∗
∗ @return An empty p a n e l .
∗/
public JComponent c r e a t e M i d d l e P a n e l ( ) {
return new JPanel ( ) ;
}
/∗ ∗
∗ C r e a t e t h e bottom p a n e l . S h o u l d be o v e r r i d d e n by s u b c l a s s e s .
∗
∗ @return An empty p a n e l .
∗/
public JComponent c r e a t e B o t t o m P a n e l ( ) {
return new JPanel ( ) ;
}
/∗ ∗
∗ Perform t h e e n t r y a c t i o n s o f t h e pane . Empty here , s h o u l d be
∗ o v e r r i d d e n by s u b c l a s s e s .
∗/
public void e n t r y A c t i o n s ( ) {}
/∗ ∗
∗ D i s p l a y a message .
∗
∗ @param msg The message t o d i s p l a y .
∗/
public void d i s p l a y M e s s a g e ( S t r i n g msg ) {
m e s s a g e L a b e l . s e t T e x t ( msg ) ;
}
/∗ ∗
∗ C l e a r t h e message l i n e .
∗/
public void c l e a r M e s s a g e ( ) {
messageLabel . setText ( ” ” ) ;
}
}
Listing 4: UserLoginPane.java
import j a v a x . swing . ∗ ;
import j a v a . awt . e v e n t . ∗ ;
/∗ ∗
∗ The GUI pane where a new u s e r l o g s i n . C o n t a i n s a t e x t
∗ t h e u s e r i d i s e n t e r e d and a b u t t o n t o l o g i n .
∗/
public c l a s s UserLoginPane extends BasicPane {
/∗ ∗
∗ The t e x t f i e l d where t h e u s e r i d i s e n t e r e d .
∗/
private J T e x t F i e l d [ ] f i e l d s ;
f i e l d where
/∗ ∗
∗ The number o f t h e f i e l d where t h e u s e r i d i s e n t e r e d .
∗/
private s t a t i c f i n a l i n t USER ID = 0 ;
/∗ ∗
∗ The t o t a l number o f f i e l d s i n t h e f i e l d s a r r a y .
∗/
16
EDAF20
Labs
private s t a t i c f i n a l i n t NBR FIELDS = 1 ;
/∗ ∗ C r e a t e t h e l o g i n pane .
∗
∗ @param db The d a t a b a s e o b j e c t .
∗/
public UserLoginPane ( Database db ) {
super ( db ) ;
}
/∗ ∗
∗ Create the top panel , c o n s i s t i n g o f the t e x t
∗
∗ @return The t o p p a n e l .
∗/
public JComponent c r e a t e T o p P a n e l ( ) {
S t r i n g [ ] t e x t s = new S t r i n g [ NBR FIELDS ] ;
t e x t s [ USER ID ] = ” User i d ” ;
f i e l d s = new J T e x t F i e l d [ NBR FIELDS ] ;
f i e l d s [ USER ID ] = new J T e x t F i e l d ( 2 0 ) ;
return new I n p u t P a n e l ( t e x t s , f i e l d s ) ;
}
field .
/∗ ∗
∗ C r e a t e t h e bottom p a n e l , c o n s i s t i n g o f t h e l o g i n b u t t o n and
∗ t h e message l i n e .
∗
∗ @return The bottom p a n e l .
∗/
public JComponent c r e a t e B o t t o m P a n e l ( ) {
JButton [ ] b u t t o n s = new JButton [ 1 ] ;
b u t t o n s [ 0 ] = new JButton ( ” Login ” ) ;
A c t i o n H a n d l e r actHand = new A c t i o n H a n d l e r ( ) ;
f i e l d s [ USER ID ] . a d d A c t i o n L i s t e n e r ( actHand ) ;
return new ButtonAndMessagePanel ( b u t t o n s , messageLabel , actHand ) ;
}
/∗ ∗
∗ Perform t h e e n t r y a c t i o n s o f t h i s pane , i . e . c l e a r t h e
∗ message l i n e .
∗/
public void e n t r y A c t i o n s ( ) {
clearMessage ( ) ;
}
/∗ ∗
∗ A c l a s s which l i s t e n s f o r b u t t o n c l i c k s .
∗/
c l a s s A c t i o n H a n d l e r implements A c t i o n L i s t e n e r {
/∗ ∗
∗ C a l l e d when t h e u s e r c l i c k s t h e l o g i n b u t t o n . Checks w i t h t h e
∗ d a t a b a s e i f t h e u s e r e x i s t s , and i f so n o t i f i e s t h e CurrentUser
∗ object .
∗
∗ @param e The e v e n t o b j e c t ( n o t used ) .
∗/
public void a c t i o n P e r f o r m e d ( ActionEvent e ) {
S t r i n g u s e r I d = f i e l d s [ USER ID ] . g e t T e x t ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
}
}
Listing 5: BookingPane.java
import j a v a x . swing . ∗ ;
import j a v a x . swing . e v e n t . ∗ ;
17
EDAF20
Labs
import j a v a . awt . ∗ ;
import j a v a . awt . e v e n t . ∗ ;
/∗ ∗
∗ The GUI pane where a u s e r b o o k s t i c k e t s f o r movie p e r f o r m a n c e s . I t
∗ c o n t a i n s one l i s t o f movies and one o f performance d a t e s . The u s e r
∗ s e l e c t s a performance by c l i c k i n g i n t h e s e l i s t s . The performance
∗ d a t a i s shown i n t h e f i e l d s i n t h e r i g h t p a n e l . The bottom p a n e l
∗ c o n t a i n s a b u t t o n which t h e u s e r can c l i c k t o book a t i c k e t t o
∗ t h e s e l e c t e d performance .
∗/
public c l a s s BookingPane extends BasicPane {
/∗ ∗
∗ A l a b e l showing t h e name o f t h e c u r r e n t u s e r .
∗/
private J L a b e l currentUserNameLabel ;
/∗ ∗
∗ The l i s t model f o r t h e movie name l i s t .
∗/
private D e f a u l t L i s t M o d e l nameListModel ;
/∗ ∗
∗ The movie name l i s t .
∗/
private J L i s t nameList ;
/∗ ∗
∗ The l i s t model f o r t h e performance d a t e l i s t .
∗/
private D e f a u l t L i s t M o d e l d a t e L i s t M o d e l ;
/∗ ∗
∗ The performance d a t e l i s t .
∗/
private J L i s t d a t e L i s t ;
/∗ ∗
∗ The t e x t f i e l d s where t h e movie d a t a i s shown .
∗/
private J T e x t F i e l d [ ] f i e l d s ;
/∗ ∗
∗ The number o f t h e movie name f i e l d .
∗/
private s t a t i c f i n a l i n t MOVIE NAME = 0 ;
/∗ ∗
∗ The number o f t h e performance d a t e f i e l d .
∗/
private s t a t i c f i n a l i n t PERF DATE = 1 ;
/∗ ∗
∗ The number o f t h e movie t h e a t e r f i e l d .
∗/
private s t a t i c f i n a l i n t THEATER NAME = 2 ;
/∗ ∗
∗ The number o f t h e ’ number o f f r e e s e a t s ’ f i e l d .
∗/
private s t a t i c f i n a l i n t FREE SEATS = 3 ;
/∗ ∗
∗ The t o t a l number o f f i e l d s .
∗/
private s t a t i c f i n a l i n t NBR FIELDS = 4 ;
18
EDAF20
Labs
/∗ ∗
∗ C r e a t e t h e b o o k i n g pane .
∗
∗ @param db The d a t a b a s e o b j e c t .
∗/
public BookingPane ( Database db ) {
super ( db ) ;
}
/∗ ∗
∗ C r e a t e t h e l e f t p a n e l , c o n t a i n i n g t h e movie name l i s t and
∗ t h e performance d a t e l i s t .
∗
∗ @return The l e f t p a n e l .
∗/
public JComponent c r e a t e L e f t P a n e l ( ) {
nameListModel = new D e f a u l t L i s t M o d e l ( ) ;
nameList = new J L i s t ( nameListModel ) ;
nameList . s e t S e l e c t i o n M o d e ( L i s t S e l e c t i o n M o d e l . SINGLE SELECTION ) ;
nameList . s e t P r o t o t y p e C e l l V a l u e ( ” 123456789012 ” ) ;
nameList . a d d L i s t S e l e c t i o n L i s t e n e r (new N a m e S e l e c t i o n L i s t e n e r ( ) ) ;
J S c r o l l P a n e p1 = new J S c r o l l P a n e ( nameList ) ;
d a t e L i s t M o d e l = new D e f a u l t L i s t M o d e l ( ) ;
d a t e L i s t = new J L i s t ( d a t e L i s t M o d e l ) ;
d a t e L i s t . s e t S e l e c t i o n M o d e ( L i s t S e l e c t i o n M o d e l . SINGLE SELECTION ) ;
d a t e L i s t . s e t P r o t o t y p e C e l l V a l u e ( ” 123456789012 ” ) ;
d a t e L i s t . a d d L i s t S e l e c t i o n L i s t e n e r (new D a t e S e l e c t i o n L i s t e n e r ( ) ) ;
J S c r o l l P a n e p2 = new J S c r o l l P a n e ( d a t e L i s t ) ;
JPanel p = new JPanel ( ) ;
p . s e t L a y o u t (new GridLayout ( 1 , 2 ) ) ;
p . add ( p1 ) ;
p . add ( p2 ) ;
return p ;
}
/∗ ∗
∗ C r e a t e t h e t o p p a n e l , c o n t a i n i n g t h e f i e l d s w i t h t h e performance d a t a .
∗
∗ @return The t o p p a n e l .
∗/
public JComponent c r e a t e T o p P a n e l ( ) {
S t r i n g [ ] t e x t s = new S t r i n g [ NBR FIELDS ] ;
t e x t s [MOVIE NAME]
= ” Movie ” ;
t e x t s [ PERF DATE ]
= ” Date ” ;
t e x t s [THEATER NAME] = ” P l a y s a t ” ;
t e x t s [ FREE SEATS ] = ” Fr e e s e a t s ” ;
f i e l d s = new J T e x t F i e l d [ NBR FIELDS ] ;
f o r ( i n t i = 0 ; i < f i e l d s . l e n g t h ; i ++) {
f i e l d s [ i ] = new J T e x t F i e l d ( 2 0 ) ;
f i e l d s [ i ] . setEditable ( false ) ;
}
JPanel i n p u t = new I n p u t P a n e l ( t e x t s ,
fields );
JPanel p1 = new JPanel ( ) ;
p1 . s e t L a y o u t (new FlowLayout ( FlowLayout . LEFT ) ) ;
p1 . add (new J L a b e l ( ” C u r r e n t u s e r : ” ) ) ;
currentUserNameLabel = new J L a b e l ( ” ” ) ;
p1 . add ( currentUserNameLabel ) ;
JPanel p = new JPanel ( ) ;
p . s e t L a y o u t (new BoxLayout ( p , BoxLayout . Y AXIS ) ) ;
p . add ( p1 ) ;
19
EDAF20
Labs
p . add ( i n p u t ) ;
return p ;
}
/∗ ∗
∗ C r e a t e t h e bottom p a n e l , c o n t a i n i n g t h e book t i c k e t −b u t t o n and
∗ t h e message l i n e .
∗
∗ @return The bottom p a n e l .
∗/
public JComponent c r e a t e B o t t o m P a n e l ( ) {
JButton [ ] b u t t o n s = new JButton [ 1 ] ;
b u t t o n s [ 0 ] = new JButton ( ”Book t i c k e t ” ) ;
return new ButtonAndMessagePanel ( b u t t o n s , messageLabel ,
new A c t i o n H a n d l e r ( ) ) ;
}
/∗ ∗
∗ Perform t h e e n t r y a c t i o n s o f t h i s pane : c l e a r a l l f i e l d s ,
∗ f e t c h t h e movie names from t h e d a t a b a s e and d i s p l a y them
∗ i n t h e name l i s t .
∗/
public void e n t r y A c t i o n s ( ) {
clearMessage ( ) ;
currentUserNameLabel . s e t T e x t
( CurrentUser . i n s t a n c e ( ) . getCurrentUserId ( ) ) ;
fillNameList ( ) ;
clearFields ();
}
/∗ ∗
∗ Fetch movie names from t h e d a t a b a s e and d i s p l a y them
∗ i n t h e name l i s t .
∗/
private void f i l l N a m e L i s t ( ) {
nameListModel . r e m o v e A l l E l e m e n t s ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
/∗ ∗
∗ Fetch performance d a t e s from t h e d a t a b a s e and d i s p l a y
∗ them i n t h e d a t e l i s t .
∗/
private void f i l l D a t e L i s t ( ) {
dateListModel . removeAllElements ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
/∗ ∗
∗ Clear a l l t e x t f i e l d s .
∗/
private void c l e a r F i e l d s ( ) {
f o r ( i n t i = 0 ; i < f i e l d s . l e n g t h ; i ++)
f i e l d s [ i ] . setText ( ”” ) ;
}
/∗ ∗
∗ A c l a s s t h a t l i s t e n s f o r c l i c k s i n t h e name l i s t .
∗/
c l a s s N a m e S e l e c t i o n L i s t e n e r implements L i s t S e l e c t i o n L i s t e n e r {
/∗ ∗
∗ C a l l e d when t h e u s e r s e l e c t s a name i n t h e name l i s t .
∗ F e t c h e s performance d a t e s from t h e d a t a b a s e and d i s p l a y s
∗ them i n t h e d a t e l i s t .
∗
∗ @param e The s e l e c t e d l i s t item .
∗/
public void valueChanged ( L i s t S e l e c t i o n E v e n t e ) {
20
EDAF20
Labs
i f ( nameList . i s S e l e c t i o n E m p t y ( ) )
return ;
S t r i n g movieName = ( S t r i n g ) nameList . g e t S e l e c t e d V a l u e ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
}
/∗ ∗
∗ A c l a s s that l i s t e n s for c l i c k s in the date l i s t .
∗/
c l a s s D a t e S e l e c t i o n L i s t e n e r implements L i s t S e l e c t i o n L i s t e n e r {
/∗ ∗
∗ C a l l e d when t h e u s e r s e l e c t s a name i n t h e d a t e l i s t .
∗ F e t c h e s performance d a t a from t h e d a t a b a s e and d i s p l a y s
∗ i t in the t e x t f i e l d s .
∗
∗ @param e The s e l e c t e d l i s t item .
∗/
public void valueChanged ( L i s t S e l e c t i o n E v e n t e ) {
i f ( nameList . i s S e l e c t i o n E m p t y ( ) | | d a t e L i s t . i s S e l e c t i o n E m p t y ( ) )
return ;
S t r i n g movieName = ( S t r i n g ) nameList . g e t S e l e c t e d V a l u e ( ) ;
S t r i n g date = ( S t r i n g ) d a t e L i s t . getSelectedValue ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
}
/∗ ∗
∗ A cl as s that l i s t e n s for button c l i c k s .
∗/
c l a s s A c t i o n H a n d l e r implements A c t i o n L i s t e n e r {
/∗ ∗
∗ C a l l e d when t h e u s e r c l i c k s t h e Book t i c k e t b u t t o n . Books a
∗ t i c k e t f o r t h e c u r r e n t u s e r t o t h e s e l e c t e d performance
∗ ( adds a b o o k i n g t o t h e d a t a b a s e ) .
∗
∗ @param e The e v e n t o b j e c t ( n o t used ) .
∗/
public void a c t i o n P e r f o r m e d ( ActionEvent e ) {
i f ( nameList . i s S e l e c t i o n E m p t y ( ) | | d a t e L i s t . i s S e l e c t i o n E m p t y ( ) )
return ;
i f ( ! CurrentUser . i n s t a n c e ( ) . isLoggedIn ( ) ) {
d i s p l a y M e s s a g e ( ”Must l o g i n f i r s t ” ) ;
return ;
}
S t r i n g movieName = ( S t r i n g ) nameList . g e t S e l e c t e d V a l u e ( ) ;
S t r i n g date = ( S t r i n g ) d a t e L i s t . getSelectedValue ( ) ;
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
}
}
Listing 6: ButtonAndMessagePanel.java
import j a v a x . swing . ∗ ;
import j a v a . awt . ∗ ;
import j a v a . awt . e v e n t . ∗ ;
/∗ ∗
∗ A GUI p a n e l which c o n t a i n s b u t t o n s and a message l i n e .
∗/
public c l a s s ButtonAndMessagePanel extends JPanel {
/∗ ∗
∗ C r e a t e t h e component w i t h t h e s p e c i f i e d b u t t o n s and message l i n e ,
∗ and a l s o an a c t i o n l i s t e n e r f o r t h e b u t t o n s .
∗
21
EDAF20
Labs
∗ @param b u t t o n s The a r r a y o f b u t t o n s .
∗ @param messageLine The message l i n e .
∗ @param actHand The a c t i o n l i s t e n e r f o r t h e b u t t o n s .
∗/
public ButtonAndMessagePanel ( JButton [ ] b u t t o n s , J L a b e l messageLine ,
A c t i o n L i s t e n e r actHand ) {
s e t L a y o u t (new GridLayout ( 2 , 1 ) ) ;
JPanel b u t t o n P a n e l = new JPanel ( ) ;
f o r ( i n t i = 0 ; i < b u t t o n s . l e n g t h ; i ++)
b u t t o n P a n e l . add ( b u t t o n s [ i ] ) ;
add ( b u t t o n P a n e l ) ;
add ( m e s s a g e L i n e ) ;
f o r ( i n t i = 0 ; i < b u t t o n s . l e n g t h ; i ++)
b u t t o n s [ i ] . a d d A c t i o n L i s t e n e r ( actHand ) ;
}
}
Listing 7: InputPanel.java
import j a v a x . swing . ∗ ;
import j a v a . awt . ∗ ;
/∗ ∗
∗ A GUI p a n e l which c o n t a i n s a number o f t e x t f i e l d s on t o p o f
∗ each o t h e r . Each t e x t f i e l d has a l a b e l .
∗/
public c l a s s I n p u t P a n e l extends JPanel {
/∗ ∗
∗ C r e a t e t h e p a n e l w i t h t h e s p e c i f i e d f i e l d s and l a b e l s .
∗
∗ @param t e x t s The l a b e l s on t h e f i e l d s .
∗ @param f i e l d s The t e x t f i e l d s .
∗/
public I n p u t P a n e l ( S t r i n g [ ] t e x t s , J T e x t F i e l d [ ] f i e l d s ) {
JPanel l e f t = new JPanel ( ) ;
l e f t . s e t L a y o u t (new GridLayout ( t e x t s . l e n g t h , 1 ) ) ;
f o r ( i n t i = 0 ; i < t e x t s . l e n g t h ; i ++) {
J L a b e l l a b e l = new J L a b e l ( t e x t s [ i ] + ”
” , J L a b e l . RIGHT ) ;
l e f t . add ( l a b e l ) ;
}
JPanel r i g h t = new JPanel ( ) ;
r i g h t . s e t L a y o u t (new GridLayout ( f i e l d s . l e n g t h , 1 ) ) ;
f o r ( i n t i = 0 ; i < f i e l d s . l e n g t h ; i ++)
r i g h t . add ( f i e l d s [ i ] ) ;
s e t L a y o u t (new BoxLayout ( this , BoxLayout . X AXIS ) ) ;
add ( l e f t ) ;
add ( r i g h t ) ;
}
}
Listing 8: CurrentUser.java
/∗ ∗
∗ CurrentUser r e p r e s e n t s t h e c u r r e n t u s e r t h a t has l o g g e d on t o
∗ t h e movie b o o k i n g s y st e m . I t i s a s i n g l e t o n c l a s s .
∗/
public c l a s s C u r r e n t U s e r {
/∗ ∗
∗ The s i n g l e i n s t a n c e o f t h i s c l a s s
∗/
22
EDAF20
Labs
private s t a t i c C u r r e n t U s e r i n s t a n c e ;
/∗ ∗
∗ The name o f t h e c u r r e n t u s e r .
∗/
private S t r i n g c u r r e n t U s e r I d ;
/∗ ∗
∗ C r e a t e a CurrentUser o b j e c t .
∗/
private C u r r e n t U s e r ( ) {
c u r r e n t U se r I d = null ;
}
/∗ ∗
∗ Returns t h e s i n g l e i n s t a n c e o f t h i s c l a s s .
∗
∗ @return The s i n g l e i n s t a n c e o f t h e c l a s s .
∗/
public s t a t i c C u r r e n t U s e r i n s t a n c e ( ) {
i f ( i n s t a n c e == n u l l )
i n s t a n c e = new C u r r e n t U s e r ( ) ;
return i n s t a n c e ;
}
/∗ ∗
∗ Check i f a u s e r has l o g g e d i n .
∗
∗ @return t r u e i f a u s e r has l o g g e d in , f a l s e o t h e r w i s e .
∗/
public boolean i s L o g g e d I n ( ) {
return c u r r e n t U s e r I d != n u l l ;
}
/∗ ∗
∗ Get t h e u s e r i d o f t h e c u r r e n t u s e r . S h o u l d o n l y be c a l l e d
∗ a u s e r has l o g g e d i n .
∗
∗ @return The u s e r i d o f t h e c u r r e n t u s e r .
∗/
public S t r i n g g e t C u r r e n t U s e r I d ( ) {
return c u r r e n t U s e r I d == n u l l ? ”<none>” : c u r r e n t U s e r I d ;
}
/∗ ∗
∗ A new u s e r l o g s i n .
∗
∗ @param u s e r I d The u s e r i d o f t h e new u s e r .
∗/
public void l o g i n A s ( S t r i n g u s e r I d ) {
currentUserId = userId ;
}
}
Listing 9: Database.java
import j a v a . s q l . ∗ ;
/∗ ∗
∗ Database i s a c l a s s t h a t s p e c i f i e s t h e i n t e r f a c e t o t h e
∗ movie d a t a b a s e . Uses JDBC and t h e MySQL Connector /J d r i v e r .
∗/
public c l a s s Database {
/∗ ∗
∗ The d a t a b a s e c o n n e c t i o n .
∗/
private C o n n e c t i o n conn ;
23
if
EDAF20
Labs
/∗ ∗
∗ C r e a t e t h e d a t a b a s e i n t e r f a c e o b j e c t . Connection t o t h e d a t a b a s e
∗ i s perfo rmed l a t e r .
∗/
public Database ( ) {
conn = n u l l ;
}
/∗ ∗
∗ Open a c o n n e c t i o n t o t h e d a t a b a s e , u s i n g t h e s p e c i f i e d u s e r name
∗ and password .
∗
∗ @param userName The u s e r name .
∗ @param password The u s e r ’ s password .
∗ @return t r u e i f t h e c o n n e c t i o n s u c c e e d e d , f a l s e i f t h e s u p p l i e d
∗ u s e r name and password were n o t r e c o g n i z e d . Returns f a l s e a l s o
∗ i f t h e JDBC d r i v e r i s n ’ t found .
∗/
public boolean open Connec tion ( S t r i n g userName , S t r i n g password ) {
try {
C l a s s . forName ( ”com . mysql . j d b c . D r i v e r ” ) ;
conn = DriverManager . g e t C o n n e c t i o n
( ” j d b c : mysql : / / s r v 0 1 6 . hbg . l u . s e / ” + userName ,
userName , password ) ;
}
catch ( SQLException e ) {
System . e r r . p r i n t l n ( e ) ;
e . printStackTrace ( ) ;
return f a l s e ;
}
catch ( ClassNotFoundException e ) {
System . e r r . p r i n t l n ( e ) ;
e . printStackTrace ( ) ;
return f a l s e ;
}
return true ;
}
/∗ ∗
∗ Close the connection to the database .
∗/
public void c l o s e C o n n e c t i o n ( ) {
try {
i f ( conn != n u l l )
conn . c l o s e ( ) ;
}
catch ( SQLException e ) {}
conn = n u l l ;
}
/∗ ∗
∗ Check i f t h e c o n n e c t i o n t o t h e d a t a b a s e has been e s t a b l i s h e d
∗
∗ @return t r u e i f t h e c o n n e c t i o n has been e s t a b l i s h e d
∗/
public boolean i s C o n n e c t e d ( ) {
return conn != n u l l ;
}
/∗ −−− i n s e r t own code h e r e −−− ∗/
}
24