|
Letzte
Bearbeitung dieses Dokuments: |
Voraussetzungen für das Verständnis dieses Dokuments:Grundkenntnisse in der Programmierung von Java (Klassen, Methoden, Schleifen) oder anderer Objekt-Orientierter Programmiersprachen (z.B. C++, Modula-2, Pascal). Tutorial Datenbank-Ladeprogramm mit Graphischer Benutzeroberfläche (Java_Intro_02) durchgearbeitet. |
Ungefährer Zeitbedarf zum Durcharbeiten dieses Dokuments:Arbeitszeit:
|
In diesem Schritt werden die Daten erfaßt und (nach Anklicken der entsprechenden Schaltfläche) auf der Datenbank gespeichert.
Als 'Herausforderung' der Datenerfassung ist vorgesehen, durch Anklicken einer Schaltfläche ein Verzeichnis des Dateisystems auszuwählen.
Die in den vorigen Schritten implementierten DBA (DataBase-Access) und BO (Business-Object) Klassen werden aufgerufen um die eingegebenen Daten auf der Datenbank zu speichern.
Dazu ist folgender zusätzlicher Code notwendig:
Das
Hinzufügen einer Klasse
JS_ProjAssist_Project__ActionHandler.
In
dieser Klasse werden die Methoden implementiert, die bei den vom
Benutzer ausgelösten Ereignissen ('Events', z.B. Anklicken
einer Schaltfläche mit der Maus) ausgeführt werden.
Methode zum Auswählen eines Verzeichnisses des Dateisystems.
Variable für das Client-Side-BO-Objekt (BOC) und 'Konstruieren' des Objektes.
Methode
zum Übertragen der Daten von den Eingabefeldern der GUI in das
Client-Side-BO-Objekt (BOC) und anschließendes Ausführen
der store()-Methode
des BOC.
Danach werden die Eingabefelder für jene Werte,
die den Anwender-bekannten-Schlüssel bilden, gesperrt damit
keine Veränderung der Werte mehr vorgenommen werden kann.
Methode zum Kopieren bestehender Eingabe-Werte für eine neue Eingabe.
Voriger Schritt: Client-Side BO (Business-Object) Klasse für 'ProjectLanguage'
Vorbemerkung
Vorbedingungen
Klasse
JS_ProjAssist_Project__ActionHandler
eröffnen
Name
der Klasse als Konstante definieren
Code
zum Feststellen des Event-Auslösers
Aufrufen
der Methode handleEvent
in
der Klasse JS_ProjAssist_Project
Zwischen-Test
1
Methode
zum Auswählen eines Verzeichnisses
* Import
der Bibliothek java.awt.*
* Methode
zum Auswählen des Verzeichnisses codieren
* Sprachabhängigen
Text in der Datei 'DisplayStrings.xml' erfassen
* Aufruf
der Methode in handleEvent
Zwischen-Test
2
Methode zum
Speichern der eingegebenen Daten
* Code
in der Klasse JS_ProjAssist_Project
* Import
der Bibliothek js_base.bo
in der Klasse JS_ProjAssist_Project__ActionHandler
* Methode
store(...)
erstellen
und in handleEvent
aufrufen
* Übertragen
der Werte aus den GUI-Elementen in die Attribute des BOC
* Methode
des BOC zum Speichern aufrufen
* Prüfen
auf ordnungsgemäße Ausführung
Zwischen-Test
3
* Anzeigen
des Inhalts der DB-Tabelle zur Überprüfung
Methode
zum Kopieren der Daten
* Methode
copy(...)
erstellen
und in handleEvent
aufrufen
Test
* Anzeigen
des Inhalts der DB-Tabelle zur Überprüfung
Gesamter
Code am Ende des Schrittes
* Klasse
JS_ProjAssist_Project
* Klasse
JS_ProjAssist_Project__ActionHandler
Weitere
Schritte und verwandte Dokumentation
Nächster
Schritt: DataBase-Access
Klasse für eine Liste von Datensätzen aus der DB-Tabelle
'ProjLang' (DBA-Set)
Obwohl
Eclipse in 'deutscher Version' installiert werden kann, sind
die Abbildungen in diesem Dokument mit der 'english Version'
erstellt. |
Tutorial Datenbank-Ladeprogramm mit Graphischer Benutzeroberfläche (Java_Intro_02) durchgearbeitet – und dessen Vorbedingungen auch.
Voriger Schritt Client-Side BO (Business-Object) Klasse für 'ProjectLanguage' abgeschlossen.
Das
Eröffnen der neuen Klasse wird nur in Stichworten und ohne
Abbildungen dokumentiert.
Wenn Sie sich unsicher sind, sehen Sie
bitte unter Schritt
2: Klasse für das StartFrame eröffnen nach, wie eine
Klasse eröffnet wird.
Package:
js_projassist.client
Name:
JS_ProjAssist_Project__ActionHandler
[ ]
public static void main(String[] args) (nicht
markiert)
[ ]
Constructors from superclass (nicht
markiert)
[ ]
Inherited abstract methods (nicht
markiert)
Generelle
Anmerkung:
Alle
Methoden in der Klasse JS_ProjAssist_Project__ActionHandler
werden als static
definiert. Damit muß die
Klasse nicht 'konstruiert' werden bevor eine Methode ausgeführt
werden kann.
Per
Definition enthält diese Klasse nur statische Methoden.
Daher
wird kein 'construct' der Klasse ausgeführt und der Name der
Klasse kann nicht über this.getClass().getName()
ermittelt
werden.
Um Tippfehler zu minimieren, wird der Name der Klasse als
Konstante festgelegt.
public
class
JS_ProjAssist_Project__ActionHandler
{
/*
* Name
der Klasse als Konstante festlegen weil bei statischen Methoden der
* Name der Klasse nicht über
'getClass().getName() ermittelt werden kann. */
private
static
String
CONST_ClassName
=
"JS_ProjAssist_Project__ActionHandler"
;
/*
Damit ein Event verarbeitet werden kann, ist die zuständige Bibliothek in der Klasse JS_ProjAssist_Project__ActionHandler zu importieren.
package
js_projassist.client;
/*
*
Package mit den Klassen zum Bearbeiten von Events */import
java.awt.event.*;
Die
Methode handleEvent(...)
wird
im zugehörigen Task-Frame aufgerufen.
Die Codierung dieses
Aufrufs wird im nächsten Abschnitt beschrieben.
*
*/public
class
JS_ProjAssist_Project__ActionHandler
{
/*
* Methode
die ermittelt, bei welchem GUI-Element ein 'ActionEvent' ausgelöst
wurde
* und die entsprechende Methode aufruft.
*/
protected
static void
handleEvent(JS_ProjAssist_Project
parmTF,
ActionEvent
parmActionEvent) {/* Zuerst
wird die 'Identifikation' des GUI-Element aus dem ActionEvent
extrahiert. */
String
cmd = parmActionEvent.getActionCommand().trim();
/* In
diesem Stadium des Tutorials wird zur Kontrolle der
Action-Command
* auf der Konsole ausgegeben.
*/
System.
out
.println(
"ActionCommand:
"
)
+ cmd);
}
Damit ein Event verarbeitet werden kann, ist die zuständige Bibliothek in der Klasse JS_ProjAssist_Project__ActionHandler zu importieren.
package
js_projassist.client;
/*
*
Packages mit den GUI-Elementen. */import
java.awt.*;
import
javax.swing.*;
/*
*
Package mit den Klassen zum Bearbeiten von Events */import
java.awt.event.*;
/*
*
Package mit der Basisklasse für das TaskFrame. */
Die
in der Basisklasse JSBS_TaskFrame
definierte Methode
actionPerformed(...)
wird
überschrieben und darin wird der Event als Parameter an die
Methode
handleEvent(...)
der
Klasse
JS_ProjAssist_Project__ActionHandler
weiter
gegeben.
/*
* Methode
die ausgeführt wird wenn ein Klick mit einer Maustaste
* auf
ein GUI-Element, dem der ActionListener hinzugefügt wurde,
erfolgt. */
public
void
actionPerformed(ActionEvent
e) {
/*
* Gleichnamige
Methode in der geerbten Basisklasse aufrufen.
* Damit
werden die 'geerbten' Verarbeitungen (die für alle
Anwendungsprogramme
* gleich sein können) zuerst
ausgeführt. */
super
.actionPerformed(e);
/*
* Weitere
Verarbeitung in einer eigenen Klasse mit statischen Methoden.
*/
JS_ProjAssist_Project__ActionHandler.handleEvent(this
,
e);
}
Diese
Methode wird aufgerufen wenn ein GUI-Element vom Typ JButton,
zu dem ein ActionListener
hinzugefügt
wurde, mit der Maus angeklickt wird. Das Hinzufügen des
ActionListener
erfolgte
bereits in der Basisklasse JSBS_StartFrame.
Eine
detaillierte Erklärung der Vorgänge ist im Dokument
Tutorial:
Datenbank-Ladeprogramm mit Graphischer Benutzeroberfläche
(Java_Intro_02) - ActionHandler beschrieben.
Die
Einstellungen und die Angabe der zu verwendenden Sprache als
Parameter wurden schon im Schritt 2 ausgeführt und bleiben als
Einstellung für das 'Project' erhalten.
Die Abfolge zum
Starten wurde bereits in vorigen Schritten mit Abbildungen
dokumentiert; deswegen folgen nur Stichworte:
Zum
Starten wird
Run
> Open Run Dialog
ausgewählt.
Im
anschließend erscheinenden Fenster (Run) werden die
Einstellungen nicht verändert und durch Anklicken der
Schaltfläche
[ Run ]
das
Programm gestartet.
|
|
|
|
Diese
Methode wird für eine besondere Aufgabe (Auswählen eines
Verzeichnisses) verwendet und wird bei den meisten Task-Frames zur
Verwaltung von Daten nicht gebraucht werden.
Wenn Sie über
den Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Notwendige Schritte zur Entwicklung des Task-Frames
zu
diesem Dokument gekommen sind, überspringen Sie diesen Abschnitt
und machen Sie bitte mit Methode
zum Speichern der Daten weiter.
In
dieser Methode wird nach Anklicken der Schaltfläche
[ Datei-Auswahl ]
das
in der Bibliothek von Java enthaltene Fenster zum Auswählen von
Verzeichnissen und Dateien aufgerufen.
Wegen des geringen Umfangs
des Codes eignet sich diese Methode für das 'Aufwärmen'
beim Codieren von Methoden, die durch 'events' in einem Java Programm
ausgelöst werden.
Diese
Bibliothek enthält die Klassen der verwendeten
GUI-Elemente.
Weil in dieser Klasse
(JS_ProjAssist_Project__ActionHandler)
die Werte aus den GUI-Elementen ausgelesen bzw. zu den GUI-Elementen
übertragen werden, ist diese Bibliothek notwendig.
/*
*
Package mit den Klassen der GUI-Elemente. */import
java.awt.*;
/**
Eine Methode mit ähnlicher Funktionalität wurde bereits im Tutorial mit den Einführungsbeispielen (Dokument Tutorial: Datenbank-Ladeprogramm mit Graphischer Benutzeroberfläche (Java_Intro_02) – Reagieren auf Schaltflächen-Klicks (ActionHandler) > Methode processSelectFile(. . .) codieren) codiert und in den Einzelheiten erklärt. Für eine Erläuterung der einzelnen Programm-Befehle lesen Sie bitte den Kommentar.
/*
* Methode
die ausgeführt wird wenn das Stamm-Verzeichnis für
generierte Dateien
* ausgewählt werden
soll. */
private
static void
processSelectDirectory(JS_ProjAssist_Project
parmTF) {
/*
* Sprachabhängigen
Text für die 'Title-Bar' des File-Dialog-Fensters aus
* der
XML-Datei 'auslesen'. */
String
strTitle =
parmTF.frmCC
.
structJSBS_XML_DisplayStrings
.getSupplementaryText(
"Project__ActionHandler*FD_TitleBar"
);
/*
* Fenster
für den 'File-Dialog' aufrufen;
* in diesem kann
der Benutzer eine Datei auswählen. */
FileDialog
fd = new
FileDialog(parmTF,
strTitle,
FileDialog.LOAD
);
/*
* Anfangswerte
für Verzeichnis und Dateiname setzen und Fenster sichtbar
machen.
*/
fd.setFile(
""
);
fd.setDirectory(""
);
fd.setVisible(true
);
/*
* Name
für gewähltes Verzeichnis aus dem 'File-dialog' holen und
in einen String übertragen. */
String
strDirectoryName = fd.getDirectory();
/*
* Verzeichnis
im entsprechenden Feld anzeigen.
*/
parmTF.get_txt_TargetDirectoryName().setText(strDirectoryName);
}
Die unter Tutorial: JavaScout ProjectAssist, Start-Frame Grundlagen (Java_Fatclient_01) – Text für die GUI-Elemente von XML-Datei einlesen > Verzeichnis und Datei mit der XML-Struktur mit den sprachabhängigen Texten erstellen) eröffnete Datei mit den Sprachabhängigen Texten wird um folgende Zeilen ergänzt.
<root>
<SupplementaryText>
<Element>
<ElementName>Project__ActionHandler*FD_TitleBar
</ElementName>
<MessageText>Wählen
Sie das Stamm-Verzeichnis,
bitte
</MessageText>
</Element>
</SupplementaryText>
<Layout>
Zum
Abschluß des Abschnittes wird jener Code implementiert, durch
den die Methode nach dem Anklicken der entsprechenden Schaltfläche
( [ Datei-Auswahl ]
)
aufgerufen wird.
Dazu wird die Methode handleEvent(...)
um
folgenden Code ergänzt:
* auf
der Konsole ausgegeben. */
System.
out
.println(
"ActionCommand:
"
+
cmd);
/* Abfragen
von welchem GUI-Element der Event ausgelöst wurde und
* Aufrufen der entsprechenden Methode.
*/
if
(cmd.equals(
"btn_TargetDirectorySelection"
))
processSelectDirectory(parmTF);
}
Das
Aufrufen des Task-Frames wurde bereits ausführlich beschrieben;
zuletzt im Abschnitt
Zwischen-Test
1
dieses
Dokuments.
Aus diesem Grund beschränkt sich diese
Beschreibung erst auf das Anklicken der Schaltfläche
[ Datei-Auswahl ]
.
|
|
|
|
In diesem Abschnitt wird der Code implementiert, der die eingegebenen Daten auf der Datenbank abspeichert.
In der Klasse JS_ProjAssist_Project werden die Variablen für das Business Object definiert.
Damit die Klasse für das BO verwendet werden kann, muß zuerst das entsprechende Java-Package importiert werden:
*
Package mit der Basisklasse für das TaskFrame. */
import
js_base.frame.*;
/*
*
Package mit den Business-Objects. */import
js_projassist.boc.*;
/*
*/
public
class
JS_ProjAssist_Project
extends
JSBS_TaskFrame
{
Anschließend werden 2 Variablen für jedes verwendete BO definiert:
public
class
JS_ProjAssist_Project
extends
JSBS_TaskFrame
{
/*
* Business-Objects (Client-Side-Klasse) definieren.
*/
protected
JS_ProjAssist_ProjectLanguage_BOC
structJS_ProjAssist_ProjectLanguage_BOC_Read
;
protected
JS_ProjAssist_ProjectLanguage_BOC
structJS_ProjAssist_ProjectLanguage_BOC_Processed
;
/*
* GUI-Elemente die für diesen Task-Frame
spezifisch sind. */
Die
Variable
structJS_ProjAssist_ProjectLanguage_BOC_Read
enthält
die Werte die von der Datenbank gelesen und angezeigt wurden.
Die
Variable structJS_ProjAssist_ProjectLanguage_BOC_Processed
enthält
die Werte, die nach einer eventuellen Veränderung auf der GUI
(Graphischen Benutzeroberfläche) zu sehen sind.
Die
Trennung ist zu diesem Zeitpunkt noch nicht notwendig; in einem
späteren Schritt des Tutorials wird mit eventuellen
Unterschieden gesteuert, wie Schaltflächen aktiviert bzw.
deaktiviert werden (z.B. wird
[ Speichern ]
erst
'aktiv', wenn eine Änderung der eingegebenen Daten erfolgt
ist).
Wegen der Nähe im Code werden bereits jetzt beide
Variable definiert und 'konstruiert' – vor allem deswegen weil
dieser Schritt des Tutorials auch eine ausführliche Erklärung
zum
Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Notwendige Schritte zur Entwicklung des Task-Frames
ist.
Bei
der realen Entwicklung von Task-Frames werden beide Variablen kurz
hintereinander verwendet.
Zuletzt müssen beide Variablen noch 'konstruiert' werden:
/*
* Methode
mit den Initialisierungen die notwendig sind bevor das Frame
(Window)
* angezeigt wird. */
private
void
initialize_before_frame()
{
/*
* 'Konstruieren'
der Business-Objects, die in diesem Task-Frame verwendet werden.
*/
structJS_ProjAssist_ProjectLanguage_BOC_Read
=
new
JS_ProjAssist_ProjectLanguage_BOC(
this
);
structJS_ProjAssist_ProjectLanguage_BOC_Processed
=
new
JS_ProjAssist_ProjectLanguage_BOC(
this
);
}/*
* Methode
mit der das Frame (Window) angezeigt wird. */
private
void
initialize_frame()
{
Ein
Business-Object enthält nach jeder DB-Operation einen
Status-Code, der signalisiert, ob die Operation fehlerfrei ausgeführt
wurde oder ob ein Fehler aufgetreten ist. Die allgemein gültigen
Werte sind in der Basisklasse JSBS_BO
festgelegt;
die Bibliothek für dieses Basisklasse wird importiert.
*
Package mit den Klassen der GUI-Elemente. */
import
java.awt.*;
/*
*
Package und Klassen mit den Status-Codes zum Prüfen auf
erfolgreiche Durchführung oder
* Fehler bei einer
Datenbank-Operation. */import
js_base.bo.JSBS_BO;
/**
*
* @author kurt@javascout.biz
Die Anweisungen zum Speichern von neu eingegebenen oder geänderten Daten werden in der Methode store(...) codiert.
/*
* Methode
die ausgeführt wird wenn eingegebene Daten auf der Datenbank
gespeichert
* werden sollen. */
private
static void
store(JS_ProjAssist_Project
parmTF) {
}
Die
Methode store(...)
wird
nach dem Anklicken der entsprechenden Schaltfläche
aufgerufen.
Dazu wird die Methode handleEvent
um
den folgenden Code erweitert.
* und
die entsprechende Methode aufruft. */
protected
static void
handleEvent(JS_ProjAssist_Project
parmTF,
ActionEvent
parmActionEvent) {...........
...........
/* Abfragen
von welchem GUI-Element der Event ausgelöst wurde und
* Aufrufen der entsprechenden Methode.
*/
if
(cmd.equals(
"btn_TargetDirectorySelection"
))
processSelectDirectory(parmTF);
if
(cmd.equals(
"btn_Store"
))
store(parmTF);
}
In
der Methode store(...)
werden
zuerst die Werte aus den GUI-Elementen auf die Variablen des BO
übertragen.
Dazu wird die Methode, die bei der BOC-Klasse
codiert wurde benutzt.
/*
* Methode
die ausgeführt wird wenn eingegebene Daten auf der Datenbank
gespeichert
* werden sollen. */
private
static void
store(JS_ProjAssist_Project
parmTF) {
/*
* Werte
aus den GUI-Elementen auf die Variablen des BO übertragen.
* Dabei
die Methode der BOC-Klasse verwenden.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectoryName());
}
Den
Code für die Methode
getFromGUI(...)
der
BOC-Klasse finden Sie unter Tutorial:
JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) –
Client-Side BO (Business-Object) Klasse für 'ProjectLanguage' >
Methoden zum 'Setzen' und 'Holen' der Werte von der GUI –
falls Sie daran Interesse haben.
In
der BOC-Klasse ist die Methode store()
implementiert.
Diese
hat die Aufgabe, die Werte in den Variablen des BO 'persistent' zu
machen. Das heißt in einfacheren Worten, die Werte werden auf
der zugeordneten Datenbank-Tabelle gespeichert.
/*
* Methode
die ausgeführt wird wenn eingegebene Daten auf der Datenbank
gespeichert
* werden sollen. */
private
static void
store(JS_ProjAssist_Project
parmTF) {
...........
...........
/*
* Methode
des BOC zum Speichern der Daten aufrufen.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.store();
}
Nach
dem Aufrufen der Methode zum Speichern, muß über den
Status-Code des BOC geprüft werden, ob das Speichern der Daten
ordnungsgemäß ausgeführt wurde oder ob ein Fehler
aufgetreten ist.
Die detaillierte Beschreibung der einzelnen
Möglichkeiten folgt nach der Liste des gesamten Codes zum
Prüfen.
/*
* Methode
die ausgeführt wird wenn eingegebene Daten auf der Datenbank
gespeichert
* werden sollen. */
private
static void
store(JS_ProjAssist_Project
parmTF) {
...........
...........
/*
* Prüfen
ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
* BOC abfragen.
*/
switch
(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
)
{
case
JSBS_BO.
CONST_OK
:
/* Datenbank-Operation
wie erwartet.
* Eingabefelder für die Werte, die
den Anwender-bekannten Schlüssel bilden, sperren.
*/
parmTF.get_txt_ProjectCode().setEditable(
false
);
parmTF.get_txt_LanguageCode().setEditable(false
);
/* Verarbeitetes
BO (xxx_Processed) mit neuen Allgemeinen Attributen (Common
Attributes) auf das
* BO, das die Werte, so wie sie auf
der Datenbank sind enthält (xxx_Read) kopieren.
* Damit
kann in einem späteren Schritt verglichen werden ob ein Attribut
geändert wurde.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read
.
copyFromJS_ProjAssist_ProjectLanguage_BO(
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
case
JSBS_BO.
CONST_DUPLICATE_KEY
:
/* Ein
Datensatz mit den Werten, die den Anwender-bekannten Schlüssel
bilden, existiert bereits.
* Fehlerbehandlungs-Methode
(in der Basisklasse für das Task-Frame) aufrufen und
zusätzlich
* zur 'Location' (Klassenname,
Locationscode "DupKey") auch die Werte für den
Anwender-bekannten
* Schlüssel als Parameter
übergeben. */
parmTF.handleErrorEvent(
CONST_ClassName
,
"DupKey"
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
ProjectCode
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
LanguageCode
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
default
:
/* Ein
anderer Fehler ist beim Speichern der Daten
aufgetreten.
* Fehlerbehandlungs-Methode (in der
Basisklasse für das Task-Frame) aufrufen und zusätzlich
* zur
'Location' (Klassenname, Locationscode "DupKey") auch den
Status-Code und die
* Fehler-Meldung des BOC als
Parameter übergeben.
*/
parmTF.handleErrorEvent(
CONST_ClassName
,
"store_DBError"
,
Integer.toString(parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
),
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusMsg
);
}
}
Das
Entscheiden, welche Verarbeitung bei welchem Status-Code des BOC
erfolgt, wird über ein switch
und
die entsprechenden case
getroffen.
Aus
diesem Grund wurde auch ein Status-Code vom Typ int
gewählt.
Zur
Steigerung der Flexibilität sind allgemeine Status-Codes in der
Klasse JSBS_BO
als konstante Werte
definiert.
switch
(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
)
{
Wenn
die Operation auf der Datenbank wie erwartet beendet wurde, wird der
Status-Code 'OK' zurückgeliefert.
In diesem Fall werden die
Eingabefelder der GUI, die den 'Anwender-bekannten Schlüssel'
bilden, gesperrt.
Weiters werden die beiden Objekte für das
BO 'synchronisiert'; d.h. die Werte der Attribute aus dem auf die
Datenbank gespeicherten BO werden auf jenes BO kopiert, daß die
Werte enthält so wie sie beim letzten Zugriff auf die Datenbank
auf der Datenbank existent waren.
Mit dieser 'Synchronisation'
wird in einem späteren Schritt eine Veränderung der Werte
durch den Anwender erkannt und danach die Schaltfläche
[ Speichern ] aktiviert bzw. deaktiviert.
switch
(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
)
{
case
JSBS_BO.
CONST_OK
:
/* Datenbank-Operation
wie erwartet.
* Eingabefelder für die Werte, die
den Anwender-bekannten Schlüssel bilden, sperren.
*/
parmTF.get_txt_ProjectCode().setEditable(
false
);
parmTF.get_txt_LanguageCode().setEditable(false
);
/* Verarbeitetes
BO (xxx_Processed) mit neuen Allgemeinen Attributen (Common
Attributes) auf das
* BO, das die Werte, so wie sie auf
der Datenbank sind enthält (xxx_Read) kopieren.
* Damit
kann in einem späteren Schritt verglichen werden ob ein Attribut
geändert wurde.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read
.
copyFromJS_ProjAssist_ProjectLanguage_BO(
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
case
JSBS_BO.
CONST_DUPLICATE_KEY
:
Mit
der Sperre der Eingabefelder wird verhindert, daß der
'Anwender-bekannte Schlüssel' nach der erstmaligen Erfassung des
BO geändert werden kann.
Um
den Umfang des Tutorials nicht unnötig zu erhöhen, wird als
einziger durch einen Anwender verursachter 'Fehler' nur geprüft,
ob ein Business-Object mit dem Anwender-bekannten Schlüssel
schon existiert.
Weitere
Prüfungen (z.B. auf zwischenzeitige Änderung des BO durch
einen anderen Anwender) werden in einem Schritt bei der 'Task-Frame
Finalisierung' vorgestellt.
Bei
Auftreten dieses nicht erwarteten 'Fehlers' wird die in den
Basisklassen vorhandene Funktionalität, ein Fenster mit der
Fehlermeldung anzuzeigen, genutzt.
Den Code, der mit dem Aufruf
der Methode handleErrorEvent(...)
ausgeführt
wird, können Sie in der Basisklasse JSBS_TaskFrame
verfolgen.
break
;
case
JSBS_BO.
CONST_DUPLICATE_KEY
:
/* Ein
Datensatz mit den Werten, die den Anwender-bekannten Schlüssel
bilden, existiert bereits.
* Fehlerbehandlungs-Methode
(in der Basisklasse für das Task-Frame) aufrufen und
zusätzlich
* zur 'Location' (Klassenname,
Locationscode "DupKey") auch die Werte für den
Anwender-bekannten
* Schlüssel als Parameter
übergeben. */
parmTF.handleErrorEvent(
CONST_ClassName
,
"DupKey"
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
ProjectCode
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
LanguageCode
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
default
:
Um
alle nicht explizit durch ein
case
behandelten
Werte des Status-Code des BOC behandeln zu können, bietet das
switch
in
Java den
default
Zweig.
Damit
werden alle nicht explizit behandelten 'Fehler', die beim Ausführen
der store()
-Methode
des BOC verarbeitet.
.
In der Fehlermeldung werden diesmal auch der
Status-Code und eine eventuelle Fehlermeldung des Datenbank-Systems
angezeigt
break
;
default
:
/* Ein
anderer Fehler ist beim Speichern der Daten
aufgetreten.
* Fehlerbehandlungs-Methode (in der
Basisklasse für das Task-Frame) aufrufen und zusätzlich
* zur
'Location' (Klassenname, Locationscode "DupKey") auch den
Status-Code und die
* Fehler-Meldung des BOC als
Parameter übergeben.
*/
parmTF.handleErrorEvent(
CONST_ClassName
,
"store_DBError"
,
Integer.toString(parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
),
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusMsg
);
}
Voraussetzung
für das Speichern der Daten ist, daß die Datenbank-Tabelle
vorhanden ist.
Das Anlegen der Datenbank-Tabelle ist unter
Tutorial:
JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) –
DataBase-Access (DBA) Klasse für DB-Tabelle 'ProjLang' >
Alternative: Einloggen in das MySQL-Datenbanksystem und Eintippen
derSQL-Kommandos
beschrieben.
Wenn
Sie für Ihre Installation Datenbankname, Benutzer oder Passwort
abweichend von den Beispielen in diesem Tutorial gewählt haben,
dann vergessen Sie bitte nicht, diese Werte auch beim Einloggen in
die Datenbank wieder zu verwenden.
Das
Aufrufen des Task-Frames wurde bereits ausführlich beschrieben;
zuletzt im Abschnitt
Zwischen-Test
1
dieses
Dokuments.
Aus diesem Grund beschränkt sich diese
Beschreibung erst auf das Eingeben von Daten und das anschließende
Anklicken der Schaltfläche [ Speichern ]
.
|
|
|
|
|
|
Anzeigen des
Inhalts der DB-Tabelle zur Überprüfung
Die
folgende Anleitung in diesem Abschnitt bezieht sich auf ein
MySQL-Datenbanksystem.
Bei den Beispielen wird angenommen, daß
die Datenbank mit den Parametern wie in JavaScout
ProjectAssist, Start-Frame Grundlagen (Java_Fatclient_01) - Weitere
XML-Strukturen einlesen > Datei mit XML-Struktur mit Parametern
für die Datenbank-Verbindung erstellen
erstellt
wurde.
Wenn
Sie für Ihre Installation Datenbankname, Benutzer oder Passwort
abweichend von den Beispielen in diesem Tutorial gewählt haben,
dann vergessen Sie bitte nicht, diese Werte auch beim Einloggen in
die Datenbank wieder zu verwenden.
Auf
einer Kommandozeile eines 'Terminal Window' erfolgt das Einloggen in
die Datenbank:
mysql
–host='127.0.0.1' –user='mysql' –password='drowssap'
js_tutorial
Im
Monitor von MySQL wird dann jeder SQL-Kommand eingegeben;
z.B.:
SELECT
ProjectCode, LanguageCode, TargetDirectory FROM ProjLang;
Vergessen
Sie dabei bitte nicht auf den Strichpunkt (;) am Ende eines jeden
SQL-Kommandos.
Im
MySQL-Monitor
wird anschließend die Liste mit den enthaltenen Datensätzen
angezeigt:
Als
letzter Punkt in diesem Schritt des Tutorials wird codiert, wie
eingegebene und gespeicherte Daten 'kopiert' werden.
Damit ist ein
Fertigstellungsgrad des Task-Frames erreicht mit dem es möglich
ist, Daten über die Anwendung auf die Datenbank zu schreiben.
Dieser
Fertigstellungsgrad ist bei größeren Projekten sinnvoll,
wenn mehrere Bereiche der Anwendung parallel entwickelt werden und
zum Testen eines Teil aus einem anderen Bereich Daten gebraucht
werden.
Die schnelle Entwicklung eines Task-Frames (das so und so
gebraucht wird) bis zu diesem Schritt ist weniger aufwändig als
Basisdaten zuerst mit SQL-Kommandos auf die Datenbank zu schreiben.
Die
Anweisungen zum Speichern von neu eingegebenen oder geänderten
Daten werden in der Methode store(...)
codiert.
Bitte
lesen Sie die Kommentare für eine Erklärung des Codes.
/*
* Methode
die ausgeführt wird wenn eingegebene Daten, die auf der
Datenbank gespeichert
* sind, verändert und als
neuer Datensatz gespeichert werden sollen. */
private
static void
copy(JS_ProjAssist_Project
parmTF) {
/*
* Anwender
darauf aufmerksam machen, daß der Anwender-bekannte
Schlüssel
* nicht gleich bleiben darf. In diesem
Tutorial wird der Wert für die Sprache geändert.
*/
parmTF.get_txt_LanguageCode().setText(
""
);
/*
* Werte
aus den GUI-Elementen auf die Variablen des BO übertragen.
* Dabei
die Methode der BOC-Klasse verwenden.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectoryName());/*
* BO
kennzeichnen, daß es sich um ein neu eingegebenes BO
handelt.
* Ein 'neues' BO ist durch die Werte '0' im
DataSetId und ObjectID zu erkennen.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
DataSetID
=
0;
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
ObjectID
=
0;
/*
* BO
auf das BO mit den (von der Datenbank) gelesenen Daten
kopieren.
* Das hat in diesem Schritt des Tutorials
noch keine Auswirkungen;
* später wird aber das
Aktivieren und Deaktivieren von Schaltflächen nach einer
Datenänderung
* über den Vergleich der Werte
gesteuert.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read
.
copyFromJS_ProjectAssist_ProjectLanguage_BO(
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
);
case
JSBS_BO.
CONST_OK
:
/*
* Eingabefelder für die Werte, die den
Anwender-bekannten Schlüssel bilden,
* für
die Eingabe öffnen.
*/
parmTF.get_txt_ProjectCode().setEditable(
true
);
parmTF.get_txt_LanguageCode().setEditable(true
);
}
Die
Methode store(...)
wird
nach dem Anklicken der entsprechenden Schaltfläche
aufgerufen.
Dazu wird die Methode handleEvent
um
den folgenden Code erweitert.
* und
die entsprechende Methode aufruft. */
protected
static void
handleEvent(JS_ProjAssist_Project
parmTF,
ActionEvent
parmActionEvent) {...........
...........
/* Abfragen
von welchem GUI-Element der Event ausgelöst wurde und
* Aufrufen der entsprechenden Methode.
*/
if
(cmd.equals(
"btn_TargetDirectorySelection"
))
processSelectDirectory(parmTF);
if
(cmd.equals(
"btn_Store"
))
store(parmTF);
if
(cmd.equals(
"btn_Copy"
))
copy(parmTF);
}
Voraussetzung
für das Speichern der Daten ist, daß die Datenbank-Tabelle
vorhanden ist.
Dies sollte schon beim Zwischen-Test
3
geprüft
worden sein; wenn Sie den
Zwischen-Test
3
nicht
ausgeführt haben und in diesem Abschnitt Fehler auftreten,
führen Sie die Anleitungen beim
Zwischen-Test
3
bitte
jetzt aus.
Das
Aufrufen des Task-Frames wurde bereits ausführlich beschrieben;
zuletzt im Abschnitt
Zwischen-Test
1
dieses
Dokuments.
Aus diesem Grund beschränkt sich diese
Beschreibung erst auf das Eingeben von Daten und das anschließende
Anklicken der Schaltflächen [ Speichern ]
und
[ Kopieren ]
.
|
|
|
|
|
|
Anzeigen
des Inhalts der DB-Tabelle zur Überprüfung
Die
folgende Anleitung in diesem Abschnitt bezieht sich auf ein
MySQL-Datenbanksystem.
Bei den Beispielen wird angenommen, daß
die Datenbank mit den Parametern wie in JavaScout
ProjectAssist, Start-Frame Grundlagen (Java_Fatclient_01) - Weitere
XML-Strukturen einlesen > Datei mit XML-Struktur mit Parametern
für die Datenbank-Verbindung erstellen
erstellt
wurde.
Wenn
Sie für Ihre Installation Datenbankname, Benutzer oder Passwort
abweichend von den Beispielen in diesem Tutorial gewählt haben,
dann vergessen Sie bitte nicht, diese Werte auch beim Einloggen in
die Datenbank wieder zu verwenden.
Auf
einer Kommandozeile eines 'Terminal Window' erfolgt das Einloggen in
die Datenbank:
mysql
–host='127.0.0.1' –user='mysql' –password='drowssap'
js_tutorial
Im
Monitor von MySQL wird dann jeder SQL-Kommand eingegeben;
z.B.:
SELECT
ProjectCode, LanguageCode, TargetDirectory FROM ProjLang;
Vergessen
Sie dabei bitte nicht auf den Strichpunkt (;) am Ende eines jeden
SQL-Kommandos.
Im
MySQL-Monitor wird anschließend die Liste mit den enthaltenen
Datensätzen angezeigt:
Gesamter
Code am Ende des Schrittes
package
js_projassist.client;
/*
*
Packages mit den GUI-Elementen. */import
java.awt.*;
import
javax.swing.*;
/*
*
Package mit den Klassen zum Bearbeiten von Events */import
java.awt.event.*;
/*
*
Package mit der Basisklasse für das TaskFrame. */import
js_base.frame.*;
/*
*
Package mit den Business-Objects. */import
js_projassist.boc.*;
/*
*/
public
class
JS_ProjAssist_Project
extends
JSBS_TaskFrame
{
/*
* Business-Objects (Client-Side-Klasse) definieren.
*/
protected
JS_ProjAssist_ProjectLanguage_BOC
structJS_ProjAssist_ProjectLanguage_BOC_Read
;
protected
JS_ProjAssist_ProjectLanguage_BOC
structJS_ProjAssist_ProjectLanguage_BOC_Processed
;
/*
* GUI-Elemente die für diesen Task-Frame
spezifisch sind. */
protected
JLabel
lbl_ProjectCode
;
protected
JTextField
txt_ProjectCode
;
protected
JLabel
lbl_LanguageCode
;
protected
JTextField
txt_LanguageCode
;
protected
JLabel
lbl_TargetDirectoryName
;
protected
JTextField
txt_TargetDirectoryName
;
protected
JButton
btn_TargetDirectorySelection
;
/*
* Constructor der Klasse.
* Code darin
wird aufgerufen wenn ein Objekt dieser Klasse erstellt wird.
* Als
Parameter wird das StartFrame (CommandCenter) übernommen;
* das
StartFrame enthält alle Einstellungen, die für die gesamte
Anwendung gelten
* und die Verbindung zu Datenbank oder
Java-Application-Server (JAS). */
public
JS_ProjAssist_Project(JS_ProjAssist_CommandCenter
parmCC)
{
/*
* Aufruf des Constructors der Basisklasse
(JSBS_TaskFrame).
* Darin werden die Klasse des
StartFrames und eventuell Werte einzelner Variablen
* in
lokale Variablen übertragen. */
super
(parmCC);
/*
* Aufrufen
der Methoden mit den individuellen Initialisierungen für diese
Klasse.
*/
initialize_before_frame();
initialize_frame();
initialize_after_frame();
}/*
* Methode
mit den Initialisierungen die notwendig sind bevor das Frame
(Window)
* angezeigt wird. */
private
void
initialize_before_frame()
{
/*
* 'Konstruieren'
der Business-Objects, die in diesem Task-Frame verwendet werden.
*/
structJS_ProjAssist_ProjectLanguage_BOC_Read
=
new
JS_ProjAssist_ProjectLanguage_BOC(
this
);
structJS_ProjAssist_ProjectLanguage_BOC_Processed
=
new
JS_ProjAssist_ProjectLanguage_BOC(
this
);
}/*
* Methode
mit der das Frame (Window) angezeigt wird. */
private
void
initialize_frame()
{
/* Frame
(Window) sichtbar machen (anzeigen).
*/
setVisible(true
);
/* Anfangsgröße
festlegen. */
setSize(800,
600);/* Grund-Panel
mit den weiteren GUI-Elementen anzeigen.
* Die
GUI-Elemente und deren Anordnung sind in der geerbten Klasse
* (JSBS_StartFrame) festgelegt.
*/
setContentPane(get_pnl_Main());
}/*
* Methode
mit den Initialisierungen die notwendig sind nachdem das Frame
(Window)
* angezeigt wird. */
private
void
initialize_after_frame()
{
/* Methode
zum Zuordnen des sprachabhängigen Textes zu den GUI-Elementen
aufrufen.
*/
JSBS_GUIServices.processLanguageDependantElements(this
);
}/*
* ******************************
* Methoden
zum 'Construct' (Initialisierung) der einzelnen GUI-Elemente.
* */
protected
JLabel
get_lbl_ProjectCode() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
lbl_ProjectCode
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
lbl_ProjectCode
=
new
JLabel();
lbl_ProjectCode
.setName(
"lbl_ProjectCode"
);
lbl_ProjectCode
.setHorizontalAlignment(SwingConstants.
TRAILING
);
}
catch
(Throwable
Exc) {
/* Fehler
beim 'construct' ist sehr unwahrscheinlich und kann nur beim
'Starten'
* des Tasks auftreten.
* Deswegen
werden Fehlermeldungen nur auf der Konsole ausgegeben.
*/
System.out
.println(
"Error
while building lbl_ProjectCode in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
lbl_ProjectCode;
}/* */
protected
JTextField
get_txt_ProjectCode() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
txt_ProjectCode
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
txt_ProjectCode
=
new
JTextField();
txt_ProjectCode
.setName(
"txt_ProjectCode"
);
}
catch
(Throwable
Exc) {
System.out
.println(
"Error
while building txt_ProjectCode in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
txt_ProjectCode;
}/* */
protected
JLabel
get_lbl_LanguageCode() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
lbl_LanguageCode
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
lbl_LanguageCode
=
new
JLabel();
lbl_LanguageCode
.setName(
"lbl_LanguageCode"
);
lbl_LanguageCode
.setHorizontalAlignment(SwingConstants.
TRAILING
);
}
catch
(Throwable
Exc) {
/* Fehler
beim 'construct' ist sehr unwahrscheinlich und kann nur beim
'Starten'
* des Tasks auftreten.
* Deswegen
werden Fehlermeldungen nur auf der Konsole ausgegeben.
*/
System.out
.println(
"Error
while building lbl_LanguageCode in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
lbl_LanguageCode;
}/* */
protected
JTextField
get_txt_LanguageCode() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
txt_LanguageCode
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
txt_LanguageCode
=
new
JTextField();
txt_LanguageCode
.setName(
"txt_LanguageCode"
);
}
catch
(Throwable
Exc) {
System.out
.println(
"Error
while building txt_LanguageCode in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
txt_LanguageCode;
}/* */
protected
JLabel
get_lbl_TargetDirectoryName() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
lbl_TargetDirectoryName
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
lbl_TargetDirectoryName
=
new
JLabel();
lbl_TargetDirectoryName
.setName(
"lbl_TargetDirectoryName"
);
lbl_TargetDirectoryName
.setHorizontalAlignment(SwingConstants.
LEADING
);
}
catch
(Throwable
Exc) {
/* Fehler
beim 'construct' ist sehr unwahrscheinlich und kann nur beim
'Starten'
* des Tasks auftreten.
* Deswegen
werden Fehlermeldungen nur auf der Konsole ausgegeben.
*/
System.out
.println(
"Error
while building lbl_TargetDirectoryName in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
lbl_TargetDirectoryName;
}/* */
protected
JTextField
get_txt_TargetDirectoryName() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
txt_TargetDirectoryName
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
txt_TargetDirectoryName
=
new
JTextField();
txt_TargetDirectoryName
.setName(
"txt_TargetDirectoryName"
);
/* Direkte
Eingabe nicht erlauben; nur über Auswahl aus der
Verzeichnis-Struktur.
*/
txt_TargetDirectoryName
.setEnabled(
false
);
}
catch
(Throwable
Exc) {
System.out
.println(
"Error
while building txt_TargetDirectoryName in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
txt_TargetDirectoryName;
}/* */
protected
JButton
get_btn_TargetDirectorySelection() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
btn_TargetDirectorySelection
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
btn_TargetDirectorySelection
=
new
JButton();
btn_TargetDirectorySelection
.setName(
"btn_TargetDirectorySelection"
);
/*
* Durch
den 'ActionListener' wird beim Anklicken der Schaltfläche mit
der Maustaste
* die Methode 'actionPerformed'
aufgerufen.
*/
btn_TargetDirectorySelection
.addActionListener(
this
);
/*
* Über
den 'ActionCommand' kann in the Methode 'actionPerformed' abgefragt
werden,
* welche Schaltfläche angeklickt wurde.
*/
btn_TargetDirectorySelection
.setActionCommand(
"btn_TargetDirectorySelection"
);
}
catch
(Throwable
Exc) {
System.out
.println(
"Error
while building btn_TargetDirectorySelection in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
btn_TargetDirectorySelection;
}/*
* ******************************
* Methode
zum 'Construct' (Initialisierung) des Panels mit den GUI-Elementen
für
* die Abwicklung des Geschäftsfalles.
* Diese
Methode überschreibt das 'Construct' des JPanel (mit gleichem
Namen) in der
* geerbten Methode aus der Klasse
JSBS_TaskFrame.
* */
protected
JPanel
get_pnl_DetailFields() {
/* Zuerst
Prüfen, ob die Variable bereits 'constructed' (initialisiert)
ist. */
if
(
pnl_DetailFields
==
null
)
{
/* Variable
noch nicht 'constructed'; Code für die Initialisierung folgt.
*/
try
{
pnl_DetailFields
=
new
JPanel();
pnl_DetailFields
.setName(
"pnl_DetailFields"
);
/*
* Mit
der folgenden Anweisung wird die Eigenschaft 'GridBagLayout
festgelegt
* 'GridBagLayout' unterteilt das JPanel in
'dehnbare' Felder; damit 'wachsen' oder
* 'schrumpfen'
darin platzierte GUI-Elemente abhängig von der Größe
des JPanel. */
pnl_DetailFields
.setLayout(
new
GridBagLayout());
/*
* Die
folgenden Anweisungen platzieren GUI-Elemente in den 'Feldern' des
JPanel. */
/* Zuerst wird eine Variable für die
Platzierungs-Eigenschaften erstellt. */
GridBagConstraints
gbc_lbl_ProjectCode = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_lbl_ProjectCode.gridx
=
0;
gbc_lbl_ProjectCode.
gridy
=
0;
gbc_lbl_ProjectCode.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_lbl_ProjectCode.
weightx
=
1;
gbc_lbl_ProjectCode.
anchor
=
GridBagConstraints.
LINE_END
;
gbc_lbl_ProjectCode.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_lbl_ProjectCode(),
gbc_lbl_ProjectCode);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_txt_ProjectCode = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_txt_ProjectCode.gridx
=
1;
gbc_txt_ProjectCode.
gridy
=
0;
gbc_txt_ProjectCode.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_txt_ProjectCode.
weightx
=
1;
gbc_txt_ProjectCode.
anchor
=
GridBagConstraints.
LINE_START
;
gbc_txt_ProjectCode.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_txt_ProjectCode(),
gbc_txt_ProjectCode);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_lbl_LanguageCode = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_lbl_LanguageCode.gridx
=
0;
gbc_lbl_LanguageCode.
gridy
=
1;
gbc_lbl_LanguageCode.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_lbl_LanguageCode.
weightx
=
1;
gbc_lbl_LanguageCode.
anchor
=
GridBagConstraints.
LINE_END
;
gbc_lbl_LanguageCode.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_lbl_LanguageCode(),
gbc_lbl_LanguageCode);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_txt_LanguageCode = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_txt_LanguageCode.gridx
=
1;
gbc_txt_LanguageCode.
gridy
=
1;
gbc_txt_LanguageCode.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_txt_LanguageCode.
weightx
=
1;
gbc_txt_LanguageCode.
anchor
=
GridBagConstraints.
LINE_START
;
gbc_txt_LanguageCode.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_txt_LanguageCode(),
gbc_txt_LanguageCode);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_lbl_TargetDirectoryName = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_lbl_TargetDirectoryName.gridx
=
0;
gbc_lbl_TargetDirectoryName.
gridy
=
2;
gbc_lbl_TargetDirectoryName.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_lbl_TargetDirectoryName.
weightx
=
1;
gbc_lbl_TargetDirectoryName.
anchor
=
GridBagConstraints.
LINE_START
;
gbc_lbl_TargetDirectoryName.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_lbl_TargetDirectoryName(),
gbc_lbl_TargetDirectoryName);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_txt_TargetDirectoryName = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_txt_TargetDirectoryName.gridx
=
0;
gbc_txt_TargetDirectoryName.
gridy
=
3;
gbc_txt_TargetDirectoryName.
fill
=
GridBagConstraints.
HORIZONTAL
;
gbc_txt_TargetDirectoryName.
weightx
=
1;
gbc_txt_TargetDirectoryName.
anchor
=
GridBagConstraints.
LINE_START
;
gbc_txt_TargetDirectoryName.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_txt_TargetDirectoryName(),
gbc_txt_TargetDirectoryName);/*
* Platzieren
des nächsten GUI-Elements. */
GridBagConstraints
gbc_btn_TargetDirectorySelection = new
GridBagConstraints();
/* Definition
der Platzierungs-Eigenschaften.
*/
gbc_btn_TargetDirectorySelection.gridx
=
1;
gbc_btn_TargetDirectorySelection.
gridy
=
2;
gbc_btn_TargetDirectorySelection.
fill
=
GridBagConstraints.
BOTH
;
gbc_btn_TargetDirectorySelection.
weightx
=
1;
gbc_btn_TargetDirectorySelection.
gridheight
=
2;
gbc_btn_TargetDirectorySelection.
anchor
=
GridBagConstraints.
LINE_START
;
gbc_btn_TargetDirectorySelection.
insets
=
new
Insets(3,
3, 3, 3);
/* Platzieren
des GUI-Elements auf dem JPanel.
*/
get_pnl_DetailFields().add(get_btn_TargetDirectorySelection(),
gbc_btn_TargetDirectorySelection);
}
catch
(Throwable
Exc) {
/* Fehler
beim 'construct' ist sehr unwahrscheinlich und kann nur beim
'Starten'
* des Tasks auftreten.
* Deswegen
werden Fehlermeldungen nur auf der Konsole ausgegeben.
*/
System.out
.println(
"Error
while building pnl_DetailFields in class
JS_ProjAssist_Project"
);
Exc.printStackTrace();
}
}
return
pnl_DetailFields;
}/*
* Methode
die ausgeführt wird wenn ein Klick mit einer Maustaste
* auf
ein GUI-Element, dem der ActionListener hinzugefügt wurde,
erfolgt. */
public
void
actionPerformed(ActionEvent
e) {
/*
* Gleichnamige
Methode in der geerbten Basisklasse aufrufen.
* Damit
werden die 'geerbten' Verarbeitungen (die für alle
Anwendungsprogramme
* gleich sein können) zuerst
ausgeführt. */
super
.actionPerformed(e);
/*
* Weitere
Verarbeitung in einer eigenen Klasse mit statischen Methoden.
*/
JS_ProjAssist_Project__ActionHandler.handleEvent(this
,
e);
}}
package
js_
projassist.client
;
/*
*
Package mit den Klassen zum Bearbeiten von Events. */import
java.awt.event.*;
/*
*
Package mit den Klassen der GUI-Elemente. */import
java.awt.*;
/*
*
Package und Klassen mit den Status-Codes zum Prüfen auf
erfolgreiche Durchführung oder
* Fehler bei einer
Datenbank-Operation. */import
js_base.bo.JSBS_BO;
/**
*
* @author kurt@javascout.biz
*
@date 2008-05-10
*
* @description
* Klasse
mit statischen Methoden die ausgeführt werden wenn ein
'event'
* (z.B. der Klick einer Maustaste auf
eine Schaltfläche) aufgetreten ist.
* Detail-Dokumentation
finden Sie bei den einzelnen Methoden.
*
*
@change-log
* when who why
*
--------------------------------------------------------
*
*/public
class
JS_ProjAssist_Project__ActionHandler
{
/*
* Name
der Klasse als Konstante festlegen weil bei statischen Methoden der
* Name der Klasse nicht über
'getClass().getName() ermittelt werden kann. */
private
static
String
CONST_ClassName
=
"JS_ProjAssist_Project__ActionHandler"
;
/*
* Methode
die ermittelt, bei welchem GUI-Element ein 'ActionEvent' ausgelöst
wurde
* und die entsprechende Methode aufruft.
*/
protected
static void
handleEvent(JS_ProjAssist_Project
parmTF,
ActionEvent
parmActionEvent) {/* Zuerst
wird die 'Identifikation' des GUI-Element aus dem ActionEvent
extrahiert. */
String
cmd = parmActionEvent.getActionCommand().trim();
/* In
diesem Stadium des Tutorials wird zur Kontrolle der
Action-Command
* auf der Konsole ausgegeben.
*/
System.
out
.println(
"ActionCommand:
"
+
cmd);
/* Abfragen
von welchem GUI-Element der Event ausgelöst wurde und
* Aufrufen der entsprechenden Methode.
*/
if
(cmd.equals(
"btn_TargetDirectorySelection"
))
processSelectDirectory(parmTF);
if
(cmd.equals(
"btn_Store"
))
store(parmTF);
if
(cmd.equals(
"btn_Copy"
))
copy(parmTF);
}
/*
* Methode
die ausgeführt wird wenn das Stamm-Verzeichnis für
generierte Dateien
* ausgewählt werden
soll. */
private
static void
processSelectDirectory(JS_ProjAssist_Project
parmTF) {
/*
* Sprachabhängigen
Text für die 'Title-Bar' des File-Dialog-Fensters aus
* der
XML-Datei 'auslesen'. */
String
strTitle =
parmTF.frmCC
.
structJSBS_XML_DisplayStrings
.getSupplementaryText(
"Project__ActionHandler*FD_TitleBar"
);
/*
* Fenster
für den 'File-Dialog' aufrufen;
* in diesem kann
der Benutzer eine Datei auswählen. */
FileDialog
fd = new
FileDialog(parmTF,
strTitle,
FileDialog.LOAD
);
/*
* Anfangswerte
für Verzeichnis und Dateiname setzen und Fenster sichtbar
machen.
*/
fd.setFile(
""
);
fd.setDirectory(""
);
fd.setVisible(true
);
/*
* Name
für gewähltes Verzeichnis aus dem 'File-dialog' holen und
in einen String übertragen. */
String
strDirectoryName = fd.getDirectory();
/*
* Verzeichnis
im entsprechenden Feld anzeigen.
*/
parmTF.get_txt_TargetDirectoryName().setText(strDirectoryName);
}
/*
* Methode
die ausgeführt wird wenn eingegebene Daten auf der Datenbank
gespeichert
* werden sollen. */
private
static void
store(JS_ProjAssist_Project
parmTF) {
/*
* Werte
aus den GUI-Elementen auf die Variablen des BO übertragen.
* Dabei
die Methode der BOC-Klasse verwenden.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectoryName());/*
* Methode
des BOC zum Speichern der Daten aufrufen.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.store();
/*
* Prüfen
ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
* BOC abfragen.
*/
switch
(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
)
{
case
JSBS_BO.
CONST_OK
:
/* Datenbank-Operation
wie erwartet.
* Eingabefelder für die Werte, die
den Anwender-bekannten Schlüssel bilden, sperren.
*/
parmTF.get_txt_ProjectCode().setEditable(
false
);
parmTF.get_txt_LanguageCode().setEditable(false
);
/* Verarbeitetes
BO (xxx_Processed) mit neuen Allgemeinen Attributen (Common
Attributes) auf das
* BO, das die Werte, so wie sie auf
der Datenbank sind enthält (xxx_Read) kopieren.
* Damit
kann in einem späteren Schritt verglichen werden ob ein Attribut
geändert wurde.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read
.
copyFromJS_ProjAssist_ProjectLanguage_BO(
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
case
JSBS_BO.
CONST_DUPLICATE_KEY
:
/* Ein
Datensatz mit den Werten, die den Anwender-bekannten Schlüssel
bilden, existiert bereits.
* Fehlerbehandlungs-Methode
(in der Basisklasse für das Task-Frame) aufrufen und
zusätzlich
* zur 'Location' (Klassenname,
Locationscode "DupKey") auch die Werte für den
Anwender-bekannten
* Schlüssel als Parameter
übergeben. */
parmTF.handleErrorEvent(
CONST_ClassName
,
"DupKey"
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
ProjectCode
,
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
LanguageCode
);
/* Verarbeitung
innerhalb dieses 'case' mit 'break' beenden.
*/
break
;
default
:
/* Ein
anderer Fehler ist beim Speichern der Daten
aufgetreten.
* Fehlerbehandlungs-Methode (in der
Basisklasse für das Task-Frame) aufrufen und zusätzlich
* zur
'Location' (Klassenname, Locationscode "DupKey") auch den
Status-Code und die
* Fehler-Meldung des BOC als
Parameter übergeben.
*/
parmTF.handleErrorEvent(
CONST_ClassName
,
"store_DBError"
,
Integer.toString(parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusCode
),
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
StatusMsg
);
}
}
/*
* Methode
die ausgeführt wird wenn eingegebene Daten, die auf der
Datenbank gespeichert
* sind, verändert und als
neuer Datensatz gespeichert werden sollen. */
private
static void
copy(JS_ProjAssist_Project
parmTF) {
/*
* Anwender
darauf aufmerksam machen, daß der Anwender-bekannte
Schlüssel
* nicht gleich bleiben darf. In diesem
Tutorial wird der Wert für die Sprache geändert.
*/
parmTF.get_txt_LanguageCode().setText(
""
);
/*
* Werte
aus den GUI-Elementen auf die Variablen des BO übertragen.
* Dabei
die Methode der BOC-Klasse verwenden.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.getFromGUI(
parmTF.get_txt_ProjectCode(),
parmTF.get_txt_LanguageCode(),
parmTF.get_txt_TargetDirectoryName());/*
* BO
kennzeichnen, daß es sich um ein neu eingegebenes BO
handelt.
* Ein 'neues' BO ist durch die Werte '0' im
DataSetId und ObjectID zu erkennen.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
DataSetID
=
0;
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Processed
.
ObjectID
=
0;
/*
* BO
auf das BO mit den (von der Datenbank) gelesenen Daten
kopieren.
* Das hat in diesem Schritt des Tutorials
noch keine Auswirkungen;
* später wird aber das
Aktivieren und Deaktivieren von Schaltflächen nach einer
Datenänderung
* über den Vergleich der Werte
gesteuert.
*/
parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read
.
copyFromJS_ProjAssist_ProjectLanguage_BO(
parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed
);
/*
* Eingabefelder für die Werte, die den
Anwender-bekannten Schlüssel bilden,
* für
die Eingabe öffnen.
*/
parmTF.get_txt_ProjectCode().setEditable(
true
);
parmTF.get_txt_LanguageCode().setEditable(true
);
}
}
Weitere Schritte und verwandte Dokumentation
Dokument |
Inhalt |
In
den nächsten Schritten des Tutorials werden die Klassen
entwickelt, die für Datenbank-Abfragen, die mehr als ein BO
zurückliefern können, gebraucht werden. |