Categorías
Rich Client Platform(RCP)

Tutorial de Eclipse GEF – GEF MVC

Este ejemplo de código pertenece a la serie de tutoriales Eclipse RCP.

Eclipse GEF (Graphical Editing Framework) contiene tres componentes: Draw2d (org.eclipse.draw2d), GEF (MVC) (org.eclipse.gef) y Zest (org.eclipse.zest). Este tutorial trata sobre GEF MVC.

Un poco sobre GEF MVC

La idea clave de GEF es su diseño MVC. En resumen, Ver es la apariencia y Model almacena los datos para mostrar. El siguiente diagrama muestra la relación entre Modelo, Vista y Controlador. EditPart desempeña el papel de controlador. Lo que hace es obtener datos de un modelo y mostrarlos apropiadamente como una figura.

* Este diagrama es de www.eclipse.org/gef/reference/GEF%20Tutorial%202005.ppt – un tutorial de lectura obligada para el diseño de GEF.

Objetivo de esta aplicación

Eclipse GEF no es nuevo, así que encontré muchos tutoriales sobre Eclipse GEF. Algunos de ellos son demasiado simples y solo hablan de agregar algunas cifras. Otros hablan de hacer un editor. Lo que quiero hacer es agregar algunas figuras a una vista (no un editor) y conectar esas figuras.

En este tutorial, crearé algunas formas y agregaré conexiones entre ellas. Finalmente, se parece a lo siguiente:

eclipse-gef-tutorial

Ahora comencemos.

Paso 1: crear un proyecto de complemento

Cree un proyecto de complemento llamado «GEFTutorial» y luego use el asistente para agregar una vista. Si no sabe cómo hacer esto, aquí se explica cómo crear un complemento con una vista.

Esta vista se cambiará para contener nuestras figuras que se crearán a continuación.

Paso 2: crear modelos

Los modelos almacenan datos sobre formas. Hay 3 modelos diferentes en este ejemplo: modelo raíz, modelo de nodo y modelo de conexión.

Modelo raíz es la raíz o contenedor de otros modelos. Como se muestra en el siguiente código, puede crear algunos modelos de nodos y conexiones entre ellos.

package gefmvc;
 
import java.util.ArrayList;
import java.util.List;
 
public class Model {
	private List<NodeModel> nodes;
 
	public Model() {
 
		nodes = new ArrayList<NodeModel>();
 
		for (int i = 0; i < 10; i++) {
			NodeModel node = new NodeModel("Node " + i );
			nodes.add(node);
		}
 
		//set the connection here
		for (int i = 0; i < 10 - 1; i++) {
			NodeConnectionModel connection = new NodeConnectionModel();
 
			connection.setSource((NodeModel) nodes.get(i));
			connection.setTarget((NodeModel) nodes.get(i + 1));
 
			((NodeModel) nodes.get(i)).addSourceConnection(connection);
			((NodeModel) nodes.get(i + 1)).addTargetConnection(connection);
		}
 
	}
 
	public List<NodeModel> getNodes() {
		return nodes;
	}
}

Modelo de nodo corresponde a una figura o forma en una aplicación GEF. Almacena las propiedades requeridas, como etiqueta, tamaño, posiciones, etc.

package gefmvc;
 
import java.util.ArrayList;
import java.util.List;
 
public class NodeModel {
 
	private List<NodeConnectionModel> sourceConnections = new ArrayList<NodeConnectionModel>();
	private List<NodeConnectionModel> targetConnections = new ArrayList<NodeConnectionModel>();
 
	public NodeModel(String s) {
		label = s;
	}
 
	public String getLabel() {
		return label;
	}
 
 
	private final String label;
 
 
	public List<NodeConnectionModel> getSourceConnections() {
		return sourceConnections;
	}
 
	public List<NodeConnectionModel> getTargetConnections() {
		return targetConnections;
	}
 
	public void addSourceConnection(NodeConnectionModel iConnection) {
		sourceConnections.add(iConnection);
	}
 
	public void addTargetConnection(NodeConnectionModel iConnection) {
		targetConnections.add(iConnection);
	}
}
  Agregue un selector / selector de archivos para el desarrollo de Eclipse RCP

Modelo de conexión corresponde a los enlaces de conexión.

package gefmvc;
/**
 * This class is the model for connections between AnodeModel objects.
 */
public class NodeConnectionModel {
 
	private NodeModel source;
	private NodeModel target;
 
	public void setSource(NodeModel s) {
		source = s;
	}
 
	public void setTarget(NodeModel t) {
		target = t;
	}
}

Paso 3: crear vista y controlador

Hay 3 tipos de EditPart en este ejemplo. El primero es el EditPart ‘raíz’ que contiene el elemento raíz del modelo. Es responsable del modelo raíz. Los otros dos son verdaderos EditParts de ‘controlador’, cada uno responsable de controlar un modelo específico (NodeModel o ConnectionModel).

Parte superiorEditar

package gefmvc;
 
import java.util.List;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
 
public class TopEditPart extends AbstractGraphicalEditPart {
	protected IFigure createFigure() {
		Figure f = new FreeformLayer();
		f.setLayoutManager(new FreeformLayout());
 
		f.setBorder(new MarginBorder(1));
		// Create a layout for the graphical screen
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		gridLayout.horizontalSpacing = 40;
		gridLayout.verticalSpacing = 40;
		gridLayout.marginHeight = 20;
		gridLayout.marginWidth = 20;
		f.setLayoutManager(gridLayout);
		f.setOpaque(true);
		return f;
	}
 
	protected void createEditPolicies() {
 
	}
 
	protected List<NodeModel> getModelChildren() {
		List<NodeModel> children = ((Model) getModel()).getNodes();
		return children;
	}
}

ÁnodoEditarParte

package gefmvc;
 
import java.beans.PropertyChangeEvent;
import java.util.List;
import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.swt.graphics.Color;
 
 
public class AnodeEditPart extends AbstractGraphicalEditPart {
 
	/** The figure's anchor. */
	private ChopboxAnchor m_anchor;
 
	protected IFigure createFigure() {
		System.out.println("Called HelloEditPart.createFigure()");
		IFigure rectangle = new RectangleFigure();
		rectangle.setBackgroundColor(new Color(null, 200, 200, 200));
		m_anchor = new ChopboxAnchor(rectangle); 
		return rectangle;
	}
 
	protected void createEditPolicies() {
		System.out.println("Called HelloEditPart.createEditPolicies()");
	}
 
	protected void refreshVisuals() {
		NodeModel node = (NodeModel)getModel();
		//This is where the actual drawing is done,
		// Simply a rectangle with text
		Rectangle bounds = new Rectangle(50, 50, 50, 50);
		getFigure().setBounds(bounds);
		Label label = new Label(node.getLabel());
		label.setTextAlignment(PositionConstants.CENTER);
		label.setBounds(bounds.crop(IFigure.NO_INSETS));
		getFigure().add(label);
	}
 
 
	public void propertyChange(PropertyChangeEvent evt) {
	}
 
	protected List getModelSourceConnections() {
		List 	sourceConnections = ((NodeModel) getModel()).getSourceConnections();
		return sourceConnections;
	}
 
 
	protected List getModelTargetConnections() {
		List targetConnection = ((NodeModel) getModel()).getTargetConnections();
		return targetConnection;
	}
 
	protected ConnectionEditPart createConnection(Object iModel) {
		NodeConnectionEditPart connectPart = (NodeConnectionEditPart) getRoot()
				.getViewer().getEditPartRegistry().get(iModel);
		if (connectPart == null) {
			connectPart = new NodeConnectionEditPart();
			connectPart.setModel(iModel);
		}
		return connectPart;
	}
}
  Aprenda el marco de trabajo de Eclipse RCP mediante el uso de proyectos de código abierto

NodeConnectionEditPart

package gefmvc;
 
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
 
public class NodeConnectionEditPart extends AbstractConnectionEditPart{
	protected void createEditPolicies() {	}
}

GraphicalPartFactory es la fábrica para producir diferentes EditPart. (Es un patrón de diseño típico de fábrica).

package gefmvc;
 
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
 
public class GraphicalPartFactory implements EditPartFactory {
 
	public EditPart createEditPart(EditPart iContext, Object iModel) {
		System.out.println("Called GraphicalPartFactory.createEditPart("
				+ iContext + "," + iModel + ")");
 
		EditPart editPart = null;
		if (iModel instanceof Model) {
			editPart = new TopEditPart();
		} else if (iModel instanceof NodeModel) {
			editPart = new AnodeEditPart();
		}
 
		if (editPart != null) {
			editPart.setModel(iModel);
		}
		return editPart;
	}
}

Paso 4: agregar a la vista

En el primer paso, creamos una vista. Ahora las formas y conexiones se pueden agregar a la vista.

package geftutorial;
 
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.editparts.FreeformGraphicalRootEditPart;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import gefmvc.*;
 
public class View extends ViewPart {
	public static final String ID = "GEFTutorial.view";
 
	// Use a standard Viewer for the Draw2d canvas
	private ScrollingGraphicalViewer viewer = new ScrollingGraphicalViewer();
 
	// Use standard RootEditPart as holder for all other edit parts
	private RootEditPart rootEditPart = new FreeformGraphicalRootEditPart();
 
	// Custom made EditPartFactory, will automatically be called to create edit
	// parts for model elements
	private EditPartFactory editPartFactory = new GraphicalPartFactory();
	// The model
	private Model model;
 
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		// Create a dummy model
		model = new Model();
 
		// Initialize the viewer, 'parent' is the
		// enclosing RCP windowframe
		viewer.createControl(parent);
		viewer.setRootEditPart(rootEditPart);
		viewer.setEditPartFactory(editPartFactory);
 
		// Inject the model into the viewer, the viewer will
		// traverse the model automatically
		viewer.setContents(model);
 
		// Set the view's background to white
		viewer.getControl().setBackground(new Color(null, 255, 255, 255));
	}
 
	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}
  Tutorial de Eclipse RCP: aplicación de cliente enriquecido de Eclipse con una vista

El proyecto final en la vista del Explorador de proyectos debería tener el siguiente aspecto:

proyecto-explorador-vista

Referencias:

1. Un breve documento: http://wiki.eclipse.org/GEF_Description
2. Interacciones del FMAM: http://www.eclipse.org/gef/reference/interactions.html

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *