2.1 Objektarten

Die auf dem Bildschirm für den Benutzer sichtbaren Attribute können auf verschiedenen Objektdefinitionsebenen definiert werden.

Die verschiedenen Objekttypen sind:

Diese unterschiedlichen Arten von Objekten werden in den nachfolgenden Kapiteln genauer vorgestellt.

2.1.1 Defaultobjekte

Zu jeder im Dialog verwendeten Objektklasse sollte ein Defaultobjekt definiert werden. Durch die Verwendung dieser Defaultobjekte können einzelne Objektattribute einmalig global definiert werden. D.h. alle nachfolgend deklarierten Objekte derselben Objektklasse enthalten implizit die in der Objektvorlage definierten Attribute, sofern diese nicht lokal umdefiniert werden. Mit diesem Hilfsmittel sind also nur noch zusätzliche Attribute zu deklarieren oder solche, die vom Default abweichen.

Die Deklaration einer Objektvorlage beginnt mit dem Schlüsselwort default, anschließend steht die Klasse des Objektes, gefolgt von der in geschweiften Klammern stehenden Objektdefinition.

Definition

{ export | reexport } default <Objektklasse> { <Bezeichner> }
{
  <Attribute>
}

Innerhalb der Definition der Defaults können alle zu der Objektklasse gehörenden Attribute verwendet werden. Zusätzlich können selbstverständlich auch benutzerdefinierte Attribute dem Defaultobjekt hinzugefügt werden.

Beispiel

default window

{

    .sensitive true;

    .visible  true;

    .fgc Medium_Gray;

    .bgc White;

    .titlebar true;

    .closeable true;

    .sizeable true;

    object MeinZusaetzlichesAttribut := null;

}

default pushbutton

{

    .sensitive true;

    .visible true;

    .fgc Medium_Gray;

    .bgc White;

    .width 80;

    .height 30;

    .xauto 1;

    .yauto 1;

}

Bei der späteren Deklaration eines Pushbuttons muss dann nur noch die Position der linken oberen Ecke und die Beschriftung angegeben werden.

D.h. es genügt dann:

pushbutton OKAY

{

    .xleft 10;

    .ytop 10;

    .text "OKAY";

}

Im Gegensatz zu allen anderen Objekten können Defaultobjekte keine Kinder haben. Wenn dem Defaultobjekt, wie üblich, kein Name gegeben wird, wird es über den Namen seiner Klassen in Großbuchstaben angesprochen; mit PUSHBUTTON ist das Defaultobjekt der Pushbuttons gemeint, mit WINDOW das Defaultobjekt aller Fenster.

Die nachfolgende Tabelle zeigt alle Namen der Defaultobjekte.

Tabelle 19-1: Namen der Defaultobjekte

Objektklasse

Name des Defaultobjektes

Bild

IMAGE

Canvas

CANVAS

Checkbox, Tristate-Button

CHECKBOX

editierbarer Text

EDITTEXT

Fenster

WINDOW

Groupbox

GROUPBOX

Poptext (Combobox)

POPTEXT

Menubox

MENUBOX

Menueintrag

MENUITEM

Menuseparator

MENUSEP

Messagebox

MESSAGEBOX

Notebook

NOTEBOOK

Notepage

NOTEPAGE

Pushbutton

PUSHBUTTON

Radiobutton

RADIOBUTTON

Rechteck

RECTANGLE

Scrollbar

SCROLLBAR

statischer Text

STATICTEXT

Statusbar

STATUSBAR

Tablefield

TABLEFIELD

Timer

TIMER

2.1.2 Modelle

Ein weiteres Hilfsmittel zur Objekterzeugung sind die Vorlagen. Mit ihnen kann ein benanntes Vorlagenobjekt definiert werden, das zur Definition des realen Objektes herangezogen wird.

Dieses Hilfsmittel ist vor allem dann nützlich, wenn eine größere Anzahl gleichartiger Objekte erzeugt werden soll (z.B. mehrere OK-Knöpfe oder mehrere editierbare Texte, in denen der Benutzer jeweils eine Artikelnummer eingeben kann). Das Objekt, das sich auf eine Vorlage bezieht, erbt von dieser alle Attribute, die es nicht lokal neu definiert.

Definition

{ export | reexport } model <Objektklasse> <Bezeichner>
{
  <Attribute>
}

Innerhalb der Definition der Vorlagen können alle zu der Objektklasse gehörenden Attribute verwendet werden. Solche Vorlagen können dann als Kinder von anderen Objekten oder Vorlagen dienen. Zusätzlich können einer solchen Vorlage auch Kinder gegeben werden, die dann automatisch an alle davon abgeleiteten Instanzen vererbt werden. Dadurch können also komplexe hierarchische Modelle aufgebaut werden, die im aktuellen Dialog immer wieder verwendet werden sollen.

Die Definition solcher hierarchischer Vorlagen sieht dann wie folgt aus:

{ export | reexport } model <Objektklasse> <Bezeichner>
{
  { export | reexport } { child } <Objektklasse> { <Bezeichner> }
  {
    <Attribute>
  }
}

Um den Einsatz von Vorlagen möglichst effizient zu gestalten, sollte man sich die Mühe machen, komplexe Modelle zu erstellen, wenn im Dialog gewisse Strukturen immer wieder auftauchen. Dadurch werden der Wartungsaufwand und der Aufwand bei Änderungen wesentlich verringert.

