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

Tutorial: Programmierung mit dem JS-FCF 

Tutorial:
JavaScout ProjectAssist, Task-Frame Finalisierung (Java_Fatclient_01) –
Verwenden des 'DocumentListener' und anderer 'Listener'

* 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-06-04



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
.

Haupt-Thema dieses Schrittes ist die Klasse 'DocumentListener'.

Ein Objekt der Klasse 'DocumentListener' wird allen GUI-Elementen hinzugefügt und bei der Veränderung des (angezeigten) Wertes eines GUI-Elementes löst der 'DocumentListener' einen 'Event' aus.
Das Auslösen eines 'Event's und die Implementierung des passenden Codes wurde bereits im Document
Tutorial: JavaScout ProjectAssist, Start-Frame Grundlagen (Java_Fatclient_01) – Auswählen der Geschäftsanwendung behandelt.

Zum Hinzufügen des 'DocumentListener's wird eine Methode verwendet, die bereits in der Basisklasse JSBS_TaskFrame implementiert ist. Diese Methode fügt auch andere 'Listener' (z.B. einen, der darauf reagiert wenn der Positionszeiger / 'Cursor' in einem Eingabefeld platziert wird) zu den GUI-Elementen hinzu.

Inhaltsverzeichnis:

Voriger Schritt:Task-Frame Grundlagen – Liste der Daten anzeigen und zur Bearbeitung auswählen 

Vorbemerkung 
Vorbedingungen 
Klasse
JS_ProjAssist_Project__DocumentListener eröffnen 
Individueller Code in
JS_ProjAssist_Project__DocumentListener, Teil 1 
* Importieren der Bibliotheken
 
* Erben der Basisklasse
JSBS_TaskFrame__DocumentListener 
* Definieren der Variablen
 
* 'Constructor' der Klasse
 
* Abfragen, in welchem GUI-Element eine Eingabe erfolgt ist
 
Zusätzlicher Code in
JS_ProjAssist_Project 
Prüf-Regeln und Hinweis-Text in der Datei 'DisplayStrings.xml' 
Zwischen-Test 1 
MouseListener zur Tabelle mit den gefundenen Datensätzen hinzufügen 
Zwischen-Test 2 
Individueller Code in
JS_ProjAssist_Project__DocumentListener, Teil 2: Aktivieren / Deaktivieren von Schaltflächen 
* Methode
checkEntriesOK() zum Prüfen auf fehlerfreie Eingabe 
* Methode zum Aktivieren/Deaktivieren der Schaltfläche [ Speichern ] 
* Methode zum Aktivieren/Deaktivieren der Schaltfläche [ Kopieren ] 
* Methode zum Aktivieren/Deaktivieren aller Schaltflächen 
* Aufrufen der Methode zum Aktivieren/Deaktivieren aller Schaltflächen 
End-Test 
Gesamter Code am Ende des Schrittes 
* Klasse
JS_ProjAssist_Project 
* Klasse
JS_ProjAssist_Project__ActionHandler 
* Klasse
JS_ProjAssist_Project__DocumentListener 
Weitere Schritte und verwandte Dokumentation 

Nächster Schritt: Letzte Feinheiten

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__DocumentListener 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__DocumentListener
[ ] public static void main(String[] args)   (nicht markiert)
[ ] Constructors from superclass   (nicht markiert)
[ ] Inherited abstract methods   (nicht markiert)

zum Inhaltsverzeichnis

Individueller Code in JS_ProjAssist_Project__DocumentListener, Teil 1

Zuerst wird der grundlegende Code des 'DocumentListener' implementiert.
Das ist neben dem Import der Bibliotheken, der Vererbung und der Definition der Variablen auch das Abfragen, von welchem GUI-Element der 'DocumentEvent' ausgelöst wurde und danach das Prüfen der Eingabe im entsprechenden GUI-Element.

Den kompletten Code der Klasse finden Sie im Abschnitt Gesamter Code für JS_ProjAssist_Project__DocumentListener.

zum Inhaltsverzeichnis

Importieren der Bibliotheken

package js_projassist.client;
/*
 * Packages mit den Klassen für die Behandlung von Document und -Event. */

import javax.swing.text.Document;
import javax.swing.event.DocumentEvent;
/*
 * Package mit der Basisklassen für das TaskFrame. */

import js_base.frame.*;
/* */
public class JS_ProjAssist_Project__DocumentListener extends JSBS_TaskFrame__DocumentListener {

Es werden Bibliotheken mit den Klassen für das 'Document', 'DocumentEvent' und den Basisklassen für Fenster (frames) importiert.
In der Bibliothek
js_base.frame ist auch die Basisklasse JSBS_TaskFrame__DocumentListener enthalten.

zum Inhaltsverzeichnis

Erben der Basisklasse JSBS_TaskFrame_DocumentListener

/* */
public class JS_ProjAssist_Project__DocumentListener extends JSBS_TaskFrame__DocumentListener {
/*

In der Basisklasse JSBS_TaskFrame_DocumentListener ist der Code für die Behandlung jener GUI-Elemente, die in der Basisklasse JSBS_TaskFrame definiert sind, enthalten.
In der Basisklasse wird auch das Aktivieren / Deaktivieren der Schaltflächen
[ Bearbeiten ] (btn_Get) und [ Löschen ] (btn_Delete) gesteuert.

zum Inhaltsverzeichnis

Definieren der Variablen

public class JS_ProjAssist_Project__DocumentListener extends JSBS_TaskFrame__DocumentListener {
/*
 * Referenz auf das zugehörige Task-Frame. */

    
private JS_ProjAssist_Project frmTF;
/*
 * Objekte der Klasse 'Document', die für die Textaufbereitung bei GUI-Elementen zuständig sind.
 * Diese werden aus Performanz-Gründen im 'Constructor' aus den GUI-Elementen herausgelesen und
 * in den folgenden Variablen gehalten. */

    
private Document doc_txt_ProjectCode;
    
private Document doc_txt_LanguageCode;
    
private Document doc_txt_TargetDirectoryName;
/*
 * Merker (Flags) ob die Eingaben in den GUI-Elementen korrekt sind. */

    
private boolean bol_txt_ProjectCode_OK;
    
private boolean bol_txt_LanguageCode_OK;
    
private boolean bol_txt_TargetDirectoryName_OK;
/*
 * Constructor der Klasse.

In der Klasse sind 3 Arten von Variablen notwendig.

zum Inhaltsverzeichnis

'Constructor' der Klasse

    private boolean bol_txt_LanguageCode_OK;
/*
 * Constructor der Klasse.
 * Code darin wird aufgerufen wenn ein Objekt dieser Klasse erstellt wird.
 * Als Parameter wird das jeweilig TaskFrame übernommen. */

    
public JS_ProjAssist_Project__DocumentListener(JS_ProjAssist_Project parmTF) {
/*
 * Aufruf des Constructors der Basisklasse (JSBS_TaskFrame__DocumentListener).
 * Darin werden die Klasse des aufrufenden TaskFrames und die 'Document's der GUI-Elemente,
 * die in der Basisklasse (JSBS_TaskFrame) definiert sind, in die dort definierten
 * Variablen übertragen. */

        
super (parmTF);
/* 
 * Übernehmen der als Parameter übergebenen Referenz auf das aufrufende Task-Frame
 * in die Variable dieser Klasse. */

        
frmTF = parmTF;
/* 
 * 'Herausholen' des jeweiligen 'Document' aus den GUI-Elementen für die Eingabe von Werten.
 * Das wird aus Performanz-Gründen einmalig im 'Constructor' durchgeführt. */

        
doc_txt_ProjectCode = frmTF.get_txt_ProjectCode().getDocument();
        
doc_txt_LanguageCode = frmTF.get_txt_LanguageCode().getDocument();
        
doc_txt_TargetDirectoryName = frmTF.get_txt_TargetDirectoryName().getDocument();
/* 
 * Erstmaliges 'Setzen' der OK-Flags.
 * Für alle als 'Mandatory' definierten GUI-Elemente wird 'false' gesetzt.
 * Damit wird bewirkt, daß beim erstmaligen Aufrufen des Task-Frames in leere Felder,
 * die als 'Mandatory' definiert sind, Werte eingegeben werden müssen. */

        
bol_txt_ProjectCode_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_ProjectCode());
        
bol_txt_LanguageCode_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_LanguageCode());
        
bol_txt_TargetDirectoryName_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_TargetDirectoryName());
    }

