|
zurück zur Homepage
MiniPanelMaker
Download von MiniPanelMaker
MiniPanelMaker ist ein weiteres SNH-Programm ("sleepless-night-hack"), das dem Java-Swing-Programmierer helfen soll, in
möglichst kurzer Zeit Oberflächen einfacherer Natur zu entwickeln. Das Programm ist selbst ebenfalls in Java
entwickelt und als Standalone-JAR-Applikation verfügbar.
Wichtige Hinweise
Wie für jedes andere meiner Programme gilt auch für dieses: Die Nutzung erfolgt auf eigene Gefahr, ich hafte
in keinster Weise für direkten oder indirekten durch dieses Programm erfolgten Schaden! Dennoch verbürge ich mich
dafür, dass das Programm keinen absichtlich schadhaften Code enthält. Da das Programm jedoch innerhalb kurzer
Zeit und ohne ausreichende Test-Phase entwickelt wurde, kann es durchaus noch etliche Fehler aufweisen. Für Hinweise
hierauf bin ich wie immer dankbar!
Das Programm ist OpenSource und Freeware, außerdem komplett in Java geschrieben. Der Quelltext liegt in der JAR-Datei
zusammen mit dem ausführbaren Programm. Wer das Programm nutzen möchte, muss also Java installiert haben. Wer
sich den Quelltext anschauen möchte, kann die JAR-Datei entpacken. Der Quelltext liegt zwar offen, gehört jedoch
mir. Wer ihn für eigene Zwecke nutzen und/oder verändern möchte, der möge bitte meine Erlaubnis
einholen. Ich erteile sie gerne, möchte jedoch vorher gerne wissen, wer den Code zu welchem Zweck verwendet. Für
die Nutzung des Programmes ist keine eigene Erlaubnis erforderlich, auch darf es beliebig weiter gegeben werden.
Entwickelt wurde das Programm unter WindowsXP, es sollte jedoch auch unter anderen Betriebssystemen laufen. Über
entsprechende Hinweise wäre ich dankbar!
Intention
Relativ häufig stehe ich vor dem Problem, dass ich ein winziges Programm "mal eben" schreiben möchte, um
eine wie auch immer gearteten Aufgabe zu lösen. Häufig benötige ich ein solches Programm auch wirklich nur
ein Mal, manchmal jedoch entstehen hierdurch Programme, die es Wert sind, häufiger genutzt zu werden. Meist starte ich
solche Programme jedoch direkt aus der Entwicklungsumgebung heraus und gebe alle Parameter "fest verdrahtet" mit,
so dass eine weitere Nutzung schwer fällt. Da dies fast immer schlicht daran liegt, dass ich einem solchen Moment zu
faul bin, eine GUI zu entwickeln, ist die Wahrscheinlichkeit sehr hoch, dass diese Programme dennoch in der Versenkung
(auf einem ungenutzten Teil der Festplatte) verschwinden.
Natürlich wäre ein GUI-Designer genau das richtige, doch diese Programme sind häufig überladen.
Schließlich benötige ich in der Regel nur eine Hand voll Komponenten, ein paar Listener und alles wäre in
bester Ordnung.
Aus diesem Grund schrieb ich den MiniPanelMaker, wobei die Betonung tatsächlich auf Mini liegen muss. Diese
Programm bietet die Möglichkeit, einfache Oberflächen in wirklich kurzer (!) Zeit zu entwickeln und eventuelle
vorher erzeugte Programmlogik (also den eigentlichen Kern des gerade geschriebenen Programmes) darin einzubinden.
Funktionsweise
Die Vorgehensweise ist denkbar einfach: Man beschreibt die gewünschte Oberfläche in einer Textform ("GUI-Text"),
lässt sich das ganze anzeigen, bessert es aus und korrigiert so lange, bis es der gewünschten Oberfläche entspricht.
Anschließend kann man sich die erzeugte Klasse (die als Datei erzeugt wurde) nehmen und anpassen.
Der folgende Screenshot zeigt die Programmoberfläche. Man gibt einen Methoden- und einen Klassennamen an, wobei
der Sourcecode automatisch in die Datei "[klassenname].java" geschrieben wird.

Erstes Beispiel
Im Folgenden zeige ich ein kurzes Beispiel für eine generierte Oberfläche. Zunächst wird der GUI-Text angedruckt,
anschließend der dazugehörige Screenshot und schließlich der hierdurch erzeugte Quellcode.
Klasse: Beispielklasse1
Methode: beispiel1
panel.border {
center:
button<beenden>("Exit")
north:
label("Drücke den Button zum Beenden des Programmes")
}

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import javax.swing.event.*;
/**
* MPM-Original-Source:
*
* panel.border {
* center:
* button<beenden>("Exit")
* north:
* label("Drücke den Button zum Beenden des Programmes")
* }
*
* @author MiniPanelMaker, (w) by Christian Packenius.
*/
public class Beispielklasse1 {
/**
* Start- und Testmethode.
* @param argv Ungenutzte Kommandozeilenparameter.
*/
public static void main(String[] argv) {
new Beispielklasse1();
}
/**
* Konstruktor.
*/
public Beispielklasse1() {
JFrame frame = new JFrame("Test-Klasse, (w) by MiniPanelMaker");
frame.setSize(300, 200);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(beispiel1(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* Erzeugen des Panels und aller darin liegenden Komponenten.
* @return JPanel-Objekt mit allen Komponenten.
*/
public JPanel beispiel1() {
// Button.
JButton beenden = new JButton();
beenden.setText("Exit");
beenden.addActionListener(new BeendenActionListener());
// Label mit vorgegebenem Text "Drücke den Button zum Beenden des Programmes".
JLabel label2 = new JLabel("Drücke den Button zum Beenden des Programmes");
// Panel mit BorderLayout.
JPanel panel1 = new JPanel();
panel1.setLayout(new BorderLayout());
panel1.add(beenden, BorderLayout.CENTER);
panel1.add(label2, BorderLayout.NORTH);
return panel1;
}
}
/**
* ActionListener für "beenden".
*/
class BeendenActionListener implements ActionListener {
/**
* Der Benutzer hat eine Aktion ausgelöst.
* @param e Der Event zur Aktion.
*/
public void actionPerformed(ActionEvent e) {
// TODO - Noch Event bearbeiten.
}
}
|
Das schaut ja erstmal ganz ordentlich aus, fast wie ein richtiger Sourcecode-Generator. Um aber auf dem Teppich
zu bleiben: Das Programm eignet sich tatsächlich nur für wirklich kleine und sehr einfache Oberflächen.
Es werden bisher die folgenden Swing-Komponenten unterstützt:
- JPanel ("panel")
- JSplitPane ("split")
- JButton ("button")
- JLabel ("label")
- JTextField ("text")
- JTextArea ("textarea")
- JPasswordField ("password")
- JCheckBox ("check")
- JList ("list")
- JComboBox ("combo")
- JSlider ("slider")
- JTree ("tree")
Diese können größtenteils auch schon mit Inhalten gefüllt werden. Die JPanel-Objekte können mit den folgenden
LayoutManagern vorbelegt und gefüllt werden, wobei jedoch nicht alle Funktionalitäten unterstützt werden:
- BorderLayout ("border", Default)
- FlowLayout ("flow")
- GridBagLayout ("gridbag")
Für die meisten kleinen Oberflächen reicht dies vollkommen aus.
Zwischendurch wie immer mein Hinweis: Sollte jemand etwas vermissen, kann ich auf Anfrage gerne weitere
Komponenten und/oder LayoutManager einbinden und unterstützen. Fragen kostet nichts!
Doch zurück zum Beispiel, das ich nun kurz erläutern möchte, um die Arbeitsweise des Programmes klar zu
machen:
panel.border {
center:
button<beenden>("Exit")
north:
label("Drücke den Button zum Beenden des Programmes")
}
Zunächst einmal wurde hier mit dem obigen GUI-Text ein panel erzeugt, dessen Inhalte mit Hilfe des
BorderLayouts angezeigt werden sollen. In der Mitte des Panels (center:) wird ein einzelner
button dargestellt, auf dem der Text Exit angezeigt wird und der im Sourcecode den (Variablen-) Namen
beenden erhalten soll. Oben im Panel (north:) wird ein einzelnes label angezeigt, das den
Text Drücke den Button zum Beenden des Programmes darstellen soll.
Dieses Beispiel soll vor allem verdeutlichen, wie man sich mit sehr wenig Aufwand (der im Eintippen des obigen
kurzes GUI-Textes besteht) das Tippen von einer Menge Sourcecode (siehe obiger Quelltext) ersparen kann.
LayoutManager
Das Programm interpretiert den vorgegebenen GUI-Text (der, um mal ein Buzz-Wort zu verwenden, natürlich in einer
eigenen DSL geschrieben wird), indem er eine einzelne Swing-Komponente erzeugt. Das liest sich jetzt seltsam, aber
um es klarer zu sagen: Alles, was sich "hinter" der ersten Swing-Komponente im GUI-Text befindet, wird
ignoriert! Einfach mal versuchen: Den obigen Text (beginnend mit panel.border [...]) kopieren und
irgend etwas Beliebiges dahinter schreiben. Dies wird nicht beachtet. "Aber da steht doch mehr als nur das Panel,
oder?..." - Ja! Aber alles andere ist dem Panel untergeordnet und gehört daher dazu.
Wie man sieht, kann man hinter einem Panel getrennt mit einem Punkt direkt das Layout angeben. Hier steht
.border, das für das BorderLayout steht. Da dies bei allen Paneln immer vorgegeben ist, kann man es auch
weg lassen.
Bei Paneln, also auch bei JSplitPane ("split"), werden die weiteren Inhalte in geschweiften Klammern
angegeben. Dass bei obigem Beispiel nach der geschweiften Klammer-Auf ein Zeilenwechsel erfolgt, dient nur der
Optik. Zeilenwechsel, Tabulatoren und Spaces werden als WhiteSpace-Zeichen interpretiert und somit ignoriert.
Je nach Layout wird das Innere eines Panels verschieden interpretiert. Beim BorderLayout werden Einzelangaben zur
Richtung ("north", "south", "east", "west" und/oder "center")
gefolgt von einer einzelnen Komponente angegeben. Wie zu sehen ist, müssen nicht alle Richtungen angegeben werden,
außerdem ist die Reihenfolge der Richtungsangaben beliebig.
Beim GridBagLayout muss man hinter dem Layoutnamen in runden Klammern angeben, wie viele Felder das Layout enthalten
soll (beispielsweise erzeugt panel.gridbag(2*1) zwei Spalten und eine Zeile) und gibt dann einfach in den
geschweiften Klammern alle im GridBag liegenden Komponenten an. Bei diesen kann man dann auch noch zusätzlich
angeben, wie viele Felder des GridBags sie verwenden sollen: 3:button erzeugt einen drei Felder breiten
Button, bei 3*2:button ist der Button sechs Felder groß (drei Felder breit und zwei Felder hoch).
Beim FlowLayout ("flow") kann man in runden Klammern angeben, wie die Komponenten ausgerichtet werden
sollen ("left", "right" oder "center") und schreibt in die geschweiften Klammern dann
nur noch die Komponenten. Beispiel: panel.flow(center){label text button}
Referenz
Hier noch eine kurze Auflistung aller vom Programm unterstützten GUI-Elemente und ihrer Attribute; die kursiven
Einträge müssen mit entsprechendem Inhalt gefüllt werden, eckige Klammern stehen für wahlfreie Attribute:
panel[.border] { [center : component_1] [north : component_2] [south : component_3] [east : component_4] [west : component_5] }
panel.flow [(left | center | right)] { [component_1 component_2 [...]] }
panel.gridbag (width * height) { [[width[*height] : ] component_1 [width[*height] : ] component_2 [...]] }
split [(horizontal | vertical)] { component_1 component_2 }
label [("text")]
check [("text")]
list [("text1" "text2" [...])]
combo [("text1" "text2" [...])]
button [("text")]
text [(["text"] [columns])]
password [(["text"] [columns])]
textarea [(["text"] [columns])]
slider [(minimum - maximum [: startValue])]
tree [(root (sub-node-1 (sub-node-1-a sub-node-1-b [...]) sub-node-2 [...]))]
Namen und Listener
Im obigen Beispiel kann man recht gut sehen, wie im erzeugten Quellcode Variablennamen vergeben werden:
Der Button wurde von uns durch die Angabe von <beenden> schon direkt mit einem Namen versehen. Im
Gegensatz dazu erhielten das Label und das Panel automatisch erzeugte Namen, an denen man den Typ der
Komponente erkennen kann und der weiterhin eine laufende Nummer erhielt.
Weiterhin werden auch Listener erzeugt. Diese werden als benannte Klasse eingerichtet, so dass man sie auf
Wunsch auch einfach auslagern kann. Allerdings erhalten nicht automatisch alle Komponenten auch Listener.
Nur für solche Komponenten, bei denen der Name explizit angegeben wurde und bei denen es auch sinnvoll ist,
erhalten auch entsprechende Listener. Diese werden direkt per addXYZListener() registriert und die
entsprechende Klasse eingerichtet.
Man kann also allen Komponenten durch spitze Klammern hintern der Typangabe Namen geben, es werden
jedoch nur für folgende Komponenten dann auch die angegebenen Listener eingerichtet:
ActionListener (JButton, JCheckBox, JComboBox)
DocumentListener (JTextField, JTextArea, JPasswordField)
ListSelectionListener (JList)
ChangeListener (JSlider)
TreeSelectionListener (JTree)
Weitere Besonderheiten
Strings werden wie in den meisten Sprachen in doppelten Anführungsstrichen angegeben. Allerdings gibt es hier
keine Escape-Zeichen. Man kann also weder Zeilenwechsel noch doppelte Anführungsstriche in Strings einfügen.
Es gibt zwei Methoden, Bemerkungen in GUI-Text einzufügen: Einmal kann man hinter dem eigentlichen GUI-Text
beliebigen Text einfügen, der vom Generator ignoriert wird. Außerdem kann man zu Beginn einer Zeile das Zeichen
# schreiben; diese Zeile wird dann ebenfalls ignoriert.
Weitere Beispiele
Im Folgenden stehen noch ein paar Beispiele mit Screenshot und GUI-Text, allen voran der GUI-Text zum
MiniPanelMaker selbst.
 | panel.border {
center: textarea
north: panel.border {
center: panel.gridbag(1*2) {text text}
west: panel.gridbag(1*2) {label("Klasse: ") label("Methode: ")}
}
south:
label
}
|
 | panel.border {
north:
label("Beispiel für FlowLayout")
center:
panel.flow(center) {
button("abc") button("def") button("ghi")
button("jkl") button("mno") button("pqr")
button("stu") combo("a" "b" "c" "d" "e" "f")
}
} |
 | panel {
north: label("north")
south: label("south")
east: label("east")
west: label("west")
center: label("center")
} |
 | panel {
north: button("north")
south: button("south")
east: button("east")
west: button("west")
center: button("center")
} |
 | panel {
west:
tree("root"
("eins"
"zwei" ("mitte-1")
"drei"))
center:
textarea("In der Mitte...")
} |
 | panel.gridbag(2*1) {
split {
label("links")
button("rechts")
}
split (vertical) {
label("oben")
button("unten")
}
} |
 | panel.gridbag(4*4) {
1*4:button("links") 2:button("unten") 1*4:button("rechts")
2*2:button("Mittelteil")
2:button("oben")
} |
Abspann
Nochmals der Hinweis: Sollte es Probleme oder Änderungswünsche geben, bin ich für alles offen und
helfe gerne, insofern es meine Zeit zulässt!
|