> Inhalt: JavaScout-Fat-Client-Framework (JS-FCF) 

Tutorial: Programmierung mit dem JS-FCF 

Tutorial:
JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) –
Daten erfassen und speichern

* Bitte beachten Sie die Hinweise und Bestimmungen bezüglich Urheberrecht, Haftungsausschluß und geschützte Marken oder Warenzeichen die für dieses Web-Dokument und möglicherweise auch für 'verlinkte' Dokumente gelten.

  • Der Betreiber dieser Web-Site (www.javascout.biz) ist nicht verantwortlich für den Inhalt von Web-Sites, die innerhalb dieses Web-Dokumentes oder anderer Dokumente von www.javascout.biz verlinkt sind.

  • Wenn dieses Web-Dokument oder andere Dokumente dieser Web-Site (www.javascout.biz) Rechte von Ihnen verletzen, oder sie glauben, daß Rechte Anderer (Dritter Personen) dadurch verletzt werden, informieren Sie bitte den Betreiber dieser Web-Site.
    Eine E-Mail können Sie ganz einfach durch anklicken des Symbols oder Textes im Frame rechts oben senden.

Dieses Dokument drucken.

 Letzte Bearbeitung dieses  Dokuments:
2008-05-09



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:
Ca. 20 bis 60 Minuten; abhängig von der bei den vorigen Beispielen erworbenen Routine
.

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:

Inhaltsverzeichnis:

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) 


Vorbemerkung

Obwohl Eclipse in 'deutscher Version' installiert werden kann, sind die Abbildungen in diesem Dokument mit der 'english Version' erstellt.
Grund ist, daß zum Zeitpunkt der Erstellung dieses Dokumentes (Oktober 2007) die Eclipse-Texte nur sehr unvollständig ins Deutsche übersetzt sind.
Damit ist (meiner Meinung nach)
1.) Eclipse in deutscher Version wesentlich schwerer verständlich als in englischer Version und
2.) wenn Eclipse weiter übersetzt wird, ist dieses Dokument stark abweichend von den dann vorhandenen deutschen Texten.



zum Inhaltsverzeichnis

Vorbedingungen:

zum Inhaltsverzeichnis

Klasse JS_ProjAssist_Project__ActionHandler eröffnen

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.

zum Inhaltsverzeichnis

