Skip to content

Draw2D Examples

Draw2D is a lightweight graphics framework built on top of SWT for creating structured graphics and diagrams.

Hello World

Draw2D  Hello World

Demonstrates the simplest Draw2D example using a FigureCanvas and Label.

This example creates a basic Draw2D application that displays "Hello World"

using Draw2D's figure system on a canvas.

Draw2DHelloWorld.java
package dev.equo.draw2d;

import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.Label;

/**
 * Demonstrates the simplest Draw2D example using a FigureCanvas and Label.
 * This example creates a basic Draw2D application that displays "Hello World"
 * using Draw2D's figure system on a canvas.
 */
public class Draw2DHelloWorld {

    public static void main(String[] args) {

        Display d = new Display();
        Shell shell = new Shell(d);
        shell.setLayout(new FillLayout());

        FigureCanvas canvas = new FigureCanvas(shell);
        canvas.setContents(new Label("Hello World")); //$NON-NLS-1$

        shell.setText("Draw2d"); //$NON-NLS-1$
        shell.setSize(200, 100);
        shell.open();
        while (!shell.isDisposed()) {
            while (!d.readAndDispatch()) {
                d.sleep();
            }
        }

    }

}

View on GitHub

Hello World Scaled Graphics

Draw2D  Hello World Scaled Graphics

Example demonstrating Draw2DHelloWorldScaledGraphics.

Draw2DHelloWorldScaledGraphics.java
package dev.equo.draw2d;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.ScaledGraphics;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class Draw2DHelloWorldScaledGraphics {

    static class ScaledStringFigure extends Figure {
        private String text;
        private double scale;

        public ScaledStringFigure(String text, double scale) {
            this.text = text;
            this.scale = scale;
        }

        @Override
        protected void paintFigure(Graphics graphics) {
            super.paintFigure(graphics);

            // Create a ScaledGraphics to force the flow through ScaledGraphics#drawString
            ScaledGraphics scaledGraphics = new ScaledGraphics(graphics);
            scaledGraphics.scale(scale);

            // This will call ScaledGraphics#drawString
            scaledGraphics.drawString(text, 10, 10);

            scaledGraphics.dispose();
        }
    }

    public static void main(String[] args) {
        Display d = new Display();
        Shell shell = new Shell(d);
        shell.setLayout(new FillLayout());

        FigureCanvas canvas = new FigureCanvas(shell);

        // Create a scaled figure that will use ScaledGraphics#drawString
        ScaledStringFigure figure = new ScaledStringFigure("Hello World via ScaledGraphics!", 3); //$NON-NLS-1$
        canvas.setContents(figure);

        shell.setText("Draw2d with ScaledGraphics"); //$NON-NLS-1$
        shell.setSize(400, 200);
        shell.open();
        while (!shell.isDisposed()) {
            while (!d.readAndDispatch()) {
                d.sleep();
            }
        }

    }

}

View on GitHub

Tree Example

Draw2D  Tree Example

Demonstrates an interactive tree visualization using Draw2D with dynamic manipulation capabilities.

This example creates a hierarchical tree structure with multiple nodes and branches, allowing users

to expand/collapse nodes, add/remove children, change alignment (center/left), toggle between normal

and hanging styles, adjust spacing, enable animation, and switch between horizontal/vertical orientations.

Features interactive node selection and real-time tree layout updates.

Draw2DTreeExample.java
package dev.equo.draw2d.tree;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.PositionConstants;
import dev.equo.draw2d.AbstractExample;

/**
 * Demonstrates an interactive tree visualization using Draw2D with dynamic manipulation capabilities.
 * This example creates a hierarchical tree structure with multiple nodes and branches, allowing users
 * to expand/collapse nodes, add/remove children, change alignment (center/left), toggle between normal
 * and hanging styles, adjust spacing, enable animation, and switch between horizontal/vertical orientations.
 * Features interactive node selection and real-time tree layout updates.
 */
public class Draw2DTreeExample extends AbstractExample {

    private static final String NORMAL_STYLE = "Normal Style"; //$NON-NLS-1$

    private static final String CHILD_2_NAME = "Child 2"; //$NON-NLS-1$

    private static final String CHILD_1_NAME = "Child 1"; //$NON-NLS-1$

    private static final String BASIC_CHILD_NAME = "child"; //$NON-NLS-1$

    boolean animate;

    public static void main(String[] args) {
        new Draw2DTreeExample().run();
    }

    private TreeRoot root;

    private PageNode selected;

    IFigure createPageNode(String title) {
        final PageNode node = new PageNode(title);
        node.addMouseListener(new MouseListener.Stub() {
            @Override
            public void mousePressed(MouseEvent me) {
                setSelected(node);
            }

            @Override
            public void mouseDoubleClicked(MouseEvent me) {
                doExpandCollapse();
            }
        });
        return node;
    }

    void doAddChild() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        parent.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME), parent.getStyle()));
    }

    void doAlignCenter() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        parent.setAlignment(PositionConstants.CENTER);
    }

    void doAlignLeft() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        parent.setAlignment(PositionConstants.LEFT);
    }

    void doDeleteChild() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        IFigure contents = parent.getContentsPane();
        if (contents.getChildren().isEmpty()) {
            return;
        }
        contents.remove(contents.getChildren().get(contents.getChildren().size() - 1));
    }

    void doExpandCollapse() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        if (parent.getSubtrees().isEmpty()) {
            return;
        }
        if (animate) {
            if (parent.isExpanded()) {
                parent.collapse();
            } else {
                parent.expand();
            }
        } else {
            parent.setExpanded(!parent.isExpanded());
        }
    }

    void doStyleHanging() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        parent.setStyle(TreeBranch.STYLE_HANGING);
    }

    void doStyleNormal() {
        if (selected == null) {
            return;
        }
        TreeBranch parent = (TreeBranch) selected.getParent();
        parent.setStyle(TreeBranch.STYLE_NORMAL);
    }

    /**
     * @see org.eclipse.draw2d.examples.AbstractExample#createContents()
     */
    @Override
    protected IFigure createContents() {
        getFigureCanvas().setBackground(ColorConstants.white);
        root = new TreeRoot(createPageNode("Graph Root")); //$NON-NLS-1$

        TreeBranch branch = new TreeBranch(createPageNode(NORMAL_STYLE));
        root.addBranch(branch);
        root.addBranch(new TreeBranch(createPageNode("Child"))); //$NON-NLS-1$
        branch.addBranch(new TreeBranch(createPageNode(CHILD_1_NAME)));
        branch.addBranch(new TreeBranch(createPageNode(CHILD_2_NAME)));
        TreeBranch subbranch = new TreeBranch(createPageNode("Child 3")); //$NON-NLS-1$
        branch.addBranch(subbranch);

        subbranch.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME)));
        subbranch.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME)));
        subbranch.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME)));

        branch = new TreeBranch(createPageNode(NORMAL_STYLE), TreeBranch.STYLE_NORMAL);
        root.addBranch(branch);
        root.addBranch(new TreeBranch(createPageNode("Child"))); //$NON-NLS-1$
        branch.addBranch(new TreeBranch(createPageNode(CHILD_1_NAME), TreeBranch.STYLE_HANGING));
        subbranch = new TreeBranch(createPageNode(CHILD_2_NAME), TreeBranch.STYLE_HANGING);
        branch.addBranch(subbranch);
        subbranch.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME)));
        subbranch.addBranch(new TreeBranch(createPageNode(BASIC_CHILD_NAME)));

        branch = new TreeBranch(createPageNode(NORMAL_STYLE));
        root.addBranch(branch);
        branch.addBranch(new TreeBranch(createPageNode(CHILD_1_NAME)));
        branch.addBranch(new TreeBranch(createPageNode(CHILD_2_NAME)));
        branch.addBranch(new TreeBranch(createPageNode("Child 3"))); //$NON-NLS-1$

        return root;
    }

    /**
     * @see org.eclipse.draw2d.examples.AbstractExample#run()
     */
    @Override
    protected void hookShell(Shell shell) {
        Composite localShell = new Composite(shell, 0);
        localShell.setLayoutData(new GridData(GridData.FILL_VERTICAL));

        localShell.setLayout(new GridLayout());
        Group rootGroup = new Group(localShell, 0);
        rootGroup.setText("Root Properties"); //$NON-NLS-1$
        FontData data = rootGroup.getFont().getFontData()[0];
        data.setStyle(SWT.BOLD);
        rootGroup.setLayout(new GridLayout());

        final Button orientation = new Button(rootGroup, SWT.CHECK);
        orientation.setText("Horizontal Orientation"); //$NON-NLS-1$
        orientation.setSelection(true);
        orientation.addListener(SWT.Selection, e -> root.setHorizontal(orientation.getSelection()));

        final Button useAnimation = new Button(rootGroup, SWT.CHECK);
        useAnimation.setText("Use Animation"); //$NON-NLS-1$
        useAnimation.setSelection(false);
        useAnimation.addListener(SWT.Selection, e -> animate = useAnimation.getSelection());

        final Button compress = new Button(rootGroup, SWT.CHECK);
        compress.setText("Compress Tree"); //$NON-NLS-1$
        compress.setSelection(false);
        compress.addListener(SWT.Selection, e -> {
            root.setCompression(compress.getSelection());
            root.invalidateTree();
            root.revalidate();
        });

        final Label majorLabel = new Label(rootGroup, 0);
        majorLabel.setText("Major Spacing: 10"); //$NON-NLS-1$
        final Scale major = new Scale(rootGroup, 0);
        major.setMinimum(5);
        major.setIncrement(5);
        major.setMaximum(50);
        major.setSelection(10);
        major.addListener(SWT.Selection, e -> {
            root.setMajorSpacing(major.getSelection());
            majorLabel.setText("Major Spacing: " + root.getMajorSpacing()); //$NON-NLS-1$
        });

        final Label minorLabel = new Label(rootGroup, 0);
        minorLabel.setText("Minor Spacing: 10"); //$NON-NLS-1$
        final Scale minor = new Scale(rootGroup, 0);
        minor.setMinimum(5);
        minor.setIncrement(5);
        minor.setMaximum(50);
        minor.setSelection(10);
        minor.addListener(SWT.Selection, e -> {
            root.setMinorSpacing(minor.getSelection());
            minorLabel.setText("Minor Spacing: " + root.getMinorSpacing()); //$NON-NLS-1$
        });

        Group selectedGroup = new Group(localShell, 0);
        selectedGroup.setText("Selected Node:"); //$NON-NLS-1$
        selectedGroup.setLayout(new GridLayout(2, true));

        Button addChild = new Button(selectedGroup, 0);
        addChild.setText("More Children"); //$NON-NLS-1$
        addChild.addListener(SWT.Selection, e -> doAddChild());

        Button removeChild = new Button(selectedGroup, 0);
        removeChild.setText("Fewer Children"); //$NON-NLS-1$
        removeChild.addListener(SWT.Selection, e -> doDeleteChild());

        Button alignCenter = new Button(selectedGroup, 0);
        alignCenter.setText("Align Center"); //$NON-NLS-1$
        alignCenter.addListener(SWT.Selection, e -> doAlignCenter());
        Button alignLeft = new Button(selectedGroup, 0);
        alignLeft.setText("Align Top/Left"); //$NON-NLS-1$
        alignLeft.addListener(SWT.Selection, e -> doAlignLeft());

        Button normal = new Button(selectedGroup, 0);
        normal.setText("Normal"); //$NON-NLS-1$
        normal.addListener(SWT.Selection, e -> doStyleNormal());

        Button hanging = new Button(selectedGroup, 0);
        hanging.setText("Hanging"); //$NON-NLS-1$
        hanging.addListener(SWT.Selection, e -> doStyleHanging());

        Button expandCollapse = new Button(selectedGroup, 0);
        expandCollapse.setText("expand/collapse"); //$NON-NLS-1$
        expandCollapse.addListener(SWT.Selection, e -> doExpandCollapse());
    }

    void setSelected(PageNode node) {
        if (selected != null) {
            selected.setSelected(false);
        }
        selected = node;
        selected.setSelected(true);
    }

}

View on GitHub

U M L Class Diagram

Draw2D  U M L Class Diagram

Demonstrates creating a UML class diagram using Draw2D with connections and decorations.

This example creates two UML class figures connected by a polyline association with containment

decoration, endpoint labels, a connection label, and a sticky note. Shows how to use anchors,

decorations, and connection locators for creating structured diagrams.

Draw2DUMLClassDiagram.java
package dev.equo.draw2d.uml;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionEndpointLocator;
import org.eclipse.draw2d.ConnectionLocator;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * Demonstrates creating a UML class diagram using Draw2D with connections and decorations.
 * This example creates two UML class figures connected by a polyline association with containment
 * decoration, endpoint labels, a connection label, and a sticky note. Shows how to use anchors,
 * decorations, and connection locators for creating structured diagrams.
 */
public class Draw2DUMLClassDiagram {

    public static void main(String[] args) {

        Display d = new Display();
        Shell shell = new Shell(d);
        shell.setLayout(new FillLayout());
        shell.setText("UML Diagram");

        FigureCanvas canvas = new FigureCanvas(shell);
        canvas.setBackground(ColorConstants.white);

        Figure diagram = new Figure();
        diagram.setLayoutManager(new XYLayout());
        canvas.setContents(diagram);

        IFigure c1, c2;

        diagram.add(c1 = new UMLClassFigure(), new Rectangle(20, 20, -1, -1));
        diagram.add(c2 = new UMLClassFigure(), new Rectangle(230, 102, -1, -1));

        PolylineConnection assoc = new PolylineConnection();
        assoc.setTargetAnchor(new ChopboxAnchor(c1));
        assoc.setSourceAnchor(new ChopboxAnchor(c2));
        PolygonDecoration containment = new PolygonDecoration();
        containment.setTemplate(new PointList(new int[] { -2, 0, -1, 1, 0, 0, -1, -1 }));
        assoc.setTargetDecoration(containment);
        diagram.add(assoc);

        Label ref = new Label("end1"); //$NON-NLS-1$
        ConnectionEndpointLocator locator = new ConnectionEndpointLocator(assoc, false);
        locator.setUDistance(8);
        assoc.add(ref, locator);

        Label connLabel = new Label("connection"); //$NON-NLS-1$
        connLabel.setBorder(new LineBorder());
        connLabel.setOpaque(true);
        connLabel.setBackgroundColor(new Color(255, 255, 255));
        assoc.add(connLabel, new ConnectionLocator(assoc, ConnectionLocator.MIDDLE));

        diagram.add(new StickyNote(), new Rectangle(180, 10, 90, -1));

        shell.setSize(500, 300);
        shell.open();
        while (!shell.isDisposed()) {
            while (!d.readAndDispatch()) {
                d.sleep();
            }
        }

    }

}

View on GitHub