Gef Examples
A Gef component.
Basic Snippet

The smallest useful GEF example: a {@link ScrollingGraphicalViewer} driven from a plain Shell,
with no workbench.
Where the draw2d snippets exercise a {@code FigureCanvas} directly, this one goes through GEF's
own stack -- {@link EditPartFactory}, {@link AbstractGraphicalEditPart}, {@link EditDomain} and a
{@link ScalableRootEditPart} -- which is how an application actually builds a diagram. The
viewer's figures are laid out well beyond the shell's client area, so the viewport scrolls and
the scrolled repaint path is covered too.
??? example "GefBasicSnippet.java"
| package dev.equo.gef;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* The smallest useful GEF example: a {@link ScrollingGraphicalViewer} driven from a plain Shell,
* with no workbench.
* <p>
* Where the draw2d snippets exercise a {@code FigureCanvas} directly, this one goes through GEF's
* own stack -- {@link EditPartFactory}, {@link AbstractGraphicalEditPart}, {@link EditDomain} and a
* {@link ScalableRootEditPart} -- which is how an application actually builds a diagram. The
* viewer's figures are laid out well beyond the shell's client area, so the viewport scrolls and
* the scrolled repaint path is covered too.
*/
public class GefBasicSnippet {
/** Model: a named box at a fixed position, optionally linked to the previous one. */
private record Node(String name, Rectangle bounds) {
}
private static class NodeEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Label label = new Label(((Node) getModel()).name());
label.setOpaque(true);
label.setBackgroundColor(ColorConstants.lightGray);
label.setBorder(new LineBorder(ColorConstants.blue, 2));
return label;
}
@Override
protected void createEditPolicies() {
}
@Override
protected void refreshVisuals() {
((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(),
((Node) getModel()).bounds());
}
}
private static class DiagramEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Figure figure = new Figure();
figure.setLayoutManager(new XYLayout());
return figure;
}
@Override
protected void createEditPolicies() {
}
@Override
@SuppressWarnings("unchecked")
protected List<Node> getModelChildren() {
return (List<Node>) getModel();
}
}
private static class DiagramEditPartFactory implements EditPartFactory {
@Override
public EditPart createEditPart(EditPart context, Object model) {
AbstractGraphicalEditPart part = (model instanceof Node) ? new NodeEditPart()
: new DiagramEditPart();
part.setModel(model);
return part;
}
}
private static List<Node> createModel() {
List<Node> nodes = new ArrayList<>();
for (int row = 0; row < 6; row++) {
for (int col = 0; col < 4; col++) {
nodes.add(new Node("Node " + (row * 4 + col + 1),
new Rectangle(40 + col * 220, 40 + row * 130, 140, 60)));
}
}
return nodes;
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("GEF Basic");
ScrollingGraphicalViewer viewer = new ScrollingGraphicalViewer();
viewer.createControl(shell);
viewer.setRootEditPart(new ScalableRootEditPart());
viewer.setEditDomain(new EditDomain());
viewer.setEditPartFactory(new DiagramEditPartFactory());
viewer.setContents(createModel());
shell.setSize(600, 450);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
|
[View on GitHub :simple-github:](https://github.com/equodev/swt-evolve/blob/main/examples/src/main/java/dev/equo/gef/GefBasicSnippet.java){ .md-button }
### Connections Snippet
[](assets/screenshots/GefConnectionsSnippet.png){.glightbox}
A GEF viewer whose nodes are joined by connections on the root part's connection layer.
Where {@link GefBasicSnippet} only paints node figures on the primary layer, this exercises the
layered side of a GEF diagram: connections live on {@link LayerConstants#CONNECTION_LAYER}, and
each one re-routes itself off its endpoints' {@link ChopboxAnchor}s rather than being positioned
by the layout.
??? example "GefConnectionsSnippet.java"
| package dev.equo.gef;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
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.Rectangle;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* A GEF viewer whose nodes are joined by connections on the root part's connection layer.
* <p>
* Where {@link GefBasicSnippet} only paints node figures on the primary layer, this exercises the
* layered side of a GEF diagram: connections live on {@link LayerConstants#CONNECTION_LAYER}, and
* each one re-routes itself off its endpoints' {@link ChopboxAnchor}s rather than being positioned
* by the layout.
*/
public class GefConnectionsSnippet {
private record Node(String name, Rectangle bounds) {
}
private static class NodeEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Label label = new Label(((Node) getModel()).name());
label.setOpaque(true);
label.setBackgroundColor(ColorConstants.lightGray);
label.setBorder(new LineBorder(ColorConstants.darkBlue, 2));
return label;
}
@Override
protected void createEditPolicies() {
}
@Override
protected void refreshVisuals() {
((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(),
((Node) getModel()).bounds());
}
}
private static class DiagramEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Figure figure = new Figure();
figure.setLayoutManager(new XYLayout());
return figure;
}
@Override
protected void createEditPolicies() {
}
@Override
@SuppressWarnings("unchecked")
protected List<Node> getModelChildren() {
return (List<Node>) getModel();
}
}
private static class DiagramEditPartFactory implements EditPartFactory {
@Override
public EditPart createEditPart(EditPart context, Object model) {
AbstractGraphicalEditPart part = (model instanceof Node) ? new NodeEditPart()
: new DiagramEditPart();
part.setModel(model);
return part;
}
}
/** Draws an arrow from the figure of {@code from} to the figure of {@code to}. */
private static void connect(ScrollingGraphicalViewer viewer, Node from, Node to) {
IFigure source = ((GraphicalEditPart) viewer.getEditPartRegistry().get(from)).getFigure();
IFigure target = ((GraphicalEditPart) viewer.getEditPartRegistry().get(to)).getFigure();
PolylineConnection connection = new PolylineConnection();
connection.setSourceAnchor(new ChopboxAnchor(source));
connection.setTargetAnchor(new ChopboxAnchor(target));
connection.setTargetDecoration(new PolygonDecoration());
connection.setForegroundColor(ColorConstants.darkBlue);
IFigure connectionLayer = ((ScalableRootEditPart) viewer.getRootEditPart())
.getLayer(LayerConstants.CONNECTION_LAYER);
connectionLayer.add(connection);
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("GEF Connections");
List<Node> nodes = new ArrayList<>();
Node root = new Node("Root", new Rectangle(190, 30, 120, 50));
Node left = new Node("Left", new Rectangle(40, 170, 120, 50));
Node right = new Node("Right", new Rectangle(340, 170, 120, 50));
Node leaf = new Node("Leaf", new Rectangle(190, 300, 120, 50));
nodes.add(root);
nodes.add(left);
nodes.add(right);
nodes.add(leaf);
ScrollingGraphicalViewer viewer = new ScrollingGraphicalViewer();
viewer.createControl(shell);
viewer.setRootEditPart(new ScalableRootEditPart());
viewer.setEditDomain(new EditDomain());
viewer.setEditPartFactory(new DiagramEditPartFactory());
viewer.setContents(nodes);
// After setContents, so every node already has an EditPart (and a figure) to anchor to.
connect(viewer, root, left);
connect(viewer, root, right);
connect(viewer, left, leaf);
connect(viewer, right, leaf);
shell.setSize(540, 420);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
|
[View on GitHub :simple-github:](https://github.com/equodev/swt-evolve/blob/main/examples/src/main/java/dev/equo/gef/GefConnectionsSnippet.java){ .md-button }
### Selection Snippet
[](assets/screenshots/GefSelectionSnippet.png){.glightbox}
A GEF viewer with selectable nodes, one of them selected on open.
Selection handles are not part of any node's own figure: GEF puts them on the root part's handle
layer, painted outside the ordinary figure pass. That makes this the snippet that covers the
layer a diagram editor uses for everything it draws *about* the diagram rather than *in* it.
??? example "GefSelectionSnippet.java"
| package dev.equo.gef;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* A GEF viewer with selectable nodes, one of them selected on open.
* <p>
* Selection handles are not part of any node's own figure: GEF puts them on the root part's handle
* layer, painted outside the ordinary figure pass. That makes this the snippet that covers the
* layer a diagram editor uses for everything it draws *about* the diagram rather than *in* it.
*/
public class GefSelectionSnippet {
private record Node(String name, Rectangle bounds) {
}
private static class NodeEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Label label = new Label(((Node) getModel()).name());
label.setOpaque(true);
label.setBackgroundColor(ColorConstants.lightGray);
label.setBorder(new LineBorder(ColorConstants.gray, 1));
return label;
}
@Override
protected void createEditPolicies() {
// What gives the part its selection handles once the viewer selects it.
installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new NonResizableEditPolicy());
}
@Override
protected void refreshVisuals() {
((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(),
((Node) getModel()).bounds());
}
}
private static class DiagramEditPart extends AbstractGraphicalEditPart {
@Override
protected IFigure createFigure() {
Figure figure = new Figure();
figure.setLayoutManager(new XYLayout());
return figure;
}
@Override
protected void createEditPolicies() {
}
@Override
@SuppressWarnings("unchecked")
protected List<Node> getModelChildren() {
return (List<Node>) getModel();
}
}
private static class DiagramEditPartFactory implements EditPartFactory {
@Override
public EditPart createEditPart(EditPart context, Object model) {
AbstractGraphicalEditPart part = (model instanceof Node) ? new NodeEditPart()
: new DiagramEditPart();
part.setModel(model);
return part;
}
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("GEF Selection");
List<Node> nodes = new ArrayList<>();
for (int i = 0; i < 6; i++) {
nodes.add(new Node("Node " + (i + 1),
new Rectangle(50 + (i % 3) * 160, 60 + (i / 3) * 140, 120, 60)));
}
ScrollingGraphicalViewer viewer = new ScrollingGraphicalViewer();
viewer.createControl(shell);
viewer.setRootEditPart(new ScalableRootEditPart());
viewer.setEditDomain(new EditDomain());
viewer.setEditPartFactory(new DiagramEditPartFactory());
viewer.setContents(nodes);
// Selecting from code rather than by click keeps the snippet deterministic when captured.
EditPart selected = (EditPart) viewer.getEditPartRegistry().get(nodes.get(1));
viewer.select(selected);
shell.setSize(560, 380);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
|
[View on GitHub :simple-github:](https://github.com/equodev/swt-evolve/blob/main/examples/src/main/java/dev/equo/gef/GefSelectionSnippet.java){ .md-button }