|
|
|
Last
revision of this document: |
As
the classes for the Business Object (BO) and the Data-Base-Access
(DBA) Objects are implemented, they can be used to save entered data.
This
step describes, how the application reacts to the click onto the
button 'Store'; i.e. how the data from the GUI-elements is
transferred to the BO and how the data goes onto the database.
Overview:This
document covers the following steps:
* Define
two Business Objects 'Project' as variables (one contains data as
read from the database; one reflects the entered data),
* Add
the ActionListener and register it with the
'Store'-button,,
* Implement
the method 'actionPerformed()',
* Create
the class JS_ErrDB_Project__ActionHandler which will contain the code
that is run after button-clicks,
* Transfer
the values from the GUI-elements to the attributes of the Business
Object,
* Call
the 'store()' method of the Business Object,
* Verify
that the data was stored in the database-table,
* Use
the debugger to track down programming errors (if the data does not
appear in the database as expected).
* Verify
that entry-errors are detected
Preface:The
first part of this step (adding an ActionHandler and reacting to a
button-click) is an repetition of an already practised exercise
(JS_FC01i - Create
and code the class for the 'Task-Frame' to maintain 'Projects' |
React to a button-click). Therefore the
description is reduced to keywords.
Next,
the Business Object 'Project' (JS_ErrDB_Project_BOC)
has to be defined as a variable in the Task-Frame.
The
third part is to transfer the values entered into the GUI-elements
(JTextFields) to the Business Object 'Project'.
The method
'getFromGUI(.....)' is described in detail.
Next,
the method 'store()' of the Business Object is called and if there
was no semantical mistake made in all derivations of the Business
Object, the Data-Base-Access Object and the file with the
XML-structure containing parameters for database-access, then the
data is stored in the database.
Finally,
aside from coding, the database-monitor is used to execute some
SQL-commands to see if the table 'Project' was populated with the
values entered on the GUI.
Credits:Too
numerous to mention; the idea is available in dozens of versions –
I refined a lot of ideas into my system.
JS_FC01p – Create the database-table 'Project' and establish the connection completed – and its prerequisites too.
Define
two Business Objects 'Project' as variables:To
define two BO has the following reason:
There is one BO that
contains the data as it was read from the database-table when the
'Project' was selected for making a change.
The other BO contains
the data as it is represented in the input-fields of the GUI.
This
concept makes no sense now – but in a later step, data from the
GUI is transferred to the BO after every keystroke (and not after the
button 'Store' is clicked like in this execise) and then it can be
checked if there was a change made.
With the knowledge about this
change, the enabling or disabling of buttons can be controlled.
In
class JS_ErrDB_Project
add the following lines to define the Business Objects as
variables: private
JTable pnl_SelectionListTable=null; private
DefaultTableColumnModel
pnl_SelectionListDefaultTableColumnModel=null;/*
* Business
Objects maintained within this task. */ protected
JS_ErrDB_Project_BOC structJS_ErrDB_Project_BOC_Read; protected
JS_ErrDB_Project_BOC structJS_ErrDB_Project_BOC_Processed;/*
*
-------------------------------
* Constructor of the class
*/
As
the BOs have to get connection-information about the database-system
or the Java-Application-Server that holds persistant data, the have
to be constructed as at that time the connection is passed to the
BOs.
You might have done this construction already in step
JS_FC01l - Develop the Client-Side-Class
for the Business Object 'Project.
Please check if the
following comands are already implemented – otherwise write
the code, please: private
void initialize_before_frame(String
parmstrLanguageCode) { }/*
Construct the Business Objects maintained by this task.
*/
structJS_ErrDB_Project_BOC_Read
= new
JS_ErrDB_Project_BOC(this); structJS_ErrDB_Project_BOC_Processed
= new
JS_ErrDB_Project_BOC(this);
Add
the ActionListener and register it with the 'Store'-button:A
more detailed description about the effects of the Interface
'ActionListener' was already given in JS_FC01i
- Create and code the class for the 'Task-Frame' to maintain
'Projects' | React to a button-click.
Therefore the description is reduced to keywords.
In
class JS_ErrDB_Project
add the following lines: *
--------------------------------------------------------
*
*/
public
class JS_ErrDB_Project
extends JSBS_TaskFrame
implements
ActionListener { private
JPanel pnl_Main=null; private
JPanel pnl_Maintain=null;
private
JPanel pnl_Select=null;N.B.:
If you decided to write the base-classes by yourself (see Create
a projject for the base-classes) this will lead to an error
because the interface requieres a method actionPerformed.
If you
are using the library (see Download the
jar-file for the base-classes), then the error will not occur
because the base-class JSBS_TaskFrame
has this method already implemented.
Then,
the ActionListener has to be added to all buttons. This is also done
om class JS_ErrDB_Project
and here is the example :
public
JButton get_btn_Store() {
/*
The code of this method auto-creates the element if it is not
already defined */
if
(btn_Store
== null) {
try
{
btn_Store
= new
JButton(); btn_ }Store.setName(“btn_);Store“ btn_Store.setHorizontalAlignment(SwingConstants.CENTER); btn_Store.addActionListener(this); btn_Store.setActionCommand
("btn_Store"); catch
(Throwable Exc) { }
System.out.println(“Error
while building
btn_);Store“
Exc.printStackTrace();
}
return
btn_Store;
}
Implement
the method 'actionPerformed'As
mentioned before, the method 'actionPerformed' is called as soon as a
button (which has the ActionListener added) is clicked.
To avoid a
congestion of the class, all code that handles 'actions' of any kind
is put into a own class, the JS_ErrDB_Project__ActionHandler
- which will be discussed in the next paragraph.
To
call the method implemented in the
JS_ErrDB_Project__ActionHandler,
add the following method in
class JS_ErrDB_Project:
public
void actionPerformed(ActionEvent parmActionEvent)
{
JS_ErrDB_Project__ActionHandler.handleEvent(this,
parmActionEvent); }
N.B.:
You will get an error as the class JS_ErrDB_Project__ActionHandler
does not exist yet. Its implementation will be describes in the next
paragraph
Create
the class JS_ErrDB_Project__ActionHandlerKeying
in each SQL-command is pretty boring particularly if the
table-definition becomes a little bit more voluminous.
So there are two alternative methods to create a
database-table.
Both of them use a text-file with the
SQL-commands.
The
folder and the name of the file can be chosen freely; I decided for
folder 'DB_SCRIPTS' with file 'Create_Tables.txt' under the
Eclipse-project JS_FC01
To
create the class, r.ight
click onto the project 'JS_FC01' and select
>New>Class
Enter
the Package (js_errdb.clientframes),
the (Class-)Name (JS_ErrDB_Project__ActionHandler),
check that no checkbox is selected; then click the [Finish]
button.
If
you are too impatient for typing the code of
JS_ErrDB_Project__ActionHandler,
just copy the code, browse the explanations in the next paragraphs
and continue with Verify that the
data was stored in the database-table.
The
code for the created class is not voluminous now; it just consists
of a method that derives which button was clicked – and
depending on the clicked button another method (that carries out the
business action) is called:/*
* Method to handle Actions that were triggered by clicking
onto a GUI-Element
* which has added the interface
'ActionListener'. */
protected
static void handleEvent(JS_ErrDB_Project parmTF, ActionEvent
parmActionEvent) {/*
Derive the ActionCommand String
cmd = parmActionEvent.getActionCommand();
* (which was attached to the
GUI-element through method setActionCommand()). *//*
Check which ActionCommand was handed over and perform the
appropriate action. */ if
(cmd.equals("btn_Store"))
{/*
Button to store the entered data.
*/ store(parmTF);
} }
That
the error disappears, an empty method store()
is created:/*
}
* Methods to carry out
business-actions
* -------------------------------------
*/
/*
* Method to store the data from the GUI-elements
to the database. */
protected
static void store(JS_ErrDB_Project parmTF) {
Transfer
the values from the GUI-elements to the attributes of the Business
Object:Most
of the coding-work was done when the Business Objects were created.
Now the fruits of this effort can be harvested as the method
implemented in
step JS_FC01l - Develop the
Client-Side-Class for the Business Object 'Project
just have to be called:
Amend
the method store(...) with
the following code: /*
*
Method to store the data from the GUI-elements to the database.
*/
protected
static void store(JS_ErrDB_Project parmTF) {parmTF./*
* Transfer the values from the GUI-elements to the
Business Objject 'Project'.
*/
structJS_ErrDB_Project_BOC_Processed.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectory());
}
Call
the 'store()' method of the Business Object:To
store the data to the database, a method of the
Client-Side-Derivation of the Business Object is used, too.
The
code to call the store()-method
is pretty small; to verify if the database-operation ended as
expected or to report an error needs a few more lines of code:/*parmTF.
*
Method to store the data from the GUI-elements to the database.
*/
protected
static void store(JS_ErrDB_Project parmTF) {/*
* Transfer the values from the GUI-elements to the
Business Objject 'Project'.
*/
structJS_ErrDB_Project_BOC_Processed.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectory()); }/*
* Use the method of the BO to store the data.
*/
parmTF.structJS_ErrDB_Project_BOC_Processed.store();/* Verify
that the store was run as expected; print out error if not.
*/ if
(parmTF.structJS_ErrDB_Project_BOC_Processed.StatusCode
!=
parmTF.)
{structJS_ErrDB_Project_BOC_Processed.CONST_OK
System.out.println(
"Error
in store() of JS_ErrDB_Project_BOC; class
JS_ErrDB_Project__ActionHandler /
store()."); System. };out.println("StatusCode:
"
+
Integer.toString(parmTF.));structJS_ErrDB_Project_BOC_Processed.StatusCode System.out.println("StatusMsg:
"
+
parmTF.);structJS_ErrDB_Project_BOC_Processed.StatusMsg
Verify
that the data was stored in the database-table:There
was a long way from the last visual result till now.
With the
coding of all derivations of the Business Object and the
Data-Base-Access Object several error might have creeped in.
So,
the expected result might not be as expected. In that case, please
start with the paragraph Use the debugger to
track down programming errors.
To
see the result of the just typed code, run the application again by
selecting
>Run>Run....
Select 'JS_ErrDB_CommandCenter'
(in the left column under 'Java
Application') and click the button [ Run ].
For
all future steps a good sign is, if the usual frames appears and the
'Console' section stays empty.
A
sign of an error is, if there is something printed out in the
'Console' section.
After
you selected the Detail-Frame for the 'Project', enter some values
in the entry fields.
Please obey that the length of the
entered values is not bigger than defined for the database-tables
(see JS_FC01p
Create the database-Table 'Project' and establish the connection |
Alternative ways to create the database-table)
i.e.
16 characters for the Project-Code and 4 characters for the
Language-Code. 
Click
the [ Store ] button and obey, that the
'Console' section stays empty.
If there is a message reported,
please continue with the paragraph Use the
debugger to track down programming errors.
To
see, if the data 'has arrived in the database-table', open a
'Terminal' window and log
on to the database-system:mysql
–-host='127.0.0.1' –-user='mysql' –-password='drowssap'
js_tutorial
That
starts the monitor of the MySQL database-system.
Expand
the 'terminal' window to the full size as this makes data better
readable.
Enter the SQL-command select
* from Project;
and you should get the following
display of the database-table 'Project':
Please
check that all attributes (except 'CreatedBy' and 'ChangedBy') have
a value and that the values of 'ProjectCode', 'LanguageCode' and
'TargetDirectory' are the same as the one entered on the
user-interface.
If there are some values missing or distorted,
please continue with Use
the debugger to track down programming errors.
You
might tinker around a little bit, e.g. changing the value of
'Target-Directory':
Then
you will see, that the first entry in the database-table was made
invalid by changing 'ValidTill' and a second entry was inserted:

For
more theory about the idea of documenting changes of an 'object'
please refer to Common
Attributes for all database-tables.
Please obey that
in that state of the development, changing values does not lead a
new 'Project' – just to different states over time for the
same 'Project'.
To create a new 'object' it is neccessary to
close the window for the Taks-Frame 'Project - Maintain Error-DB'
and reopen it.
In a later step, the [ Copy ] button will
be activated, which copies the values of the current 'Project'.
Use
the debugger to track down programming errors:As
mentioned before, a lot of programming was done after the last step
with a visible result.
When I began to implement the process model
with the design patterns, I made several small semantical mistakes
(forgetting a command, assigning wrong values, etc.) which caused a
completely different result than planned.
As
it is boring and also error-prone to compare the code with the
samples in this tutorial.
The best way to see what is happening
in the code and find semantical errors is, to use the debugger.
If
the class 'JS_ErrDB_Project' is not already open for editing, open
it. 
This
is neccessary as there will be a 'Breakpoint' set later on.
Start
the debugger by selecting
>Run>Debug....
Select 'JS_ErrDB_CommandCenter'
(in the left column under 'Java
Application') and check [x] 'Stop in main'.
Select
the tab 'Arguments' and enter
en.
This will cause the application to look
for the language dependant GUI-elements in the directory
'TEXT.en'.
To
start debugging, click the button [ Debug ].
A
good sign is, if the usual frame appears and the 'Console' section
stays empty.
Depending
on the processor-speed an memory of your machine, a rquest to
confirm the 'switch to debug perspective' will show up and after a
few moments the debugger will stop in the main()
method of the application.
Select
the tab 'JS_ErrDB_Project' and scroll down to the method public
void actionPerformed(ActionEvent parmActionEvent).
Position
the mouse-cursor over the first line within the method an click the
right mouse-button.
On the context menu select Run to Line.
After
clicking the [ Store ] button on the Task-Frame
'Project – Maintain Error-DB', the debugger stops at the
selected line and you are able to step ahead using the
debugging-buttons:![]()
It
is out of scope of this tutorial to explain the functionality of the
debugger and to discuss every possible semantical error.
I
recommend to use the 'Step Into' (a method) function of the debugger
if it is a method that was developed into this tutorial.
For the
expenditure of time you should calculate several hours –
particularly if you are debugging within Eclipse for the first time.
Verify
that entry-errors are detected:A
good practise of software-development is, to verify if the
application reacts correct to errors caused by faulty entries of a
user.
The final task in this step is, to enter not allowed data
and check, if the application responds correct.
The feedback
to errors is poor at this stage of development – it is just a
technical printout to the 'Console'.
For mature commercial
applications there is a much better response shown to the user –
this just is not documented yet (October 2006) ;-) .
First,
an already existing combination of Project-Code/Language-Code is
entered.
If you used ErrDB/en
in the step before, use it again and after pressing the [ Store ]
button,
the message in the 'Console' section should look similar
to this:
Then,
a too long value for the 'Project-Code' is entered.
As I
realised during testing, MySQL simply cuts of the value and does not
report an error in this case – so I am unable to show you the
outcome.
If you use another database that reports an error (IBMs
DB/2, I think) please verify that the expected error is reported.
Next
Step:Next,
a list of 'Projects' stored in the database will be displayed and
one out of the list can be selected for update.
JS_FC01r
– Re-display the list with the Project/Language combinations.