Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Draw2d

The Draw2D is part of the DWT-Addons. Draw2D originates to the Eclipse GEF project.

The source code for this example is less than 200 lines to draw this UML diagram. The original source of this example can be found here:

Draw2D on Linux-GTK
http://downloads.dsource.org/projects/dwt/screenshots/linux/draw2d/UmlExample.png

Draw2D on Windows
http://downloads.dsource.org/projects/dwt/screenshots/win/draw2d/UmlExample.png

/++
 + Original sources from http://www.eclipse.org/articles/Article-GEF-Draw2d/GEF-Draw2d.html
 + Ported to the D programming language
 +     Frank Benoit <benoit@tionex.de>
 +/

module umlexample.UmlExample;

import dwt.dwthelper.utils;
import dwt.dwthelper.ByteArrayInputStream;

import dwtx.draw2d.Figure;
import dwtx.draw2d.IFigure;
import dwtx.draw2d.geometry.PointList;
import dwtx.draw2d.geometry.Rectangle;
import dwtx.draw2d.geometry.Insets;
import dwt.DWT;
import dwt.graphics.Font;
import dwt.graphics.Image;
import dwt.graphics.ImageData;
import dwt.widgets.Display;
import dwt.widgets.Shell;
import dwtx.draw2d.AbstractBorder;
import dwtx.draw2d.Graphics;
import dwt.graphics.Color;
import dwtx.draw2d.Label;
import dwtx.draw2d.ToolbarLayout;
import dwtx.draw2d.LineBorder;
import dwtx.draw2d.ConnectionEndpointLocator;
import dwtx.draw2d.ChopboxAnchor;
import dwtx.draw2d.PolygonDecoration;
import dwtx.draw2d.PolylineConnection;
import dwtx.draw2d.ColorConstants;
import dwtx.draw2d.LightweightSystem;
import dwtx.draw2d.XYLayout;

version(JIVE) import jive.stacktrace;

public class CompartmentFigure : Figure {

    public this() {
        ToolbarLayout layout = new ToolbarLayout();
        layout.setMinorAlignment(ToolbarLayout.ALIGN_TOPLEFT);
        layout.setStretchMinorAxis(false);
        layout.setSpacing(2);
        setLayoutManager(layout);
        setBorder(new CompartmentFigureBorder());
    }

    public class CompartmentFigureBorder : AbstractBorder {
        public Insets getInsets(IFigure figure) {
            return new Insets(1,0,0,0);
        }
        public void paint(IFigure figure, Graphics graphics, Insets insets) {
            graphics.drawLine(getPaintRectangle(figure, insets).getTopLeft(),
                    tempRect.getTopRight());
        }
    }
}

public class UMLClassFigure : Figure {
    public static Color classColor;
    static this(){
        classColor = new Color(null,255,255,206);
    }

    private CompartmentFigure attributeFigure;
    private CompartmentFigure methodFigure;

    public this(Label name) {

        attributeFigure = new CompartmentFigure();
        methodFigure = new CompartmentFigure();

        ToolbarLayout layout = new ToolbarLayout();
        setLayoutManager(layout);
        setBorder(new LineBorder(ColorConstants.black,1));
        setBackgroundColor(classColor);
        setOpaque(true);

        add(name);
        add(attributeFigure);
        add(methodFigure);
    }
    public CompartmentFigure getAttributesCompartment() {
        return attributeFigure;
    }
    public CompartmentFigure getMethodsCompartment() {
        return methodFigure;
    }
}

static void[] imgDataClass = import("draw2d.umlexample.class.gif");
static void[] imgDataMethod = import("draw2d.umlexample.method.gif");
static void[] imgDataField = import("draw2d.umlexample.field.gif");

Image getImage( Display disp, void[] data ){
    ImageData imageData = new ImageData( new ByteArrayInputStream( cast(byte[]) data ));
    return new Image( disp, imageData );
}

/**
 * A test class to display a UMLFigure
 */
