Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Sphinx/tutorials"

(Adding Transient Nodes)
(Adding Transient Nodes)
Line 75: Line 75:
 
     }  
 
     }  
  
*getText(Object object) - for specifying the transient node name:<br>
+
*''getText''(Object object) - for specifying the transient node name:<br>
  
 
     @Override
 
     @Override
Line 82: Line 82:
 
     }
 
     }
  
*getChildrenFeatures(Object object) – for adding children feature (e.g., parameter values from a component) to display as children of the transient node in tree view:
+
*''getChildrenFeatures''(Object object) – for adding children feature (e.g., parameter values from a component) to display as children of the transient node in tree view:
  
 
     @Override
 
     @Override
Line 88: Line 88:
 
         if (childrenFeatures == null) {
 
         if (childrenFeatures == null) {
 
           super.getChildrenFeatures(object);
 
           super.getChildrenFeatures(object);
           childrenFeatures.add(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES);
+
           childrenFeatures.'''add'''(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES);
 
         }
 
         }
 
         return childrenFeatures;
 
         return childrenFeatures;
 +
    }
 +
 +
*''collectNewChildDescriptors''(Collection<Object> newChildDescriptors, Object object) – for adding New child actions to the transient node and allowing however creating children (e.g., parameter values) from this transient node.
 +
 +
    @Override
 +
    protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) {
 +
        super.collectNewChildDescriptors(newChildDescriptors, object);
 +
   
 +
        newChildDescriptors.'''add'''(createChildParameter(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES, 
 +
                                InstanceModel20Factory.eINSTANCE.createParameterValue()));
 +
    }
 +
 +
*''createDragAndDropCommand''(EditingDomain domain, Object owner, float location, int operations, int operation, Collection<?> collection) – for enabling dropping only possible children into the transient node.
 +
 +
  @Override
 +
  protected Command createDragAndDropCommand(EditingDomain domain, Object owner, float location, int operations, int operation,  Collection<?> collection) {
 +
      if (new '''AddCommand'''(domain, (EObject) owner, InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES, collection).'''canExecute'''()) {
 +
          return super.createDragAndDropCommand(domain, owner, location, operations, operation, collection);
 +
      }
 +
      return UnexecutableCommand.INSTANCE;
 +
  }
 +
 +
*''getResourceLocator()'' – for returning the resource locator for item provider's resources using specific plug-in Activator (e.g., org.eclipse.sphinx.examples.hummingbird20.edit.Activator).
 +
 +
  @Override
 +
  public ResourceLocator getResourceLocator() {
 +
      return Activator.INSTANCE;
 +
  }
 +
 +
'''Create (or modify if exist) an extended item provider''' (e.g., ExtendedComponentItemProvider) that extends an existing item provider (e.g., ComponentItemProvider) and overrides following methods:
 +
 +
*The first thing consists of adding required fields corresponding to transient nodes which are displaying as children of Component elements.
 +
 +
    protected ParameterValuesItemProvider parameterValuesItemProvider;
 +
    protected OutgoingConnectionsItemProvider outgoingConnectionsItemProvider;
 +
 +
*''getChildrenFeatures(Object object)'' – for no longer displaying directly ParameterValue and outgoing Connection objects as children of component objects into the view:
 +
 +
    @Override
 +
    public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) {
 +
        super.getChildrenFeatures(object);
 +
        childrenFeatures.'''remove'''(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES);
 +
        childrenFeatures.'''remove'''(InstanceModel20Package.Literals.COMPONENT__OUTGOING_CONNECTIONS);
 +
        return childrenFeatures;
 +
    }
 +
 +
*''getChildren(Object object)'' – for adding transient nodes (e.g., “Parameter Values” or “Outgoing Connections”) as children of component objects:
 +
 +
    @Override
 +
    public Collection<?> getChildren(Object object) {
 +
        if (parameterValuesItemProvider == null) {
 +
            parameterValuesItemProvider = new ParameterValuesItemProvider(adapterFactory, (Component) object);
 +
        }
 +
        if (outgoingConnectionsItemProvider == null) {
 +
            outgoingConnectionsItemProvider = new OutgoingConnectionsItemProvider(adapterFactory, (Component) object);
 +
        }
 +
   
 +
        List<Object> children = new ArrayList<Object>(super.getChildren(object));
 +
        children.'''add'''(parameterValuesItemProvider);
 +
        children.'''add'''(outgoingConnectionsItemProvider);
 +
   
 +
        return children;
 +
  }
 +
 +
