# GEF: Connections?



## josch (18. Okt 2006)

Hallo,

ich arbeite mich gerade in GEF ein und versuche ein (im ersten Schritt) einfaches Modell zu visualisieren. Es ist ähnlich wie wenn man die Knoten einer bestimmten Ebene eines XML-Dokumentes anzeigt und diese Knoten mit Connections verbindet. 


```
Knoten 1
           |
           V
       Knoten 2
           |
           V
       Knoten 3
```
Die Connections haben keine direkte Entsprechung im Modell, sondern sind eben nur ggf. Vorgänger und Nachfolger. Somit ist mir nicht ganz klar was denn getModelSourceConnections() des jeweiligen EditParts zurückliefern soll - so das die Factory dann auch wirklich ConnectionEditParts erstellen kann.
Meine Versuche im EditPart des jeweiligen XML-Knotens eine Instanz für source und eine für target einer eigenen ConnectionModellClass zu erstellen führen zu sichtbaren Ergebnissen - aber leider nicht den gewünschten. Wollkneul oder Chaos sind glaube ich treffende Umschreibungen.


```
public class MyEditPart extends AbstractGraphicalEditPart implements NodeEditPart {

	private void createConnections() {
		if ((node != null) && (node.NextSibling() != null)) {  
			ConnectionModelElement conn = new ConnectionModelElement(node, node.NextSibling());
			addConnection(conn);
		}
		
		if ((node != null) && (node.PrevSibling() != null)) {
			ConnectionModelElement conn = new ConnectionModelElement(node.nodePrevSibling(), node);
			addConnection(conn);
		}
	}


	protected List getModelSourceConnections() {
		sourceConnections.clear();
		createConnections();
		
		return sourceConnections;
	}	

}
```


ConnectionModelElement selber merkt sich gerade mal die beiden Nodes, mehr nicht.


```
public class ConnectionModelElement {
	
	private Node source;
	private Node target;

	public ConnectionModelElement(Node source, Node target) {
		this.source = source;
		this.target = target;
	}

	public Node getSource() {
		return source;
	}

	public Node getTarget() {
		return target;
	}
}
```

Wie GEF die Connections nun aufbaut ist mir nicht ganz klar. So wie ich es verstanden habe merkt sich GEF die Zuordnung von ConnectionModelElement und dem entsprechenden ConnectionEditPart beim erstellen in der Factory. So kann GEF ggf. beim ConnectionModelElement mittels getSource()/getTarget() die beteiligten Objekte ermitteln. Die zu diesen Objekten widerrum gehörenden EditParts hat GEF sich auch gemerkt. Damit liegen alle benötigten Infos vor und es kann gemalt werden. Erscheint mir zumindest im Moment schlüssig. Aber es sieht verdammt noch mal nicht richtig aus! 

Irgendjemand eine Idee dazu? Irgendwo soll es auch eine Anleitung geben, wie man sinnigerweise vorgeht, wenn eben nicht alle Infos der View direkt im Modell vorliegen. Aber ich kann es nicht finden. Hat Jemand einen Link für mich?

thx
josch


----------



## Wildcard (22. Okt 2006)

Ich würde dir vorschlagen entsprechende Klassen im Model anzulegen.
GEF basiert darauf das die visuelle Repräsentation eine direkte Darstellung des Models ist.
Du tust dir leichter wenn du auf implizite Connections verzichtet und stattdessen einfach Klassen für die Connections einführst deren Objekte nicht persistiert werden.
So zumindest meine Erfahrung.


----------



## josch (27. Okt 2006)

Wildcard hat gesagt.:
			
		

> Ich würde dir vorschlagen entsprechende Klassen im Model anzulegen.



Genau das mach(t)e ich ja (falsch) in createConnections().
Mein Fehler war, dass ich die selbe Verbindung nicht einfach beim source- wie auch dem target-Modelelement der jeweilige Liste zugeordnet habe.

Da ich ja nun meine Connections habe, kommt natürlich gleich die nächste Frage 
Eine spezielle Sorte von Connections soll Knoten verbinden, die nicht direkt benachbart sind. Dabei soll die Connection aber nicht durch alle dazwischenliegende Knoten gehen, sondern "aussen rum". 

