# EMF und Notification Framework



## Gast2 (9. Dez 2010)

Hallo zusammen,

ich hätte ein paar Fragen zum Notification Framework von EMF. Ich nöchte einen ContentProvider für einen TableViewer machen.

1. Gibt es auch einen Adapter der nur auf ein Attribut reagiert oder muss immer überpüft werden, ob das richtige Attribut ankommt?

2. Ich verteh nicht für was die AdapterFactory genau da ist? Und was daran besser sein soll und wie man diese verwendet.

EMF generiert mir ja eine AdapterFactoryImpl aber die einzelenen createMyObjectAdapter sind alle mit null implementiertl.

Mit dem adapt kriert die Factory den richtigen Adapter und fügt diesen meinem eObject zu.
Aber wie bekomme ich den Adapter wieder aus der Liste raus? Bin ich dafür selber verantwortlich oder gehe ich dafür auch über den Adapter?

Wie gesagt seh den Vorteil der Factory noch nicht?!?



```
public class FahrtContentProvider implements IStructuredContentProvider{

	private MyEObject eObject;
	private Viewer viewer;
	private Adapter adapter;
	
	public FahrtContentProvider(){
		adapter = new EContentAdapter(){
			@Override
			public void notifyChanged(Notification notification) {
                                   //1. geht das auch leichter?
				   switch (notification.getFeatureID(MyEObject.class))
				    {
				      case KindergeldPackage.MYEOBJECT__PERSONLIST:
				      viewer.refresh();
				       break;
				    }
			}
		};
	eObject.eAdapters().add(adapter);
		
                 //2.
		 AdapterFactory someAdapterFactory = .;
		  Object requiredType = ...;
		  if(someAdapterFactory.isFactoryForType(requiredType))
		  {
		    Adapter theAdapter = someAdapterFactory.adapt(someObject, requiredType);
		    ...
		  }
		

	
	}
	
	@Override
	public void dispose() {
		eObject.eAdapters().remove(adapter);
		
	}

	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		this.viewer = viewer;
		
	}

	@Override
	public Object[] getElements(Object inputElement) {
		return eObject.getPersonList().toArray();
	}

}
```


----------



## Wildcard (9. Dez 2010)

Die generierte Factory ist primär zum extenden Gedacht um bestimmte Adaptertype zu erstellen.
Adapter sind nicht nur Listener, sie können auch verwendet werden um zusätzliche Funktionalität an ein Objekt anzuklinken.
Wenn es dir nur um einen Content Provider geht der automatisch den Tree aktualisiert, dann kannst du dir die Arbeit sparen:

```
treeViewer.setContentProvider(new AdapterFactoryContentProvider(new YourModelItemProviderAdapterFactory));
//beachte das 'Item' Provider Adapter Factory
```
Gleiches gibt es auch für den Label Provider, AdapterFactoryLabelProvider.
Wenn du dir die YourModelItemProviderAdapterFactory Klasse ansiehst, dann verstehst du vielleicht auch wie die generierte leere AdapterFactory zu verstehen ist.


----------



## Gast2 (10. Dez 2010)

Okay das schau ich mir mal an...

Aber ich beschreib mein Problem nochmal genauer vielleicht kennst du dazu auch ne coole Variante ...

Also ich hab Object1 das hat eine 1:n beziehung zu Object2...

Das heißt Object1 hat eine EList<Object2>...

So nun stell ich von Object1 alle Object 2 in einem TableViewer dar.

Dafür hab ich dem oberen ContentProvider geschrieben. Es gibt einen Add/Remove Dialog für Object2.
Das heißt wenn ich Object1 ein Object2 hinzufüge muss ich ich den tableviewer refresehen. Aber ja nur auf das attribut von wenn sich die Liste änder darum der switch case.

Verständlich?


----------



## Wildcard (10. Dez 2010)

> Das heißt wenn ich Object1 ein Object2 hinzufüge muss ich ich den tableviewer refresehen.


Nein, musst du nicht, der AdapterFactoryContentProvider  und AdapterFactoryLabelProvider macht das automatisch, auch bei strukturellen Änderungen.


----------



## Gast2 (13. Dez 2010)

okay versuche ich das mal... Extra nen eigenen geschrieben shit^^...


