Wenn Du es noch nicht getan hast, lies über Umfang und Syntax der Designsprache GDL im Allgemeinen, bevor Du zu diesem Abschnitt übergehst. Hier ist etwas über den Unterschied von Komponenten und Containern zu erfahren. Wir erinnern uns, dass Komponenten als Elemente in einen Container eingefügt werden, Container hingegen Komponenten - oder andere Container - enthalten.
Im einfachsten Fall wird pro Zeile eines GDL-Skriptes eine Komponente aufgeführt. Haben wir dann ein Skript mit mehreren solcher Zeilen, dann erhalten wir im zugehörigen Layout untereinander angeordnete Komponenten.
Wollen wir in einer Zeile des Layouts mehrere Komponenten
nebeneinander anordnen, dann platzieren wir - jeweils getrennt von
den Zeichen "||
" (und Leerzeichen) - auch im Skript mehrere
Komponenten in einer Zeile nebeneinander (in der XML-Notation setzen wir
hier stattdessen das Attribut eol="false"
).
In der Regel ist es also nicht nötig, für eine Komponente explizit eine x- oder y-Position im Gitter anzugeben.Wollen wir aber komplexere Muster erzeugen, so können wir Komponenten auf diese Weise Positionen im Gitter zuweisen und dadurch eine bessere Übersicht verschaffen.
Folgende Komponenten können in GDL einem Container zugeordnet werden:
Eine Textbox kann mit einem vorangestellten Label versehen werden. Ihre horizontale Viskosität (Attribut wx) sowie ihre Spaltenanzahl (Attribut w) haben den voreingestellten Wert 3. Eine Textbox breitet sich also gerne in ihrer Zeile aus.
Die Ausrichtung des Textes ist per default linksbündig; sie kann aber
auch auf rechtsbündig (al=R
) und zentriert
(al=C
) gesetzt werden.
Ihr kann ein ToolTipText und ein Text für die Anzeige in der Statuszeile zugewiesen werden.
Der Inhalt der TextBox kann auf einen initialen Wert gesetzt werden.
Mit dem Schalter "nn=y"
wird die Komponente mit Eingabezwang
versehen (NotNull); ist das Feld beim Verlassen leer, erscheint ein
entsprechender Hinweis.
Das Attribut maxlen=40
begrenzt die Eingabe hier auf maximal
40 Zeichen; default ist 2000.
Mit regexp=[RegulärerAusdruck]
kann zur
Eingabeüberprüfung ein regulärer Ausdruck gesetzt werden.
Vollständige Liste der für Textboxen wirksamen Attribute:
<Text label="[LabelTitle]" x= y= w= wx= it=[Insets.Top] il=[Insets.left]
ib=[Insets.Bottom] ir=[Insets.right] px=[ipadx] py=[ipady] cols=[columns]
do=y nn=y tt="[TootTipText]" st="[StatusBarText]" val="[InitialValue]"
al=[alignment]
/>
Von der Klasse Text
sind vier weitere Klassen abgeleitet, die
ein bestimmtes Eingabeformat ermöglichen und fordern. Mit dem Attribut
format=
kann das Eingabeformat auch umgesetzt werden.
Die vier Klassen unterscheiden sich von "Text" in ihrem Verhalten neben dem
Eingabeformat vor allem durch spezielle Default-Eigenschaften:
cols
wird auf einen jeweils passenden Wert gesetzt, sowie eine
spezielle Ausrichtung (zentriert, rechtsbündig) vorgesehen. Horizontale
Viskosität gibt es nicht (wx=0
und w=1)
.
Bei Date und Time kann auch das Attribut val=TODAY
bzw.
val=NOW
zum Setzen des Tagesdatums bzw. der aktuellen Uhrzeit
verwendet werden.
Komponente für die Eingabe eines Passwords (eingegebener Text wird als "******" dargestellt).
Eine Default-ComboBox hat eine gewisse horizontale Viskosität (wx=1) und nimmt eine Spalte ein (w=1).
Die Werteliste in der ComboBox kann auf zweierlei Art definiert werden:
Items="Wert1|Wert2|usw."
file="MyValues.txt"
Gelegentlich sollen intern andere Daten gespeichert werden, als in der
Oberfläche dargestellt wird. Hierzu dient das Attribut map= bei dem
im Unterschied zu Items= eine enstsprechende Menge von EInträgen für
die interne Speicherung definiert wird. Beispiel:
... Items="Frau|Herrn|Firma" map="0|1|2"
...
Der aktuelle Anzeige der Combobox kann mit val=
auf eine bestimmte
(0-relative) Eintragnummer gesetzt werden.
Mit dem Attribut typ=EDIT
kann die Combobox als editierbar
gekennzeichnet werden, sonst ist sie nicht-editierbar.
<Combo label="[LabelTitle]" Items="[ItemList]" file="[FileName]"
val="[selectedIndex]" typ="EDIT
" />
Kann in beide Richtungen wachsen. Initialisierung der Listeneinträge geschieht genauso wie bei Combo.
In der Regel werden Listboxen verwendet, die sich genauso verhalten wie
Comboboxen:
Aus einer Menge von Einträgen kann der Benutzer einen auswählen.
Gelegentlich werden aber auch Listboxen mit hiervon abweichendem Verhalten
eingesetzt:
Um diese Verhaltenstypen festzulegen, wird das Attribut typ
verwendet.
Seit JDK 1.4 können ListBoxen auch zweispaltig gefüllt werden;
hierzu gibt es das Attribut:
layout="VERTICAL|VERTICAL_WRAP|HORIZONTAL_WRAP
"
<List label="[LabelTitle]" Items="[ItemList]" file="[FileName]"
val="[selectedIndex]"
typ="NORMAL|MULTI|ALL"
/>
Eine Checkbox nimmt so viel horizontalen Raum ein, wie ihr Titel Platz
benötigt. Sie kann mit dem Schlüsselwort val=true
initialisiert werden.
Mit dem Attribut map="trueValue|falseValue"
werden zwei Strings
definiert, die statt true
und false
geliefert werden
bzw. die CheckBox gesetzt oder zurückgesetzt wird.
<Check label="[CheckBoxTitle]" x= y= val=[true|false]
/>
Ein ToggleButton sieht aus wie ein Button, verhält sich aber wie eine
Checkbox, d.h. er repräsentiert einen true/false-Wert.
Mit den Attributen gif
und sicon
werden zwei Icons
angegeben, die den Zustand "NichtGedrückt" bzw. "Gedrückt" grafisch
darstellen.
Ein ToggleButton kann auch in der Toolbar eingesetzt werden.
<TButton label="Bold" />
<TButton img="[NotSelectedIcon]" sicon="[SelectedIcon]"/>
Ist eine Container für Radiobuttons. Es dürfen ihm beliebig viele
Optionen zugewiesen werden. Im Kern verhält sich eine OptionGroup
ähnlich wie eine Combo- oder ListBox:
Der Benutzer kann aus einer Reihe von vordefinierten Einträgen wählen.
Der Wert, den die OptionGroup repäsentiert, entspricht dem ActionCommand des selektierten Buttons.
Mit dem Attribut val= kann der Radiobutton vorselektiert werden, der das entsprechende ActionCommand hält (Attribut cmd=).
<OptionGroup name="auswahl" val="X" OnChange="geaendert">
<Option label="ja" cmd="J" />
<Option label="nein" cmd="N" />
<Option label="vielleicht" cmd="X" />
</OptionGroup>
Radio Buttons können nur einmal je Container gruppiert werden. Am
sinnvollsten werden sie innerhalb eines beschrifteten Rahmens untereinander
angeordnet.
Mit dem Attribut "cmd=
" kann der Wert gesetzt werden, den eine
Option - abweichend von ihrem Label - repräsentiert; diese Werte
müssen für einen Satz von Radio Buttons verschieden sein.
Mit val=true
wird eine Option präselektiert.
<Option label="[OptionTitle]" x= y= cmd=[ActionCommand]
val=true|false
/>
Ein Multilinetextfeld kann in beide Richtungen wachsen.
Mit dem Attribut "val="
kann der Komponente ein initialer Text
zugewiesen werden. Mit dem Trennzeichen "|
" können
Textabschnitte auf verschiedene Zeilen verteilt werden.
<Memo label="[LabelTitle]" x= y= w= h= wx= wy=
val="[InitialValue]"
/>
Implementierung eines einfachen Editors, der je nach Typ normalen Text, HTML oder RTF-Dokumente verarbeiten kann.
Mit dem Attribut "file="
kann dem Editor ein dem Typ entsprechendes
Dokument zur Verarbeitung vorgegeben werden.
<Editor typ=text_plain|text_html|text_rtf file=[URL]
/>
Ist so breit, wie sein Text Platz benötigt.
Es kann auch eine Grafik zugeordnet werden. Der LabelTitle kann dann auch leer gelassen werden. So können nach Lust und Laune Grafiken in der Oberfläche platziert werden.
Die Beschriftung eines Label kann auch in HTML erfolgen. Auf diese Art sind
mehrzeilige Labels möglich.
Beispiel: <Label label="<html>Erste Zeile<br>Zweite
Zeile</html>"
/>
Mit dem Attribut typ=STATUSBAR
kann ein Label zur Anzeige von
Statuszeilentexten veranlasst werden.
<Label label="[LabelTitle]" x= y= img="[IconFilename]" typ=
/>
Ist im Grundzustand so breit, wie sein Text Platz benötigt.
Ein Button kann einen Labeltext tragen, einen Icon (Attribut gif), oder beides.
Der Labeltext kann mit einem mnemonischen Buchstaben versehen werden. Dieser
Buchstabe kann durch ein vorangestelles "%" im Label gekennzeichnet werden
und ist dann im Layout unterstrichen: "%Speichern
" wird auf
dem Button als "Speichern" dargestellt.
Bei Buttons und Menüs kann ein Dateiname einer
Oberflächenspezifikation angegeben werden (Attribut file
),
um so einen einfachen Dialogablauf zu gestalten. Hierbei müssen die
Beschriftungen der Menüs und der Buttons eindeutig sein. Für den
(seltenen) Fall, dass die Bezeichungen zweier Objekte gleich sind, sie aber
verschiedenen Aktionen auslösen sollen, kann mit dem Schlüsselwort
cmd="[actionCommand]"
ein abweichendes Kennzeichen vergeben
werden.
<Button label="[ButtonTitle]" x= y= img="[IconFilename]"
file="[filename]" cmd="[actionCommand]"
/>
Hinweis:
Wird der Button mit "OK" beschriftet, wird er automatisch zum Default-Button
(das ist der Button, der über die Taste "Return" ausgelöst wird).
Dieses Verhalten kann auch erzielt werden, wenn das ActionCommand auf "OK"
gesetzt wird. Beispiel: Button "Weiter >>>" cmd=OK
Ein OK-Button muß mit "OK" beschriftet werden! Und nicht mit "Ok", "ok" oder gar "OK" usw. usf.
Ein Document sieht aus wie ein Button kann aber die Referenz auf einen Datenamen halten.
Wird der Button gedrückt, wird die mit dem Dokument verbundene Anwendung gestartet. Dem Document kann eine Dokument-Vorlage beigegeben werden, welche beim ersten Aufruf kopiert wird.
<Document label="Protokoll" typ="ProtokollVorlage.doc" />
Der Dateiname wird aus dem Label und einer eindeutigen Ziffer gebildet.
Der Benutzer muß das Dokument explizit speichern, darf aber kein SaveAs verwenden.
In welchem Directory die Dokumente gespeichert werden, ist in
guibuilder.properties
unter "Office=" abgelegt.
Tabellen wachsen in beide Richtungen. Sie ist ein Container von Spalten, d.h. daß eine Tabelle ein Begin- und End-Tag haben muß (siehe unten stehendes Beispiel).
Die Tabellen können als Spalten die Componenten Text, Date, Time, Money, Number, Combo, Check, Label und Hidden enthalten.
Wird die Tabelle auf "do=y"
gesetzt, können alle ihre Spalten
nicht geändert werden und werden gegraut dargestellt.
"do=y
" ist aber auch auf einzelne Spalten anwendbar.
Mit den Attributen "min"
und "max"
kann der Wert
für die minimale bzw. die maximale Spaltenbreite in Pixeln gesetzt werden.
Wird keiner dieser Attribute angegeben, nimmt die Spalte den verfügbaren
Platz ein.
Ist den Spalten bildenden Komponenten ein ToolTipText zugewiesen (Attribut
tt=
), so wird dieser im Spaltenkopf angezeigt.
Alle anderen Attribute, die sich auf das GridbagLayout beziehen, haben keine Wirkung.
Um Beispielzeilen einzufügen, verwenden wir das Shlüsselwort Row.
Pro Beispielzeile in der Tabelle wird eine Zeile mit Werten benötigt,
die der Menge der Spalten entspreicht. Der Wert einer Checkbox wird mit den
Schlüsselworten "true
" oder "false
" gesetzt.
<Row>Spalte0|Spalte1|Spalte2</Row>
Sollen Leerzeilen in die Tabelle eingefügt werden, ist der Wert auf
die gewünschte Anzahl zu setzen.
"<Row>4</Row>
" bewirkt z.B. vier Leerzeilen.
Wenn eine Tabellenzeile nicht editierbar sein soll, dann das Attribut
do="y"
setzen.
Der Inhalt einer Tabelle kann auch über das Attribut
val="[FileName]"
gesetzt werden; hier wird eine Textdatei erwartet,
in der zeilenweise die Spalten mit "|
" getrennt eingegeben wurden.
Es müssen in jeder Zeile gemäß der Tabellendefinition die
entsprechende Anzahl Spalten aufgeführt sein.
Alternativ können bei Tabellen auch Spalten mit definierten Werten
gefüllt werden:
<Column
val="0">Zeile0|Zeile1|Zeile2</Column>
Hierbei ist die Spalte im Attribut val=
(beginnend mit "0")
anzugeben, sowie die Liste der Werte mit "|
" getrennt.
Es werden automatisch so viele Zeilen erzeugt, wie Werte je Spalte angegeben
werden.
Der Tabelle kann ein Popup Menü zugewiesen werden; ein solches lässt sich z.B. verwenden, um eine Zeile in die Tabelle einzufügen oder aus ihr zu löschen (siehe unten stehendes Beispiel).
Der Tabelle kann mit dem Attribut "file="
ein Folgedialog beigegeben
werden, der beim DoppelKlick auf die Tabelle oder über die eingebaute
Methode "EditRow()"
aufgerufen wird.
Die Spalten einer Tabelle können mit einer auf die Tabelle folgende
Komponente verknüpft werden (siehe Attribut "linkCol=#"
.
Wird diese Komponente editiert, wird der mit ihr verbundenen Spalte ihr Wert
zugewiesen. Umgekehrt, wird den verknüpften Komponenten der Wert aus
der Tabelle zugewiesen, wenn eine andere Zeile selektiert wird.
Beispiel: tutorial/LinkTable.xml
<Table file=[EditDialog] >
>
<Text label="[ColumnTitle]" min=[MinColumnWidth]
max=[MaxColumnWidth] />
<Date />
<Time />
<Money />
<Number />
<Check />
<Combo Items="[ItemList]" file= />
...
<Row>[ItemList]</Row>
<Row>10</Row>
<Column val="3">[ItemList]</Column>
...
<Popup>
<Item label="Zeile einfügen" file="InsertRow()"
/>
<Item label="Zeile löschen" file="DeleteRow()"
/>
<Item label="Zeile bearbeiten" file="EditRow()"
/>
...
</Popup>
</Table
Es kann eine Tree-Komponente mit beliebig tief geschachtelten Ordnern sowie Einträgen in diesen Ordnern gestaltet werden. Jedem Eintrag wird ein bezeichnender Text beigegeben.
<Tree label="[RootTitle]" file="[filename]"
img="[iconfile]">
>
<Folder label="[FolderTitle]" file="[filename]"
img="[iconfile]">
<Node label="[NodeTitle]" file="[filename]"
img="[iconfile]" />
...
</Folder>
...
</Tree
Das Attribut do="true"
sorgt dafür, daß die
Einträge nicht editiert werden können.
Mit dem Attribut img="myIcon.gif"
können die Knoten auch
einzeln mit einer gesonderten Grafik versehen werden.
Eine spezielle Technik der Dialog-Gestaltung besteht darin, eine Tree-Komponente quasi als Menü einzusetzen, das aber keine Folgedialoge aufruft, sondern ein bestimmtes Panel jeweils austauscht.
file="[filename]"
jeweils entsprechende
Spezifikationsfiles zugeordnet. Wird nun auf diese Nodes geklickt, wird das
rechte Panel mit den im Spezifikationsfile definierten Komponenten versehen.
Soll der Inhalt bestimmter Felder des rechten Panels im Titel des selektierten
Nodes erscheinen, sind diese Felder mit dem Attribut
nodeTitle=[index]
zu versehen. Der Index kann von 0 bis 4 laufen.
Mit den eingebauten Methoden NewNode(), CopyNode(), CutNode()
und PasteNode()
kann der Inhalt der Tree-Komponente verändert
werden.
Dem Baum selbst und den Foldern oder Nodes können eine Liste von Spezifikationsfiles mitgegeben werden, aus der der Anwender beim Erstellen eines neuen Knoten wählen kann (siehe Attribut "Items").
Unter Windows ist es möglich, Dateien aus dem Explorer per Drag-Drop in den Baum mit aufzunehmen.
Hierzu muß in guibuilder.properties
der Eintrag
DocumentElement
definiert sein. DocumentElement bezeichnet ein
TreeElement (siehe Schlüsselwort "<Element ...>") welches als
KnotenTyp für den neu anzulegenden Knoten vorgesehen ist.
Dem Element muß auch ein Panel zugeordnet sein, welches über folgende Feldnamen verfügt:
Siehe Beispiel unter lib/tutorial/buero
.
Dies ist ein sog. Schieberegler. Per Default wird er horizontal angeordnet;
mit typ=VERTICAL
kann dieses auch senkrecht geschehen.
Es kann ein Minimal- und ein Maximalwert eingestellt werden.
<Slider label="[LabelTitle]" x= y= w= wx= tt= typ= min= max=
/>
Erzeugt einen Scrollbalken. Per Default wird die Komponente vertikal angeordnet;
mit typ=HORIZONTAL
kann vertikale Anordnung gewählt werden.
<Scrollbar x= y= h= wy= tt= typ=HORIZONTAL|VERTICAL
/>
Eine Menüzeile kann nur in einem Formular (Form), also nicht in Dialogen dargestellt werden.
Die Menüs werden im Formular in der angegebenen Reihenfolge angezeigt.
Ein Menü wird mit der Zeile "<Menubar>
" eingeleitet.
Jede Zeile
<Menu label="[MenuTitle]"
>
erzeugt dann einen Hauptmenü-Eintrag, dem dann zeilenweise - wie unten im Beispiel vorgeführt - mit
<Item label="[MenuItemTitle]"
/>
seine Menü-Einträge zugeordnet werden.
Menüs können auch in Untermenüs können geschachtelt werden.
Menüs können mit einem mnemonischen Buchstaben versehen werden.
Der angegebene Buchstabe muss im Labeltext des Menu-Items enthalten sein.
Dieser Buchstabe kann durch ein vorangestelles "%" im Label gekennzeichnet
werden: "%Datei
".
Außerdem kann ein Keyboard Shortcurt (Accelerator) angegeben werden.
Er ist im Format Fx, Ctrl+x, Alt+x, Shift+Fx einzugeben.
Menüs und Menü-Einträge können mit einem Icon versehen
werden (Attribut img=
).
Die Menüeinträge können durch den Separator gruppiert werden.
Über die Schlüsselworte ItemCheck
und
ItemOption
können Menüeinträge auch als CheckBox
oder RadioButten definiert werden.
Hierbei kann zusätzlich mit dem Attribut val="true"|"false"
festgelegt werden, ob der Eintrag selektiert ist oder nicht.
Diese beiden Komponenten können nicht direkt der Menüzeile zugeordnet
werden.
Jedes Menü kann nur eine einzige Gruppe von RadioButtons enthalten.
Einem Menü-Eintrag kann der Dateiname einer Oberflächenspezifikation
(eines GDL-Skripts) zugeordnet werden. Dann wird bei Anwahl des
Menü-Eintrags das entsprechende Skript gestartet. So können wir
einen einfachen Dialogablauf gestalten. Hierbei müssen die Beschriftungen
der Menü-Einträge eindeutig sein. Für den (seltenen) Fall,
dass die Bezeichnungen zweier Objekte gleich sind, sie aber verschiedenen
Aktionen auslösen sollen, kann mit dem Schlüsselwort
cmd="[actionCommand]"
ein abweichendes Kennzeichen vergeben
werden.
<Menubar label="[MenubarTitle]">
>
<Menu label="[MenuTitle]" img="[IconFileName]">
<Item label="[ItemLabel]" acc=[accelerator] img=
file="[filename]" cmd="[actionCommand]" />
<Separator/>
<ItemCheck label="[ItemLabel]" acc=[accelerator]
val=true|false img= cmd="[actionCommand]" />
<ItemOption label="[ItemLabel]" acc=[accelerator]
val=true|false img= cmd="[actionCommand]" />
...
</Menu>
...
</Menubar
Ein Popup Menu (Kontextmenü) wird dargestellt, wenn der Anwender die
Komponente, der das Popup Menu zugeordnet ist, mit der rechten Maustaste
anklickt. Sie sind z.Z. nur für die Komponenten-Typen Tree, Table, Memo
und List realisiert. Einem Popup Menu kann - wie gewöhnlichen
Menüs - Menü-Einträge und Untermenüs zugewiesen werden.
Das Label von Popupmenüs wird nur angezeigt, wenn auf der
GuiBuilder-Bedienoberfläche Motif als UI-Manager eingestellt wird.
<Table>
>
<Text ...
...
<Row ...
...
<Popup label="Tabelle">
<Item label="Zeile &einfügen" file=InsertRow()
/>
<Item label="Zeile &löschen" file=DeleteRow()
/>
</Popup>
</Table
Es kann eine Toolbar mit einer Liste von Werkzeugen spezifiziert werden.
Die einzelnen Toolbuttons können neben einem Label mit einer Grafik
und Tooltip-Text versehen werden. Der Aufruf einer weiteren Spezifikationsdatei
mit dem Attribut file
funktioniert wie bei den Menüs und
Buttons. Beachten Sie, daß wenn die Toolbuttons keine Bezeichnung tragen,
sie für den Dialogaufruf mit verschiedenen ActionCommands versehen werden
müssen.
Die einzelnen Buttons können durch einen Separator gruppiert werden.
Durch das Setzen des Attributes tabstop=n
wird erreicht, dass
die Toolbar nicht mit den Tasten <Tab> oder <Shift+Tab> erreichbar
ist.
Mit typ=FLOAT
erhalten wir eine Toolbar, die verschiebbar ist.
<Toolbar tabstop="n" typ="FLOAT">
>
<Button label="[ItemLabel]" img="[IconFilename]"
file="[filename]" cmd="[actionCommand]" />
<TButton label="Bold" OnChange="[actionCommand]" />
<Separator/>
...
</Toolbar
Für Statusinfomationen, die der Benutzer nicht sehen muß/darf, kann dieses "versteckte" Feld eingesetzt werden. Es kann auch unsichtbare Spalte in Tabellen bilden.
<Hidden name="adressId" val="4711" />
Die folgenden beiden Komponenten sind dazu da, um leere Zellen im GridBagLayout anzulegen.
Horizontaler Füllstoff wird dann gebraucht, wenn eine Nachbarkomponente schmaler werden soll.
<xFiller x= y= w= wx=
/>
Vertikaler Füllstoff dient vor allem zum Auffüllen eines Containers, wenn in ihm sonst keine Komponente enthalten ist, die vertikal wächst.
<yFiller x= y= w= h= wx= wy=
/>