Creating the SvgCanvas2 class

Simple canvas that renders SVG content, provided separately with a ready-made SVG picture. It will be used by LoadStaticMIDlet.

Note: The W3C namespace is used for this document, which can be found from the W3C Website. All the xml attributes, elements, definitions etc. used by this example can be found from the latest SVG specification linked to from that page.

  1. Create the SvgCanvas2 class file.

  2. Import the required classes and assign this class to the com.nokia.midp.examples.svg package.

    /* Copyright © 2006 Nokia. */
    package com.nokia.midp.examples.svg;
    
    
    import java.util.*;
    import java.io.*;
    
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.lcdui.game.GameCanvas;
    import javax.microedition.io.*;
    
    import javax.microedition.m2g.*;
    import org.w3c.dom.svg.*;
    
    
    
  3. Extend the GameCanvas to render the 2D vector graphics.

    /**
     * Simple canvas that uses JSR-226 to render SVG content.
     */
    public class SvgCanvas2 extends GameCanvas  {
    
    	
  4. Write a constructor that will create the image displayed by LoadStaticMIDlet. Use the createInstance method to the newly created ScalableGraphics instance for sg. Write a constructor that will create the image displayed by HelloWorldMidlet. Use the createInstance method to the newly created ScalableGraphics instance for sg. Also setup sg with the setRenderingQuality method using the value RENDERING_QUALITY_HIGH (though this is the default setting in S60 and Series 40). This quality level is dependent on the phone and the code it runs on, and is mapped to definitions in the SVG specification (shape, text, image and color rendering). If you are concerned about portability, you might want to check the specifications of the devices the code will be used in, as the results will be different depending on their capabilities. .For more information, see createInstance and setRenderingQuality in the M2G API specification.

    /**
    * Constructor.
    */
        public SvgCanvas2 (boolean suppressKeyEvents)  {
    	    super(suppressKeyEvents);
    
    		// *** setup an instance of ScalableGraphics
        	sg = ScalableGraphics.createInstance();
    		sg.setRenderingQuality(sg.RENDERING_QUALITY_HIGH);
    
            

    Get the external SVG image from where you placed it (JAR file, URL, etc.) as an object of InputStream with the getClass and getResourceAsStream methods. There is no need to use the default external resource handler here, since no rasters are handled inside the SVG file. Next, use the createImage method to get the image from the stream object (svgStream). Use the setViewportWidth and setViewportHeight methods to fit the viewport to the image. For more information, see createImage, setViewportWidth and setViewportHeight in the M2G API specification.

         // *** load an svg image from a file
        	try {
    	        InputStream svgStream = 
    					getClass().getResourceAsStream("content2.svg");
    	        svgImage = (SVGImage)( SVGImage.createImage( svgStream, null ) );
    
    			// ** set the width and height of the document 
    					 to match the screen capabilities
    	        svgImage.setViewportWidth( getWidth() );
    	        svgImage.setViewportHeight( getHeight() );
    
                } catch ( Exception e ){
                    e.printStackTrace();
    	    }
        }
    
    
    	
  5. Add functionality to both render and clear within the paint(Graphics g) event of Canvas class. Both the sg and SVGImage are defined below in Step 11. Use the bindTarget method to set where your SVG image will be created. Next, set the transparency with the setTransparency method. Choose the coordinates you wish to set the image in and render it with the render method. Finish by flushing the rendered ScalableImage (SVGImage) to the currently bound target (g) and then releasing the target with the releaseTarget method. For more information, see bindTarget, setTransparency, render and releaseTarget in the M2G API specification.

    /**
    * Paint method.
    */
        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();
        }
    
    
    
  6. Create a method for detecting changes in the size of the viewport.

        protected void sizeChanged(int w, int h)
        {
        		System.out.println("sizeChanged(): w = "+w+", h = "+h);
        		svgImage.setViewportWidth(w);
        		svgImage.setViewportHeight(h);
        		repaint();
        }
    
  7. Create a method that restores the original view of the image. Use the setCurrentRotate and setCurrentScale methods to restore the original zoom and rotation settings.

    /**
    * Restore the original view of the SVG Image.
    */
        public void restoreView() {
    	    SVGSVGElement myEl = (SVGSVGElement) 
    				svgImage.getDocument().getDocumentElement();
    	    myEl.setCurrentRotate(0);
    	    myEl.setCurrentScale(1);
    	    SVGPoint origin = myEl.getCurrentTranslate();
    	    origin.setX(0);
    	    origin.setY(0);
    	    repaint();
        }
    
    	
  8. Create the functionality for the zoom feature of this example. Grab the image with the getDocument and get DocumentElement methods and change it by using the setCurrentScale to myEl object, multiplying the original scale (obtained with the getCurrentScale method) by 1.2. Use repaint to refresh the screen with the newly magnified image. To get the reverse (for the Zoom out feature), multiply with 0.8. For more information, see setCurrentScale and getCurrentScale in the M2G API specification.

    /**
    * Zoom in on the SVG Image.
    */
        public void zoomIn() {
    	    SVGSVGElement myEl = (SVGSVGElement)
    				(svgImage.getDocument().getDocumentElement());
    	    myEl.setCurrentScale(myEl.getCurrentScale() * 1.2f);
    	    repaint();
        }
    
    /**
    * Zoom out on the SVG Image.
    */
        public void zoomOut() {
    	    SVGSVGElement myEl = (SVGSVGElement)
    				(svgImage.getDocument().getDocumentElement());
    	    myEl.setCurrentScale(myEl.getCurrentScale() * 0.8f);
    	    repaint();
        }
    
    
    	
  9. Create the functionality for rotating the image. Proceed first as in step 7 by getting the document element. Then manipulate it with the setCurrentRotate and getCurrentRotate methods. Create different methods for rotating the image left and right, the direction depending on the attribute beginning either with "+" or "-". For more information, see setCurrentRotate and getCurrentRotate in the M2G API specification.

    /**
    * Rotate out on the SVG Image.
    */
        public void rotateOut() {
    	    SVGSVGElement myEl = (SVGSVGElement)
    				(svgImage.getDocument().getDocumentElement());
    	    myEl.setCurrentRotate(myEl.getCurrentRotate() + 10);
    	    repaint();
        }
    
    
    /**
    * Rotate in on the SVG Image.
    */
        public void rotateIn() {
    	    SVGSVGElement myEl = (SVGSVGElement)
    				(svgImage.getDocument().getDocumentElement());
    	    myEl.setCurrentRotate(myEl.getCurrentRotate() - 10);
    	    repaint();
        }
    
    
    	
  10. Write a method to handle repeat key presses, which refers to a method you are going to write next (one that handles the key presses themselves).

    /**
    * Key repeat method.
    */
        protected void keyRepeated(int keyCode){
    		keyPressed(keyCode);
        }
    
    
    	
  11. Create functionality for key presses, so that the viewport may be scrolled. Grab the image with the getDocument and getDocumentElement methods. Use the SVGPoint interface to create a centre point, which the keys presses move. For more information, see SVGPoint in the M2G API specification.

    /**
    * Handle key presses.
    */
        protected void keyPressed(int keyCode) {
    			SVGSVGElement svgDoc = (SVGSVGElement) 
    				svgImage.getDocument().getDocumentElement();
    			int action = getGameAction(keyCode);
    			SVGPoint origin = svgDoc.getCurrentTranslate();
    			switch (action) {
    			case RIGHT:
    				origin.setX(origin.getX() + 5f);
    				break;
    			case LEFT:
    				origin.setX(origin.getX() - 5f);
    				break;
    			case UP:
    				origin.setY(origin.getY() - 5f);
    				break;
    			case DOWN:
    				origin.setY(origin.getY() + 5f);
    				break;
    		}
    		repaint();
        }
    
    
    	
  12. Define objects for the ScalableGraphics and SVGImage classes.

    /*
    * Private members
    */
    
        private ScalableGraphics sg;
        private SVGImage svgImage;
    
    }