⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppsvgcanvas.java

📁 一个用Java写的
💻 JAVA
字号:
/******************************************************************
 * Copyright (C) 2002-2006 Andrew Girow. All rights reserved.     *
 * ---------------------------------------------------------------*
 * This software is published under the terms of the TinyLine     *
 * License, a copy of which has been included with this           *
 * distribution in the TINYLINE_LICENSE.TXT file.                 *
 *                                                                *
 * For more information on the TinyLine,                          *
 * please see <http://www.tinyline.com/>.                         *
 *****************************************************************/
package com.tinyline.app;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import java.net.URL;
import java.util.zip.*;

import com.tinyline.tiny2d.*;
import com.tinyline.svg.*;

/**
 * The <tt>PPSVGCanvas</tt> is the J2ME Personal Profile
 * implementation of the SVG Canvas.
 * <p>
 * @author (C) Andrew Girow
 * @version 1.11
 * <p>
 */

public class PPSVGCanvas extends  Canvas  implements Runnable, ImageLoader,
org.w3c.dom.events.EventTarget
{
    /** The canvas offscreen image */
    Image bimg;
    /** The canvas bounds */
    int width,height;

    /** The SVG renderer */
    public SVGRaster raster;
    /** The SVGImageProducer implementation */
    PPSVGImageProducer imageProducer;

    /** The events queue */
    public SVGEventQueue   eventQueue;
    /** The events dispatching thread */
    Thread   thread;
    /** The events listeners */
    TinyVector listeners;

    /** The base URL */
    URL      baseURL;
    /** The current URL to go */
    public String   currentURL="";
    /** True if the loading is finished */
    boolean loaded;

    /** The image cash */
    Hashtable imageCash;
    MediaTracker tracker;

    /** The status bar */
    StatusBar statusBar;

    /**
     * Constructs a new PPSVGCanvas instance.
     *
     * @param w The width of this canvas.
     * @param h The height of this canvas.
     */
    public PPSVGCanvas(int w, int h)
    {
        // Creates the SVG raster
        TinyPixbuf      buffer = new TinyPixbuf(w, h);
        raster = new SVGRaster(buffer);
        imageProducer = new PPSVGImageProducer(raster);
        raster.setSVGImageProducer(imageProducer);

        // Sets the SVG raster size and the color model
        imageProducer.setColorModel(ColorModel.getRGBdefault());

        // Sets the ImageLoader implementation needed for
        // loading bitmaps
        SVGImageElem.setImageLoader(this);
        // Uncomment the following line for full antialiasing
        raster.setAntialiased(true);

        // Makes the events queues
        eventQueue  =  new SVGEventQueue();
        listeners   =  new TinyVector(4);
        // Makes the image cash
        imageCash = new Hashtable();
        tracker   = new MediaTracker(this);
    }

    /**
     * Returns a TinyBitmap for the given image URL or path.
     * @param imgRef The image URL or path.
     * @return a TinyBitmap object which gets its pixel data from
     *                         the specified URL or path.
     */
    public TinyBitmap createTinyBitmap(TinyString uri)
    {
       String imgRef = new String(uri.data);
       PPSVGBitmap bitmap = null;
       try
       {
           URL url = new URL(baseURL,imgRef);
           // check in the cash
           bitmap = (PPSVGBitmap)imageCash.get(url);
           // not found
           if(bitmap == null)
           {
             bitmap = new PPSVGBitmap(tracker,url);
             imageCash.put(url, bitmap);
           }
       }
       catch (Exception ex)
       {
       }
       return bitmap;
    }

    /**
     * Creates a TinyBitmap which decodes the image stored in the specified
     * byte array, and at the specified offset and length.
     * @param     imageData   an array of bytes, representing
     *                         image data in a supported image format.
     * @param     imageOffset  the offset of the beginning
     *                         of the data in the array.
     * @param     imageLength  the length of the data in the array.
     * @return    a TinyBitmap object.
     */
    public TinyBitmap createTinyBitmap(byte[] imageData, int imageOffset, int imageLength)
    {
       return new PPSVGBitmap(tracker,imageData, imageOffset, imageLength);
    }

    /** Starts the events dispatching thread */
    public synchronized void start()
    {
        thread = new Thread(this);
        thread.setPriority(Thread.MIN_PRIORITY);
        thread.start();
    }


    /** Stops the events dispatching thread */
    public synchronized void stop()
    {
        thread = null;
        SVGEvent  event = new SVGEvent(SVGEvent.EVENT_UNLOAD, null);
        postEvent(event);
    }

    /**
     * The events dispatching thread run()
     */
    public void run()
    {

        Thread currentThread = Thread.currentThread();
        try
        {
            while (currentThread == thread)
            {
                eventQueue.handleEvent(eventQueue.getNextEvent());
            }
        }
        catch (InterruptedException e)
        {
           return;
        }
        catch( Throwable thr)
        {
            thr.printStackTrace();
            alertError("Internal Error");
        }
    }

    /**
     * Loads and dispalys an SVG document from the given URL.
     * External hyperlinks handling
     */
    synchronized public void goURL(String url)
    {
        SVGEvent event = new SVGEvent(SVGEvent.EVENT_LOAD,url);
        postEvent(event);
    }

    /**
     *  Returns the current SVGT document to its original view.
     */
    public void origView()
    {
        SVGEvent  event = new SVGEvent(SVGEvent.EVENT_ORIGVIEW, null);
        postEvent(event);
    }

    /**
     * Switches the rendering quality of this <tt>SVGPlayer</tt> .
     */
    public void switchQuality()
    {
        SVGEvent event = new SVGEvent(SVGEvent.EVENT_QUALITY, null );
        postEvent(event);
    }

    /**
     * Suspends or unsuspends all animations that are defined
     * within the current SVGT document fragment.
     */
    public void pauseResumeAnimations()
    {
        SVGEvent event = new SVGEvent(SVGEvent.EVENT_PAUSERESUME, null );
        postEvent(event);
    }

    /**
     * This method is called when information about an image which was
     * previously requested using an asynchronous interface becomes
     * available.  Asynchronous interfaces are method calls such as
     * getWidth(ImageObserver) and drawImage(img, x, y, ImageObserver)
     * which take an ImageObserver object as an argument.
     *
     * @param     img   the image being observed.
     * @param     flags the image status flags.
     * @param     x   the <i>x</i> coordinate.
     * @param     y   the <i>y</i> coordinate.
     * @param     width    the width.
     * @param     height   the height.
     * @return    <code>false</code> if the infoflags indicate that the
     *            image is completely loaded; <code>true</code> otherwise.
     */
    public boolean imageUpdate(Image img, int flags, int x, int y, int width, int height)
    {
        if((flags & 0x30) != 0)
            repaint(x, y, width, height);
        return (flags & 0x60) == 0;
    }

    /**
     * Updates this canvas
     * @param      g   the specified Graphics context.
     */
    public void update(Graphics g)
    {
          paint(g);
    }

    /**
     * Paints this canvas
     * @param      g   the specified Graphics context.
     */
    public void paint(Graphics g)
    {
       if(bimg == null)
       {
           raster.sendPixels();
           bimg = createImage(imageProducer);
       }

       if(bimg != null)
       {
          g.drawImage(bimg, 0, 0, this);
          Toolkit.getDefaultToolkit().sync();// ????
       }
    }

    /**
     * The minimum size of the canvas.
     *
     * @return The minimum size of the canvas.
     */
    public Dimension getMinimumSize()
    {
        return new Dimension(width, height);
    }

    /**
     * The preferred size of the canvas.
     *
     * @return The preferred size of the canvas.
     */
    public Dimension getPreferredSize()
    {
       return new Dimension(width, height);
    }

    /** Flushes the allocated resources. */
    public void flush()
    {
        raster.flush();
        if(bimg!= null)
        {
            bimg.flush();
            bimg = null;
        }
    }

    /**
     * Loads an SVGT document from the given URL.
     * @param urlStr  The SVGT document URL or path.
     * @return     An SVGT document.
     */
    public SVGDocument loadSVG(String urlStr)
    {
//        System.out.println(""+urlStr);
        alertWait("Wait...");
        InputStream is = null;
        try
        {
            URL url = new URL(baseURL,urlStr);
            baseURL = url;
            is = url.openStream();
            if(url.toString().endsWith("svgz"))
            {
                is = new GZIPInputStream(is);
            }
        }
        catch( Exception ex)
        {
//System.out.println("ioe" + ex);
            alertError("Not in SVGT format");
        }
        return loadSVG(is);
    }

    /**
     * Loads an SVGT document from the given InputStream.
     * @param   is  The InputStream.
     * @return     An SVGT document.
     */
    public SVGDocument loadSVG(InputStream is)
    {
        alertWait("Wait...");
        String str = "";
        loaded = false;
        SVGDocument doc = raster.createSVGDocument();
        int error;
        try
        {
            // Read and parse the SVGT stream
            TinyPixbuf pixbuf = raster.getPixelBuffer();
            // Create the SVGT attributes parser
            SVGAttr attrParser = new SVGAttr(pixbuf.width, pixbuf.height);
            // Create the SVGT stream parser
            SVGParser parser = new SVGParser(attrParser);
            // Parse the input SVGT stream parser into the document
            parser.load(doc,is);
            str = "www.tinyline.com";
            loaded = true;
            alertInit(str);
        }
        catch(OutOfMemoryError memerror)
        {
            doc = null;
            Runtime.getRuntime().gc();
            alertError("Not enought memory");
        }
        catch(SecurityException secex)
        {
            doc = null;
            alertError("Security violation");
        }
        catch( Exception ex)
        {
//System.out.println("ioe" + ex);
            doc = null;
            alertError("Not in SVGT format");
        }
        catch( Throwable thr)
        {
//System.out.println("ioe" + thr);
            doc = null;
            alertError("Not in SVGT format");
        }
        finally
        {
            try
            {
               if (is != null) is.close();
            }
            catch( IOException ioe)
            {
//System.out.println("ioe" + ioe);
               alertError(ioe.getMessage());
            }
        }
        return doc;
    }

    /** Sets the status bar implementation */
    public void setStatusBar(StatusBar aStatusBar)
    {
       statusBar = aStatusBar;
    }

    /** StatusBar: shows an alert */
    public void alertError(String s)
    {
       if(statusBar!=null) statusBar.alertError(s);
    }

    /** StatusBar: shows a wait */
    public void alertWait(String s)
    {
       if(statusBar!=null) statusBar.alertWait(s);
    }

    /** StatusBar: inits the bar */
    public void alertInit(String s)
    {
       if(statusBar!=null) statusBar.alertInit(s);
    }

 //////////////////////////////////////////////////////////////////
    /**
     * Posts an event to the event queue.
     *
     * @param theEvent an instance of Event, or a
     * subclass of it.
     */
    public synchronized void postEvent(SVGEvent theEvent)
    {
        //IMPORTANT
        theEvent.eventTarget = this;
        eventQueue.postEvent(theEvent);
    }

    /*
     * Methods inherited from interface org.w3c.dom.events.EventTarget
     */

    /**
     *
     * <b>uDOM:</b> This method allows the registration of event listeners on the event target.
     *
     * @param type The event type for which the user is registering
     *
     * @param listener The listener parameter takes an interface implemented by the
     * user which contains the methods to be called when the event occurs.
     *
     * @param useCapture If true, useCapture indicates that the user wishes
     * to initiate capture. After initiating capture, all events of the
     * specified type will be dispatched to the registered EventListener
     * before being dispatched to any EventTargets beneath them in the tree.
     * Events which are bubbling upward through the tree will not trigger an
     * EventListener designated to use capture.
     */
    public void addEventListener(java.lang.String type,
                 org.w3c.dom.events.EventListener listener,
                  boolean useCapture)
    {
        listeners.addElement(listener);
    }

    /**
     *
     * <b>uDOM:</b> This method allows the removal of event listeners from the event target.
     *
     * @param type Specifies the event type of the EventListener being removed.
     * @param listener The listener parameter indicates the EventListener to be removed.
     * @param useCapture Specifies whether the EventListener being removed was
     * registered as a capturing listener or not.
     */
    public void removeEventListener(java.lang.String type,
                                org.w3c.dom.events.EventListener listener,
                                boolean useCapture)

    {
        int i = listeners.indexOf(listener,0);
        if(i>0)
        {
          listeners.removeElementAt(i);
        }
    }
    /**
     * <b>uDOM:</b> This method allows the dispatch of events into the implementations event model.
     * Events dispatched in this manner will have the same behavior as events dispatched
     * directly by the implementation.
     *
     * @param evt  Specifies the event type, behavior, and contextual
     * information to be used in processing the event.
     * @return    The return value of dispatchEvent indicates whether
                 * any of the listeners which handled the event called preventDefault.
                 * If preventDefault was called the value is false, else the value is true.
                 */
    public boolean dispatchEvent(org.w3c.dom.events.Event evt)
    {
        org.w3c.dom.events.EventListener h;
        for(int i=0; i < listeners.count; i++)
        {
           h = (org.w3c.dom.events.EventListener)listeners.data[i];
           if(h!=null) h.handleEvent(evt);
        }
        return true;
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -