# Gantt Diagramm mit Swing - Designfragen



## meister-g (20. Feb 2007)

Hallo Java-Gemeinde,

ich plane ausgehend von einem existierendem Projektbaum ein Gantt-Diagramm zu erstellen.
In den Baumobjekten sind alle Daten dazu gespeichert.
Ziel ist es eben nun rechts auf einer Zeitachse die entsprechenden Daten mit Balken zu visualisieren (+ später evtl. manipulieren zu können).

Kann mir hier jemand Designtipps geben?
Gäbe es z.B. die Möglichkeit den Baum links zu "kopieren" (wg Listener usw aber eben irgendwie doch das gleiche Objekt) und den Renderer gewaltig umzuschreiben?

Oder wäre eben ein extremer Renderer, der eben das koplette Gantt-Diagramm (Baum und Balken rechts daneben) zeichnet eine Möglichkeit?

Oder kann man eine JTable so gestalten, dass sie sich von den Zellenabmessungen genau an den Baum hält und je nach Baumzustand Zeilen ausblendet? Wenn ja wie?

Wenn nicht über einen Tree oder Renderer gelöst, was könnte sonst noch eine elegante Lösung sein? Einen Balken in einer Zeitachse zu zeichnen sollte ja nicht das Problem sein - aber eben dass er genau auf der höhe des zugehörigen Blattes im Baum links erscheint - und das eben nur alle geöffneten Äste/Blätter rechts erscheinen...

Wäre toll von Eurer Erfahrung mit Ähnlichem oder einfach nur Kreatives zu hören.



Rainer


----------



## AlArenal (20. Feb 2007)

Stichwort: MVC

Überleg dir in Ruhe welche Daten ein Gantt-Diagramm benötigt und leite daraus ein allgemeingültiges GanttModel ab. Schreib dir einen Dummy-GanttView, basierend z.B. auf JComponent und verbinde Model und View mit einem GanttModelChangedListener, der GanttModelChangedEvents transportiert, welche benötigte Informatioen enthält. Wenn du verstehst wie die entsprechenden Pendants für JTRee oder JTable aufgebaut sind und funktionieren, ist das im Grunde nur noch eine Fleißarbeit.

Dann überlegst du dir in Ruhe wie du den View Daten anzeigen lässt. Analog zu den oben genannten Komponenten kannst du auch dafür sorgen, dass du den View mit Renderern ausstatten kannst. 

Verzettel dich nicht zu früh indem du zuviel gleichzeitig machen willst. Mache einen logischen Schritt nach dem anderen und erweitere sukzessive. Nur so kannst du auch vernünftig testen.

Um das Ganze evtl. später einmal interaktiv zu gestalten, würdest du z.B. den View auf Maus und Tatstur mit einem GanttViewChangedEvent reagieren lassen. Einen Listener würdest du dann entsprechende Manipulationen im Model tätigen lassen, um einen Eintrag zu verschieben, oder zurückzuweisen (Controller).


----------



## meister-g (21. Feb 2007)

Vielen Dank für die ersten Gedanken,

Aber hier stehe ich irgendwie total auf der Leitung.

Klar will ich mit den Basics einsteigen... ein GanttView basierend auf JComponent (dh einfach eine Balkenanzeige) ist ja kein Problem.
Wozu hier aber die Listener? Für den Fall dass sich der Prozess verändert? Das ist erst einmal vernachlässigbar denke ich. Oder meinst Du das anders?
Mein Problem wäre - auf welcher höhe zeichne ich diese JComponent? Wie funktioniert die Verbindung zu dem entsrpehenden Objekt im linken Baum?

Ich kapiere in dem Fall schon leider das MVC nicht ganz. Denn der Tree links ist ja schon Model und View in einem, richtig?!

Ich habe schon einige Erfahrung in der Java Entwickllunf und selbst schon öfters MVC implementiert... aber hier hakt es irgendwie. Hängt auch damit zusammen dass ich ausgerechnet mit JTables und JTrees nicht ganz firm bin.


----------



## AlArenal (21. Feb 2007)

Eins nach dem anderen 



			
				meister-g hat gesagt.:
			
		

> Klar will ich mit den Basics einsteigen... ein GanttView basierend auf JComponent (dh einfach eine Balkenanzeige) ist ja kein Problem.



Gut.



> Wozu hier aber die Listener? Für den Fall dass sich der Prozess verändert? Das ist erst einmal vernachlässigbar denke ich. Oder meinst Du das anders?



Erstmal vielleicht. Über kurz oder lang kommst du aber nicht daran vorbei. Du willst schließlich nicht bei jeder beliebigen Änderung das Model komplett neu aufbauen?



> Mein Problem wäre - auf welcher höhe zeichne ich diese JComponent?



Was für ne "Höhe"???



> Wie funktioniert die Verbindung zu dem entsrpehenden Objekt im linken Baum?



Auf der Datenebene über das GanttModel, welches auf dieselben Daten zugreift wie der Tree, oder vielleicht direkt aufs TreeModel. Auf Event-Ebene z.B. über einen TreeSelectionListener.



> Ich kapiere in dem Fall schon leider das MVC nicht ganz. Denn der Tree links ist ja schon Model und View in einem, richtig?!



Nein, falsch. Ein JTree ist ein View für eine Instanz einer beliebigen Klasse, welche das TreeModel-Interface implementiert und als Model fungiert => JTree#setModel(TreeModel)



> Ich habe schon einige Erfahrung in der Java Entwickllunf und selbst schon öfters MVC implementiert... aber hier hakt es irgendwie. Hängt auch damit zusammen dass ich ausgerechnet mit JTables und JTrees nicht ganz firm bin.



Na wenn du weißt wo noch was fehlt, weißt du ja auch wo du ansetzen musst.


----------



## meister-g (21. Feb 2007)

OK, danke für die Antworten. Teils haben sie mir geholfen Teils haben wir aneinander vorbeigeredet (was wohl daran liegt dass ich mich schlecht ausgedrückt habe.

Es wird ein GanttModell benötigt.
Du meinst ich möge ein solches schreiben. Aber das vorhandene Treemodel mit den entsprechenden Node-Objekten die die Prozessdaten enthalten stellt doch im Prinzip schon ein GanttModell dar?! Warum nicht dieses vewenden!?

Wenn GanttModell:  Links der View soll ja ein JTree sein - soll das Ganttmodell ein TreeModel sein?! Oder kann/muss man ein "Zwischenmodell" für den JTree erstellen?!

Was ich in jeden Fall nicht verstehe (und das war im vorigen Post mit der "Höhe" gemeint): Was ist die Höhe einer Prozesskomponente. Um links den Baum und rechts xxx (siehe unten) zu synchroniseren müsste ich ja entweder eine Höhe im Modell (oder woanders) speichern (wie bekomme ich JTree dazu genau diese zu verwenden? - ist das nicht unheimliches Renderer-Gefrickel?) oder eben diese Höhe einer Node im Tree (mit allem - ich sage mal "Astgezeichne") ermitteln und dann auf den rechten View anwenden.

View Rechts: Hier eignen sich ja generell JTable oder eben ein eigenes Layout mit JComponents. Wenn JTable benötige ich ja wieder ein Tablemodell. Kann man ein Treemodell mit einem Tablemodell "vereinigen"? Oder eben wenn allgemeingültiges Ganttmodell hier auch ein "Zwischenmodell"?

Stichwort Listener:
Ich benötige ja dann Quasi 2 Listener: Einen SelectionListener im JTree links der rechts im View Neuladen oder Zeilen einfügen/entfernen verursacht. Und einen evtl. dafür falls sich ein Prozess geändert hat, worauf beide Views (oder nur der rechte) dann reagieren). Soweit richtig?
Was ich nicht verstehe ist Deine Aussage, dass ich einen Listener benötige um das Ganttmodell nicht jedesmal neu aufbauen zu müssen.
(+ evtl einen der nach Manipulation rechts Aktualisierungen links im JTree vornimmt)

Benötigt man - wenn die zwei Views direkt auf dem gleichen Modell arbeiten überhaupt solche Listener? (bis auf den SelectionListener natürlich)


Ein wirrer Gedanke zum Schluss: Sollen überhaupt beide Views auf einem Modell arbeiten? Im Prinzip ist doch der linke View das Modell für den rechten View. Denn nur expandierte (sichtbare) Nodes werden ja rechts dargestellt.

Du siehst ich bin immer nich etwas verwirrt in Bezug auf das MVC hier... Danke für die bisherige Hilfe und hoffentlich für zukünftige.


----------



## AlArenal (21. Feb 2007)

meister-g hat gesagt.:
			
		

> Es wird ein GanttModell benötigt.
> Du meinst ich möge ein solches schreiben. Aber das vorhandene Treemodel mit den entsprechenden Node-Objekten die die Prozessdaten enthalten stellt doch im Prinzip schon ein GanttModell dar?! Warum nicht dieses vewenden!?



Wenn du meinst, dass das passt, kannst du ein "interface GanttModel extends TreeModel" machen. Selbst wenn du fürs GanttModel erstmal keine weiteren Methoiden meinst zu brauchen ist das sauberer und du kannst später einfacher erweitern, als wenn du überall ein TreeModel in deinem Code verwendest.



> Wenn GanttModell:  Links der View soll ja ein JTree sein - soll das Ganttmodell ein TreeModel sein?! Oder kann/muss man ein "Zwischenmodell" für den JTree erstellen?!



Kommt drauf an 
Wie gesagt würde ich ein eigenes Model erstellen. Mir erschließt sich auf Anhieb nicht dass ein Gantt durch einen Baum darstellbar wäre, aber mit Gantt habe ich auch wenig am Hut, ich kenne ihm vom sehen und das isses auch.

Ich habe auch schon TreeModels geschrieben, die nichts anderes machten als sich als Listener (gewissermaßen als View) an einem anderen TreeModel anzumelden und Events umzubiegen, um eine Filterfunktion zu bilden. Wenn du etwas AHnugn von SQL hast, dann stell dir das Model nicht als Tabelle in der Datenbank vor, sondern als View. Ein Model ist nicht die Kiste in die ich meine Daten packe, sondern nur eine Art und Weise auf meine Daten zu schauen und auf si zuzugreifen. Ob ein solches Model nun direkt auf eine Datei, eine Datenbank oder Instanzen zugreift, oder ob es sich die Daten aus anderen Models holt, ist aus Sicht des View im MVC absolut unerheblich.



> Was ich in jeden Fall nicht verstehe (und das war im vorigen Post mit der "Höhe" gemeint): Was ist die Höhe einer Prozesskomponente. Um links den Baum und rechts xxx (siehe unten) zu synchroniseren müsste ich ja entweder eine Höhe im Modell (oder woanders) speichern (wie bekomme ich JTree dazu genau diese zu verwenden? - ist das nicht unheimliches Renderer-Gefrickel?) oder eben diese Höhe einer Node im Tree (mit allem - ich sage mal "Astgezeichne") ermitteln und dann auf den rechten View anwenden.



Ich glaube mir dämmert was du meinst... Ich habe den GanttView bisher als komplett eigenständige Komponente betrachtet. Was du beschreibst liest sich eher danach als wolltest du einer Spalte im JTree einen GanttRenderer vepassen und gut iss. Das hört sich dann eher nach einer JTreeTable an....



> View Rechts: Hier eignen sich ja generell JTable oder eben ein eigenes Layout mit JComponents. Wenn JTable benötige ich ja wieder ein Tablemodell. Kann man ein Treemodell mit einem Tablemodell "vereinigen"? Oder eben wenn allgemeingültiges Ganttmodell hier auch ein "Zwischenmodell"?



Es gibt JTreeTable als Gegenstand der betrachtung einer Serie von Tutorials von Sun. Ist schon mehrere Jahre alt und wird von mir in modifizierter Form benutzt, da ich noch auf Basis von java 1.4 entwickeln muss. Für Java 5 und neuer gibts in den SwingLabs JXTreeTable, weiterhin gibts einige im Web schwer zu findende kommerzielle Komponenten dieses Typs, die auch schonmal TableTree heißen..



> Stichwort Listener:
> Ich benötige ja dann Quasi 2 Listener: Einen SelectionListener im JTree links der rechts im View Neuladen oder Zeilen einfügen/entfernen verursacht. Und einen evtl. dafür falls sich ein Prozess geändert hat, worauf beide Views (oder nur der rechte) dann reagieren). Soweit richtig?
> Was ich nicht verstehe ist Deine Aussage, dass ich einen Listener benötige um das Ganttmodell nicht jedesmal neu aufbauen zu müssen.
> (+ evtl einen der nach Manipulation rechts Aktualisierungen links im JTree vornimmt)
> ...



Wenn du kein eigenes Model entwickelst nicht, nein.




> Ein wirrer Gedanke zum Schluss: Sollen überhaupt beide Views auf einem Modell arbeiten? Im Prinzip ist doch der linke View das Modell für den rechten View. Denn nur expandierte (sichtbare) Nodes werden ja rechts dargestellt.



Wenn ich das richtig verstehe visualisiert der JTree eine Prozesshierarchie, während der Gantt-Graph für einen Prozess (und ggf. alle seine Unterprozesse) Infos bzgl. Verlauf der Prozessphasen auf einer Zeitachse darstellt. M.E. ist beides nicht ausschließlich auf demselben TreeModel sauber machbar. 

Ob du nun zwei Models verwendest oder eines, das beide Aspekte berücksichtigt, hängt davon ab ob du dich entscheidest Prozesslandschaft + Gantt in einem gemeinsamen View oder in zwei getrennten (und irgendwie synchronsiierten) Views darzustellen. Letzteres ist natürlich flexibler für spätere Änderungen. Was mir auf Anhieb als Entscheidungskriterium einfällt ist die Informationsmenge im Gantt. Wenn du für einen Eintrag im JTree eine Zeile geringer Höhe im Gantt darstellen kannst und du absolut sicher bist, dass dies auf immer und ewig so bleiben wird, kannst du einen gemeinsamen View auf einem gemeinsamen Model entwickeln, mglw. aufbauend auf JTreeTable/JXTreeTable oder zumindest mit Anleihen bzgl. Umsetzung.
Nehmen wir aber mal an im Gantt sei ein Kalender abgebildet und jeder Eintrag könne Fließtext als Beschriftung enthalten und damit vielleicht recht hoch ausfallen, so würde das zu klaffenden Lücken im JTree führen und es wäre sinniger das vertikale Scrolling von GanttView und JTree getrennt zu machen, damit auf beiden Seiten gleichermaßen für Übersichtlichkeit gesorgt werden kann.

Mir hilft es immer mir ein blankes Blatt Papier zu schnappen, zu meinen Druckminenbleistiften zu greifen und mir Skizzen zu machen...


----------