Name der Klasse als Konstante definieren

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";
/*

zum Inhaltsverzeichnis

Code zum Festellen des Event-Auslösers

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);
    }

zum Inhaltsverzeichnis

Aufrufen der Methode handleEvent in der Klasse JS_ProjAssist_Project

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.

zum Inhaltsverzeichnis

Zwischen-Test 1

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:

Daraufhin erscheint das Fenster mit der Benutzeroberfläche wie schon im vorigen Schritt.

Anmerkung:
Bei der zur Zeit der Erstellung dieses Tutorials (Mai 2008) installierten Version von Java und/oder Eclipse erscheinen die Elemente der Benutzeroberfläche erst nachdem die Größe des Fensters verändert wurde.
Dieser Fehler ist hoffentlich bereits behoben wenn Sie dieses Tutorial durcharbeiten.

Durch Anklicken der Auswahlmöglichkeit 'P- Projekt und Sprache verwalten' wird der Code in das Feld 'Auswahl' übertragen.

Nach Anklicken der Schaltfläche [ Weiter ] wird das Task-Frame aufgerufen.


 

Nach Anklicken einer Schaltfläche wird im 'Console' Bereich von Eclipse der 'ActionCommand' der Schaltfläche angezeigt.


 


zum Inhaltsverzeichnis

Methode zum Auswählen eines Verzeichnisses

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.

zum Inhaltsverzeichnis

Import der Bibliothek java.awt.*

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.*;
/**

zum Inhaltsverzeichnis

Methode zum Auswählen des Verzeichnisses codieren

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);
    }

zum Inhaltsverzeichnis

Sprachabhängigen Text in der Datei 'DisplayStrings.xml' erfassen

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 Inhaltsverzeichnis

Aufruf der Methode in handleEvent

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);
    }

zum Inhaltsverzeichnis

Zwischen-Test 2

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 ].

Nach Anklicken einer Schaltfläche [ Datei-Auswahl ] wird das Fenster für die Auswahl eines Verzeichnisses geöffnet.


 

Nach dem Schließen des Fensters für die Datei-Auswahl steht der Namen des ausgewählten Verzeichnisses im Eingabefeld.

Das Eingabefeld ist für die direkte Eingabe gesperrt – deswegen ist der Text nur grau - und nicht schwarz – dargestellt.


 


zum Inhaltsverzeichnis

Methode zum Speichern der eingegebenen Daten

In diesem Abschnitt wird der Code implementiert, der die eingegebenen Daten auf der Datenbank abspeichert.

Code in der Klasse JS_ProjAssist_Project

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() {

zum Inhaltsverzeichnis

Import der Bibliothek js_base.bo in der Klasse JS_ProjAssist_Project__ActionHandler

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

zum Inhaltsverzeichnis

Methode store(...) erstellen und in handleEvent aufrufen

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);
    }

zum Inhaltsverzeichnis

Übertragen der Werte aus den GUI-Elementen in die Attribute des BOC

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.

zum Inhaltsverzeichnis

Methode des BOC zum Speichern aufrufen

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();
    }

zum Inhaltsverzeichnis

Prüfen auf ordnungsgemäße Ausführung

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);
      }

zum Inhaltsverzeichnis

Zwischen-Test 3

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 ].

Nach dem Erfassen von 'Projekt-Code* und *Sprach-Code' und eventuell einem Auswählen einer Datei und dem Anklicken der Schaltfläche [ Speichern ] werden die Eingabefelder für 'Projekt-Code* und *Sprach-Code' deaktiviert.

In diesem Stadium wird die Gültigkeit der Eingaben noch nicht geprüft – es ist auch möglich, 'leere' Eingabefelder zu speichern.
Zum Prüfen, ob auch die eingegebenen Werte aller Felder gespeichert werden, wird empfohlen, in allen drei Eingabefeldern Werte einzugeben.


 

Nach dem ordnungsgemäßen Speichern der Daten sind die Felder für die Werte, die den Anwender-bekannten Schlüssel bilden, für eine weitere Eingabe gesperrt.


 

Wenn ein Fehler auftritt, wird das Fenster für Fehlermeldungen angezeigt.
Mit der derzeitigen Fertigstellung sind noch keine Texte für die GUI-Elemente definiert – deswegen wirkt das Fenster etwas merkwürdig.

Die 'Location' des Fehlers, der Status-Code und ein eventueller Fehler-Text des Datenbanksystems werden trotzdem angezeigt.


 


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.

zum Inhaltsverzeichnis

Methode zum Kopieren der Daten

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.

zum Inhaltsverzeichnis

Methode copy(...) erstellen und in handleEvent aufrufen

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);
    }

zum Inhaltsverzeichnis

End-Test dieses Schrittes

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 ].

Nach dem Erfassen von 'Projekt-Code* und *Sprach-Code' und eventuell einem Auswählen einer Datei und dem Anklicken der Schaltfläche [ Speichern ] werden die Eingabefelder für 'Projekt-Code* und *Sprach-Code' deaktiviert.

In diesem Stadium wird die Gültigkeit der Eingaben noch nicht geprüft – es ist auch möglich, 'leere' Eingabefelder zu speichern.
Zum Prüfen, ob auch die eingegebenen Werte aller Felder gespeichert werden, wird empfohlen, in allen drei Eingabefeldern Werte einzugeben.


 

Nach dem ordnungsgemäßen Speichern der Daten sind die Felder für die Werte, die den Anwender-bekannten Schlüssel bilden, für eine weitere Eingabe gesperrt.

Nach Anklicken der Schaltfläche [ Kopieren ] wird wieder eine Eingabe in den Feldern erlaubt und der Wert für den Sprach-Code gelöscht.


 

Es können wieder 'Projekt-Code* und *Sprach-Code' erfaßt werden und ein Verzeichnis ausgewählt werden. Nach dem Anklicken der Schaltfläche [ Speichern ] werden die neu eingegebenen Werte auf der Datenbank gespeichert und die Eingabefelder für 'Projekt-Code* und *Sprach-Code' wieder deaktiviert.

Anschließend könnte neuerlich die Schaltfläche [ Kopieren ] angeklickt werden und weitere Werte erfaßt werden.


 


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.

zum Inhaltsverzeichnis

Gesamter Code am Ende des Schrittes

zum Inhaltsverzeichnis

Klasse JS_ProjAssist_Project

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);
    }

}

zum Inhaltsverzeichnis

Klasse JS_ProjAssist_Project__ActionHandler

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);
    }

}

zum Inhaltsverzeichnis

Weitere Schritte und verwandte Dokumentation

Dokument

Inhalt

JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) – DataBase-Access-Klasse für eine Liste von Datensätzen aus der DB-Tabelle 'ProjLang' (DBA-Set)  

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.
Der nächste Schritt des Tutorials beschreibt die Entwicklung der DBA-Set-Klasse.

zum Inhaltsverzeichnis