Áö´Ï°¡ GEF¸¦ ¸¸³µÀ»¶§4 (Connection)(2008/11/21)

JLab Çã¿øÁø

¡¡

À̹ø ±â»ç¿¡¼­´Â ¸ðµ¨°ú ¸ðµ¨À» ¿¬°áÇÒ Connection¿¡ ´ëÇØ¼­ ¾Ë¾Æ º»´Ù. Connection¿¡´Â ¾ÕÀ¸·Î ¼Ò°³ÇÒ ÄÚµåµéÀÌ ±×´ë·Î ÂÞ¿í ¾²ÀδÙ. ³ªÁß¿¡ ·¡ÆÛ·±½º ó·³ ÀÌ¿ëÇϱ⸦ ¹Ù¶õ´Ù.

¡¡

Connection

À§ ±×¸²Àº À̹ø ±â»ç¿¡¼­ ÇϰíÇÏ ÇÏ´Â ³»¿ëÀÇ ÃÖÁ¾ ¸ð½ÀÀÌ´Ù. GEFÀÇ ºä¾î ¿ä¼ÒµéÀÌ Å©°Ô 2°¡Áö·Î ³ª´¶´Ù. Component, ConnectionÀÌ´Ù. Component´Â ´ÜÀÏ·Î Á¸ÀçÇÏ´Â ¿ä¼ÒÀÌ´Ù. ConnectionÀº À§ ±×¸²¿¡¼­ ¿ø°ú »ç°¢ÇüÀ» ¿¬°áÇÑ ¼±ÀÌ´Ù. ConectionÀº Component¿Í Ư¼ºÀÌ ¸¹ÀÌ Â÷ÀÌ ³­´Ù.

1.ConnectionÀº Ȧ·Î Á¸Àç ÇÒ ¼ö ¾ø´Ù. À§ ±×¸²¿¡¼­ ¿øÀ̳ª »ç°¢ÇüÀÌ ¾ø´Ù¸é ConnectionÀº ¸¸µé ¼ö ¾ø´Ù.

2.¿¬°áµÈ ComponentÀÇ À§Ä¡ Å©±â¿¡ µû¶ó¼­ ¸ð¾çÀÌ ¹Ù²ï´Ù. ¶ÇÇÑ ComponentÀÇ edge¿¡ ¿¬°á µÈ´Ù.

3.¿¬°áµÈ Component°¡ »èÁ¦ µÇ¸é Connectionµµ »èÁ¦ µÈ´Ù. À§ ±×¸²¿¡¼­ ¿øÀ̳ª »ç°¢ÇüÀÌ »èÁ¦ µÈ´Ù¸é Connectionµµ »èÁ¦ µÈ´Ù.

´ÙÇàÈ÷µµ ¿¬°áÇÒ ComponentÀÇ Å©±â³ª À§Ä¡ º¯°æ ¹®Á¦´Â ¿ì¸®°¡ ½Å°æ¾²Áö ¾Ê¾Æµµ µÈ´Ù. ¿ì¸®°¡ ÀÌÀü ±â»ç¿¡¼­ Canvas¿¡ ±×¸®±â À§ÇØ EditPart¸¦ Á¤ÀÇÇÏ°í ÆÈ·§Æ®¿¡ º¸À̱âÀ§ÇØ PalleteFactory¸¦ Á¤ÀÇÇÑ Á¤µµÀÇ ÀÛ¾÷¸¸ ÇØÁÖ¸é OKÀÌ´Ù. (°ÅÁþ¸»ÀÌ´Ù, ÀÏÁ¤ÇÑ ÇüÅÂÀÇ Ãß°¡ ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù. ConnetionÀÇ ÄÚµå´Â ¾ÕÀ¸·Î ¼Ò°³ÇÒ Äڵ忡¼­ °ÅÀÌ ¹Ù²î´Â°ÍÀÌ ¾ø´Ù)

 

Model

ÀÌÀü Section¿¡¼­ º»°Å¿Í °°ÀÌ ConnectionÀÇ Æ¯¼º»ó Model¿¡ Ãß°¡ Á¤º¸°¡ ÇÊ¿äÇÏ´Ù. Connection°ú ¼öÁ¤µÈ SimpleModel¼øÀ¸·Î »ìÆì º¸ÀÚ.

package net.jlab.get.example.editor.model;


public class SimpleConnection extends SimpleModel {
  public static final int SOLID_CONNECTION = 1;
  public static final int DASHED_CONNECTION = 2;

  private SimpleModel startPoint;
  private SimpleModel endPoint;
  private boolean connected;

  public SimpleModel getStartPoint() {
    return startPoint;
  }

  public void setStartPoint(SimpleModel startPoint) {
    this.startPoint = startPoint;
  }

  public SimpleModel getEndPoint() {
    return endPoint;
  }

  public void setEndPoint(SimpleModel endPoint) {
    this.endPoint = endPoint;
  }

  public boolean isConnected() {
    return connected;
  }

  public void setConnected(boolean connected) {
    this.connected = connected;
  }
  
  public void disconnect() {
    if (connected) {
      startPoint.removeConnection(this);
      endPoint.removeConnection(this);
      setConnected(false);
    }
  }
  public void reconnect() {
    if (!connected) {
      startPoint.addConnection(this);
      endPoint.addConnection(this);
      setConnected(true);
    }
  }

  public void reconnect(SimpleModel start, SimpleModel end) {
    if (start == null || end == null || start == end) {
      throw new IllegalArgumentException();
    }
    disconnect();
    this.startPoint = start;
    this.endPoint = end;
    reconnect();
  }

}

SimpleConnecion.java

À§ Äڵ带 º¸¸é connect, reconnectµîÀÇ Äڵ尡 Àִµ¥ ConnectionÀÇ Command¿Í ControllerÀÇ ¿ªÇÒ ¶§¹®¿¡ ÇÊ¿äÇÑ ÄÚµåÀÌ´Ù. ¸Þ¼ÒµåÀÇ À̸§Àº »ó°ü ¾øÀ¸³ª ´ÙÀ½°ú °°Àº ¿ªÇÒÀ» ÇÏ´Â ¸Þ¼Òµå°¡ ÇÊ¿äÇÏ´Ù.

1. ¿¬°á ¸Þ¼Òµå - ÃÖÃÊ ¿¬°á »ý¼º½Ã ÇÊ¿äÇÑ ¸Þ¼Òµå ÀÌ´Ù.

2. ¿¬°á È®ÀÎ ¸Þ¼Òµå - Àڽſ¡°Ô ¿¬°áµÇ´Â Connection Á¦ÇѵîÀ» ó¸® ÇÒ¶§ ¾²ÀδÙ.

3. À翬°á ¸Þ¼Òµå - ÀÌ¹Ì »ý¼ºµÈ ConnectionÀÇ StartPoint³ª EndPoint¸¸ ¹Ù²Ü¶§ »ç¿ë µÈ´Ù.

package net.jlab.get.example.editor.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;

public class SimpleModel {
  /** Property ID to use when the location of this shape is modified. */
  public static final String LOCATION_PROP = "Simple.Location";
  /** Property ID to use then the size of this shape is modified. */
  public static final String SIZE_PROP = "Simple.Size";
  /** Property ID to use when the list of outgoing connections is modified. */
  public static final String SOURCE_CONNECTIONS_PROP = "Simple.SourceConn";
  /** Property ID to use when the list of incoming connections is modified. */
  public static final String TARGET_CONNECTIONS_PROP = "Simple.TargetConn";

  private int type;

  public void setType(int type) {
    this.type = type;
  }

  public int getType() {
    return type;
  }

  private String content;

  public String getContent() {
    return content;
  }

  public void setContent(String content) {
    this.content = content;
  }

  /** Location of this shape. */
  private Point location = new Point(00);
  /** Size of this shape. */
  private Dimension size = new Dimension(5050);

  public Dimension getSize() {
    return size;
  }

  public void setSize(Dimension size) {
    this.size = size;
    firePropertyChange(SIZE_PROP, null, size);

  }

  public Point getLocation() {
    return location;
  }

  public void setLocation(Point location) {
    this.location = location;
    firePropertyChange(LOCATION_PROP, null, location);

  }

  private transient PropertyChangeSupport pcsDelegate = new PropertyChangeSupport(
      this);