Der 'Constructor' der Klasse enthält Code für folgende Verarbeitungen:

zum Inhaltsverzeichnis

Abfragen, in welchem GUI-Element eine Eingabe erfolgt ist

In dieser Methode wird abgefragt, von welchem 'Document' (eines GUI-Elementes) der 'Event' ausgelöst wurde.
Anschließend wird der betreffende geänderte Wert geprüft und – wenn die Prüf-Regeln bestanden wurden - auf die zugehörige Variable des dafür vorgesehenen BO übertragen.

Im Detail sind nur die einzelnen Anweisungen für ein GUI-Element beschrieben; den kompletten Code finden Sie im Abschnitt Gesamter Code für
JS_ProjAssist_Project__DocumentListener.

/*
 * Methode die indirekt aufgerufen wird wenn ein Wert eines GUI-Elements verändert wird.
 * 'Indirekt aufgerufen' bedeutet, daß die mit dem 'DocumentListener' zu implementierenden
 * 'abstrakten Methoden' in der Basisklasse (JSBS_TaskFrame__DocumentListener) 'konkret'
 * implementiert sind und in diesen Methoden diese Methode (anyUpdate) aufgerufen wird.
 * Dieser Code ist also das 'Überschreiben' der Methode der geerbten Klasse. */

    
public void anyUpdate(DocumentEvent e) {
/*
 * Aufruf der Methode in der geerbten Klasse.
 * Damit werden die in den Basisklassen definierten GUI-Elemente verarbeitet. */

        
super.anyUpdate(e);
/* 
 * 'Document' welches den Event ausgelöst hat, aus dem Event ermitteln. */

        Document edoc = e.getDocument();
/* 
 * 'Document' mit allen als Variable definierten (und im Constructor ermittelten)
 * 'Document's der GUI-Elemente vergleichen. */

        
if (edoc == doc_txt_ProjectCode) {
/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)
 * übertragen. In der verwendeten Methode wird auch die Prüfung auf Gültigkeit
 * des eingegebenen Wertes durchgeführt und der Hintergrund des GUI-Elements eingefärbt. */

          
strAuxString =
            JSBS_GUIServices.getTextFromJTextField(
frmTF.get_txt_ProjectCode(), frmTF);
/* Wenn der eingegebene Wert nicht den Prüf-Regeln entspricht dann ist von der Methode
 * zurückgelieferte Wert 'null'. Das wird abgefragt und damit das Flag gesetzt. */
          
bol_txt_ProjectCode_OK = (strAuxString == null);
/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das
 * zugehörige Attribut des BO übertragen. */

          
bol_txt_ProjectCode_OK = (strAuxString == null);
          
if (bol_txt_ProjectCode_OK)
            
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.ProjectCode =
            
strAuxString;
        }
/* 
 * Nächstes 'Document' vergleichen. */

        
if (edoc == doc_txt_LanguageCode) {
. . . . . . . .
. . . . . . . .

Zuerst wird die Methode in der geerbten Klasse aufgerufen.
Das ist notwendig, weil beim 'Überschreiben' einer Methode die Methode mit gleichem Namen in der geerbten Klasse 'stillgelegt' ist.
In der geerbten Klasse werden alle GUI-Elemente bearbeitet, die schon in der Basisklasse JSBS_TaskFrame definiert sind.

    public void anyUpdate(DocumentEvent e) {
/*
 * Aufruf der Methode in der geerbten Klasse.
 * Damit werden die in den Basisklassen definierten GUI-Elemente verarbeitet. */

        super.anyUpdate(e);
/* 

Aus dem im Parameter übergebenen 'Event' wird 'herausgelöst' von welchem 'Document' dieser ausgelöst wurde.
Anschließend wird durch Vergleich des 'Document's ermittelt, in welchem GUI-Element die Eingabe erfolgt ist.


/* 
 * 'Document' welches den Event ausgelöst hat, aus dem Event ermitteln. */

        Document edoc = e.getDocument();
/* 
 * 'Document' mit allen als Variable definierten (und im Constructor ermittelten)
 * 'Document's der GUI-Elemente vergleichen. */

        
if (edoc == doc_txt_ProjectCode) {
/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)

Der Eingabe-Wert des GUI-Elementes wird durch eine leistungsfähige Methode der Basisklassen (siehe Klasse JSBS_GUIServices) auf eine Hilfs-Variable (in der geerbten Klasse definiert) übertragen.
Die Methode zum 'Auslesen' des Wertes führt auch gleichzeitig die Prüfung durch, ob der eingegebene Wert den (eventuell) definierten Prüf-Regeln entspricht und färbt (abhängig von bestandener / nicht bestandener Prüfung) den Hintergrund des GUI-Elements.

Wenn die Eingabe nicht der Prüf-Regel entspricht wird der Wert 'null' zurückgeliefert und in die Hilfs-Variable übertragen.


/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)
 * übertragen. In der verwendeten Methode wird auch die Prüfung auf Gültigkeit
 * des eingegebenen Wertes durchgeführt und der Hintergrund des GUI-Elements eingefärbt. */

          
strAuxString =
            JSBS_GUIServices.getTextFromJTextField(
frmTF.get_txt_ProjectCode(), frmTF);
/* Wenn der eingegebene Wert nicht den Prüf-Regeln entspricht dann ist von der Methode
 * zurückgelieferte Wert 'null'. Das wird abgefragt und damit das Flag gesetzt. */
          
bol_txt_ProjectCode_OK = ( strAuxString != null);
/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das

Durch eine boolsche Operation (mit kürzest-möglichem Code – aber hoffentlich durchschaubar) wird das entsprechende Flag gesetzt.
Wenn die Prüf-Regeln erfüllt sind, wird der Wert aus dem Eingabe-Feld in die entsprechende Variable des dafür vorgesehenen BO übertragen.


/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das
 * zugehörige Attribut des BO übertragen. */

          
if (bol_txt_ProjectCode_OK)
            
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.ProjectCode =
            
strAuxString;
        }

zum Inhaltsverzeichnis

Zusätzlicher Code in JS_ProjAssist_Project

zum Inhaltsverzeichnis

Prüf-Regeln und Hinweis-Texte in der Datei 'DisplayStrings.xml'

Die Datei 'DisplayStrings.xml' wurde in Tutorial: JavaScout ProjectAssist, Start-Frame Grundlagen (Java_Fatclient_01) – Text für die GUI-Elemente von XML-Datei einlesen > XML-Struktur für sprachabhängige Texte konstruieren erstellt.
Der sprachabhängige Text für das Task-Frame wurde in
Tutorial: JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) – Klasse für das Task-Frame zu Verwaltung von Projekt und Sprache eröffnen > Datei mit der XML-Struktur mit den sprachabhängigen Texten erweitern erfaßt.

In den folgenden Vorlagen sind nur die neuen Teile der Datei 'DisplayStrings.xml' dokumentiert.
Bitte fügen Sie die Texte in die Datei ein und achten Sie darauf, daß Sie nicht bestehenden Text versehentlich löschen !

Im Bereich <CommonElements> werden bei den Definitionen für die GUI-Elemente für die Eingabe von Projekt-Code und Sprach-Code folgende Prüf-Regeln erfaßt.

<root>
. . . . .
. . . . .
  <CommonElements>
    
<CommonElement>
      
<ElementName>btn_Continue</ElementName>
. . . . .
. . . . .
    <CommonElement>
      
<ElementName>lbl_LanguageCode</ElementName>
      
<ElementText>ISO-Sprach-Code:</ElementText>
      
<ToolTipText>Code der Sprache für die die Daten gelten</ToolTipText>
    
</CommonElement>
    
<CommonElement>
      
<ElementName>lbl_ProjectCode</ElementName>
      
<ElementText>Projekt-Code:</ElementText>
      
<ToolTipText>Code des Projektes für das die Daten gelten</ToolTipText>
    
</CommonElement>
    
<CommonElement>
      
<ElementName>txt_LanguageCode</ElementName>
      
<ToolTipText>Code der Sprache für die die Daten gelten</ToolTipText>
      
<InfoMessage>Code der Sprache für die die Daten gelten</InfoMessage>
      
<MinimumLength>2</MinimumLength>
      
<MaximumLength>4</MaximumLength>
    
</CommonElement>
    
<CommonElement>
      
<ElementName>txt_ProjectCode</ElementName>
      
<ToolTipText>Code des Projektes für das die Daten gelten</ToolTipText>
      
<InfoMessage>Code des Projektes für das die Daten gelten</InfoMessage>
      
<MinimumLength>4</MinimumLength>
      
<MaximumLength>16</MaximumLength>
    
</CommonElement>
    
<CommonElement>
. . . . .
. . . . .
  
</CommonElements>
  
<FrameIndividual>
    
<Frame>
. . . . .
. . . . .

Im Bereich <SupplementaryText> werden die Texte erfaßt, die bei Fehlern angezeigt werden. Das Auslesen erfolgt durch Methoden in der Basisklasse JSBS_GUIServices.

</root>
  <SupplementaryText>
    
<Element>
      
<ElementName>Project__ActionHandler*FD_TitleBar</ElementName>
      
<MessageText>Project__ActionHandler*FD_TitleBar</MessageText>
    
</Element>
    <Element>
      
<ElementName>JSBS_StringTooShort</ElementName>
      
<MessageText>Eingabe zu kurz; mindestens notwendig:</MessageText>
    
</Element>
    
<Element>
      
<ElementName>JSBS_StringTooLong</ElementName>
      
<MessageText>Eingabe zu lang; maximal erlaubt:</MessageText>
    
</Element>
  </SupplementaryText>
. . . . .
. . . . .
</root>

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 den beiden vorigen Schritten mit Abbildungen dokumentiert; deswegen folgen nur Stichworte:

Daraufhin erscheint das Fenster mit der Benutzeroberfläche.

Anmerkung:
Bei der zur Zeit der Erstellung dieses Tutorials (Februar 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.

Die Auswahl des Task-Frames (durch Eingabe des Codes 'P') wurde bereits ausführlich dokumentiert und wird deswegen nicht mehr mit Abbildungen dokumentiert.

Gegenüber vorigen Schritten sehen Sie noch keine Veränderung.



 

Eine Veränderung ist erst erkennbar, wenn Sie Werte für Projekt-Code und Sprach-Code eingeben.

Bei einer Eingabe, die die Eingabe-Regeln nicht erfüllt wird am unteren Rand des Frames der Hinweis zur Ursache angezeigt.

.


 

Wenn die Länge der Zeichenkette die Prüf-Regel erfüllt, wird der Hintergrund des Eingabe-Feldes weiß eingefärbt – sonst rot.

 
 
 
 

 
 
 
 

Eine weitere Auswirkung des implementierten Codes ist, daß die Ränder der Eingabefelder eingefärbt werden.
Zum jetzigen Zeitpunkt passiert das erst wenn ein GUI-Element den 'Focus' erhält; d.h. wenn der Positionszeiger (Cursor) im Feld positioniert ist.

Jene Felder, in denen eine verpflichtende Eingabe erforderlich ist, sind mit einem roten Rand versehen,

Jenes Feld in dem der Positionszeiger (Cursor) positioniert ist, ist mit einem Rand in der Farbe magenta versehen.

Die Farben sind Standard-Werte und können verändert werden.
Eine Anleitung zur Veränderung finden Sie im Dokument
Datei 'DisplayStrings.xml' mit sprachabhängigen Texten für die Anzeige auf der GUI.


 


zum Inhaltsverzeichnis

MouseListener zur Tabelle mit den gefundenen Datensätzen hinzufügen

Um einen angezeigten Datensatz auch mit der Maus auswählen zu können, muß das GUI-Element pnl_SelectionListTable mit einem MouseListener versehen werden.
Der zusätzliche Code wird in der Methode
initialize_frame() in der Klasse JS_ProjAssist_Project implementiert.

Hintergrundinformation:
Das Hinzufügen des
MouseListener kann nicht in der Basisklasse erfolgen weil das GUI-Element pnl_SelectionListTable erst 'konstruiert' werden muß bevor der Listener hinzugefügt werden kann.
Auf das Hinzufügen von
MouseListener zu allen GUI-Elementen in der Methode addListeners(...) (siehe Abschnitt Zusätzlicher Code in JS_ProjAssist_Project) wird aus Performanz-Gründen verzichtet.

/* 
 * Methode mit der das Frame (Window) angezeigt wird. */

    
private void initialize_frame() {
/* Frame (Window) sichtbar machen (anzeigen). */
. . . . . . .
. . . . . . .
      setContentPane(get_pnl_Main());
/* Mouse-Listener zu der JTable, in der die auswählbaren Business-Objects angezeigt
 * werden, hinzufügen. Damit wird beim Anklicken einer Zeile der JTable die Nummer der
 * Zeile in das JTextField für die Auswahl (txt_Selection) übertragen.
 * Das Feststellen der Zeile und das Übertragen wird durch eine Methode in der
 * geerbten Basisklasse durchgeführt. */

      get_pnl_SelectionListTable().addMouseListener(
this);
    }

zum Inhaltsverzeichnis

Zwischen-Test 2

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 den beiden vorigen Schritten mit Abbildungen dokumentiert; deswegen folgen nur Stichworte:

Daraufhin erscheint das Fenster mit der Benutzeroberfläche.

Anmerkung:
Bei der zur Zeit der Erstellung dieses Tutorials (Februar 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.

Die Auswahl des Task-Frames (durch Eingabe des Codes 'P') wurde bereits ausführlich dokumentiert und wird deswegen nicht mehr mit Abbildungen dokumentiert.

Gegenüber vorigen Schritten sehen Sie noch keine Veränderung.



 

Eine Veränderung ist erst erkennbar, wenn Sie einzelne Zeilen der Tabelle 'Gefundene Datensätze:' mit der linken Maustaste anklicken.

Die Nummer der angeklickten Zeile wird im Eingabefeld 'Auswahl' angezeigt.



 



zum Inhaltsverzeichnis

Individueller Code in JS_ProjAssist_Project__DocumentListener, Teil 2: Aktivieren / Deaktivieren von Schaltflächen

Um dem Anwender klar zu zeigen, welche 'Aktion' er durchführen kann, werden nur jene Schaltflächen aktiviert, die die eingegebenen Daten auch weiter verarbeiten können.

Die Steuerung der Schaltflächen beschränkt sich in diesem Tutorial nur auf jene Schaltflächen, die in diesem Tutorial auch verwendet werden ([ Speichern ] und [ Speichern ]; weiters [ Bearbeiten ] und [ Löschen ] die bereits in der geerbten Basisklasse gesteuert werden).

zum Inhaltsverzeichnis

Methode checkEntriesOK() zum Prüfen auf fehlerfreie Eingabe

/*
 * Methode, die alle Flags (boolsche Variablen die signalisieren, ob die Eingabe im zugehörigen
 * GUI-Element die Eingabe-Regel erfüllt) zu einer boolschen Variable zusammenfaßt.
 * Die dafür verwendete Variable ist in der geerbten Klasse definiert. */

    
private void checkEntriesOK() {
/* Boolsche Operation die prüft, ob alle Eingaben den Eingabe-Regeln entsprechen. */
        
bolCompleteEntryOK =
              
bol_txt_ProjectCode_OK
           && 
bol_txt_LanguageCode_OK
           && 
bol_txt_TargetDirectoryName_OK;
    }

Es ist häufig notwendig zu Prüfen, ob die Eingabe der Werte in den Feldern fehlerfrei ist.
Deswegen ist bereits in der geerbten Basis-Klasse eine Variable dafür vorgesehen (
bolCompleteEntryOK) und die boolsche Verknüpfung wird in einer eigenen Methode implementiert.

zum Inhaltsverzeichnis

Methode zum Aktivieren/Deaktivieren der Schaltfläche [ Speichern ]

/*
 * Methode, die prüft ob die Schaltfläche 'btn_Store' (Speichern) zu aktivieren oder zu
 * deaktivieren ist. */

    
private void setButtonStatus_Store() {
/* Zuerst die Methode aufrufen, die alle OK-Flags in eine Variable zusammenfaßt. */
        checkEntriesOK();
/*
 * Boolsche Operation innerhalb der 'setEnabled'-Methode des JButton:
 * Es müssen alle Eingaben (in den GUI-Elementen) der jeweiligen Eingabe-Regel entsprechen
 * (geprüft über 'bolCompleteEntryOK')
 *  und
 * mindestens eine Variable des BO muß verändert worden sein
 * (geprüft durch den Vergleich des BO nach dem Lesen von / Speichern auf der Datenbank oder
 * nach dem 'Kopieren' mit dem BO, daß die aktuellen Eingaben in den GUI-Elementen enthält). */

        
frmTF.get_btn_Store().setEnabled(bolCompleteEntryOK &&
              (
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.isDifferent(
                  
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed)));
    }

Um einen klar strukturierten Code zu erreichen wird die Prüfung für jede Schaltfläche in einer eigener Methode implementiert – auch um den Preis, redundante Verarbeitungen auszuführen.

In dieser Methode wird zuerst die Methode zum Prüfen, ob alle Eingabe-Werte die jeweiligen Eingabe-Regeln erfüllen, aufgerufen.
Die Schaltfläche wird dann aktiviert, wenn alle Eingabe-Werte fehlerfrei sind und überhaupt ein Eingabe-Wert verändert wurde.
Die Prüfung auf Veränderung wird durchgeführt, indem das BO (Business Object) mit den aktuell angezeigten Werten mit jenem BO, daß die Werte zum Zeitpunkt der Datenbank-Operation (Speichern oder Lesen) enthält, verglichen wird.

zum Inhaltsverzeichnis

Methode zum Aktivieren/Deaktivieren der Schaltfläche [ Kopieren ]

/*
 * Methode, die prüft ob die Schaltfläche 'btn_Copy' (Kopieren) zu aktivieren oder zu
 * deaktivieren ist. */

    
private void setButtonStatus_Copy() {
/* Zuerst die Methode aufrufen, die alle OK-Flags in eine Variable zusammenfaßt. */
        checkEntriesOK();
/*
 * Boolsche Operation innerhalb der 'setEnabled'-Methode des JButton:
 * Es müssen alle Eingaben (in den GUI-Elementen) der jeweiligen Eingabe-Regel entsprechen
 * (geprüft über 'bolCompleteEntryOK')
 *  und
 * es darf keine Variable des BO seit dem letzen Lesen von / schreiben auf die Datenbank
 * verändert worden sein
 * (geprüft durch den Vergleich des BO nach dem Lesen von / Speichern auf der Datenbank oder
 * nach dem 'Kopieren' mit dem BO, daß die aktuellen Eingaben in den GUI-Elementen enthält). */

        
frmTF.get_btn_Copy().setEnabled(bolCompleteEntryOK &&
              ! (
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.isDifferent(
                    
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed)));
    }

Ein BO kann kopiert werden, wenn noch kein Wert einer Variable verändert wurde.
Das Abfragen, ob alle eingegebenen Werte fehlerfrei sind, verhindert, daß die Schaltfläche aktiviert wird wenn das Frame 'konstruiert' wurde.
Zu diesem Zeitpunkt sind zwar die Variablen-werte beider BO identisch – aber noch keine Werte angezeigt.

zum Inhaltsverzeichnis

Methode zum Aktivieren/Deaktivieren aller Schaltflächen

/*
 * Methode, die alle Methoden, die einzelne Schaltflächen (JButtons) aktivieren bzw.
 * deaktivieren. */

    
public void setButtonStatus() {
/* Button-Status für die Schaltflächen zur Auswahl oder zum Löschen eines BO (Datensatzes)
 * setzen. Diese Methode ist in der geerbten Basis-Klasse implementiert. */

        
super.setButtonStatus_Selection();
/* Methoden dieser Klasse aufrufen. */
        setButtonStatus_Store();
        setButtonStatus_Copy();

    }

In dieser Methode wurde der Einfachheit des Codes der Vorzug gegeben – und Methoden redundant ausgeführt.

Dabei werden alle Methoden zum Prüfen und Aktivieren / Deaktivieren der einzelnen Schaltflächen aufgerufen.

zum Inhaltsverzeichnis

Aufrufen der Methode zum Aktivieren/Deaktivieren aller Schaltflächen

Die Prüfung, ob einzelne Schaltflächen zu aktivieren oder zu deaktivieren sind, muß an verschiedenen Stellen des Anwendungsprogramms aufgerufen werden.

zum Inhaltsverzeichnis

End-Test

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 den beiden vorigen Schritten mit Abbildungen dokumentiert; deswegen folgen nur Stichworte:

Daraufhin erscheint das Fenster mit der Benutzeroberfläche.

Anmerkung:
Bei der zur Zeit der Erstellung dieses Tutorials (Februar 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.

Die Auswahl des Task-Frames (durch Eingabe des Codes 'P') wurde bereits ausführlich dokumentiert und wird deswegen nicht mehr mit Abbildungen dokumentiert.

Gegenüber vorigen Schritten sehen Sie, daß die Schaltflächen (die in diesem Tutorial eine Funktion haben) deaktiviert sind.



 

Wenn Sie eine gültige Auswahl getroffen haben, wird die Schaltfläche [ Bearbeiten ] aktiviert.



 

Durch [ Bearbeiten ] kann der Datensatz 'geholt' werden.
Nachdem die Daten gültig und nicht verändert sind, kann durch Anklicken der Schaltfläche [ Kopieren ] ein neuer Datensatz angelegt werden.



 

Nachdem jetzt das Feld 'Iso-Sprach-Code' keinen gültigen Wert erhält, können die Daten weder kopiert noch gespeichert werden – die entsprechenden Schaltflächen sind deaktiviert.



 

Erst nachdem alle Felder gültige Daten enthalten ist Schaltfläche [ Speichern ] aktiviert.



 

Nach dem Speichern der Daten ist die Schaltfläche [ Speichern ] deaktiviert.



 



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 {
/*
 * Zugehöriges DocumentListener Objekt definieren. */

    
protected JS_ProjAssist_Project__DocumentListener
                
structJS_ProjAssist_Project__DocumentListener;
/*
 * 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;
/*
 * Liste mit Business-Objects (Client-Side-Klasse) für die Anzeige definieren. */

    
protected JS_ProjAssist_ProjectLanguage_BOC_Set
                
structJS_ProjAssist_ProjectLanguage_BOC_Set;
/*
 * 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);
      
structJS_ProjAssist_ProjectLanguage_BOC_Set =
                
new JS_ProjAssist_ProjectLanguage_BOC_Set(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());
/* Mouse-Listener zu der JTable, in der die auswählbaren Business-Objects angezeigt
 * werden, hinzufügen. Damit wird beim Anklicken einer Zeile der JTable die Nummer der
 * Zeile in das JTextField für die Auswahl (txt_Selection) übertragen.
 * Das Feststellen der Zeile und das Übertragen wird durch eine Methode in der
 * geerbten Basisklasse durchgeführt. */

      get_pnl_SelectionListTable().addMouseListener(
this);
    }
/* 
 * 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);
/* DocumentListener konstruieren und anschlißend die Methode der geerbten Klasse
 * aufrufen mit der die notwendigen Listener zu den GUI-Elementen hinzugefügt werden. */

      
structJS_ProjAssist_Project__DocumentListener =
          
new JS_ProjAssist_Project__DocumentListener(this);
      addListeners(
this.getContentPane(), structJS_ProjAssist_Project__DocumentListener);
/* GUI-Elemente, bei denen eine Eingabe zwingend erforderlich ist ('Mandatory'),
 * festlegen. Die Festlegung hier ist 'stärker' als eine eventuelle Prüf-Regel
 * in der Datei 'DisplayStrings.xml'. */

      
structJSBS_EntryRules.addApplicationMandatoryGUIElement(get_txt_ProjectCode());
      
structJSBS_EntryRules.addApplicationMandatoryGUIElement(get_txt_LanguageCode());
/* Methode zum Anzeigen der aktuell gültigen Projekt-/Sprach-Kombinationen aufrufen. */
      JS_ProjAssist_Project__ActionHandler.redisplayList(
this);
/* 
 * Prüfen und Aktivieren / Deaktivieren von Schaltflächen (JButtons). */

      
structJS_ProjAssist_Project__DocumentListener.setButtonStatus();
    }
/* 
 * ******************************
 * 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;
/*
 * Package und Klassen mit Methoden zum Auslesen von Werten aus GUI-Elementen bzw.
 * Anzeigen von Werten in GUI-Elementen. */

import js_base.frame.JSBS_GUIServices;
/*
 * Package und Klasse für ein zu bearbeitendes Business-Object. */

import js_projassist.bo.JS_ProjAssist_ProjectLanguage_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);
      if(cmd.equals("btn_Get")) getForUpdate(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 zum Anzeigen der Liste mit den aktuell gültigen Daten aufrufen. */

      redisplayList(parmTF);
/*
 * Methode zum Aktivieren / Deaktivieren von Schaltflächen (JButtons) aufrufen. */
        parmTF.structJS_ProjAssist_Project__DocumentListener.setButtonStatus();
    }

/*
 * 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);
/*
 * Methode zum Aktivieren / Deaktivieren von Schaltflächen (JButtons) aufrufen. */
        parmTF.structJS_ProjAssist_Project__DocumentListener.setButtonStatus();
    }

/*
 * Methode zum Anzeigen der Liste mit den aktuell gültigen Projekt-/Sprach-Kombinationen. */
    protected static void redisplayList(JS_ProjAssist_Project parmTF) {
/* 
 * Methode des BOC-Set zum Selektieren der Daten aufrufen. */
      parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Set.selectAllProjectLanguageCombinations();
/* 
 * Prüfen ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
 * BOC-Set abfragen. */
      switch(parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Set.StatusCode) {
      
case JSBS_BO.CONST_OK:
/* Datenbank-Operation wie erwartet.
 
* Verarbeitung innerhalb dieses 'case' mit 'break' beenden. */
        break;
      
case JSBS_BO.CONST_NOT_FOUND:
/* Noch keine Daten erfaßt; kein Fehler.
 
* Verarbeitung innerhalb dieses 'case' mit 'break' beenden. */
        break;
      
default:
/* Ein anderer Fehler ist beim Selektieren 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, "redisplay_DBError",
          Integer.toString(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Set.StatusCode),
          parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Set.StatusMsg);
      }
/* 
 * Werte aus den BO des selektierten Sets auf die JTable der GUI übertragen.
 * Dabei die Methode der BOC-Set-Klasse verwenden.
 * Die Daten-Struktur 'structJSBS_FramePosition_BOC.columnWidthArrey01' ist in der
 * Basisklasse für das Task-Frame (JSBS_TaskFrame) definiert und enthält die Information
 * über die Spaltenbreite für die Tabelle.
 * Die Information über die Spaltenbreite wird in diesem Schritt des Tutorials noch nicht
 * verwendet – ist aber als Parameter für die Methode erforderlich. */
      parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Set.setToGUI(
        parmTF.get_pnl_SelectionListTable(),
        parmTF.
structJSBS_FramePosition_BOC.ColumnWidthArray01);
/* 
 * Zuletzt wird noch ermittelt, wieviele BO in der Liste sind und damit die Eingabe-Regel
 * im GUI-Element für die Eingabe der Auswahl festgelegt.
 * Mit dieser Regel kann später (bei der Auswahl für die Detail-Anzeige) geprüft werden,
 * ob mit dem eingegeben Wert auch ein BO ausgewählt werden kann. */
      int intListSize =
            parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Set.vecRecordSet.size();
/* Die umfangreiche Parameterisierung der Eingabe-Regel wird derzeit nicht genutzt;
 * nicht verwendete Parameter werden durch 'null'-Werte ersetzt. */
      parmTF.structJSBS_EntryRules.setEntryRuleValues(
        parmTF.get_txt_Selection().getName(),
        
null, 1, intListSize, null, null, null, null);
/* 
 * Als Service für den Anwender wird, wenn nur ein BO in der Liste enthalten ist,
 * diese gleich zur Auswahl vorgeschlagen. */
      if (intListSize == 1)
            parmTF.get_txt_Selection().setText(
"1");
    }

/*
 * Methode zum Auswählen eines Business-Objects aus der angezeigten Liste,
 * neuerliches Lesen des BO von der Datenbank (falls ein anderer Anwender in der
 * Zwischenzeit eine Veränderung vorgenommen hat) und Anzeigen der Werte im Detail-Bereich
 * (Teil der GUI mit den GUI-Elementen für die Eingabe von Werten) der GUI. */
    protected static void getForUpdate(JS_ProjAssist_Project parmTF) {
/* 
 * Nummer aus dem Auswahl-Feld der GUI auslesen.
 * Mit der verwendeten Methode wird die (in der Methode 'redisplayList(...)' parameterisierte)
 * Klasse 'JSBS_EntryRules' auf die erlaubten Grenzen für die eingegebene Ziffer geprüft.
 * Bei einem ungültigen Wert wird der Hintergrund rot gefärbt. */
      Integer intSelectedRow =
        JSBS_GUIServices.getInteger(parmTF.get_txt_Selection(), parmTF); 
/* 
 * Bei einer ungültigen Eingabe (auch wenn der Wert außerhalb der erlaubten Grenzen ist)
 * wird von der Methode ein 'null'-Wert zurückgeliefert.
 * In diesem Fall wird die Methode beendet; dem Anwender wird durch den roten Hintergrund
 * die fehlerhafte Eingabe signalisiert. */
      if (intSelectedRow == null) return;
/* 
 * Eingegebene Nummer ist gültig; indiziertes BO in eigenes Objekt übertragen.
 * Durch das eigene Objekt ist der folgende Code leichter lesbar. */
      int intListIndex = intSelectedRow.intValue() - 1;
      JS_ProjAssist_ProjectLanguage_BO structJS_ProjAssist_ProjectLanguage_BO =
        (JS_ProjAssist_ProjectLanguage_BO) 
        parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Set.vecRecordSet.elementAt(intListIndex);
/* 
 * Aktuell gültiges BO von der Datenbank lesen. */
      parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.selectByUserKnownKey(
        structJS_ProjAssist_ProjectLanguage_BO.
ProjectCode,
        structJS_ProjAssist_ProjectLanguage_BO.
LanguageCode);
/* 
 * Prüfen ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
 * BOC-Set abfragen. */
      switch(parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.StatusCode) {
      
case JSBS_BO.CONST_OK:
/* Datenbank-Operation wie erwartet.
 * Werte auf die GUI-Elemente übertragen. */
        parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.setToGUI(
          parmTF.get_txt_ProjectCode(), parmTF.get_txt_LanguageCode(),
          parmTF.get_txt_TargetDirectoryName());
/* Felder, die Teil des Anwender-bekannten-Schlüssels sind für die Eingabe sperren. */
        parmTF.get_txt_ProjectCode().setEditable(false);
        parmTF.get_txt_LanguageCode().setEditable(false);
/* Werte des BO mit den von der DB gelesenen Daten auf ein weiteres BO kopieren.
 * Dieses BO enthält dann (in einem späteren Schritt implementiert) die aktuell
 * auf der GUI eingegebenen Werte.
 * Damit können Änderungen erkannt werden und damit Schaltflächen aktiviert oder
 * deaktiviert werden. */
        parmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.
          copyFromJS_ProjAssist_ProjectLanguage_BO(
          parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read);
/* Verarbeitung innerhalb dieses 'case' mit 'break' beenden. */
        break;
      
case JSBS_BO.CONST_NOT_FOUND:
/* In der Liste angezeigtes BO wurde in der Zwischenzeit gelöscht. */
        parmTF.handleErrorEvent(CONST_ClassName, "getForUpdate_NotFound");
/* Verarbeitung innerhalb dieses 'case' mit 'break' beenden. */
        break;
      
default:
/* Ein anderer Fehler ist beim Selektieren 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, "getForUpdate_DBError",
          Integer.toString(parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read.StatusCode),
          parmTF.
structJS_ProjAssist_ProjectLanguage_BOC_Read.StatusMsg);
      }
    }

}

zum Inhaltsverzeichnis

Klasse JS_ProjAssist_Project__DocumentListener

package js_projassist.client;
/*
 * Packages mit den Klassen für die Behandlung von Document und -Event. */

import javax.swing.text.Document;
import javax.swing.event.DocumentEvent;
/*
 * Package mit der Basisklassen für das TaskFrame. */

import js_base.frame.*;
/* */
public class JS_ProjAssist_Project__DocumentListener extends JSBS_TaskFrame__DocumentListener {
/*
 * Referenz auf das zugehörige Task-Frame. */

    
private JS_ProjAssist_Project frmTF;
/*
 * Objekte der Klasse 'Document', die für die Textaufbereitung bei GUI-Elementen zuständig sind.
 * Diese werden aus Performanz-Gründen im 'Constructor' aus den GUI-Elementen herausgelesen und
 * in den folgenden Variablen gehalten. */

    
private Document doc_txt_ProjectCode;
    
private Document doc_txt_LanguageCode;
    
private Document doc_txt_TargetDirectoryName;
/*
 * Merker (Flags) ob die Eingaben in den GUI-Elementen korrekt sind. */

    
private boolean bol_txt_ProjectCode_OK;
    
private boolean bol_txt_LanguageCode_OK;
    
private boolean bol_txt_TargetDirectoryName_OK;
/*
 * Constructor der Klasse.
 * Code darin wird aufgerufen wenn ein Objekt dieser Klasse erstellt wird.
 * Als Parameter wird das jeweilig TaskFrame übernommen. */

    
public JS_ProjAssist_Project__DocumentListener(JS_ProjAssist_Project parmTF) {
/*
 * Aufruf des Constructors der Basisklasse (JSBS_TaskFrame__DocumentListener).
 * Darin werden die Klasse des aufrufenden TaskFrames und die 'Document's der GUI-Elemente,
 * die in der Basisklasse (JSBS_TaskFrame) definiert sind, in die dort definierten
 * Variablen übertragen. */

        
super(parmTF);
/* 
 * Übernehmen der als Parameter übergebenen Referenz auf das aufrufende Task-Frame
 * in die Variable dieser Klasse. */

        
frmTF = parmTF;
/* 
 * 'Herausholen' des jeweiligen 'Document' aus den GUI-Elementen für die Eingabe von Werten.
 * Das wird aus Performanz-Gründen einmalig im 'Constructor' durchgeführt. */

        
doc_txt_ProjectCode = frmTF.get_txt_ProjectCode().getDocument();
        
doc_txt_LanguageCode = frmTF.get_txt_LanguageCode().getDocument();
        
doc_txt_TargetDirectoryName = frmTF.get_txt_TargetDirectoryName().getDocument();
/* 
 * Erstmaliges 'Setzen' der OK-Flags.
 * Für alle als 'Mandatory' definierten GUI-Elemente wird 'false' gesetzt.
 * Damit wird bewirkt, daß beim erstmaligen Aufrufen des Task-Frames in leere Felder,
 * die als 'Mandatory' definiert sind, Werte eingegeben werden müssen. */

        
bol_txt_ProjectCode_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_ProjectCode());
        
bol_txt_LanguageCode_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_LanguageCode());
        
bol_txt_TargetDirectoryName_OK =
            
frmTF.structJSBS_EntryRules.checkMandatory(frmTF.get_txt_TargetDirectoryName());
    }

/*
 * Methode die indirekt aufgerufen wird wenn ein Wert eines GUI-Elements verändert wird.
 * 'Indirekt aufgerufen' bedeutet, daß die mit dem 'DocumentListener' zu implementierenden
 * 'abstrakten Methoden' in der Basisklasse (JSBS_TaskFrame__DocumentListener) 'konkret'
 * implementiert sind und in diesen Methoden diese Methode (anyUpdate) aufgerufen wird.
 * Dieser Code ist also das 'Überschreiben' der Methode der geerbten Klasse. */

    
public void anyUpdate(DocumentEvent e) {
/*
 * Aufruf der Methode in der geerbten Klasse.
 * Damit werden die in den Basisklassen definierten GUI-Elemente verarbeitet. */

        
super.anyUpdate(e);
/* 
 * 'Document' welches den Event ausgelöst hat, aus dem Event ermitteln. */

        Document edoc = e.getDocument();
/* 
 * 'Document' mit allen als Variable definierten (und im Constructor ermittelten)
 * 'Document's der GUI-Elemente vergleichen. */

        
if (edoc == doc_txt_ProjectCode) {
/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)
 * übertragen. In der verwendeten Methode wird auch die Prüfung auf Gültigkeit
 * des eingegebenen Wertes durchgeführt und der Hintergrund des GUI-Elements eingefärbt. */

          
strAuxString =
            JSBS_GUIServices.getTextFromJTextField(
frmTF.get_txt_ProjectCode(), frmTF);
/* Wenn der eingegebene Wert nicht den Prüf-Regeln entspricht dann ist von der Methode
 * zurückgelieferte Wert 'null'. Das wird abgefragt und damit das Flag gesetzt. */

          
bol_txt_ProjectCode_OK = (strAuxString != null);
/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das
 * zugehörige Attribut des BO übertragen. */

          
if (bol_txt_ProjectCode_OK)
            
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.ProjectCode =
            
strAuxString;
        }
/* 
 * Nächstes 'Document' vergleichen. */

        
if (edoc == doc_txt_LanguageCode) {
/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)
 * übertragen. In der verwendeten Methode wird auch die Prüfung auf Gültigkeit
 * des eingegebenen Wertes durchgeführt und der Hintergrund des GUI-Elements eingefärbt. */
          
strAuxString =
            JSBS_GUIServices.getTextFromJTextField(
frmTF.get_txt_LanguageCode(), frmTF);
/* Wenn der eingegebene Wert nicht den Prüf-Regeln entspricht dann ist von der Methode
 * zurückgelieferte Wert 'null'. Das wird abgefragt und damit das Flag gesetzt. */

          
bol_txt_LanguageCode_OK = (strAuxString != null);
/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das
 * zugehörige Attribut des BO übertragen. */

          
if (bol_txt_LanguageCode_OK)
            
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.LanguageCode =
            
strAuxString;
        }
/* 
 * Nächstes 'Document' vergleichen. */

        
if (edoc == doc_txt_TargetDirectoryName) {
/* Wert des GUI-Elementes in die Hilfs-Variable (definiert in der geerbten Klasse)
 * übertragen. In der verwendeten Methode wird auch die Prüfung auf Gültigkeit
 * des eingegebenen Wertes durchgeführt und der Hintergrund des GUI-Elements eingefärbt. */
          
strAuxString =
            JSBS_GUIServices.getTextFromJTextField(
frmTF.get_txt_TargetDirectoryName(), frmTF);
/* Wenn der eingegebene Wert nicht den Prüf-Regeln entspricht dann ist von der Methode
 * zurückgelieferte Wert 'null'. Das wird abgefragt und damit das Flag gesetzt. */
          
bol_txt_TargetDirectoryName_OK = (strAuxString != null);
/* Wenn der eingegebene Wert die Prüf-Regeln bestanden hat dann wird der Wert auf das
 * zugehörige Attribut des BO übertragen. */

          
if (bol_txt_TargetDirectoryName_OK)
            
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed.TargetDirectory =
            
strAuxString;
        }
/* 
 * Prüfen und Aktivieren / Deaktivieren von Schaltflächen (JButtons). */

        setButtonStatus();

    }

/*
 * Methode, die alle Flags (boolsche Variablen die signalisieren, ob die Eingabe im zugehörigen
 * GUI-Element die Eingabe-Regel erfüllt) zu einer boolschen Variable zusammenfaßt.
 * Die dafür verwendete Variable ist in der geerbten Klasse definiert. */

    
private void checkEntriesOK() {
/* Boolsche Operation die prüft, ob alle Eingaben den Eingabe-Regeln entsprechen. */
        
bolCompleteEntryOK =
              
bol_txt_ProjectCode_OK
           && 
bol_txt_LanguageCode_OK
           && 
bol_txt_TargetDirectoryName_OK;
    }

/*
 * Methode, die prüft ob die Schaltfläche 'btn_Store' (Speichern) zu aktivieren oder zu
 * deaktivieren ist. */

    
private void setButtonStatus_Store() {
/* Zuerst die Methode aufrufen, die alle OK-Flags in eine Variable zusammenfaßt. */
        checkEntriesOK();
/*
 * Boolsche Operation innerhalb der 'setEnabled'-Methode des JButton:
 * Es müssen alle Eingaben (in den GUI-Elementen) der jeweiligen Eingabe-Regel entsprechen
 * (geprüft über 'bolCompleteEntryOK')
 *  und
 * mindestens eine Variable des BO muß verändert worden sein
 * (geprüft durch den Vergleich des BO nach dem Lesen von / Speichern auf der Datenbank oder
 * nach dem 'Kopieren' mit dem BO, daß die aktuellen Eingaben in den GUI-Elementen enthält). */

        
frmTF.get_btn_Store().setEnabled(bolCompleteEntryOK &&
              (
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.isDifferent(
                  
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed)));
    }

/*
 * Methode, die prüft ob die Schaltfläche 'btn_Copy' (Kopieren) zu aktivieren oder zu
 * deaktivieren ist. */

    
private void setButtonStatus_Copy() {
/* Zuerst die Methode aufrufen, die alle OK-Flags in eine Variable zusammenfaßt. */
        checkEntriesOK();
/*
 * Boolsche Operation innerhalb der 'setEnabled'-Methode des JButton:
 * Es müssen alle Eingaben (in den GUI-Elementen) der jeweiligen Eingabe-Regel entsprechen
 * (geprüft über 'bolCompleteEntryOK')
 *  und
 * es darf keine Variable des BO seit dem letzen Lesen von / schreiben auf die Datenbank
 * verändert worden sein
 * (geprüft durch den Vergleich des BO nach dem Lesen von / Speichern auf der Datenbank oder
 * nach dem 'Kopieren' mit dem BO, daß die aktuellen Eingaben in den GUI-Elementen enthält). */

        
frmTF.get_btn_Copy().setEnabled(bolCompleteEntryOK &&
              ! (
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Read.isDifferent(
                    
frmTF.structJS_ProjAssist_ProjectLanguage_BOC_Processed)));
    }

/*
 * Methode, die alle Methoden, die einzelne Schaltflächen (JButtons) aktivieren bzw.
 * deaktivieren. */

    
public void setButtonStatus() {
/* Button-Status für die Schaltflächen zur Auswahl oder zum Löschen eines BO (Datensatzes)
 * setzen. Diese Methode ist in der geerbten Basis-Klasse implementiert. */

        
super.setButtonStatus_Selection();
/* Methoden dieser Klasse aufrufen. */
        setButtonStatus_Store();
        setButtonStatus_Copy();

    }

}

zum Inhaltsverzeichnis

Weitere Schritte und verwandte Dokumentation

Dokument

Inhalt

JavaScout ProjectAssist, Task-Frame Finalisierung (Java_Fatclient_01) – Letzte Feinheiten  

In diesem Schritt des Tutorials wird dem Anwendungsprogramm der 'letzte Schliff' gegeben.
Damit wird die Benutzerführung weiter optimiert.

zum Inhaltsverzeichnis