Ex05 Aufgabe 2.1/2.2
-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Ex05 Aufgabe 2.1/2.2
Okay, also Aufgabe 1 haben wir jetzt endlich gelöst: Mit einem Adapter, der die Company auf HierarchyDisplay adaptiert, und mit einem zweiten, der Employee auf CompositeNode adaptiert. Das klappt soweit auch alles mit der Anzeige und mit dem "Change" menu wunderbar. Problematisch wird es nur bei der zweiten Aufgabe.
Zuerst einmal muss man ja CompositeNode mit einem weiteren Adapter auf ICollapsedCompositeNode adaptieren, was sich noch relativ leicht umsetzen lässt (wenn man irgendwann mal herausgefunden hat, wie man überhaupt verhindert, dass die Kinder eines Knotens dargestellt werden). Damit nun tatsächlich ICollapsedCompositeNode's anstelle von CompositeNodes erzeugt werden, mussten wir zwangsläufig auch die Adapter aus Aufgabe 1 anpassen. Employee wird nun auf also direkt auf ICollapsedCompositeNode adaptiert.
Das Problem ist nun, dass in dem vorgegebenen HierarchyDisplay nun zwar ICollapsedCompositeNode's drinstecken (genauer gesagt CompsiteNodeAdapter, die ICollapsedCompositeNode realisieren), der statische Typ ist aber weiterhin Node. Das ist vorgegeben und kann auch nicht geändert werden! Um tatsächlich collapse() oder expand() verweden zu können, muss man nun leider die Nodes, die sich der RandomCompanyChange (oder jetzt besser gesagt der RandomVisibilityChange) aus dem HierarchyDisplay "herausholt", auf CompsiteNodeAdapter casten. Diese Typecasts sind aber extrem hässlich!
Die Frage ist nur, wie man so etwas umgehen kann. Noch einen weiteren Adapter um HierarchyDisplay zu bauen (oder den bestehenden CompanyAdapter zu erweitern), um die statischen Typen auf CollapsedCompositeNodes zu ändern, klappt leider nicht. Zum Beispiel kann der statische Typ von setRoot() ja beim Erben von HierarchyDisplay nicht auf CollapsedCompositeNodes eingeschränkt, sondern höchstens erweitert werden. Der Rückgabewert von getRoot() ließe sich natürlich einschränken auf CollapsedCompositeNode, dann bräuchte man aber intern (d.h. beim Adaptieren des HierarchyDisplay) wieder einen unsicheren Typecast...
Zuerst einmal muss man ja CompositeNode mit einem weiteren Adapter auf ICollapsedCompositeNode adaptieren, was sich noch relativ leicht umsetzen lässt (wenn man irgendwann mal herausgefunden hat, wie man überhaupt verhindert, dass die Kinder eines Knotens dargestellt werden). Damit nun tatsächlich ICollapsedCompositeNode's anstelle von CompositeNodes erzeugt werden, mussten wir zwangsläufig auch die Adapter aus Aufgabe 1 anpassen. Employee wird nun auf also direkt auf ICollapsedCompositeNode adaptiert.
Das Problem ist nun, dass in dem vorgegebenen HierarchyDisplay nun zwar ICollapsedCompositeNode's drinstecken (genauer gesagt CompsiteNodeAdapter, die ICollapsedCompositeNode realisieren), der statische Typ ist aber weiterhin Node. Das ist vorgegeben und kann auch nicht geändert werden! Um tatsächlich collapse() oder expand() verweden zu können, muss man nun leider die Nodes, die sich der RandomCompanyChange (oder jetzt besser gesagt der RandomVisibilityChange) aus dem HierarchyDisplay "herausholt", auf CompsiteNodeAdapter casten. Diese Typecasts sind aber extrem hässlich!
Die Frage ist nur, wie man so etwas umgehen kann. Noch einen weiteren Adapter um HierarchyDisplay zu bauen (oder den bestehenden CompanyAdapter zu erweitern), um die statischen Typen auf CollapsedCompositeNodes zu ändern, klappt leider nicht. Zum Beispiel kann der statische Typ von setRoot() ja beim Erben von HierarchyDisplay nicht auf CollapsedCompositeNodes eingeschränkt, sondern höchstens erweitert werden. Der Rückgabewert von getRoot() ließe sich natürlich einschränken auf CollapsedCompositeNode, dann bräuchte man aber intern (d.h. beim Adaptieren des HierarchyDisplay) wieder einen unsicheren Typecast...
Also
entweder haben wir was mißverstanden in der Gruppe oder wir kommen um das ganze drum herum ohne häßlichen Casts.
In der Aufgabe 1 haben wir folgendes definiert:
public class CompanyAdapter extends CompositeNode
public class DepartmentAdapter extends CompositeNode
EmployeeAdapter extends Node
damit klappt die 1 hervoragend.
bei der Aufgabe 2 dann
public class CollapsedCompanyAdapter extends CompanyAdapter implements ICollapsedCompositeNode
public class CollapsedDepartmentAdapter extends DepartmentAdapter implements ICollapsedCompositeNode
Damit läuft alles wunderbar
bei getChildCount
@Override
public int getChildCount(){
return (collapsed)?0:_department.getWorkerCount();
}
haben wir obenaufgeführten code, wobei collapsed dann eben angibt ob es auf oder zugeklappt ist.
Also bei der abfrage ob es Childs gibt wird dann 0 zurückgeliefert und folglich nicht auf Kinder zugegriffen.
Das einzige Problem wäre:
wenn man doch trotz geliefertes 0 aus getChildCount mittels auf Child zugreift und null zurückbekommt, falls collapsed auf true gesetzt wird, und dann versucht was auf null z.B. getChildCount aufzurufen,
also z.B. getChildAt(1).getChildCount () wobei getChildAt(i) dann immer null liefert, falls collapsed auf true gesetzt ist.
entweder haben wir was mißverstanden in der Gruppe oder wir kommen um das ganze drum herum ohne häßlichen Casts.
In der Aufgabe 1 haben wir folgendes definiert:
public class CompanyAdapter extends CompositeNode
public class DepartmentAdapter extends CompositeNode
EmployeeAdapter extends Node
damit klappt die 1 hervoragend.
bei der Aufgabe 2 dann
public class CollapsedCompanyAdapter extends CompanyAdapter implements ICollapsedCompositeNode
public class CollapsedDepartmentAdapter extends DepartmentAdapter implements ICollapsedCompositeNode
Damit läuft alles wunderbar

bei getChildCount
@Override
public int getChildCount(){
return (collapsed)?0:_department.getWorkerCount();
}
haben wir obenaufgeführten code, wobei collapsed dann eben angibt ob es auf oder zugeklappt ist.
Also bei der abfrage ob es Childs gibt wird dann 0 zurückgeliefert und folglich nicht auf Kinder zugegriffen.
Das einzige Problem wäre:
wenn man doch trotz geliefertes 0 aus getChildCount mittels
Code: Alles auswählen
@Override
public Node getChildAt(int i){
if (collapsed)
return null;
Department department = _company.getDepartmentAt(i);
if (!departmentAdapterList.containsKey(department.hashCode())){
departmentAdapterList.put(department.hashCode(),new CollapsedDepartmentAdapter(this.hierarchyDisplay,department));
}
return departmentAdapterList.get(department.hashCode());
}
also z.B. getChildAt(1).getChildCount () wobei getChildAt(i) dann immer null liefert, falls collapsed auf true gesetzt ist.
-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Danke, das klingt natürlich auch ziemlich sinnvoll. Vllt sollten wir unseren Ansatz noch mal überdenken.Evgeni hat geschrieben:Also
entweder haben wir was mißverstanden in der Gruppe oder wir kommen um das ganze drum herum ohne häßlichen Casts.
In der Aufgabe 1 haben wir folgendes definiert:
public class CompanyAdapter extends CompositeNode
public class DepartmentAdapter extends CompositeNode
EmployeeAdapter extends Node
damit klappt die 1 hervoragend.
bei der Aufgabe 2 dann
public class CollapsedCompanyAdapter extends CompanyAdapter implements ICollapsedCompositeNode
public class CollapsedDepartmentAdapter extends DepartmentAdapter implements ICollapsedCompositeNode
Damit läuft alles wunderbar
Waren ja bloß zweit Tage rumgefuddel ...

-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Evgeni, bei deinem Ansatz seh ich leider folgendes Problem:
Wenn sich die Company Struktur ändert (Transfer Worker), wie bekommt mein CompanyAdapter/DepartmentAdapter das mit?
Der Adapter muss seine "interne" Struktur ja dann neu aufbauen, damit die Änderung auch übernommen wird.
Eine Methode von CompositeNode werde ich dazu wohl überschreiben müssen. Aber welche nur?
//EDIT
Eine Frage:
Verwaltest du in deinem DepartmentAdapter eine Liste von Employees bzw. EmployeeAdaptern,
oder erzeugst du ad-hoc einen neuen EmployeeAdapter, wenn DepartmentAdapter.getChildAt() aufgerufen wird?
So oder so, muss man ja alle Employees bzw. EmployeeAdapter auch mit CompositeNode.addChild() adden.
Wenn sich nun ein Empolyee transferiert wird, muss ich die Kinder des Knotens ja zwangsläufig auch neu erzeugen...
//EDIT 2
Hmmm, mir fällt gerade eine ganz andere Variante ein:
Wir wäre es mit dem hier?
* public class CompanyAdapter extends Company implements ICompositeNode
* public class DepartmentAdapter extends Department implements ICompositeNode
* public class EmployeeAdapter extends Company implements INode
Damit müsste man aber die ganzen Node Funktionen in den Adaptern implementieren, das is auch Käse.
Allerdings hat man dann nich mehr das Problem, auf Änderungen an der Company zu reagieren.
Oh mann, ich weiss echt nich, wie man das sinnvoll lösen soll
Wenn sich die Company Struktur ändert (Transfer Worker), wie bekommt mein CompanyAdapter/DepartmentAdapter das mit?
Der Adapter muss seine "interne" Struktur ja dann neu aufbauen, damit die Änderung auch übernommen wird.
Eine Methode von CompositeNode werde ich dazu wohl überschreiben müssen. Aber welche nur?
//EDIT
Eine Frage:
Verwaltest du in deinem DepartmentAdapter eine Liste von Employees bzw. EmployeeAdaptern,
oder erzeugst du ad-hoc einen neuen EmployeeAdapter, wenn DepartmentAdapter.getChildAt() aufgerufen wird?
So oder so, muss man ja alle Employees bzw. EmployeeAdapter auch mit CompositeNode.addChild() adden.
Wenn sich nun ein Empolyee transferiert wird, muss ich die Kinder des Knotens ja zwangsläufig auch neu erzeugen...
//EDIT 2
Hmmm, mir fällt gerade eine ganz andere Variante ein:
Wir wäre es mit dem hier?
* public class CompanyAdapter extends Company implements ICompositeNode
* public class DepartmentAdapter extends Department implements ICompositeNode
* public class EmployeeAdapter extends Company implements INode
Damit müsste man aber die ganzen Node Funktionen in den Adaptern implementieren, das is auch Käse.
Allerdings hat man dann nich mehr das Problem, auf Änderungen an der Company zu reagieren.
Oh mann, ich weiss echt nich, wie man das sinnvoll lösen soll

