X

Geertjan's Blog

  • October 11, 2011

ANTLRWorks SynDiag Chart

Geertjan Wielenga
Product Manager

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.

Join the discussion

Comments ( 1 )
  • thfaure Wednesday, October 12, 2011

    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


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.