*''createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index)'' and ''createRemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection)'' for setting the selection (i.e., the affected object) when adding or removing elements containing in transient nodes. The selection must be in this case the appropriate transient node.
 +
 +
    @Override
 +
    protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) {
 +
        return createWrappedCommand(super.createAddCommand(domain, owner, feature, collection, index), owner, feature);
 +
    }
 +
 +
    @Override
 +
    protected Command createRemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection) {
 +
        return createWrappedCommand(super.createRemoveCommand(domain, owner, feature, collection), owner, feature);
 +
    }
 +
 +
*Adds the ''createWrappedCommand(Command command, final EObject owner, final EStructuralFeature feature)'' method returning the appropriate transient node (i.e., the item provider) and the “real” affected object is its owner (e.g., the component object).
 +
 +
    protected Command createWrappedCommand(Command command, final EObject owner, final EStructuralFeature feature) {
 +
        if (feature == InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES ||
 +
            feature == InstanceModel20Package.Literals.COMPONENT__OUTGOING_CONNECTIONS) {
 +
            return '''new CommandWrapper'''(command) {
 +
                @Override
 +
                public Collection<?> '''getAffectedObjects()''' {
 +
                    Collection<?> affected = super.getAffectedObjects();
 +
                    if (affected.contains(owner)) {
 +
                        affected = Collections.singleton(feature == InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES ?
 +
            getParameterValues() : getOutgoingConnections());
 +
                    }
 +
                    return affected;
 +
                }
 +
    };
 +
        }
 +
        return command;
 +
    }
 +
 +
*''dispose()'' – for disposing any remaining children wrappers (including transient nodes) in the children store.
 +
 +
    @Override
 +
    public void dispose() {
 +
        super.dispose();
 +
        if (parameterValuesItemProvider != null && outgoingConnectionsItemProvider != null) {
 +
          ((IDisposable) parameterValuesItemProvider).dispose();
 +
          ((IDisposable) outgoingConnectionsItemProvider).dispose();
 +
        }
 +
    }
 +
 +
*Adds getters methods returning transient node fields (i.e., transient item providers)
 +
 +
  public Object getParameterValues() {
 +
      return parameterValuesItemProvider;
 +
  }
 +
 
 +
  public Object getOutgoingConnections() {
 +
      return outgoingConnectionsItemProvider;
 +
  }
 +
 +
'''
 +
Create (or modify if exist) an extended item provider for each child of the transient node''' (e.g., ExtendedParameterValueItemProvider or ExtendedConnectionItemProvider classes) that extends existing item providers (e.g., respectively ParameterValueItemProvider or ConnectionItemProvider):
 +
 +
*Creates a constructor that calls its super:
 +
 +
    public ExtendedParameterValueItemProvider(AdapterFactory adapterFactory) {
 +
        super(adapterFactory);
 +
    }
 +
 +
*Overrides the ''getParent(Object object)'' method to return the appropriate transient node:
 +
 +
    @Override
 +
    public Object getParent(Object object) {
 +
        Object component = super.getParent(object);
 +
        ExtendedComponentItemProvider componentItemProvider = (ExtendedComponentItemProvider) adapterFactory.adapt(component,
 +
IEditingDomainItemProvider.class);
 +
        return componentItemProvider != null ? componentItemProvider.getParameterValues() : null;
 +
    }
 +
 +
'''Create (or modify if exist) an extended item provider adapter factory''' (e.g., ''ExtendedInstanceModel20ItemProviderAdapterFactory'' class) that extends an existing adapter factory (e.g., ''InstanceModel20ItemProviderAdapterFactory'') and overrides methods allowing creating item providers to be use (for example objects of Component, ParameterValue or Connection types) and returning the appropriate extended item providers.
 +
 +
    @Override
 +
    public Adapter createComponentAdapter() {
 +
        return new ExtendedComponentItemProvider(this);
 +
    }
 +
 
 +
    @Override
 +
    public Adapter createParameterValueAdapter() {
 +
        return new ExtendedParameterValueItemProvider(this);
 +
    }
 +
   
 +
    @Override
 +
    public Adapter createConnectionAdapter() {
 +
        return new ExtendedConnectionItemProvider(this);
 +
    }
 +
 +
'''Add the new created extended item provider adapter factory to those to be use''' (i.e., adds ''ExtendedInstanceModel20ItemProviderAdapterFactory'' to ''Hummingbird20ItemProviderAdapterFactory'' adapter factories to be use. Hummingbird20ItemProviderAdapterFactory must be used to give custom adapter factory in content and label provider classes.
 +
 +
    public class Hummingbird20ItemProviderAdapterFactory extends ComposedAdapterFactory {
 +
        public '''Hummingbird20ItemProviderAdapterFactory'''() {
 +
            super(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
 +
            addAdapterFactory(new '''ExtendedInstanceModel20ItemProviderAdapterFactory'''());
 +
        }
 
     }
 
     }
  

Revision as of 05:35, 22 July 2011

Model Editing Enhancements

Customizing Tree Views

The EMF Edit framework and its code generator allow creating easily editors and tree views from EMF models. However, the structure that we want displaying into tree view may be often different to the EMF model structure. The EMF Edit framework provides also mechanisms allowing customizing editors and tree views.

In the following sections, we’ll describe how to easily customize tree views in order to display customized tree view structure. There are several kings of tree view customization. For instance, we may want displaying object references as children, adding non-model elements or suppressing model objects in tree views. We’ll use an extract of the Hummingbird meta-model to illustrate these kinds of tree views customization, as shown in Figure 1:

An extract of the Hummingbird meta-model 2.0

    Figure 1: An extract of the Hummingbird meta-model 2.0.

Displaying References as Children

This section describes how displaying references as children into tree views. For example, we’ll display source port and target component (of a Connection object) as children of objects of Connection type. Realizing this kind of view customization is quite simple. The following figure illustrates this kind of tree view customization:

An example displaying references as children
   Figure 2: An example displaying references as children.

We must initially override the getChildren (Object object) method of the appropriate item provider (e.g., ConnectionItemProvider. We decide creating an extended class of ConnectionItemProvider named ExtendedConnectionItemProvider) like this:

   @Override
   public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) {
       super.getChildrenFeatures(object);
       childrenFeatures.add(InstanceModel20Package.Literals.CONNECTION__SOURCE_PORT);
       childrenFeatures.add(InstanceModel20Package.Literals.CONNECTION__TARGET_COMPONENT);
       return childrenFeatures;
   }

We must also override the notifyChanged(Notification notification) method of the ExtendedConnectionItemProvider class for refreshing the view if referenced objects (e.g., source port or target component) are set or modified toward the property sheet.

   @Override
   public void notifyChanged(Notification notification) {
        updateChildren(notification);
   
        // For refreshing the view if source port and/or target component references are updated
        switch (notification.getFeatureID(Connection.class)) {
               case InstanceModel20Package.CONNECTION__SOURCE_PORT:
                    fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
               case InstanceModel20Package.CONNECTION__TARGET_COMPONENT:
                    fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
                    return;
       }
       super.notifyChanged(notification);
   }

If referenced objects are displayed as children under a transient node (i.e., a non-model object, please see section 1.1.2 for more details) then we must override in this case the notifyChanged(Notification notification) method of this transient node for refreshing node content like this:

   @Override
   public void notifyChanged(Notification notification) {
        updateTransientItemProviderChildren(notification, this);
   
        switch (notification.getFeatureID(Connection.class)) {
             case InstanceModel20Package.CONNECTION__SOURCE_PORT:
                  fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
             case InstanceModel20Package.CONNECTION__TARGET_COMPONENT:
                  fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
                  return;
        }
        super.notifyChanged(notification);
   }

Adding Transient Nodes

This section describes how to easily add transient nodes (i.e., non-model objects) between an object and its children into the tree view. We will for example introduce into the view, as shown in Figure 3, “Parameter Values” and “Outgoing Connections” transient nodes in order to separate children (of ParameterValue and Connection types) of Component model objects. SphinxExampleAddingTransientNode.jpg Figure 3: An example adding transient nodes.

The following are the main steps for adding non-model intermediary objects into views:

Create a transient node item provider class (e.g. ParameterValuesItemProvider) that extends org.artop.ecl.emf.edit.TransientItemProvider class and overrides following methods:

  • The first thing consists of defining a constructor that calls its super for giving the parent class (e.g., Component in our example) of the element like this:
   public ParameterValuesItemProvider(AdapterFactory adapterFactory, Component component) {
        super(adapterFactory, component); 
   } 
  • getText(Object object) - for specifying the transient node name:
   @Override
   public String getText(Object object) {
        return "Parameter Values"; //$NON-NLS-1$
   }
  • getChildrenFeatures(Object object) – for adding children feature (e.g., parameter values from a component) to display as children of the transient node in tree view:
   @Override
   public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) {
       if (childrenFeatures == null) {
          super.getChildrenFeatures(object);
          childrenFeatures.add(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES);
       }
       return childrenFeatures;
   }
  • collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) – for adding New child actions to the transient node and allowing however creating children (e.g., parameter values) from this transient node.
   @Override
   protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) {
        super.collectNewChildDescriptors(newChildDescriptors, object);
   
        newChildDescriptors.add(createChildParameter(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES,   
                                InstanceModel20Factory.eINSTANCE.createParameterValue()));
   }
  • createDragAndDropCommand(EditingDomain domain, Object owner, float location, int operations, int operation, Collection<?> collection) – for enabling dropping only possible children into the transient node.
  @Override
  protected Command createDragAndDropCommand(EditingDomain domain, Object owner, float location, int operations, int operation,  Collection<?> collection) {
      if (new AddCommand(domain, (EObject) owner, InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES, collection).canExecute()) {
          return super.createDragAndDropCommand(domain, owner, location, operations, operation, collection);
      }
      return UnexecutableCommand.INSTANCE;
  }
  • getResourceLocator() – for returning the resource locator for item provider's resources using specific plug-in Activator (e.g., org.eclipse.sphinx.examples.hummingbird20.edit.Activator).
  @Override
  public ResourceLocator getResourceLocator() {
      return Activator.INSTANCE;
  }

Create (or modify if exist) an extended item provider (e.g., ExtendedComponentItemProvider) that extends an existing item provider (e.g., ComponentItemProvider) and overrides following methods:

  • The first thing consists of adding required fields corresponding to transient nodes which are displaying as children of Component elements.
   protected ParameterValuesItemProvider parameterValuesItemProvider;
   protected OutgoingConnectionsItemProvider outgoingConnectionsItemProvider;
  • getChildrenFeatures(Object object) – for no longer displaying directly ParameterValue and outgoing Connection objects as children of component objects into the view:
   @Override
   public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) {
       super.getChildrenFeatures(object);
       childrenFeatures.remove(InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES);
       childrenFeatures.remove(InstanceModel20Package.Literals.COMPONENT__OUTGOING_CONNECTIONS);
       return childrenFeatures;
   }
  • getChildren(Object object) – for adding transient nodes (e.g., “Parameter Values” or “Outgoing Connections”) as children of component objects:
   @Override
   public Collection<?> getChildren(Object object) {
       if (parameterValuesItemProvider == null) {
           parameterValuesItemProvider = new ParameterValuesItemProvider(adapterFactory, (Component) object);
       }
       if (outgoingConnectionsItemProvider == null) {
            outgoingConnectionsItemProvider = new OutgoingConnectionsItemProvider(adapterFactory, (Component) object);
       }
   
       List<Object> children = new ArrayList<Object>(super.getChildren(object));
       children.add(parameterValuesItemProvider);
       children.add(outgoingConnectionsItemProvider);
   
       return children;
  }
  • createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) and createRemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection) for setting the selection (i.e., the affected object) when adding or removing elements containing in transient nodes. The selection must be in this case the appropriate transient node.
   @Override
   protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) {
       return createWrappedCommand(super.createAddCommand(domain, owner, feature, collection, index), owner, feature);
   }
   @Override
   protected Command createRemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection) {
       return createWrappedCommand(super.createRemoveCommand(domain, owner, feature, collection), owner, feature);
   }
  • Adds the createWrappedCommand(Command command, final EObject owner, final EStructuralFeature feature) method returning the appropriate transient node (i.e., the item provider) and the “real” affected object is its owner (e.g., the component object).
   protected Command createWrappedCommand(Command command, final EObject owner, final EStructuralFeature feature) {
        if (feature == InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES ||
            feature == InstanceModel20Package.Literals.COMPONENT__OUTGOING_CONNECTIONS) {
           return new CommandWrapper(command) {
               @Override
               public Collection<?> getAffectedObjects() {
                   Collection<?> affected = super.getAffectedObjects();
                   if (affected.contains(owner)) {
                       affected = Collections.singleton(feature == InstanceModel20Package.Literals.COMPONENT__PARAMETER_VALUES ? 
 		           getParameterValues() : getOutgoingConnections());
                   }
                   return affected;
               }

};

       }
       return command;
   }
  • dispose() – for disposing any remaining children wrappers (including transient nodes) in the children store.
   @Override
   public void dispose() {
       super.dispose();
       if (parameterValuesItemProvider != null && outgoingConnectionsItemProvider != null) {
          ((IDisposable) parameterValuesItemProvider).dispose();
          ((IDisposable) outgoingConnectionsItemProvider).dispose();
       }
   }
  • Adds getters methods returning transient node fields (i.e., transient item providers)
  public Object getParameterValues() {
      return parameterValuesItemProvider;
  }
  
  public Object getOutgoingConnections() {
      return outgoingConnectionsItemProvider;
  }

Create (or modify if exist) an extended item provider for each child of the transient node (e.g., ExtendedParameterValueItemProvider or ExtendedConnectionItemProvider classes) that extends existing item providers (e.g., respectively ParameterValueItemProvider or ConnectionItemProvider):

  • Creates a constructor that calls its super:
   public ExtendedParameterValueItemProvider(AdapterFactory adapterFactory) {
       super(adapterFactory);
   }
  • Overrides the getParent(Object object) method to return the appropriate transient node:
   @Override
   public Object getParent(Object object) {
       Object component = super.getParent(object);
       ExtendedComponentItemProvider componentItemProvider = (ExtendedComponentItemProvider) adapterFactory.adapt(component, 

IEditingDomainItemProvider.class);

       return componentItemProvider != null ? componentItemProvider.getParameterValues() : null;
   }

Create (or modify if exist) an extended item provider adapter factory (e.g., ExtendedInstanceModel20ItemProviderAdapterFactory class) that extends an existing adapter factory (e.g., InstanceModel20ItemProviderAdapterFactory) and overrides methods allowing creating item providers to be use (for example objects of Component, ParameterValue or Connection types) and returning the appropriate extended item providers.

   @Override
   public Adapter createComponentAdapter() {
       return new ExtendedComponentItemProvider(this);
   }
 
   @Override
   public Adapter createParameterValueAdapter() {
       return new ExtendedParameterValueItemProvider(this);
   }
   
   @Override
   public Adapter createConnectionAdapter() {
       return new ExtendedConnectionItemProvider(this);
   }

Add the new created extended item provider adapter factory to those to be use (i.e., adds ExtendedInstanceModel20ItemProviderAdapterFactory to Hummingbird20ItemProviderAdapterFactory adapter factories to be use. Hummingbird20ItemProviderAdapterFactory must be used to give custom adapter factory in content and label provider classes.

   public class Hummingbird20ItemProviderAdapterFactory extends ComposedAdapterFactory {
        public Hummingbird20ItemProviderAdapterFactory() {
            super(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
            addAdapterFactory(new ExtendedInstanceModel20ItemProviderAdapterFactory());
        }
   }

Suppressing Model Objects in views

Customizing Object Property Sheet

Back to the top