Es gibt keine interne Struktur. Nur company-"Baum" in CompanyAdapter und eine Liste von DepartmentAdapter, die schon mal "verwendet" wurden, also bei denen GetChild MEthode die geleifert hat.dasgleiche gilt füe DepartmentAdapter allerding mit departmentMuldeR hat geschrieben:Evgeni, bei deinem Ansatz seh ich leider folgendes Problem:
Wenn sich die Company Struktur ändert (Transfer Worker), wie bekommt mein CompanyAdapter/DepartmentAdapter das mit?
Der Adapter muss seine "interne" Struktur ja dann neu aufbauen, damit die Änderung auch übernommen wird.
Eine Methode von CompositeNode werde ich dazu wohl überschreiben müssen. Aber welche nur?
//EDIT
Eine Frage:
Verwaltest du in deinem DepartmentAdapter eine Liste von Employees bzw. EmployeeAdaptern,
oder erzeugst du ad-hoc einen neuen EmployeeAdapter, wenn DepartmentAdapter.getChildAt() aufgerufen wird?
So oder so, muss man ja alle Employees bzw. EmployeeAdapter auch mit CompositeNode.addChild() adden.
Wenn sich nun ein Empolyee transferiert wird, muss ich die Kinder des Knotens ja zwangsläufig auch neu erzeugen...
-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Danke für die Antwort, aber so ganz wird mir das leider immer noch nich klar.Evgeni hat geschrieben:Es gibt keine interne Struktur. Nur company-"Baum" in CompanyAdapter und eine Liste von DepartmentAdapter, die schon mal "verwendet" wurden, also bei denen GetChild MEthode die geleifert hat.dasgleiche gilt füe DepartmentAdapter allerding mit department
Also bei uns bekommt ein CompanyAdapter (extends CompositeNode) im seinem Konstruktor ein Company-Objekt übergeben. Er durchläuft dann alle Departments der Company und fügt jedes einzelne Department-Objekt als DepartmentAdapter (ebenfalls extends CompositeNode) als Kind in sich selbst ein. Dazu benutzt der CompanyAdapter die addChild() Methode, die er von CompositeNode erbt. Der DepartmentAdapter funktioniert analog, nur dass er ein Department übergeben bekommt, die Employees durchläuft und diese als EmployeeAdapter in sich selbst einfügt.
Das ganze funktioiert erstmal und wird auch korrekt angezeigt. Auch die Namen der Mitartbeiter zu ändern is kein Problem. Das Probelm entsteht, wenn ein Worker transferiert wird! Dann muss man ja quasi den Baum neu aufbauen. Allerdings is da schon die Frage, wie man das überhaupt mitbekommen soll, um darauf zu reagieren. Bisher klappt das leider nur über eine einzige Funktion: HierarchyDisplay.refresh().
Deshalb benötigen wir einen weiteren Adapter, den HierarchyDisplayAdapter, der im Grunde nur die refresh() Funktion überschreibt, so dass CompanyAdapter.update(), eine zusätzliche Funktion, aufgerufen wird. Der CompanyAdapter erstellt darauf hin die DepartmentAdapter neu - nachdem er alle Childs erstmal gecleart hat. Die jeweiligen DepartmentAdapter erstellen entsprechend ihre EmployeeAdapter neu. Das funktioniert zwar irgendwie, ist aber alles andere als schön! Und der HierarchyDisplayAdapter ist eigentlich auch kein "echter" Adapter, sondern eher ein hässlicher Workarround...
Spätestens bei Aufgabe 2 wird das dann ganz ganz böse. Vorallem weil ein HierarchyDisplay ja auf Nodes als statischem Typ arbeitet. Da ist nach wie vor die Frage, wie Application die CollapsedCompositeNodes da ohne Typecast rausbekommen soll, um tatsächlich expand() bzw. collapse() aufrufen zu können .....
das machen wir eben nicht! Sondern bei addChild extrahieren wir den Department und fügen es der company hinzu und departmentadapter ist uns völlig wurscht
Wir bauen also kein Baum mit Company-, Departtment- und Employee- Adaptern, sondern liefern bei getChild einfach entweder neuen Adapter, falls auf das Kind noch nicht zugegriffen wurde oder eben schon existierten Adapter, falls aufs Kind vorher zugegriffen wurde.

