Implementation

For information about the design and functionality of the MIDlet, see section Design.

The SvgCanvas1 class handles the setting up and drawing of the static SVG image. The constructor of the class first sets up the 2D rendering context by using a ScalableGraphics object:

    public SvgCanvas1(boolean suppressKeyEvents) {
        super(suppressKeyEvents);

        // *** setup an instance of ScalableGraphics
        sg = ScalableGraphics.createInstance();
        sg.setRenderingQuality(sg.RENDERING_QUALITY_HIGH);

Rendering quality is set to RENDERING_QUALITY_HIGH, which is also the default setting on Series 40 and Symbian devices. This quality level is dependent on the device and the MIDlet code, and is mapped to definitions in the SVG specification (shape, text, image, and color rendering). If you are concerned about portability, check the specifications of the devices the MIDlet is targeted for, since the results are different depending on device capabilities.

Next, the constructor creates an empty SVGImage:

        // ** create an empty image
        svgImage = (SVGImage) (SVGImage.createEmptyImage(null));

The viewport size of the newly-created empty image is 100x100 pixels by default.

Finally, the constructor creates new SVGElements, which specify the content of the image, and adds these elements to the SVG document root of the image, an SVGSVGElement:

        // ** grab the root <svg> element
        SVGSVGElement rootElement = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());

        // ** create some basic colors to work with
        SVGRGBColor yellow = rootElement.createSVGRGBColor(255, 255, 0);
        SVGRGBColor black = rootElement.createSVGRGBColor(0, 0, 0);

        // ** create the face and add it to the document
        SVGElement circle = (SVGElement) (svgImage.getDocument().createElementNS("http://www.w3.org/2000/svg", "circle"));
        circle.setRGBColorTrait("fill", yellow);
        circle.setFloatTrait("r", 50);
        circle.setFloatTrait("cx", 50);
        circle.setFloatTrait("cy", 50);
        rootElement.appendChild(circle);

        // ** create the left eye and add it to the document
        circle = (SVGElement) (svgImage.getDocument().createElementNS("http://www.w3.org/2000/svg", "circle"));
        circle.setFloatTrait("r", 5);
        circle.setFloatTrait("cx", 30);
        circle.setFloatTrait("cy", 30);
        rootElement.appendChild(circle);

        // ** create the right eye and add it to the document
        circle = (SVGElement) (svgImage.getDocument().createElementNS("http://www.w3.org/2000/svg", "circle"));
        circle.setFloatTrait("r", 5);
        circle.setFloatTrait("cx", 70);
        circle.setFloatTrait("cy", 30);
        rootElement.appendChild(circle);

        // ** create the mouth and add it to the document
        SVGElement path = (SVGElement) (svgImage.getDocument().createElementNS("http://www.w3.org/2000/svg", "path"));
        SVGPath d = rootElement.createSVGPath();
        d.moveTo(20, 60);
        d.quadTo(50, 80, 80, 60);
        path.setPathTrait("d", d);
        path.setRGBColorTrait("stroke", black);
        path.setFloatTrait("stroke-width", 3);
        path.setTrait("fill", "none");
        rootElement.appendChild(path);

    }

Note: This SVG document uses the W3C namespace. You can find all the XML attributes, elements, definitions, and such used by the document from the latest SVG specification.

The GameCanvas.paint method handles the painting of the GameCanvas. The ScalableGraphics object renders the SVGImage set up in the constructor:

    public void paint(Graphics g) {
        // *** clear the display
        g.setColor(255, 255, 255);
        g.fillRect(0, 0, getWidth(), getHeight());

        // *** render the SVG image
        sg.bindTarget(g);
        sg.setTransparency(1f);
        sg.render(0, 0, svgImage);
        sg.releaseTarget();
    }

The ScalableGraphics.bindTarget method sets where the SVG image is rendered, that is, the target Graphics object. Transparency is set to 1.0, which means fully opaque. The image is drawn in the top-left corner of the GameCanvas, at coordinates 0,0.

Implementation specific to the Series 40 full touch version of the MIDlet

To detect display orientation changes, register an OrientationListener using the static Orientation.addOrientationListener method provided by the Orientation API. Register the listener before setting up and drawing the SVG image in the SvgCanvas1 constructor.

    public SvgCanvas1(boolean suppressKeyEvents) {
        super(suppressKeyEvents);
 
        /**
         * Orientation is supported for Java Runtime 2.0.0 for Series 40
         * onwards. Registers the orientation listener. Applications that need
         * information about events related to display orientation changes need
         * to register with Orientation to get notifications of the events.
         */
        Orientation.addOrientationListener(this);
 
        // *** setup an instance of ScalableGraphics
        sg = ScalableGraphics.createInstance();
        sg.setRenderingQuality(ScalableGraphics.RENDERING_QUALITY_HIGH);
 
        // *** create a simple SVG image
 
        // ...

Note: The Orientation API is supported from Java Runtime 2.0.0 for Series 40 onwards.

Finally, implement the OrientationListener by defining the displayOrientationChanged method. The method is called every time the display orientation changes. Use the displayOrientationChanged method to set the UI orientation by calling the static Orientation.setAppOrientation method.

     public void displayOrientationChanged(int newDisplayOrientation) {
        /**
         * Change MIDlet UI orientation
         */
        Orientation.setAppOrientation(newDisplayOrientation);
    }
}

Note: To adjust the MIDlet UI orientation using the Orientation API, declare the Nokia-MIDlet-App-Orientation JAD attribute with the value manual in the MIDlet JAD file:

Nokia-MIDlet-App-Orientation: manual