Over a million developers have joined DZone.

Map Scene Sample in Visual Library

DZone 's Guide to

Map Scene Sample in Visual Library

· Java Zone ·
Free Resource

An old sample by Visual Library creator David Kaspar, which I never got around to documenting before:

David writes: "Note that the sample is a view-only - it does not allow to edit the map, does not have object selection... only Labels of the Markers can be moved."

Create the Widgets

There are two special widgets in the screenshot above, a CircleWidget and a MarkerWidget:

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import org.netbeans.api.visual.widget.Scene;
import org.netbeans.api.visual.widget.Widget;

class CircleWidget extends Widget {

    private final int radius;

    public CircleWidget(Scene scene, int radius) {
        this.radius = radius;

    protected Rectangle calculateClientArea() {
        Rectangle rect = new Rectangle (-radius, -radius, 2 * radius, 2 * radius);
        rect.grow (1, 1); // counting with line-width
        return rect;

    protected void paintWidget() {
        Graphics2D gr = getGraphics();
        gr.setColor (getForeground());
        gr.fill(new Ellipse2D.Float (-radius, -radius, 2 * radius, 2 * radius));

import java.awt.Color;
import java.awt.Point;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.widget.LabelWidget;
import org.netbeans.api.visual.widget.Scene;
import org.netbeans.api.visual.widget.Widget;

class MarkerWidget extends Widget {

    private final CircleWidget circle;
    private final LabelWidget label;

    MarkerWidget(Scene scene, String name) {
        circle = new CircleWidget (scene, 10);
        addChild (circle);
        label = new LabelWidget (scene, name);
        label.setBackground (Color.WHITE);
        label.setOpaque (true);
        label.setPreferredLocation (new Point (20, 0));
        addChild (label);
        label.getActions().addAction (ActionFactory.createMoveAction()); // moveable label

    Widget getCircleWidget() {
        return circle;


Create the Scene 

Use the widgets above in a scene, as follows:

import java.awt.Color;
import java.awt.Point;
import java.util.Arrays;
import org.netbeans.api.visual.anchor.AnchorFactory;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.layout.LayoutFactory.ConnectionWidgetLayoutAlignment;
import org.netbeans.api.visual.widget.ConnectionWidget;
import org.netbeans.api.visual.widget.LabelWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Widget;

public class MapScene extends GraphScene<String,String> {

    private final LayerWidget backgroundLayer;
    private final LayerWidget mainLayer;
    private final LayerWidget connectionLayer;

    public MapScene() {
        addChild (backgroundLayer = new LayerWidget (this));
        backgroundLayer.addChild(createCountryBoundary ());
        addChild (mainLayer = new LayerWidget (this));
        addChild (connectionLayer = new LayerWidget (this));

    private Widget createCountryBoundary() {
        ConnectionWidget country = new ConnectionWidget (this);
        country.setControlPoints(Arrays.asList (
                new Point (200, 0),
                new Point (150, 0),
                new Point (0, 150),
                new Point (150, 300),
                new Point (350, 280),
                new Point (500, 140),
                new Point (200, 0)
        ), true);
        return country;

    void createSampleData() {
        addNode ("Praha").setPreferredLocation(new Point (150, 120));
        addNode ("Brno").setPreferredLocation(new Point (300, 240));
        addEdge ("D1");
        setEdgeSource ("D1", "Praha");
        setEdgeTarget ("D1", "Brno");

    protected Widget attachNodeWidget(String node) {
        Widget marker = new MarkerWidget (this, node);
        return marker;

    protected Widget attachEdgeWidget(String edge) {
        ConnectionWidget conn = new ConnectionWidget (this);
        LabelWidget label = new LabelWidget (this, edge);
        conn.setConstraint(label, ConnectionWidgetLayoutAlignment.CENTER, 0.5f);
        return conn;

    protected void attachEdgeSourceAnchor(String edge, String oldNode, String newNode) {
        ConnectionWidget conn = (ConnectionWidget) findWidget (edge);
        MarkerWidget marker = (MarkerWidget) findWidget (newNode);
        conn.setSourceAnchor(AnchorFactory.createCenterAnchor(marker.getCircleWidget ()));

    protected void attachEdgeTargetAnchor(String edge, String oldNode, String newNode) {
        ConnectionWidget conn = (ConnectionWidget) findWidget (edge);
        MarkerWidget marker = (MarkerWidget) findWidget (newNode);
        conn.setTargetAnchor(AnchorFactory.createCenterAnchor(marker.getCircleWidget ()));


Hook the Scene into the TopComponent

In the constructor of the TopComponent:

        scene = new MapScene ();
        scene.createSampleData ();
        add (scene.createView (), BorderLayout.CENTER);

Now run the application and you'll see a window with the map shown at the start of this article.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}