----------



## Gast2 (13. Dez 2010)

Wildcard hat gesagt.:


> Nein, musst du nicht, der AdapterFactoryContentProvider  und AdapterFactoryLabelProvider macht das automatisch, auch bei strukturellen Änderungen.



Mhm also irgendwie kapier ich es nicht... hab mit jetzt den edit code generieren lassen

Hab nur ein Object1ItemProvider und ein Object2ItemProvider

und eine ItemProviderAdapterFactory dann hab ich folgendes gemacht aber es passiert gar nichts...


```
tableViewer.setContentProvider(new AdapterFactoryContentProvider(new ItemProviderAdapterFactory()));
		tableViewer.setLabelProvider(new AdapterFactoryLabelProvider (new ItemProviderAdapterFactory()));
```


muss ich noch was bestimmtes aufrufen? Oder geht die Variante nur für TreeViewer?
Hier wird immer Null zurück gegegen da, das 2te if nicht gegeben ist. Was muss ich den in das setInput den reinmachen? Ich dachte die Liste die der tableviewer anzeigen soll ... 

```
@Override
	public Object adapt(Object object, Object type) {
		if (isFactoryForType(type)) {
			Object adapter = super.adapt(object, type);
			if (!(type instanceof Class<?>) || (((Class<?>)type).isInstance(adapter))) {
				return adapter;
			}
		}

		return null;
	}
```

Will eigentlich jetzt sowas machen object1.getObjects2().add(object2) und die Table soll ein refresh erhalten...


----------



## Wildcard (13. Dez 2010)

Lass deine generierten ItemProvider zusätzlich ITableItemContentProvider implementieren.
Siehe dazu hier im Kapitel Tables:
Using EMF


----------



## Gast2 (13. Dez 2010)

Wildcard hat gesagt.:


> Lass deine generierten ItemProvider zusätzlich ITableItemContentProvider implementieren.
> Siehe dazu hier im Kapitel Tables:
> Using EMF



Kannte ich noch nicht sieht interessant aus. Morgen mal genauer durchlesen.


----------



## Gast2 (13. Dez 2010)

Wildcard hat gesagt.:


> Lass deine generierten ItemProvider zusätzlich ITableItemContentProvider implementieren.
> Siehe dazu hier im Kapitel Tables:
> Using EMF


Der Labelprovider funktioniert einwandfrei =)...


Mhm was muss ich für den ContentProvider noch machen? DDie Tabelle wird nicht gerefreshed...
Was muss ich den als Input mitgeben? Object 1 oder die Liste von Object2?


----------



## Wildcard (14. Dez 2010)

> Mhm was muss ich für den ContentProvider noch machen? DDie Tabelle wird nicht gerefreshed...


Änderst du auch die gleiche Instanz die auch in der Tabelle enthalten ist?


> Was muss ich den als Input mitgeben? Object 1 oder die Liste von Object2?


Normal den Parent der Objekte die du anzeigen möchtest, du kannst aber auch eine Liste verwenden.


----------



## Gast2 (14. Dez 2010)

Wildcard hat gesagt.:


> Änderst du auch die gleiche Instanz die auch in der Tabelle enthalten ist?


Es kommt ersteinmal gar nichts in die Tabelle rein. Also ich hab ein AddCommand
und dann mach ich sowas object1.getObjects2().add(object)




Wildcard hat gesagt.:


> Änderst du auch die gleiche Instanz die auch in der Tabelle enthalten ist?
> 
> Normal den Parent der Objekte die du anzeigen möchtest, du kannst aber auch eine Liste verwenden.



Hab beides versucht... Wenn ich den parent übergebe verstehe ich halt nicht woher er wissen soll dass er die Objekte 2 von objekt1 anzeigen lassen soll.
Muss ich den ItemProvider vom parent(Object1) auch händisch überarbeiten?


----------



## Wildcard (14. Dez 2010)

> Hab beides versucht... Wenn ich den parent übergebe verstehe ich halt nicht woher er wissen soll dass er die Objekte 2 von objekt1 anzeigen lassen soll.
> Muss ich den ItemProvider vom parent(Object1) auch händisch überarbeiten?


