ANTLRWorks SynDiag Chart

Let's try to reproduce this graph from ANTLRWorks via the NetBeans Visual Library:

So, this will be the result of the code that follows:

Here you go. As you can see, everything is hardcoded below, you would need to generate the various values yourself:

public final class SynDiagTopComponent extends TopComponent {

    public SynDiagTopComponent() {

        initComponents();

        setName("SynDiag Window");

        setLayout(new BorderLayout());

        Scene scene = new Scene();

        LayerWidget baseLayer = new LayerWidget(scene);
        LayerWidget connectionLayer = new LayerWidget(scene);
 
        //First row of widgets:
        Color darkGreen = new java.awt.Color(0, 153, 51);
        LabelWidget g = new MyLabelWidget(scene, "'G'", 105, 50, darkGreen);
        baseLayer.addChild(g);
        LabelWidget rna1 = new MyLabelWidget(scene, "rna", 220, 50, Color.MAGENTA);
        baseLayer.addChild(rna1);
        LabelWidget c = new MyLabelWidget(scene, "'C'", 335, 50, darkGreen);
        baseLayer.addChild(c);
 
        //Second row of widgets:
        LabelWidget a = new MyLabelWidget(scene, "'A'", 105, 110, darkGreen);
        baseLayer.addChild(a);
        LabelWidget rna2 = new MyLabelWidget(scene, "rna", 220, 110, Color.MAGENTA);
        baseLayer.addChild(rna2);
        LabelWidget u = new MyLabelWidget(scene, "'U'", 335, 110, darkGreen);
        baseLayer.addChild(u);

        //Connections between widget/widget and widget/point:
        connectionLayer.addChild(new MyPartlyFixedConnectionWidget(
                scene, true, g, 10, 45));
        connectionLayer.addChild(new MyRelativeConnectionWidget(
                scene, g, rna1));
        connectionLayer.addChild(new MyRelativeConnectionWidget(
                scene, rna1, c));
        connectionLayer.addChild(new MyPartlyFixedConnectionWidget(
                scene, false, c, 450, 45));
        connectionLayer.addChild(new MyPartlyFixedConnectionWidget(
                scene, true, a, 45, 105));
        connectionLayer.addChild(new MyRelativeConnectionWidget(
                scene, a, rna2));
        connectionLayer.addChild(new MyRelativeConnectionWidget(
                scene, rna2, u));
        connectionLayer.addChild(new MyPartlyFixedConnectionWidget(
                scene, false, u, 400, 105));
        connectionLayer.addChild(new MyPartlyFixedConnectionWidget(
                scene, false, u, 400, 105));

        //Connections between points:
        connectionLayer.addChild(new MyFixedConnectionWidget(
                scene, 45, 45, 45, 170, false));
        connectionLayer.addChild(new MyFixedConnectionWidget(
                scene, 45, 170, 400, 170, false));
        connectionLayer.addChild(new MyFixedConnectionWidget(
                scene, 400, 170, 400, 45, true));

        //Adding the LayerWidgets to the Scene:
        scene.addChild(baseLayer);
        scene.addChild(connectionLayer);

        add(scene.createView(), BorderLayout.CENTER);

    }

    private class MyLabelWidget extends LabelWidget {
        private MyLabelWidget(
                Scene scene,
                String label,
                int x,
                int y,
                Color fontColor) {
            super(scene);
            setLabel(label);
            setFont(new Font("Helvetica", Font.BOLD, 12));
            setForeground(fontColor);
            //Different borders for different content:
            if (label.startsWith("'")) {
                setBorder(
                        BorderFactory.createRoundedBorder(
                        5, 3, Color.WHITE, Color.BLACK));
            } else {
                setBorder(
                        BorderFactory.createRoundedBorder(
                        5, 5, Color.WHITE, Color.BLACK));
            }
            setPreferredLocation(new Point(x, y));
        }
    }

    /**
     * ConnectionWidget for connecting a widget to another widget
     */
    private class MyRelativeConnectionWidget extends ConnectionWidget {
        private MyRelativeConnectionWidget(
                Scene scene,
                Widget source,
                Widget target) {
            super(scene);
            setSourceAnchor(AnchorFactory.createDirectionalAnchor(
                    source, AnchorFactory.DirectionalAnchorKind.HORIZONTAL));
            setTargetAnchor(AnchorFactory.createDirectionalAnchor(
                    target, AnchorFactory.DirectionalAnchorKind.HORIZONTAL));
            setRouter(RouterFactory.createOrthogonalSearchRouter());
            setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
        }
    }

    /*
     * ConnectionWidget for connecting a widget to a point
     */
    private class MyPartlyFixedConnectionWidget extends ConnectionWidget {
        private MyPartlyFixedConnectionWidget(
                Scene scene,
                boolean sourceFixed,
                Widget widget,
                int x,
                int y) {
            super(scene);
            if (sourceFixed) {
                setSourceAnchor(AnchorFactory.createFixedAnchor(new Point(x, y)));
                setTargetAnchor(AnchorFactory.createRectangularAnchor(widget));
                setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
            } else {
                setSourceAnchor(AnchorFactory.createRectangularAnchor(widget));
                setTargetAnchor(AnchorFactory.createFixedAnchor(new Point(x, y)));
                setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
            }
        }
    }

    /*
     * ConnectionWidget for connecting a point to another point
     */
    private class MyFixedConnectionWidget extends ConnectionWidget {
        private MyFixedConnectionWidget(
                Scene scene,
                int sourcePointX,
                int sourcePointY,
                int targetPointX,
                int targetPointY,
                boolean isEndPoint) {
            super(scene);
            setSourceAnchor(AnchorFactory.createFixedAnchor(
                    new Point(sourcePointX, sourcePointY)));
            setTargetAnchor(AnchorFactory.createFixedAnchor(
                    new Point(targetPointX, targetPointY)));
            if (isEndPoint){
                setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
            }
        }
    }

    ...
    ...
    ...

As you can see, everything is hardcoded above, you'll need to generate the values somehow yourself.

Comments:

Nice example as usual

To avoid hard-coding graph it would be nice to be able to use some dot syntax (http://en.wikipedia.org/wiki/DOT_language) from ATT labs to define the graphs.

Thierry

Posted by thfaure on October 12, 2011 at 12:06 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

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.

Search

Archives
« September 2015
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today