Saturday Sep 08, 2012

How to Draw Lines on the Screen (Part 1)

I've seen occasional questions on mailing lists about how to use the NetBeans Visual Library to draw lines, e.g., to make graphs or diagrams of various kinds by drawing on the screen. So, rather than drag/drop causing widgets to be added, you'd want widgets to be added on mouse clicks, and you'd want to be able to connect those widgets together somehow.

Via the code below, you'll be able to click on the screen, which causes a dot to appear. When you have multiple dots, you can hold down the Ctrl key and connect them together. A guiding line appears to help you position the dots exactly in line with each other. When you go to File | Print, you'll be able to preview and print the diagram you've created.

A picture that speaks 1000 words:

Here's the code (first create a NetBeans module, then use the New Window wizard to create a new TopComponent, then integrate the code below into the TopComponent):

public final class PlotterTopComponent extends TopComponent {

    private final Scene scene;
    private final LayerWidget baseLayer;
    private final LayerWidget connectionLayer;
    private final LayerWidget interactionLayer;

    public PlotterTopComponent() {

        setLayout(new BorderLayout());

        this.scene = new Scene();
        this.baseLayer = new LayerWidget(scene);
        this.interactionLayer = new LayerWidget(scene);
        this.connectionLayer = new LayerWidget(scene);

        scene.getActions().addAction(new SceneCreateAction());
        add(scene.createView(), BorderLayout.CENTER);
        putClientProperty("print.printable", true);

    private class SceneCreateAction extends WidgetAction.Adapter {
        public WidgetAction.State mousePressed(Widget widget, 
        WidgetAction.WidgetMouseEvent event) {
            if (event.getClickCount() == 1) {
                if (event.getButton() == MouseEvent.BUTTON1 || 
                        event.getButton() == MouseEvent.BUTTON2) {
                    baseLayer.addChild(new BlackDotWidget(scene, widget, event));
                    return WidgetAction.State.CONSUMED;
            return WidgetAction.State.REJECTED;

    private class BlackDotWidget extends ImageWidget {
        public BlackDotWidget(Scene scene, Widget widget, 
                WidgetAction.WidgetMouseEvent event) {
                       connectionLayer, new BlackDotConnectProvider()));
                       baseLayer, interactionLayer,

    private class BlackDotConnectProvider implements ConnectProvider {

        public boolean isSourceWidget(Widget source) {
            return source instanceof BlackDotWidget && source != null ? true : false;

        public ConnectorState isTargetWidget(Widget src, Widget trg) {
            return src != trg && trg instanceof BlackDotWidget ? 
                    ConnectorState.ACCEPT : ConnectorState.REJECT;

        public boolean hasCustomTargetWidgetResolver(Scene arg0) {
            return false;

        public Widget resolveTargetWidget(Scene arg0, Point arg1) {
            return null;

        public void createConnection(Widget source, Widget target) {
            ConnectionWidget conn = new ConnectionWidget(scene);
            conn.setTargetAnchor(AnchorFactory.createCircularAnchor(target, 10));
            conn.setSourceAnchor(AnchorFactory.createCircularAnchor(source, 10));



Note: The code above was written based on the Visual Library tutorials on the NetBeans Platform Learning Trail, in particular via the "ConnectScene" sample in the "test.connect" package, which is part of the very long list of Visual Library samples referred to in the Visual Library tutorials on the NetBeans Platform Learning Trail.

The next steps are to add a reconnect action and an action to delete a dot by double-clicking on it. Would be interesting to change the connecting line so that the length of the line were to be shown, i.e., as you draw a line from one dot to another, you'd see a constantly changing number representing the current distance of the connecting line. Also, once lines are connected to form a rectangle, would be cool to be able to write something within that rectangle. Then one could really create diagrams, which would be pretty cool.


Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.


  • NetBeans IDE
« September 2012 »