Im Genmodel kann man in der Properties View für jedes Feature eintragen ob es ein 'children' Feature ist. Standardmäßig passiert das bei Containment References. Aus dieser Information wird dann pro ItemProvider die getChildrenFeatures Methode generiert die dem ItemProvider sagt was er bei getChildren liefern soll.


----------



## Gast2 (14. Dez 2010)

Wildcard hat gesagt.:


> Im Genmodel kann man in der Properties View für jedes Feature eintragen ob es ein 'children' Feature ist. Standardmäßig passiert das bei Containment References. Aus dieser Information wird dann pro ItemProvider die getChildrenFeatures Methode generiert die dem ItemProvider sagt was er bei getChildren liefern soll.



Okay in dem part wo feature steht ist containment true

in dem part wo edit steht ist bei children false.


EDIT: 

Also wenn ich edit children auf true setze und notify auf true dann klappts.

aber mein labelprovider wird noch nicht benachrichtigt wenn ich ein object aus der tabelle heraus veränder. das heißt bei den sturktur änderungen passt was noch nicht. 
denkeder labelprovider bekommt keine struktur änderungen.


----------



## Wildcard (15. Dez 2010)

> Okay in dem part wo feature steht ist containment true
> 
> in dem part wo edit steht ist bei children false.


Wenn du das Feature erst anlegst nachdem das genmodel erstellt wurde auf, oder du es erst später auf Containment setzt, dann musst du das genmodel selbst anpassen (oder neu erstellen).


> aber mein labelprovider wird noch nicht benachrichtigt wenn ich ein object aus der tabelle heraus veränder. das heißt bei den sturktur änderungen passt was noch nicht.
> denkeder labelprovider bekommt keine struktur änderungen.


Gab mal ein Beispiel was und wie du es tust und was anschließend in der Tabelle passieren soll.


----------



## Gast2 (15. Dez 2010)

Wildcard hat gesagt.:


> Wenn du das Feature erst anlegst nachdem das genmodel erstellt wurde auf, oder du es erst später auf Containment setzt, dann musst du das genmodel selbst anpassen (oder neu erstellen).



Ah gut zu wissen, dachte ein reload reicht...



Wildcard hat gesagt.:


> Gab mal ein Beispiel was und wie du es tust und was anschließend in der Tabelle passieren soll.



Wo gab es mal ein Beispiel? Auf der eclipse Seite?


----------



## Wildcard (15. Dez 2010)

Hier mal ein Beispiel für ein einfaches Ecore (nur eine Node die wieder Nodes enthalten kann).
[XML]<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0"
    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="providermodel"
    nsURI="http://example.org/provider" nsPrefix="pr">
  <eClassifiers xsi:type="ecore:EClass" name="Node">
    <eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
        eType="#//Node" containment="true"/>
  </eClassifiers>
</ecore:EPackage>[/XML]

Dann eine View um das ganze zu testen:

```
public class ViewPart1 extends ViewPart {

	private TreeViewer viewer;


	@Override
	public void createPartControl(final Composite parent) {
		viewer = new TreeViewer(parent);
		AdapterFactory factory = new ProvidermodelItemProviderAdapterFactory();
		viewer.setLabelProvider(new AdapterFactoryLabelProvider(factory));
		viewer.setContentProvider(new AdapterFactoryContentProvider(factory));
		final Node root = ProvidermodelFactory.eINSTANCE.createNode();
		Node child = ProvidermodelFactory.eINSTANCE.createNode();
		root.getChildren().add(child);
		viewer.setInput(root);
		parent.getDisplay().timerExec(1000, new Runnable() {
		
			@Override
			public void run() {
				root.getChildren().add(ProvidermodelFactory.eINSTANCE.createNode());
				parent.getDisplay().timerExec(1000, this);
			}
		});
		
	}

	@Override
	public void setFocus() {
		viewer.getControl().setFocus();

	}

}
```

Wie du siehst wird jede Sekunde eine neue Node hinzugefügt und die View aktualisiert sich vollautomatisch. Ob Tree, Table, Liste, oder sonstwas ist dabei egal. Wenn das bei dir nicht funktioniert, dann weil du irgendetwas anders machst als in diesem Beispiel und ohne zu wissen was du anders machst kann ich dir nicht helfen.


----------



## Gast2 (15. Dez 2010)

Wildcard hat gesagt.:


> Hier mal ein Beispiel für ein einfaches Ecore (nur eine Node die wieder Nodes enthalten kann).
> [XML]<?xml version="1.0" encoding="UTF-8"?>
> <ecore:EPackage xmi:version="2.0"
> xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> ...



Ja das klappt bei mir auch, aber jetzt will von einem Node ein Attribut ändern. z.B. den Namen.
Dann wird die Instanz geändert aber der LabelProvider macht nichts. Weißt wie ich mein?
Ich mach morgen auch mal ein KSKB...


----------



## Wildcard (15. Dez 2010)

SirWayne hat gesagt.:


> Ja das klappt bei mir auch, aber jetzt will von einem Node ein Attribut ändern. z.B. den Namen.
> Dann wird die Instanz geändert aber der LabelProvider macht nichts. Weißt wie ich mein?
> Ich mach morgen auch mal ein KSKB...



Nein, das stimmt nicht, siehe hier (ich habe im Ecore ein zusätliches Attribut 'name' eingefügt:

```
public class ViewPart1 extends ViewPart {

	private TreeViewer viewer;


	@Override
	public void createPartControl(final Composite parent) {
		viewer = new TreeViewer(parent);
		AdapterFactory factory = new ProvidermodelItemProviderAdapterFactory();
		viewer.setLabelProvider(new AdapterFactoryLabelProvider(factory));
		viewer.setContentProvider(new AdapterFactoryContentProvider(factory));
		final Node root = ProvidermodelFactory.eINSTANCE.createNode();
		Node child = ProvidermodelFactory.eINSTANCE.createNode();
		root.getChildren().add(child);
		viewer.setInput(root);
		parent.getDisplay().timerExec(1000, new Runnable() {
		
			@Override
			public void run() {
				root.getChildren().add(ProvidermodelFactory.eINSTANCE.createNode());
				parent.getDisplay().timerExec(1000, this);
				for (Node node : root.getChildren()) {
					node.setName(SimpleDateFormat.getTimeInstance().format(new Date()));
				}
			}
		});
		
	}

	@Override
	public void setFocus() {
		viewer.getControl().setFocus();

	}

}
```


----------



## Gast2 (15. Dez 2010)

Mhm versuch ich morgen mal und mach es mit 2 verschiedene Klassen velleicht kannst mir dann mein fehler sagen wenn ich ein KSKB hab ...


----------



## Gast2 (16. Dez 2010)

Danke jetzt klappts.

Ich hab 2 Unterschiede festgestellt:

1. In meinem genModel createChild false. Hab das genModel wegeschmissen und nochmal neu erzeugt.

2. Habe ich meinen beiden Provider (Label und Content) jeweils eine neue Factory mitgegeben anstatt die gleiche jetzt tuts =)...

Erspart echt viel Arbeit Danke für den Tip..


----------



## Gast2 (16. Dez 2010)

Vielleicht nochmal eine kleine Frage.

Gibt es auch was wo EMF einen Eingabe Editoren (Masken) erstellt?
Also das nicht alles in einem Baum dargestellt wird sondern, alle Attribute mit Label und Textfeldern wie in der PropertView?
z.B. Person(name,vorname)

Editor

label textfeld(name)
label textfeld(vorname)


----------



## Wildcard (16. Dez 2010)

Du meinst aber explizit in nicht in der Properties View, sondern in zB einem Dialog oder einer Eclipse Forms Section?
Jein. Es gibt EEF das die default Properties View durch eine Forms basierte ersetzt und dabei auch gleich Wizards/Dialoge mit der gleichen Funktionalität produziert.
Dann gibt es noch den Generic EMF Editor der ebenfalls die Properties View durch eine Forms basierte Tabbed Properties View ersetzt, allerdings ohne dabei Code zu generieren. 
EEF ist IMO noch zu sehr incubation und der Generic EMF Editor verwendet wie gesagt die Properties View.
Aber: du kannst dir die Technik des Generic EMF Editors zu nutze machen um automatisch aus den EClasses Forms ausserhalb der Properties View zu instanzieren. Wenn du bereit bist selbst etwas Arbeit zu investieren ist es mit EMF auch sehr einfach dir ein solches Framework selbst zu schreiben.
Du kannst problemlos alle Features einer EClass und deren Typ auslesen und aus dieser Information Widgets erstellen und mit Databinding Verknüpfen. Wenn du zusätzliche Informationen wie Labels oder Gruppierungsinformationen haben möchtest, kannst du EAnnotations in dein Ecore einfügen.
Dadurch das dein Modell explizit im Ecore bekannt ist lässt sich soetwas sehr leicht programmieren.

Auf die Schnelle habe ich zB dieses Beispiel gefunden:
http://www.conceptualprocessengineering.com/library/


----------



## Gast2 (16. Dez 2010)

Wildcard hat gesagt.:


> Du meinst aber explizit in nicht in der Properties View, sondern in zB einem Dialog oder einer Eclipse Forms Section?
> Jein. Es gibt EEF das die default Properties View durch eine Forms basierte ersetzt und dabei auch gleich Wizards/Dialoge mit der gleichen Funktionalität produziert.
> Dann gibt es noch den Generic EMF Editor der ebenfalls die Properties View durch eine Forms basierte Tabbed Properties View ersetzt, allerdings ohne dabei Code zu generieren.
> EEF ist IMO noch zu sehr incubation und der Generic EMF Editor verwendet wie gesagt die Properties View.
> ...



Ja ich sollte erst einmal genauer EMF lernen , bevor ich an sowas denke.
Aber war neugierig ob es sowas schon gibt. Aber des EEF wäre ja schon mal ein Ansatz ein paar Sachen verwenden zu können.
Besser wie grad alles mit händisch + databinding zu machen . Aber da ich nur am versuchen und lernen bin ist es nicht schlimm.
Muss auch sagen dass es mit ein paar eigenen Klasse und Factory methoden nicht viel Code ist einen Editor + Databinding zu machen. Undo/Redo sind ja auch gleich dabei.
Aber danke für die infos.


----------



## Wildcard (16. Dez 2010)

Wie gesagt, es ist sehr einfach Code zu schreiben der aus den Definitionen in EClasses automatisch Widgets instanziert und diese Widgets dann per Databinding an passende EObjects bindet. Primär Fleißarbeit, eine Fingerübung... ich würde davon ausgehen das entweder EEF bald entsprechend mature wird, oder jemand anders ein entsprechendes Projekt vorantreibt. Wenn du selbst so etwas haben willst und dich dabei auf die für dich relevanten Use-Cases beschränkst schafft man das an einem Abend, inklusive Validierung und Field Decorations.
Wenn du dann noch das WidgetToolkit für Forms subclassed kannst du sogar den 'Style' der erzeugten Widgets on-the-fly ändern, also zB wahlweise Eclipse Forms oder Plain Widgets mit grauem Hintergrund erzeugen.


----------



## Gast2 (17. Dez 2010)

Wildcard hat gesagt.:


> Wie gesagt, es ist sehr einfach Code zu schreiben der aus den Definitionen in EClasses automatisch Widgets instanziert und diese Widgets dann per Databinding an passende EObjects bindet. Primär Fleißarbeit, eine Fingerübung... ich würde davon ausgehen das entweder EEF bald entsprechend mature wird, oder jemand anders ein entsprechendes Projekt vorantreibt. Wenn du selbst so etwas haben willst und dich dabei auf die für dich relevanten Use-Cases beschränkst schafft man das an einem Abend, inklusive Validierung und Field Decorations.
> Wenn du dann noch das WidgetToolkit für Forms subclassed kannst du sogar den 'Style' der erzeugten Widgets on-the-fly ändern, also zB wahlweise Eclipse Forms oder Plain Widgets mit grauem Hintergrund erzeugen.



Joa klingt interessant, aber zuerst einmal sollte ich mich noch mit EMF beschäftigen, um alle Möglichkeiten zu kennen


----------



## Gast2 (20. Dez 2010)

Weißt du wie man das Databinding bei einem TableViewer mit EMF Undo/Redo gescheit macht?
Ich versteh es noch nicht so richtig bei einem Viewer...

Also ich denke ich benötige die Liste von Nodes: Diesen ContentProvider...
Aber weiter fehlt es mir jetzt...