Code: Alles auswählen
@Override
public void addChild(Node child){
if (null == child) throw new IllegalArgumentException("Cannot add 'null' as a child.");
if (child instanceof DepartmentAdapter){
_company.addDepartment(((DepartmentAdapter)child).getDepartment());
}
}
-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Öhm? Irgendwie muss man doch in CompanyAdapter die einzelnen Departments bzw. DepartmentAdapter erst einmal dem unterliegenden CompositeNode via addChild() hinzufügen. Der Knoten, von dem CompanyAdapter erbt, muss doch seine Kinder kennen. Sonst klappt das nicht mit dem Zeichnen! Und das selbe gilt in DepartmentAdapter für die Employees bzw. EmployeeAdapter.
Demnentsprechend muss man die Childs dann auch aktualisieren, wenn sich etwas an der Company Struktur ändert. Ich weiss leider nich, wie das sonst funktionieren sollte ....
Demnentsprechend muss man die Childs dann auch aktualisieren, wenn sich etwas an der Company Struktur ändert. Ich weiss leider nich, wie das sonst funktionieren sollte ....
- dinkelaker
- Mausschubser
- Beiträge: 72
- Registriert: 9. Okt 2007 10:35
Hallo MuldeR,
Aus Nachricht 1, 29.11. um 7:56 pm
Mehr folgt...
Gruß, Tom
Aus Nachricht 1, 29.11. um 7:56 pm
Warum hab ihr das so implementiert? Employee enthält doch keine weiteren Nodes ist in sofern kein CompositeNode. Geschweigedenn dass man Employee zusammen könnte.Employee wird nun auf also direkt auf ICollapsedCompositeNode adaptiert.
Mehr folgt...
Gruß, Tom
- dinkelaker
- Mausschubser
- Beiträge: 72
- Registriert: 9. Okt 2007 10:35
Hallo MuldeR,
Wie man das mitbekommen soll?
RandomCompanyChange.actionPerformed() ruft erst transferWorker() auf und danach HierarchyDisplay.refresh(), was den Baum komplett neu aufbaut.
Du bekommst dies also geschenkt. Oder funktioniert es aus irgendeinem Grund bei Dir nicht?
Gruß, Tom
Ein Aufruf von HierarchyDisplay.refresh() ist voll ausreichend als Lösung um den Baum neu zeichnen zu lassen.Das ganze funktioiert erstmal und wird auch korrekt angezeigt. Auch die Namen der Mitartbeiter zu ändern is kein Problem. Das Probelm entsteht, wenn ein Worker transferiert wird! Dann muss man ja quasi den Baum neu aufbauen. Allerdings is da schon die Frage, wie man das überhaupt mitbekommen soll, um darauf zu reagieren. Bisher klappt das leider nur über eine einzige Funktion: HierarchyDisplay.refresh().
Wie man das mitbekommen soll?
RandomCompanyChange.actionPerformed() ruft erst transferWorker() auf und danach HierarchyDisplay.refresh(), was den Baum komplett neu aufbaut.
Du bekommst dies also geschenkt. Oder funktioniert es aus irgendeinem Grund bei Dir nicht?
Gruß, Tom
-
- BASIC-Programmierer
- Beiträge: 131
- Registriert: 18. Okt 2005 16:14
- Wohnort: (d)armstadt
- Kontaktdaten:
Naja, dann muss man dafür aber einen weiteren Adapter um HierarchyDisplay bauen, um refresh() überschreiben zu können. Und die frage ist, was refresh() dann genau macht, um dem CompanyAdapter bzw. den DepartmentAdaptern mitzuteilen, dass sich etwas geändert hat. Natürlich könnte man eine neue Methode update() in CompanyAdapter und analog in DepartmentAdapter einfügen, aber auch das is irgendwie nich so schön. Und die Frage is vorallem, ob CompanyAdapter seine "interne" Knotenstruktur jedesmal bei refresh() respektive update() komplett neu aufbauen soll...dinkelaker hat geschrieben:Hallo MuldeR,
Ein Aufruf von HierarchyDisplay.refresh() ist voll ausreichend als Lösung um den Baum neu zeichnen zu lassen.
Wie man das mitbekommen soll?
RandomCompanyChange.actionPerformed() ruft erst transferWorker() auf und danach HierarchyDisplay.refresh(), was den Baum komplett neu aufbaut.
Du bekommst dies also geschenkt. Oder funktioniert es aus irgendeinem Grund bei Dir nicht?
Gruß, Tom
Und nach wie vor die Frage: Das HierarchyDisplay enthält als statischen Type Nodes. Klar, da stecken tatsächlich meine CollapsedCompanyAdapter drin, aber wenn das Menubar auf HierachyDisplay zugreift, dann bekommt er als Typ zunächst einmal nur normale Nodes. Ist es legitim an dieser Stelle einen Typecast auf ICollapsedCompositeNode zu benutzen, um collapse() bzw. expand() testen zu können?