public static void main(){
    Display d = Display.getCurrent();
    final Shell shell = new Shell(d);
    shell.setSize(400, 400);
    shell.setText("UMLClassFigure Test");
    LightweightSystem lws = new LightweightSystem(shell);
    Figure contents = new Figure();
    XYLayout contentsLayout = new XYLayout();
    contents.setLayoutManager(contentsLayout);

    Font classFont = new Font(null, "Arial", 12, DWT.BOLD);
    Label classLabel1 = new Label("Table", getImage(d, imgDataClass));
    classLabel1.setFont(classFont);

    Label classLabel2 = new Label("Column", getImage(d, imgDataClass));
    classLabel2.setFont(classFont);

    final UMLClassFigure classFigure = new UMLClassFigure(classLabel1);
    final UMLClassFigure classFigure2 = new UMLClassFigure(classLabel2);

    Label attribute1 = new Label("columns: Column[]", getImage(d, imgDataField));
    Label attribute2 = new Label("rows: Row[]", getImage(d, imgDataField));
    Label attribute3 = new Label("columnID: int", getImage(d, imgDataField));
    Label attribute4 = new Label("items: List", getImage(d, imgDataField));

    classFigure.getAttributesCompartment().add(attribute1);
    classFigure.getAttributesCompartment().add(attribute2);
    classFigure2.getAttributesCompartment().add(attribute3);
    classFigure2.getAttributesCompartment().add(attribute4);

    Label method1 = new Label("getColumns(): Column[]", getImage(d, imgDataMethod));
    Label method2 = new Label("getRows(): Row[]", getImage(d, imgDataMethod));
    Label method3 = new Label("getColumnID(): int", getImage(d, imgDataMethod));
    Label method4 = new Label("getItems(): List", getImage(d, imgDataMethod));

    classFigure.getMethodsCompartment().add(method1);
    classFigure.getMethodsCompartment().add(method2);
    classFigure2.getMethodsCompartment().add(method3);
    classFigure2.getMethodsCompartment().add(method4);

    contentsLayout.setConstraint(classFigure, new Rectangle(10,10,-1,-1));
    contentsLayout.setConstraint(classFigure2, new Rectangle(200, 200, -1, -1));

    /* Creating the connection */
    PolylineConnection c = new PolylineConnection();
    ChopboxAnchor sourceAnchor = new ChopboxAnchor(classFigure);
    ChopboxAnchor targetAnchor = new ChopboxAnchor(classFigure2);
    c.setSourceAnchor(sourceAnchor);
    c.setTargetAnchor(targetAnchor);

    /* Creating the decoration */
    PolygonDecoration decoration = new PolygonDecoration();
    PointList decorationPointList = new PointList();
    decorationPointList.addPoint(0,0);
    decorationPointList.addPoint(-2,2);
    decorationPointList.addPoint(-4,0);
    decorationPointList.addPoint(-2,-2);
    decoration.setTemplate(decorationPointList);
    c.setSourceDecoration(decoration);

    /* Adding labels to the connection */
    ConnectionEndpointLocator targetEndpointLocator =
        new ConnectionEndpointLocator(c, true);
    targetEndpointLocator.setVDistance(15);
    Label targetMultiplicityLabel = new Label("1..*");
    c.add(targetMultiplicityLabel, targetEndpointLocator);

    ConnectionEndpointLocator sourceEndpointLocator =
        new ConnectionEndpointLocator(c, false);
    sourceEndpointLocator.setVDistance(15);
    Label sourceMultiplicityLabel = new Label("1");
    c.add(sourceMultiplicityLabel, sourceEndpointLocator);

    ConnectionEndpointLocator relationshipLocator =
        new ConnectionEndpointLocator(c,true);
    relationshipLocator.setUDistance(10);
    relationshipLocator.setVDistance(-20);
    Label relationshipLabel = new Label("contains");
    c.add(relationshipLabel,relationshipLocator);

    contents.add(classFigure);
    contents.add(classFigure2);
    contents.add(c);

    lws.setContents(contents);
    shell.open();
    while (!shell.isDisposed())
        while (!d.readAndDispatch())
            d.sleep();
}