```
ObservableListContentProvider cp =new ObservableListContentProvider();
	IEMFEditListProperty list = EMFEditProperties.list(editingDomain, Package.Literals.NODE__NODES);
		list.
```


----------



## Gast2 (20. Dez 2010)

Mhm so hab ich es mal hinbekommen passt zu unserem Beispiel oben wenns mal jemand braucht:


```
final TableViewer viewer = new TableViewer(parent);
	        AdapterFactory factory = new ProvidermodelItemProviderAdapterFactory();
	        viewer.setLabelProvider(new AdapterFactoryLabelProvider(factory));
	        
	        IEMFEditListProperty list = EMFEditProperties.list(editingDomain,ProvidermodelPackage.Literals.NODE__CHILDREN);
			ObservableListContentProvider cp =new ObservableListContentProvider();
			viewer.setContentProvider(cp);
	       
//	        viewer.setContentProvider(new AdapterFactoryContentProvider(factory));
	        final Node root = ProvidermodelFactory.eINSTANCE.createNode();
	        Node child = ProvidermodelFactory.eINSTANCE.createNode();
//	        root.getChildren().add(child);
	        viewer.setInput(list.observe(root));
	        
	        Button button = new Button(parent, SWT.PUSH);
	        button.setText("Add");
	        button.addSelectionListener(new SelectionAdapter() {
	        	@Override
	        	public void widgetSelected(SelectionEvent e) {
	        		
	        		   Command cmd = AddCommand.create(
	 			   	        editingDomain,
	 			   	    root,
	 			   	    ProvidermodelPackage.Literals.NODE__CHILDREN,
	 			   	ProvidermodelFactory.eINSTANCE.createNode());
	        		   System.out.println(cmd.canUndo());
	 			   	      if (cmd.canExecute())
	 			   	      {
	 			   	    	editingDomain.getCommandStack().execute(cmd);
	 			   	      }
//	        		 root.getChildren().add(ProvidermodelFactory.eINSTANCE.createNode());
	        	}
			});
```


----------



## Wildcard (20. Dez 2010)

Es gibt übrigens auch ein ChangeCommand. Damit kannst du ganz normal auf dem Domain Modell arbeiten (also ohne Commands) und bleibst trotzdem Undo/Redo fähig.
Den ObservableListContentProvider solltest du eigentlich nicht brauchen, der AdapterFactoryContentProvider müsste genügen.


----------



## Gast2 (20. Dez 2010)

Wildcard hat gesagt.:


> Es gibt übrigens auch ein ChangeCommand. Damit kannst du ganz normal auf dem Domain Modell arbeiten (also ohne Commands) und bleibst trotzdem Undo/Redo fähig.


He? Das ChangeCommand ist doch auch ein Command?
Oder wie führe ich das dann aus?
Meinst du so?
	
	
	
	





```
ChangeCommand changeCommand = new ChangeCommand(node) {
				
				@Override
				protected void doExecute() {
					node.getNodes().add(newNode);
					
				}
			};
			
			EditingDomain editingDomain = ((EditingDomain) HandlerUtil.getActiveEditor(event))
			.getEditingDomain();
			if (changeCommand.canExecute()) {

				editingDomain.getCommandStack().execute(changeCommand);
			}
```



Wildcard hat gesagt.:


> Den ObservableListContentProvider solltest du eigentlich nicht brauchen, der AdapterFactoryContentProvider müsste genügen.



Tatsache perfekt =)... Ist ja echt cool dann brauch man ja nur noch eine Zeile

```
EMFEditProperties.list(editingDomain,MyPackage.Literals.NODE__NODES);
```


----------



## Wildcard (20. Dez 2010)

> He? Das ChangeCommand ist doch auch ein Command?
> Oder wie führe ich das dann aus?
> Meinst du so?


Ja, so. Bei einem einfachen Command spielt es keine große Rolle, aber bei komplexeren Operationen ist das Change Command IMO komfortabler als n atomare Commands zu verketten.


----------



## Gast2 (20. Dez 2010)

Wildcard hat gesagt.:


> Ja, so. Bei einem einfachen Command spielt es keine große Rolle, aber bei komplexeren Operationen ist das Change Command IMO komfortabler als n atomare Commands zu verketten.