  /**
   * Attach a non-null PropertyChangeListener to this object.
   
   @param l
   *            a non-null PropertyChangeListener instance
   @throws IllegalArgumentException
   *             if the parameter is null
   */
  public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
    if (l == null) {
      throw new IllegalArgumentException();
    }
    pcsDelegate.addPropertyChangeListener(l);
  }

  /**
   * Remove a PropertyChangeListener from this component.
   
   @param l
   *            a PropertyChangeListener instance
   */
  public synchronized void removePropertyChangeListener(
      PropertyChangeListener l) {
    if (l != null) {
      pcsDelegate.removePropertyChangeListener(l);
    }
  }

  /**
   * Report a property change to registered listeners (for example edit
   * parts).
   
   @param property
   *            the programmatic name of the property that changed
   @param oldValue
   *            the old value of this property
   @param newValue
   *            the new value of this property
   */
  protected void firePropertyChange(String property, Object oldValue,
      Object newValue) {
    if (pcsDelegate.hasListeners(property)) {
      pcsDelegate.firePropertyChange(property, oldValue, newValue);
    }
  }

  /** List of outgoing Connections. */
  private List<SimpleConnection> sourceConnections = new ArrayList<SimpleConnection>();

  public List<SimpleConnection> getSourceConnections() {
    return sourceConnections;
  }

  public List<SimpleConnection> getTargetConnections() {
    return targetConnections;
  }

  /** List of incoming Connections. */
  private List<SimpleConnection> targetConnections = new ArrayList<SimpleConnection>();

  void addConnection(SimpleConnection simpleConnection) {
    if (simpleConnection == null) {
      throw new IllegalArgumentException();
    }
    if (simpleConnection.getStartPoint() == this) {
      sourceConnections.add(simpleConnection);
      firePropertyChange(SOURCE_CONNECTIONS_PROP, null, simpleConnection);
    else if (simpleConnection.getEndPoint() == this) {
      targetConnections.add(simpleConnection);
      firePropertyChange(TARGET_CONNECTIONS_PROP, null, simpleConnection);
    }
  }

  public void removeConnection(SimpleConnection simpleConnection) {
    if (simpleConnection == null) {
      throw new IllegalArgumentException();
    }
    if (simpleConnection.getStartPoint() == this) {
      sourceConnections.remove(simpleConnection);
      firePropertyChange(SOURCE_CONNECTIONS_PROP, null, simpleConnection);
    else if (simpleConnection.getEndPoint() == this) {
      targetConnections.remove(simpleConnection);
      firePropertyChange(TARGET_CONNECTIONS_PROP, null, simpleConnection);
    }

  }
}

SimpleModel.java

½ÇÁ¦ Ãß°¡ÇÑ ³»¿ëÀº À̰÷ ºÎÅÍ ÀÌ´Ù. sourceConnectionÀº startPoint°¡ ÀÚ½ÅÀÎ ConnecionÀ» ¶æ ÇÑ´Ù. ¹Ý´ë·Î targetConnectionÀº ÀÚ½ÅÀÌ endPointÀÎ ConnecionÀ» ¶æ ÇÑ´Ù. ¿Ö ÀÌ Çʵ尡 ÇÊ¿äÇÒ±î »ý°¢Çß¾ú´Âµ¥ GEFÀÇ Connection refresh ¸ÞÄ«´ÏÁò »ó ÇÊ¿äÇÏ´Ù. ÀÌ ºÎºÐÀÇ Äڵ尡 ¾øÀ¸¸é ³ªÁß¿¡ SimpleModelEditPart¿¡¼­ º°µµÀÇ ºÐ·ù ÀÛ¾÷À» ÇÏ´Â Äڵ带 »ðÀÔÇØ¾ßÇÑ´Ù. ´ÙÀ½ ºÎºÐµéÀº ÀÚ¼¼È÷ º¼ ºÎºÐÀº ¾ø°í SOURCE_CONNECTIONS_PROP¿Í TARGET_CONNECTIONS_PROP°¡ Àִµ¥ À̰ÍÀº ¾î¶² Component¸¦ refreshÇÒ°ÍÀΰ¡ ¹®Á¦ ¶§¹®¿¡ Á¸Àç ÇÑ´Ù.

before

after

À§¿Í °°ÀÌ ¹Ù²î¾ú´Ù¸é ¾î¶²°ÍµéÀÌ ´Ù½Ã ±×·ÁÁ®¾ß ÇÒ±î? ¿øÀÇ StartPoint¿Í ÇÏ´Ü »ç°¢ÇüÀÇ StartPoint°¡ ´Ù½Ã ±×·ÁÁ®¾ß ÇÑ´Ù.(Connecion ÀÚüÀÇ Refresh´Â GEF°¡ ÀÚµ¿À¸·Î ó¸®ÇØÁØ´Ù)

¿©±â ±îÁöÀÇ ÄÚµå·Î ¸ðµ¨ ¼öÁØ¿¡¼­ ¿¬°áµÉ Áغñ°¡ ³¡³µ´Ù.

Pallete

GEF °³¹ß»ó EditPart°¡ ¸ÕÀú Áö¸¸ Äڵ尡 ÀÛÀ¸¹Ç·Î ÆÈ·§Æ® ºÎÅÍ ¾Ë¾Æº¸ÀÚ.

package net.jlab.get.example.editor;

import net.jlab.get.example.editor.model.SimpleConnection;
import net.jlab.get.example.editor.model.SimpleModel;

import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.MarqueeToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.PaletteToolbar;
import org.eclipse.gef.palette.PanningSelectionToolEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.SimpleFactory;
import org.eclipse.jface.resource.ImageDescriptor;

final class SimplePaletteFactory {
  static PaletteRoot createPalette() {
    PaletteRoot palette = new PaletteRoot();
    palette.add(createToolsGroup(palette));
    palette.add(createShapesDrawer());
    return palette;
  }

  private static PaletteEntry createToolsGroup(PaletteRoot palette) {
    PaletteToolbar toolbar = new PaletteToolbar("Tools");

    // Add a selection tool to the group
    ToolEntry tool = new PanningSelectionToolEntry();
    toolbar.add(tool);
    palette.setDefaultEntry(tool);
    
    // Add a marquee tool to the group
    toolbar.add(new MarqueeToolEntry());
    
    // Add (solid-line) connection tool 
    tool = new ConnectionCreationToolEntry(
        "Solid connection",
        "Create a solid-line connection",
        new CreationFactory() {
          public Object getNewObject() { return null}
          // see ShapeEditPart#createEditPolicies() 
          // this is abused to transmit the desired line style 
          public Object getObjectType() { return SimpleConnection.SOLID_CONNECTION; }
        },
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/connection_s16.gif"),
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/connection_s24.gif"));
    toolbar.add(tool);
    
    // Add (dashed-line) connection tool
    tool = new ConnectionCreationToolEntry(
        "Dashed connection",
        "Create a dashed-line connection",
        new CreationFactory() {
          public Object getNewObject() { return null}
          // see ShapeEditPart#createEditPolicies()
          // this is abused to transmit the desired line style 
          public Object getObjectType() { return SimpleConnection.DASHED_CONNECTION; }
        },
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/connection_d16.gif"),
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/connection_d24.gif"));
    toolbar.add(tool);
    
    return toolbar;
  }
  
  private static PaletteContainer createShapesDrawer() {
    PaletteDrawer componentsDrawer = new PaletteDrawer("Simple");

    CombinedTemplateCreationEntry component = new CombinedTemplateCreationEntry(
        "Ellipse"
        "Create an elliptical shape"
        SimpleModel.class,
        new SimpleFactory(SimpleModel.class)
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/ellipse16.gif")
        ImageDescriptor.createFromFile(SimpleEditor.class, "icons/ellipse24.gif"));
    componentsDrawer.add(component);

    return componentsDrawer;
  }
}

SimplePaletteFactory.java

ÀÌ ºÎºÐµµ µüÈ÷ ¼³¸íÇÒ ºÎºÐÀº ¾ø´Ù. Äڵ尡 Ãß°¡µÈ ºÎºÐÀº ºÎºÐÀÌ´Ù. ±×³É ConnecionToolEntry´Â ÀÌ·¸°Ô Ãß°¡Çϴ±¸³ª ¶ó°í ¹Þ¾ÆµéÀÌÀÚ. getObjectType() ºÎºÐ¸¸ ÀÏ´Ü ºÁµÎÀÚ ³ªÁß¿¡ ¿¬°áµÈ Äڵ尡 ÀÖ´Ù.

¿©±â ±îÁöÀÇ Äڵ常À» ¼öÁ¤ÇÏ¿© Ãß°¡ÇÏ¸é ÆÈ·§Æ®¿¡¼­ ConnecionToolEntry¸¦ ¼±Åà ÇÒ ¼ö ÀÖ°í ¸ðµ¨ÀÇ ¼±ÅÃÀº EditPolicy ¶§¹®¿¡ ¾ÈµÇ´Â°ÍÀ¸·Î Ç¥½ÃµÈ´Ù.

 

EditFactory

ÀÌ ºÎºÐ¿¡¼­ Ãß°¡ÇÒ°ÍÀº ¾øÁö¸¸ ÇÊÀÚ°¡ ½Ç¼öÇÑ°Í ¶§¹®¿¡ ¸ðµç Äڵ带 ¿Ï¼ºÇصµ Á¦´ë·Î ½ÇÇà µÇÁö ¾Ê±â ¶§¹®¿¡ ¾ð±Þ ÇÑ´Ù.

(÷ºÎÇÑ ÇÁ·ÎÁ§Æ®¿¡´Â Á¦´ë·Î ¼öÁ¤µÇ¾î ÀÖ´Ù)
public class SimpleEditPartFactory implements EditPartFactory {

  @Override
  public EditPart createEditPart(EditPart context, Object model) {
    EditPart part = null;

    if (model instanceof SimpleConnection) {
      part = new SimpleConnectionEditPart();
      part.setModel(model);
      return part;
    }
    if (model instanceof SimpleDiagram) {
      part = new SimpleDiagramEditPart();
      part.setModel(model);
      return part;
    }
    if (model instanceof SimpleModel) {
      part = new SimpleModelEditPart();
      part.setModel(model);
      return part;
    }
    part.setModel(model);
    return part;
  }

}

SimpleEditPartFactory.java

SimpleConnecion°ú SimpleDiagram ¸ðµÎ SimpleModelÀ» È®ÀåÇÑ Å¬·¡½º¶ó connection°ú diagram º¸´Ù SimpleModelÀ» È®ÀÎ ÇÏ´Â Äڵ尡 À§¿¡ ÀÖÀ¸¸é Ç׽à SimpleModelEditPart¸¸ ¸®ÅÏÇÏ°Ô µÈ´Ù.

 

Edit Part

ÀÌ ºÎºÐÀº ¼öÁ¤µÈ Äڵ尡 ¸¹Àº ÆíÀÌ´Ù. ¸¶Âù°¡Áö·Î ConnectionÀÇ EditPart¿Í SimpleModelÀÇ EditPart ¼øÀ¸·Î »ìÆì º¸ÀÚ.

package net.jlab.get.example.editor.edit;

import net.jlab.get.example.editor.command.SimpleConnectionDeleteCommand;
import net.jlab.get.example.editor.model.SimpleConnection;

import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEditPolicy;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.gef.requests.GroupRequest;

public class SimpleConnectionEditPart extends AbstractConnectionEditPart {

  /*
   * (non-Javadoc)
   
   * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
   */
  protected void createEditPolicies() {
    installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
        new ConnectionEndpointEditPolicy());
    // Allows the removal of the connection model element
    installEditPolicy(EditPolicy.CONNECTION_ROLE,
        new ConnectionEditPolicy() {
          protected Command getDeleteCommand(GroupRequest request) {
            return new SimpleConnectionDeleteCommand(
                getCastedModel());
          }
        });
  }

  /*
   * (non-Javadoc)
   
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
   */
  protected IFigure createFigure() {
    PolylineConnection connection = (PolylineConnectionsuper
        .createFigure();
    connection.setTargetDecoration(new PolygonDecoration());
    connection.setLineStyle(getCastedModel().getType());
    if (getCastedModel().getType() == SimpleConnection.SOLID_CONNECTION)
      connection.setLineStyle(Graphics.LINE_SOLID);
    if (getCastedModel().getType() == SimpleConnection.DASHED_CONNECTION)
      connection.setLineStyle(Graphics.LINE_DASH);
    return connection;
  }

  private SimpleConnection getCastedModel() {
    return (SimpleConnectiongetModel();
  }

}

SimpleConnectionEditPart.java

SimpleModelEditPart¿Í ¸¶Âù°¡Áö·Î ±âº»ÄÚµåÀÌ´Ù.

SimplePaletteFactory¿¡¼­ ³Ñ¾î¿À´Â ÀÎÀÚ¸¦ ÀÌ¿ëÇØ¼­ ½ºÅ¸ÀÏÀ» ±¸ºÐÇØ »ý¼ºÇÑ´Ù.

package net.jlab.get.example.editor.edit;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import net.jlab.get.example.editor.command.SimpleConnectionCreateCommand;
import net.jlab.get.example.editor.command.SimpleConnectionReconnectCommand;
import net.jlab.get.example.editor.model.SimpleConnection;
import net.jlab.get.example.editor.model.SimpleModel;

import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Ellipse;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.NodeEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;

public class SimpleModelEditPart extends AbstractGraphicalEditPart implements
    NodeEditPart, PropertyChangeListener {

  private ConnectionAnchor anchor;

  @Override
  /*
   * (non-Javadoc)
   
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
   */
  protected IFigure createFigure() {
    SimpleModel model = (SimpleModelthis.getModel();
    IFigure f = null;
    if (model.getType() == 1) {
      f = new Ellipse();
      f.setOpaque(true)// non-transparent figure
      f.setBackgroundColor(ColorConstants.green);
    }

    if (model.getType() != 2) {
      f = new RectangleFigure();
      f.setOpaque(true)// non-transparent figure
      f.setBackgroundColor(ColorConstants.yellow);
      f.setLocation(model.getLocation());
      f.setSize(5050);
    }
    return f;
  }

  /*
   * (non-Javadoc)
   
   * @seejava.beans.PropertyChangeListener#propertyChange(java.beans.
   * PropertyChangeEvent)
   */
  public void propertyChange(PropertyChangeEvent evt) {
    String prop = evt.getPropertyName();
    if (SimpleModel.SIZE_PROP.equals(prop)
        || SimpleModel.LOCATION_PROP.equals(prop)) {
      refreshVisuals();
    else if (SimpleModel.SOURCE_CONNECTIONS_PROP.equals(prop)) {
      refreshSourceConnections();
    else if (SimpleModel.TARGET_CONNECTIONS_PROP.equals(prop)) {
      refreshTargetConnections();
    }
  }

  /**
   * Upon activation, attach to the model element as a property change
   * listener.
   */
  public void activate() {
    if (!isActive()) {
      super.activate();
      ((SimpleModelgetModel()).addPropertyChangeListener(this);
    }
  }

  /**
   * Upon deactivation, detach from the model element as a property change
   * listener.
   */
  public void deactivate() {
    if (isActive()) {
      super.deactivate();
      ((SimpleModelgetModel()).removePropertyChangeListener(this);
    }
  }

  private SimpleModel getCastedModel() {
    return (SimpleModelgetModel();
  }

  protected void refreshVisuals() {
    // notify parent container of changed position & location
    // if this line is removed, the XYLayoutManager used by the parent
    // container
    // (the Figure of the ShapesDiagramEditPart), will not know the bounds
    // of this figure
    // and will not draw it correctly.
    Rectangle bounds = new Rectangle(getCastedModel().getLocation(),
        getCastedModel().getSize());
    ((GraphicalEditPartgetParent()).setLayoutConstraint(this,
        getFigure(), bounds);
  }

  @Override
  protected void createEditPolicies() {
    installEditPolicy(EditPolicy.COMPONENT_ROLE,
        new SimpleModelEditPolicy());

    installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE,
        new GraphicalNodeEditPolicy() {

          @Override
          protected Command getConnectionCompleteCommand(
              CreateConnectionRequest request) {
            SimpleConnectionCreateCommand cmd = (SimpleConnectionCreateCommandrequest
                .getStartCommand();
            cmd.setEndPoint((SimpleModelgetHost().getModel());
            return cmd;
          }

          @Override
          protected Command getConnectionCreateCommand(
              CreateConnectionRequest request) {
            SimpleModel source = (SimpleModelgetHost().getModel();
            int style = ((Integerrequest.getNewObjectType())
                .intValue();
            SimpleConnectionCreateCommand cmd = new SimpleConnectionCreateCommand(
                source, style);
            request.setStartCommand(cmd);
            return cmd;
          }

          @Override
          protected Command getReconnectSourceCommand(
              ReconnectRequest request) {
            SimpleConnection conn = (SimpleConnectionrequest
                .getConnectionEditPart().getModel();
            SimpleModel newSource = (SimpleModelgetHost()
                .getModel();
            SimpleConnectionReconnectCommand cmd = new SimpleConnectionReconnectCommand(
                conn);
            cmd.setNewSource(newSource);
            return cmd;
          }

          @Override
          protected Command getReconnectTargetCommand(
              ReconnectRequest request) {
            SimpleConnection conn = (SimpleConnectionrequest
                .getConnectionEditPart().getModel();
            SimpleModel newTarget = (SimpleModelgetHost()
                .getModel();
            SimpleConnectionReconnectCommand cmd = new SimpleConnectionReconnectCommand(
                conn);
            cmd.setNewTarget(newTarget);
            return cmd;
          }
        });

  }

  protected ConnectionAnchor getConnectionAnchor() {
    if (anchor == null) {
      anchor = new ChopboxAnchor(getFigure());
    }
    return anchor;
  }

  @Override
  public ConnectionAnchor getSourceConnectionAnchor(
      ConnectionEditPart connection) {
    if (anchor == null) {
      anchor = new ChopboxAnchor(getFigure());
    }
    return anchor;
  }

  @Override
  public ConnectionAnchor getSourceConnectionAnchor(Request request) {
    return getConnectionAnchor();
  }

  @Override
  public ConnectionAnchor getTargetConnectionAnchor(
      ConnectionEditPart connection) {
    return getConnectionAnchor();
  }

  @Override
  public ConnectionAnchor getTargetConnectionAnchor(Request request) {
    return getConnectionAnchor();
  }

  /*
   * (non-Javadoc)
   
   * @see
   * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections
   * ()
   */
  protected List getModelSourceConnections() {
    return getCastedModel().getSourceConnections();
  }

  /*
   * (non-Javadoc)
   
   * @see
   * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections
   * ()
   */
  protected List getModelTargetConnections() {
    return getCastedModel().getTargetConnections();
  }

}

Model Section¿¡¼­ ¼³¸íÇÑ Refresh ¸ÞÄ«´ÏÁò°ú ¿¬°áÇØ¼­ »ý°¢ÇÏ¸é µÈ´Ù.

Connection¿¡¼­ delete¸¦ Á¦¿ÜÇÑ ÇÊ¿äÇÑ ¸í·É¾î ÁýÇÕÀÌ´Ù.

~

¾ÆÁ÷ ConnectionÀÌ ¿Ï·á µÇÁö ¾ÊÀº »óÅ¿¡¼­ÀÇ VisualÀ» ó¸® ÇϴºκÐÀÌ´Ù. ÀÌ Äڵ尡 ¾øÀ¸¸é ÄÁ³Ø¼Ç ¿¬°á½Ã Canvas ¿µ¿ª¿¡ ConnectionÀÌ º¸ÀÌÁö ¾Ê´Â´Ù. ´ÙÀ½ ¼½¼Ç¿¡¼­ ÀÚ¼¼È÷ ¼³¸í ÇÑ´Ù.

Connection ¿Ï·á ÈÄ¿¡ 󸮸¦ À§ÇÑ ÄÚµåÀÌ´Ù. ÀÌ Äڵ尡 ¾øÀ¸¸é ÄÁ³Ø¼Ç ¿Ï·á ÈÄ Canvas¿µ¿ª¿¡ ConnectionÀÌ º¸ÀÌÁö ¾Ê´Â´Ù. ´ÙÀ½ ¼½¼Ç¿¡¼­ ÀÚ¼¼È÷ ¼³¸í ÇÑ´Ù.

 

Anchor

±â»ç óÀ½¿¡ º¸°í ½ÃÀÛÇÑ ±×¸²ÀÌ´Ù. º¸¸é Âü ±×·²½ÎÇÏ°Ô ¿¬°áµÇ¾î ÀÖ´Ù. ±âƯÇϰԵµ Çǰܸ¦ ¿ñÁ÷¿©µµ ±×·²½ÎÇÏ°Ô ¿¬°áÇØ ÁØ´Ù. GEFÀÇ Ä˹ö½º¿¡ ±×·ÁÁö´Â FigureµéÀº À§Ä¡¿Í Å©±â¸¦ °¡Áö°í ÀÖ´Ù. ÇÏÁö¸¸ ConnectionÀº À§Ä¡¿Í Å©±â°¡ ¾ø´Ù(°­Á¦ ÁöÁ¤Àº °¡´ÉÇÏ´Ù). 2°³ÀÇ Figure¿¡ µû¶ó¼­ À§Ä¡¿Í Å©±â°¡ ÀÚµ¿À¸·Î °è»êµÈ´Ù. ¾î¶»°Ô GEF°¡ À§Ä¡¿Í Å©±â¸¦ ÀÚµ¿À¸·Î °è»ê ÇÏ´ÂÁö ¾Ë¾Æº¸ÀÚ.

  /*
   * (non-Javadoc)
   
   * @see
   * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections
   * ()
   */
  protected List getModelSourceConnections() {
    return getCastedModel().getSourceConnections();
  }

  /*
   * (non-Javadoc)
   
   * @see
   * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections
   * ()
   */
  protected List getModelTargetConnections() {
    return getCastedModel().getTargetConnections();
  }

¿ì¼± ÇØ´ç ¸ðµ¨(ÇǰÜ)¿¡ ¿¬°áÀÌ ÀÖ´ÂÁö ºÎÅÍ È®ÀÎ ÇÑ´Ù. 5ÀÇ °æ¿ì´Â ÇØ´ç ¸ðµ¨ÀÌ ¿¬°á¼±ÀÇ ½ÃÀÛÁ¡ ÀÎ °æ¿ì ÀÌ´Ù. ±×¸²¿¡¼­ ¿ø¿¡ ÇØ´ç µÈ´Ù. 6ÀÇ °æ¿ì ¹Ý´ë·Î ÇØ´ç ¸ðµ¨ÀÌ ¿¬°á¼±ÀÇ ³¡ Á¡ÀÎ °æ¿ì´Ù. GEF ÇØ´ç ¸ðµ¨ÀÇ refresh°¡ ÇÊ¿ä ÇÒ¶§(³»¿ëÀÌ ¹Ù²î°Å³ª À§Ä¡ À̵¿ µîµî) ÀÌ ¸Þ¼Òµå¸¦ È£ÃâÇØ¼­ ÇØ´ç ¸ðµ¨ÀÌ ¿¬°áÀÚ¸¦ °¡Áö°í ÀÖ´ÂÁö È®ÀÎÇÑ´Ù. GEF´Â ÇØ´ç ¿¬°áÀÚÀÇ EditPart°¡ ¾øÀ» °æ¿ì ¿¬°áÀÚÀÇ EditPart¸¦ »ý¼ºÇϰí Ä˹ö½º¿¡ ±×¸± Áغñ¸¦ ÇÑ´Ù. ´ÙÀ½¿¡´Â SourceConnection ¸ðµ¨ÀÇ EditPart¿¡ ÀÖ´Â getSourceConnectionAnchor¸¦ È£Ãâ ÇÑ´Ù. ÀÌ ¸Þ¼Òµå¸¦ ÅëÇØ ½ÃÀÛ Á¡ÀÇ À§Ä¡¸¦ °è»ê ÇÒ ¼ö ÀÖ´Â ConnectionAnchor¸¦ ¹Þ´Â´Ù. ±× ´ÙÀ½¿¡´Â TartgetConnectin ¸ðµ¨ÀÇ EditPart¿¡ ÀÖ´Â getTargetConnectionAnchor¸¦ È£Ãâ ÇÏ¿© ³¡Á¡ÀÇ À§Ä¡¸¦ °è»ê ÇÒ ¼ö ÀÖ´Â ConnectionAnchor¸¦ ¹Þ´Â´Ù.

  @Override
  public ConnectionAnchor getSourceConnectionAnchor(
      ConnectionEditPart connection) {
    if (anchor == null) {
      anchor = new ChopboxAnchor(getFigure());
    }
    return anchor;
  }

  @Override
  public ConnectionAnchor getTargetConnectionAnchor(
      ConnectionEditPart connection) {
    return getConnectionAnchor();
  }

Drawing connection sequence

¼Ò½º¸¦ À¯½ÉÈ÷ º» µ¶ÀÚ¶ó¸é getSourceConnectionAnchor ¿Í getTargetConnectionAnchor¸Þ¼Òµå°¡ 2°¡Áö Á¾·ù¶ó´Â°ÍÀ» ¾Ë °ÍÀÌ´Ù. Request¸¦ ÀÎÀÚ·Î ÇÏ´Â ¸Þ¼Òµå ÀÌ´Ù. ÀÌÀü¿¡ ConnectionEditPart¸¦ ÀÎÀÚ·Î ÇÏ´Â ¸Þ¼Òµå´Â ¿¬°á ¿Ï·áÈÄÀÇ Ä˹ö½º¿¡ ±×·ÁÁö´Â°ÍÀ» ÁÖ°ü Çϰí Request¸¦ ÀÎÀÚ·Î ÇÏ´Â ¸Þ¼Òµå´Â ¿¬°áÀÌ ¿Ï·á µÇ±â Àü Ä˹ö½º¿¡ ±×·ÁÁö´Â°ÍÀ» ÁÖ°ü ÇÑ´Ù. ±×°Ô ±×°Å ¾Æ´Ñ°¡ »ý°¢ ÇÒ ¼öµµ ÀÖÁö¸¸ ¸ðµ¨ Ư¼º »ó 2¿øÈ­ µÉ ¼öµµ ÀÖ´Ù.

  @Override
  public ConnectionAnchor getSourceConnectionAnchor(Request request) {
    return getConnectionAnchor();
  }

  @Override
  public ConnectionAnchor getTargetConnectionAnchor(Request request) {
    return getConnectionAnchor();
  }

À§ÀÇ ÇÊÀÚ°¡ ´ÙÀ½ ±â»ç¸¦ À§ÇØ ¸¸µé°í ÀÖ´Â SequenceDiagramÀ» º¸ÀÚ. óÀ½¿¡´Â Object¿Í LifeLine(±×¸²ÀÇ Á¡¼±)¸¸ ÀÖ´Ù. Object¿¡ ¸Þ¼¼Áö¸¦ Ãß°¡Çϸé ActivationÀÌ »ý¼ºµÇ°í Message ConnectionÀÌ ¿¬°áµÈ´Ù. ÀϹÝÀûÀÎ GEF ConnectionÀº StartPointÀÇ Model°ú EndPointÀÇ ModelÀÌ ¿¬°á µÈ´Ù. ÇÏÁö¸¸ À§¿Í °°ÀÌ ÆíÁý Ư¼º»ó Connecion À̺¥Æ®¸¦ ¹Þ´Â LifeLine°ú LifeLineÀÌ ¿¬°áµÇ´Â ÇüŰ¡ ¾Æ´Ñ ´Ù¸¥ ¸ðµ¨¿¡ ConnecionÀ» ¿¬°á ÇÒ °æ¿ì 2¿øÈ­µÈ Connecion Drawing RuleÀÌ ÇÊ¿ä ÇÒ ¼ö ÀÖ´Ù.

 

ConnectionAnchor

ÀÌÀü ¼½¼ÇÀ» ÅëÇØ GEF°¡ ¾î¶»°Ô ConnectionÀ» ±×¸®´ÂÁö ¾Ë¾Ò´Ù. ÀÌÁ¦ ¾î¶»°Ô ÀûÀýÇÑ À§Ä¡¸¦ °è»ê ÇÏ´ÂÁö ¾Ë¾Æº¸ÀÚ.

À̹ø ±â»ç¿¡¼­ Âü ÀÚÁÖ º¸´Â ±×¸²ÀÌ´Ù. ÀÌ ±â»çÀÇ ¿¹Á¦³ª GEF ExampleÀ» ½ÇÇà ÇØ º» µ¶ÀÚ¶ó¸é ¾Ë°ÚÁö¸¸, ConnectionÀÌ µÎ°³ÀÇ FigureÀÇ Áß½ÉÁ¡ ±âÁØÀ¸·Î Figure¿Ü°¢ÀÇ ±³Â÷Á¡ÀÌ StartPoint¿Í EndPoint°¡ µÈ´Ù.

Áï ¿øÀÇ ConnectionAnchor¿Í »ç°¢ÇüÀÇ ConnectionAnchor°¡ ÀÌ ±³Â÷Á¡À» °è»êÇÏ¿© GEFÇÑÅ× ¾Ë·Á Áִ°ÍÀÌ´Ù.

QUIZ 1. ±ô¦ ÄûÁî°¡ ³ª°£´Ù. »óǰÀº ¾øÁö¸¸ ´äÀ» ¸ð¸¦ °æ¿ì ÀÌÀü ¼½¼ÇÀ» ´Ù½Ã ºÁ¾ßÇÏ´Â ¹úÄ¢ÀÌ ÀÖ´Ù. À§ »óȲ¿¡¼­ µÎÁ¡À» °è»êÇϱâ À§¿¡ ¿ø°ú »ç°¢ÇüÀÇ ¾î¶² ¸Þ¼Òµå°¡ È£Ã⠵ɱî?(Á¤´äÀº ±â»ç ÇÏ´ÜÀÇ Á¤º¸¿¡ ÀÖ´Ù)

1.¿øgetSourceConnectionAnchor(Request request, »ç°¢ÇügetTargetConnectionAnchor(Request request)

2.¿øgetSourceConnectionAnchor(ConnectionEditPart connection), »ç°¢ÇügetTargetConnectionAnchor(Request request)

3.¿øgetSourceConnectionAnchor(Request request), »ç°¢ÇügetTargetConnectionAnchor(ConnectionEditPart connection)

4.¿øgetSourceConnectionAnchor(ConnectionEditPart connection), »ç°¢ÇügetTargetConnectionAnchor(ConnectionEditPart connection)

package net.jlab.draw2d.figure.sequence;

import org.eclipse.draw2d.AbstractConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;

public class MessageOutgoingConnectionAnchor extends AbstractConnectionAnchor {

  public MessageOutgoingConnectionAnchor(IFigure owner) {
    super(owner);
  }

  Point result = new Point();

  @Override
  public Point getLocation(Point reference) {
     System.out.println("Out "+reference.x + " " + reference.y);
    Rectangle rectangle = this.getOwner().getClientArea();
    if(reference.x<rectangle.x){
      result.x = rectangle.x;
      result.y = rectangle.y + rectangle.height;
    }else{
      result.x = rectangle.x + rectangle.width;
      result.y = rectangle.y + rectangle.height;
    }
      
    
    return result;