Hast Du ein paar Stichwörter, Links oder gar konkrete Hinweise für mich?

thx
josch


----------



## Wildcard (27. Okt 2006)

Das ist ein sehr anwendungsspezifisches Problem. Dir wird nichts anderes übrig bleiben als dafür selbst einen Routing Algorithmus bzw. einen LayoutManager zu implementieren.


----------



## josch (27. Okt 2006)

Hi,

ich hätte eigentlich erwartet, dass der ShortestPathConnectionRouter dies für mich übernimmt. Aber aus irgendeinem Grunde will er nicht. Ich denke, dass das Problem die Verschachtelung meiner Figuren ist und der Router überhaupt keine Chance hat nicht über eine Figure zu gehen?!

Es soll eine Connection wie folgt erzeugt werden. 


```
|-------- Figure A -------------------------|
|                                                       
|   |----------- Figure B ---------|           
|   |                              |           
|   |   |------- Figure C ------|  |           
|   |   |                       |  |           
|   |   |  |-------- D ------|  |  |          
|   |   |  |                 |  |  |          
|   |   |  |  |---- E 1 ---| |  |  |          
|   |   |  |  |            |==================
|   |   |  |  |------------| |  |  |          V
|   |   |  |                 |  |  |          V
|   |   |  |-----------------|  |  |          V
|   |   |                       |  |          V
|   |   |-----------------------|  |          V
|   |                              |          V
|   |------------------------------|          V
|                                             V
|                                             V  
|                                             V 
|   |----------- Figure B ---------|          V 
|   |                              |          V 
|   |   |------- Figure C ------|  |          V 
|   |   |                       |  |          V 
|   |   |  |-------- D ------|  |  |          V
|   |   |  |                 |  |  |          V
|   |   |  |  |---- E   ---| |  |  |          V
|   |   |  |  |            | |  |  |          V
|   |   |  |  |------------| |  |  |          V
|   |   |  |                 |  |  |          V
|   |   |  |-----------------|  |  |          V
|   |   |                       |  |          V
|   |   |-----------------------|  |          V
|   |                              |          V
|   |------------------------------|          V
|                                             V 
|                                             V
|   |----------- Figure B ---------|          V           
|   |                              | <=========          
|   |   |------- Figure C ------|  |           
|   |   |                       |  |           
|   |   |  |-------- D ------|  |  |          
|   |   |  |                 |  |  |          
|   |   |  |  |---- E   ---| |  |  |          
|   |   |  |  |            | |  |  |
|   |   |  |  |------------| |  |  |          
|   |   |  |                 |  |  |          
|   |   |  |-----------------|  |  |          
|   |   |                       |  |          
|   |   |-----------------------|  |          
|   |                              |          
|   |------------------------------|
```

In manchen Beispielen/Artikeln wird der Router der Connection zugewiesen, in anderen einer Figure oder auch dem Connectionlayer. Ich blicke nicht durch. Hast Du einen Literaturtipp für mich?

Bisher ist der Editor ein Viewer, er dient nur der Visualisierung des Models. Policies und Commands werden dann doch nicht  benötigt, oder?

thx
josch


----------



## Wildcard (27. Okt 2006)

Nein, solange die Visualisierung nicht auf Userinput reagiern sollts und du über die View auch nichts am Model änderst brauchst du eigentlich weder EditPolicies, noch Commands.
Hmm, die Klasse kannte ich noch gar nicht. Mein Graph war damals etwas anders gelagert. Überschneidungen waren da gar nicht möglich.
Ich kann jetzt auch nur sagen was ich in den Java-Docs gefunden habe.
Ich versteh das so, das der Router dem Container zugewiesen werden soll.


----------



## josch (27. Okt 2006)

Ja, der ShortestPathConnectionRouter ist wohl noch nicht so alt. Ich habe auch irgendwo gelesen, dass der nicht in allen Fällen funktioniert - finde die Stelle aber nicht mehr. Überhaupt finde ich keine wirklich gute und aktuelle Quelle für Infos. Das ist alles ziemlich zerstreut und recht mühsam. Allein eine Auflistung und ausführliche Beschreibung der Router ist nicht zu finden. Jetzt dreht sich der Kopf und ich mach erstmal Schluss.

Schönes Wochenende
josch


----------



## Wildcard (27. Okt 2006)

Ja, GEF ist mitunter sehr mühsam zu erlernen. Trotzdem hat mir das Framework sehr gut gefallen und bin gerade wieder dabei mich einzulernen. Wenn du also doch noch irgendwo auf gute Quellen stößt lass es mich bitte wissen :wink: Schönes Wochende


----------



## Guest (1. Nov 2006)

Hi,

etwas wirklich gutes UND umfassendes habe ich (noch) nicht gefunden. Meine Ausflüge zu GEF starte ich meistens bei http://roots.iai.uni-bonn.de/lehre/xp2005a/Wiki.jsp?page=GEF. Sehr gut (alles relativ zu verstehen) hat mir http://eclipsewiki.editme.com/GefDescription gefallen. Hier bekommt man einen ganz guten Überblick. Aber bei einigen Sachen fehlt mir die Tiefe. 

Zur Zeit bastele ich immer noch (oder wieder) an dieser blöden Connection. Nun ist mir aufgefallen, dass das zuweisen eines ShortPathRouter zum ConnectionLayer die Zuweisung meines BendpointRouter bei der Connection wirkungslos macht. Bisher hatte ich es so verstanden, dass die Router der Connection prio haben. Ob sich das bei anderen Routern auch so verhält muss ich noch testen. Wahrscheinlich steht das sogar irgendwo, aber wo?

gruss
josch


----------



## Natorion (2. Nov 2006)

Ja, GEF ist hart 

Ich geb dir mal nen alternativen Tipp: Schau dir mal GMF an und modellier dort dein Programm. Lass alles generieren und schau mal wie das dort gemacht wird. Vielleicht hilft es ja


----------



## Wildcard (2. Nov 2006)

Ich bin mit GMF nie wirklich klar gekommen. Vielleicht bin einfach zu blöd.


----------



## josch (9. Nov 2006)

Hi,

da bin ich wieder  Mit meiner Connection bin ich noch nicht wirklich weiter. 


```
public class ConnectionFigure extends PolylineConnection {
	
	public ConnectionFigure() {
		setTargetDecoration(new PolygonDecoration()); // arrow at target endpoint
		setLineWidth(2);
		setConnectionRouter(new BendpointConnectionRouter());
	}
}
```

Im refreshVisuals() des entsprechenden ConnectionEditPart rufe ich meine Methode 


```
protected void refreshBendpoints() {
		ArrayList list = new ArrayList();
		RelativeBendpoint rbp = new RelativeBendpoint(getConnectionFigure());
		rbp.setRelativeDimensions(new Dimension(0,0), new Dimension(0, 0));
		rbp.setWeight(0);
		list.add(rbp);
		getConnectionFigure().setRoutingConstraint(list);
	}
```

auf. Prinzipiell scheint mir das nicht verkehrt, da es zumindest irgendeine Auswirkung hat  Aber bei Dimensionen von 0/0 sollte es doch gar keine Veränderung ergeben!? Kann mir das mit den Dimensionen und den relativen Bendpoints jemand erklären (oder einen Link geben)? Was für Werte muss ich denn angeben um eine Linie entsprechend meiner ASCII-Grafik zu bekommen?

Danke
josch


----------



## josch (9. Nov 2006)

Hi,

habe da noch eine Frage; Wie verhindere ich, dass die Breite einer Figure durch den Wert des Labels der Border bestimmt wird?


```
public MyFigure() {
		super();
		
		ToolbarLayout layout = new ToolbarLayout(false);
		layout.setSpacing(15);
		layout.setStretchMinorAxis(true);
		setLayoutManager(layout);  
		
		setMinimumSize(new Dimension(100,40));
		setMaximumSize(new Dimension(200,40));

		FrameBorder fb = new FrameBorder();
                fb.setLabel("Ich bin ein verdammt langer Text, der eigentlich nicht komplett erscheinen sollte.");
		setBorder(fb);
	}
```


----------

