Inhalt:
2. Was benötigt man? 3. Installation und Starten des Programms 4. Benutzung der Software 5. Lösungsalgorithmen Zugegeben, der Name ist gewöhnungsbeürftig, die Software jedoch nicht. Ich entwickelte diese kleine Applikation, weil ich eine kompfortable Lösung suchte, um einen JavaScript-Baum-Menü zu erstellen. Wie im nächsten Kapitel zu lesen ist, kann man sich all die Sourcen von dem TreeMenu aus dem Netz ziehen. Sie sind Open Source. Genau wie meine Anwendung auch. Zieht man jedoch nur die Sourcen, ist es etwas mühselig, von Hand die ganzen Menüdaten einzutragen, da sich oft auch Fehler einschleichen können, die zur Fehlfunktion des Baummenüs führen. Die Anwendung hier, stellt somit eine grafische Ergänzung dar, welche es ermöglicht, schnell an sein eigenes schönes Baummenü zu erstellen. Hier ein paar Bilder von meiner Anwendung:
zurück
Zunächst die Quellen im Downloadbereich.
Ist dies erledigt, kommt es nur darauf an, unter
welchem Betriebssystem man es kompilieren und ausführen möchte. Getestet habe ich es sowohl
unter Linux als auch unter Windows. Je nachdem werden die Java-Runtime, bzw. die Java SDK (hier 1.3.1 oder
höher) benötigt. Unter dem folgenden Link: können Sie bezogen werden. Danach müssen Sie sich die JavaScript-Baummenü-Quellen von: Vielen Dank auch für seine Entwicklungsarbeit. Ist dies erledigt kann man mit dem nächsten Kapitel fortfahren. zurück 3. Installation und Starten des Programms
Allgemein: Achten Sie auf Gross und Kleinschreibung! zurück Die Benutzung ist dank MVC Steuerung recht komfortabel und einfach. Folgende Tabelle gibt Ihnen ein Überblick über die wichtigsten Funktionen:
zurück Zum Quelltext allgemein: Der vollständige Quelltext ist im tar.gz-File enthalten und kann frei kopiert und verändert werden. Ich möchte nur kurz auf meine Programmlösung eingehen, so daß im Falle einer Modifikation der ursprüngliche Gedankengang für mich nachvollziehbar bleibt. Wenn Sie eine bessere Lösung entwickeln sollten, und meine als Vorlage nehmen, so würde ich gerne (ist kein Muß) eine Version zugeschickt bekommen, denn wie gewöhnlich, kann man nie auslernen, und erst recht nicht in der Programmierwelt. Es lebe Open Source. Nun zum Quelltext. 5.1. Baumerstellung (Quelltextauszug) Der Kommentierte Quelltext:
Baum2Liste.clear(); Enumeration enum; for (enum = top.preorderEnumeration() ; enum.hasMoreElements() ;) {
System.out.println(Element.returnLinkName()); if (Baum2Liste.add(Element)) System.out.println("Element eingefügt"); else System.out.println("Element nicht eingefügt"); catch (java.lang.NullPointerException e) {
System.out.println("Gebe Baum als JavaScript aus:\n"); ListIterator iter = Baum2Liste.listIterator(); char c='"'; // Fuer die JavaScript Funktionen int tiefe=0; // Fuer den Tiefenvergleich JSStringList.add("var menu = null;"); // Initialer Zustand JSStringList.add("var menu = new MTMenu();"); for (;iter.hasNext();) {
if (Element.getParent().toString().compareTo("Navigationsbaum")==0) { // Ist das der Fall handelt es sich um die Root-Elemente if (Element.returnLinkName().compareTo("*")!=0) {
if (Element.isLeaf()) { // Ist es ein Blatt oder ein Knoten ?
else {
JSStringList.add(line); tiefe = Element.returnTiefe(); else {
String newLine = "var "+Hilfe.returnLinkName()+" = null;"; JSStringList.add(newLine); newLine = Hilfe.returnLinkName()+" = new MTMenu();"; JSStringList.add(newLine); String line = Element.getParent().toString(); while (line.compareTo(Element.getParent().toString())==0) {
String newLine = ""; Item Hilfe = (Item) Element.getParent(); if (Element.isLeaf()) { // Ist es ein Blatt oder ein Knoten ?
Hilfe.returnLinkName()+".addItem( new MTMenuItem( "+c+ Element.toString()+c+", "+c+Element.returnLink()+c+", "+c+"text"+c+" ));"; JSStringList.add(newLine); else {
Hilfe.returnLinkName()+".addItem( new MTMenuItem( "+c+ Element.toString()+c+" ));"; JSStringList.add(newLine); tiefe = Element.returnTiefe(); Element = (Item) iter.next(); // Unterschieden werden muss jetzt, ob das Element tiefer oder nicht tiefer liegt // Vergleich der Tiefen Item Hilfe = (Item) iter.previous(); // Diese Stelle scheint ungenau zu sein if (tiefe>Element.returnTiefe()) {
String newLine =""; if (Element.getParent().toString().compareTo("Navigationsbaum")==0)
// fixes the problem with some links like C/C++ on 03.04.2002 newLine = newLine+".makeLastSubmenu( "+isValid(line)+" );"; JSStringList.add(newLine); catch (java.lang.NullPointerException e) {
5.2 Speichern/Laden des Baumes Diese Persistenzhaltung, die die Swing-Klassen mitbringen, genauer gesagt, die Serialisierbarkeit der einzelnen Java-Klassen ist wirklich erwähnenswert. Man muß sich keine Gedanken machen, wie beispielsweise bei der QT-Bibliothek für C++ unter Linux/Windows und einen eigenen Datei stil erfinden, sonder kann auf die schnelle Abspeicherung der Java-Klassen zurückgreifen. Zunächst wieder zum Quelltext. Hier sind die speziellen Stellen in meinem Source-Code:
try {
JFileChooser fchoose = new JFileChooser(); int returnVal = fchoose.showSaveDialog(null); if (returnVal==JFileChooser.APPROVE_OPTION) {
ObjectOutputStream JTreeStream = new ObjectOutputStream(ostream); JTreeStream.writeObject(top); JTreeStream.flush(); ostream.close(); catch (java.io.FileNotFoundException e) {
catch (java.io.IOException e) {
if (pressed==Laden) {
try {
JFileChooser fchoose = new JFileChooser(); int returnVal = fchoose.showOpenDialog(null); if (returnVal==JFileChooser.APPROVE_OPTION) {
ObjectInputStream JTreeStream = new ObjectInputStream(istream); Item root = (Item) JTreeStream.readObject(); istream.close(); System.out.println(Navigator.isRootVisible()); Item LoadedItem = (Item) root.getFirstChild(); for (int i=0;i!=root.getChildCount()+2;i++) {
LoadedItem = (Item) root.getNextNode(); DefaultMutableTreeNode Last = new DefaultMutableTreeNode ("*"); top.add(Last); Navigator.updateUI(); catch (java.io.IOException e) {
catch (java.lang.ClassNotFoundException e) {
Alles soweit leicht nachvollziehbar. Schwerpunkt sind hier die writeObject und readObject- Methoden. Wichtig ist nur, wie auch hier im Beispiel zu sehen, daß, eigene Object-Instanzen, wie Item, welches von DefaulMutableTreeNode erbt, auch über eine writeObject und readObject-Methode verfügt. Diese sehen hier wie folgt aus:
throws IOException {
out.writeObject(link); out.writeInt(Tiefe); private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
link = (String) in.readObject(); Tiefe = in.readInt();
Man fügt lediglich die eigenen Variablen mit ein, damit sie ebenfalls abgespeichert werden
können. Die Klasse selbst wurde wie folgt deklariert: |