Okay. 
Was ich noch nicht verstehe ist das ComposedAdapterFactory die geb ich ja dem AdapterFactoryEditingDomain im Konstruktor mit. Und der ComposedAdapterFactory kann ich noch weitere Factory adden. Ich check net ganz für was das gut ist?


----------



## Wildcard (20. Dez 2010)

2 wichtige Gründe:
1. Eine Adapter Factory kann nicht nur die Edit Adapter erstellen, sondern auch Adapter die deinem Modell zB neue Funktionalität verleiht, ähnlich wie IAdaptable in Eclipse. Anstatt nun alle denkbaren Adapter Typen in einer einzigen Factory Bündeln zu müssen kannst du dank der Composed Adapter Factory mehrere verschiedene Adapter Factories implementieren und sie dann alle einer Composed Adapter Factory hinzufügen. Die Composed Adapter Factory unterstützt dann alle Adapter Typen der einzelnen Factories

2. Wenn man sich mit EMF vertraut gemacht hat will man es nicht mehr missen. Man verwendet EMF nun für so ziemlich jede Art Modell in der eigenen Anwendung. Manche dieser Modelle referenzieren wieder andere Modell. Willst du nun zB ein Modell in einem TreeViewer darstellen dessen Kinder wieder aus anderen Modellen kommen dann erlaubt dir die Composed Adapter Factory das du alle benötigten Item Provider in einer einzigen Factory bündelst. Der TreeViewer kann jetzt Objekte aus den unterschiedlichsten Domainen (Ecore Modellen) korrekt rendern ohne die anderen Modelle überhaupt zu 'kennen'.


----------



## Gast2 (20. Dez 2010)

Okay soweit bin ich wohl noch nicht ...



Wildcard hat gesagt.:


> 2 wichtige Gründe:
> 1. Eine Adapter Factory kann nicht nur die Edit Adapter erstellen, sondern auch Adapter die deinem Modell zB neue Funktionalität verleiht, ähnlich wie IAdaptable in Eclipse. Anstatt nun alle denkbaren Adapter Typen in einer einzigen Factory Bündeln zu müssen kannst du dank der Composed Adapter Factory mehrere verschiedene Adapter Factories implementieren und sie dann alle einer Composed Adapter Factory hinzufügen. Die Composed Adapter Factory unterstützt dann alle Adapter Typen der einzelnen Factories


Gibt es dazu ne gut Seite ? Wie man durch einen Adapater neue Funktioniltät einem Model gibt?


Aber das hat jetzt nichts mit dem undo/Redo support zu tun oder? Weil ich hab der ComposedAdapterFactory keine weitere Factory hinzugefügt und es klappt trotzdem


```
ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
		BasicCommandStack commandStack = new BasicCommandStack();
		
		editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, new HashMap<Resource, Boolean>());
```


----------



## Wildcard (20. Dez 2010)

> Aber das hat jetzt nichts mit dem undo/Redo support zu tun oder? Weil ich hab der ComposedAdapterFactory keine weitere Factory hinzugefügt und es klappt trotzdem


Indirekt schon. Du übergibst die globale Registry an die ComposedAdapterFactory. In der Registry sind alle ItemProviderAdapterFactories bekannt die sich per ExtensionPoint anmelden (der per default generierte Edit Code enthält auch eine plugin.xml mit einer solchen Extension).
Wenn nun ein Objekt deines Modells auf einen Item Provider adaptiert werden soll findet die Composed Adapter Factory die passende ItemProviderAdapterFactory über den Extension Point und instanziert sie. Damit werden deine Item Provider verwendet um die Labels, Kinder usw berechnen.
Beim Databinding werden dann die gleichen Item Provider verwendet um Commands zu erzeugen. Diese Commands werden über die Edit Domain ausgeführt und damit funktioniert Undo und Redo.


----------



## Gast2 (21. Dez 2010)

Wildcard hat gesagt.:


> Indirekt schon. Du übergibst die globale Registry an die ComposedAdapterFactory. In der Registry sind alle ItemProviderAdapterFactories bekannt die sich per ExtensionPoint anmelden (der per default generierte Edit Code enthält auch eine plugin.xml mit einer solchen Extension).
> Wenn nun ein Objekt deines Modells auf einen Item Provider adaptiert werden soll findet die Composed Adapter Factory die passende ItemProviderAdapterFactory über den Extension Point und instanziert sie. Damit werden deine Item Provider verwendet um die Labels, Kinder usw berechnen.
> Beim Databinding werden dann die gleichen Item Provider verwendet um Commands zu erzeugen. Diese Commands werden über die Edit Domain ausgeführt und damit funktioniert Undo und Redo.



Ah den Extension Point hab ich noch gar nie beachtet, gut dann macht das Sinn =)


----------



## Gast2 (7. Jan 2011)

Wildcard hat gesagt.:


> Nein, das stimmt nicht, siehe hier (ich habe im Ecore ein zusätliches Attribut 'name' eingefügt:
> 
> ```
> public class ViewPart1 extends ViewPart {
> ...



1.Klappt das eigentlich auch irgendwie wenn als input mehrere roots hat? oder muss man dann extra noch ein Root Object anlegen in EMF?

Also ich hab quasi eine Klasse Root und die kann mehrer Nodes aufnehmen.
Ich habe mehrere Roots die würde ich gerne auch anzeigen lassen.

2. Unterstützt die Factory auch DeferredTrees? Oder muss man hierfür noch etwas anlegen?
Also es wäre schön wenn da auch "Pending" steht wenn das Laden der Kinder etwas länger dauert? Ist das so ohne weiteres möglich?

Also sowas :

```
AdapterFactory factory = new ProvidermodelItemProviderAdapterFactory();
	        viewer.setLabelProvider(new AdapterFactoryLabelProvider(factory));
	        viewer.setContentProvider(new AdapterFactoryContentProvider(factory));
			List<Root> roots= new ArrayList<Root>();
			for(int i = 0 ;i < 5; i++){
				Root root = ProvidermodelFactory.eINSTANCE.createRoot();
				for(int j = 0; j<5;j++){
					Node node = ProvidermodelFactory.eINSTANCE.createNode();
					root.getChildren().add(node);
				}
				roots.add(root);
			}
	        
	        viewer.setInput(roots);
```


----------



## Wildcard (8. Jan 2011)

> 1.Klappt das eigentlich auch irgendwie wenn als input mehrere roots hat? oder muss man dann extra noch ein Root Object anlegen in EMF?


Wenn etwas nicht funktioniert mach dir einfach einen ContentProvider der an einen AdapterFactoryContentProvider delegiert aber bestimmte Anfragen anders/selbst handelt.



> 2. Unterstützt die Factory auch DeferredTrees? Oder muss man hierfür noch etwas anlegen?
> Also es wäre schön wenn da auch "Pending" steht wenn das Laden der Kinder etwas länger dauert? Ist das so ohne weiteres möglich?


Eclipse bietet dafür schon eine fertige Klasse. AFAIR hieß sie DeferredTreeContentManager


----------



## Alan4 (22. Aug 2016)

Hallo zusammen,
ich habe eine Frage bitte bezüglich EMF Forms.

Ich bin bis jetzt dazu bekommen, dass ich aus einer XSD ein Listobjekt nun nur Pull-Down-Menü in EMF Forms bekomme, und das wäre die Fragestellung, wie ich aus einer XSD eine ListBox in EMF Forms bekommen kann?
Ist das möglich? Oder es ist schon so festgelegt?

Außerdem könnte man die UI nach der Erstellung irgendwie als XML Beschreibung (Also XML Datei) abspeichern?

Ich bedanke mich im Voraus für eure Antwort und Unterstützung.

Beste Grüße
Alan Jaff


----------



## temi (24. Sep 2018)

bizitag hat gesagt.:


> Before writing your own utility functions, keep an eye on brand class.


Before writing an answer, keep an eye on the date of the question


----------



## Xyz1 (24. Sep 2018)

temi hat gesagt.:


> Before writing an answer, keep an eye on the date of the question


Welches Jahr haben wir denn nochmal heute/in diesem Jahr?  .... Bei dem ganzen Nicht mehr Zeitumsteller kann man ja wohl Durcheinander kommen  

(Oder anders, scannst du alte Themenlücken?)


----------