Wenn nun eine Vorlage für die Definition eines Objektes genutzt werden soll, muss das Objekt wie folgt definiert werden:

<Modellbezeichner> { <Bezeichner> }
{
  <Attribute>
}

Beispiel: Eingabefeld für Artikelnummer

In einer Anwendung sollen in verschiedenen Fenstern Eingabefelder definiert werden, in denen eine Artikelnummer eingetragen werden kann. Im Normalfall ist für eine Anwendung das Schema, wie eine Artikelnummer aussieht, überall gleich. Aus diesem Grund sollte man hierfür also eine Vorlage schaffen und diese dann in den entsprechenden Fenstern verwenden. Wenn sich dann später das Schema für die Artikelnummer ändert, muss nur eine Stelle im Dialog, nämlich die Vorlage, verändert werden.

model edittext MEtArtikelNummer

{

  .posraster true;

  .sizeraster true;

  .format "AA.NN.NN/NN";

  .width 12;

}

Diese Vorlage kann dann in verschiedenen Fenstern verwendet und dabei in ihren Attributen verändert werden.

window WnFenster1

{

    child MEtArkitelNummer

    {

        .ytop 2;

        .xleft 2;

    }

}

 

window WnFenster2

{

    child MEtArtikelNummer EtErsterArtikel

    {

        .ytop 1;

        .xleft 10;

    }

    child MEtArtikelNummer EtZweiterArtikel

    {

        .ytop 2;

        .xleft 10;

    }

}

Im ersten Fenster WnFenster1 wird die ArtikelNummer verwendet, ohne dass ihr dabei ein neuer Name gegeben wird. Die von der Vorlage abgeleitete Instanz kann daher über WnFenster1.MEtArtikelNummer angesprochen werden. Im zweiten Fenster WnFenster2 wird die Vorlage gleich an zwei Stellen benutzt. Hier sollten den Objekten neue Namen gegeben werden, damit diese eindeutig angesprochen werden können.

Beispiel: Fenster mit Abbrechen und OK-Pushbutton

In einem Dialog sollen mehrere Fenster angelegt werden, in denen Daten eingegeben werden können. Diese Fenster sollten daher mit zwei Pushbuttons ausgestattet werden. Der erste Pushbutton "OK" übernimmt die Veränderungen des Benutzers in das Programm, der "Abbrechen" Pushbutton verwirft alle Aktionen des Benutzers. Damit das entsprechende System komfortabel aufgebaut werden kann, wird zunächst ein Modell eines Pushbuttons "MPbButton" angelegt, bei dem nur die Fixierung des Pushbuttons an der unteren Kante des Vaters definiert wird. Davon werden dann die eigentlichen Pushbuttons "MPbOK" und "MPbAbbrechen" ebenfalls als Vorlage abgeleitet. Anschließend wird ein Modell eines Fensters definiert, das Ableitungen der Pushbuttons "MPbOK" und "MPbAbbrechen" beinhaltet. Abschließend wird dann von diesem Fenster eine Instanz gebildet. Die Instanz hat dann folgendes Aussehen:

Abbildung 19-1: Fenster mit zwei Pushbuttons

Das zugehörige Dialogskript sieht wie folgt aus:

model pushbutton MPbButton

{

  .yauto -1;

}

model MPbButton MPbAbbrechen

{

  .xleft 15;

  .text "Abbrechen";

}

model pushbutton MPbOK

{

  .yauto -1;

  .text "OK";

}

model window MWnEingabeFenster

{

  .title "Eingabefenster";

  child MPbAbbrechen

  {

  }

  child MPbOK

  {

  }

}

MWnEingabeFenster WnAddresse

{

}

In dem Fenster "WnAdresse" können selbstverständlich beliebig viele weitere Kinder definiert werden.

Abbildung 19-2: Darstellung der Modellhierarchie

2.1.2.1 Problematische Modellhierarchie

Die folgende Modellhierarchie ist zwar möglich, wird aber ausdrücklich nicht empfohlen, da sie dem Charakter einer Modellhierarchie eigentlich widerspricht und in größeren Dialogen zu Verständnisproblemen führen kann.

Folgende Definition bildet ein Instanzenfenster WnInstanz mit zwei von Et1 abgeleiteten Editierfeldern (edittext) und einem weiteren, unabhängigen Fenster, welches ebenfalls eine Instanz von Et1 enthält:

model window MWnModel

{

child edittext Et1

  {

    .xleft 16;
    .ytop 2;

  }

}

MWnModel WnInstanz

{

  child Et1 NeuerEt

  {

    .xleft 30;

  }

}

window AnderesFenster

{

  child Et1 Eingabe

  {

    .xleft 10;

    .ytop 5;

    .width 20;

  }

}

Die hier skizzierte Vererbung ist auch über Modulgrenzen hinweg möglich, allerdings müssen dafür die entsprechenden Objekte mit export oder reexport freigegeben werden.

In diesen Fällen ist die getrennte Definition eines Modells für Et1 besser und auch leichter verständlich.

2.1.3 Instanz

Instanzen sind die Objekte, die auf dem Bildschirm sichtbar gemacht werden können. Sie können von einem Modell abgeleitet sein und neben den vom Modell geerbten Kindern eine beliebige Anzahl weitere Kinder definiert haben. Bei der Instanz können alle Attributwerte überschrieben werden und auch die Attribute von geerbten Kindern verändert werden. Im Modell definierte Kindern müssen dabei übernommen werden, sie können nicht in der Instanz gelöscht werden.