创建M2G应用程序
为了创建一个M2G应用程序,你需要可以工作的JSR-226实现。在写这篇文章时,这个规范才刚刚被定案;没有设备实现它,并且没有官方的参考实现可用。你可以下载一个有限的、实现的实现,作为mpowerplayer
开发者工具箱的附加包。
你还需要一些SVG-Tiny内容。这篇文章是用上面的“brave world”图像,但是更多的SVG-Tiny示例可以从移动开发工具制造者TinyLine上获得。你也可以使用一个商用
Java应用程序创建自己的内容,这个应用程序被称为Sketsa,它可以像一个插图工具一样工作,并且使用SVG作为它的文件格式。
只有很少的方法用来将你的SVG内容绘制到屏幕上。最简单的是为你的图像创建一个SVGAnimator,然后把它Canvas放到屏幕上。另外一个方法是创建一个ScalableImage的实例,然后使用ScalableGraphics的实例将它绘制到你自己的Canvas或者CustomItem的图形上下文中。你将会获得除了展现外的更多控制,但是你必须负责处理输入事件,并且为动画
效果或者用户交互进行重绘。
使用一个SVGAnimator显示2D图像
你可以通过SVGAnimator的静态方法createAnimator()获得一个它的实例,需要提供你自己的图像。使用SVGAnimator是一个不错的选择,因为它处理所有的用户交互,和动态内容的动画。play()、pause()、stop()和setTimeIncrement()方法会给你除了重放之外的对动画的可编程
控制。实现可能提供一个本地用户接口,可以同样的处理动态行为。
一旦你获得SVGAnimator,就可以很容易的将它嵌入到你的应用程序中。调用getTargetComponent()会一个Canvas实例,它可以被放置在屏幕上。下面是一个例子:
public void animationTest()
{
// create an animator to load the content
SVGAnimator animator =
SVGAnimator.createAnimator( image );
// add our custom event listener
animator.setEventListener(
new CustomEventListener( animator ) );
// get the Canvas for this player; requires a cast
Canvas canvas = (Canvas) animator.getTargetComponent();
// add a "back" command
canvas.addCommand( backCommand );
canvas.setCommandListener( this );
// show
it Display.getDisplay(this).setCurrent( canvas );
// start it
animator.play();
}
在MIDP环境中,从getTargetComponent()返回的值是一个MIDP Canvas。在非MIDP环境中,返回值将适合本地窗口系统,例如在AWT环境中,返回值是Component。如果当前环境拥有一个以上的可用的选择,那么就提供需要的类型的名字作为createAnimator()的第二个参数。
图3显示了运行时结果。根据不同的实现,和笔触设备的可用性,动画绘制器可能允许用户和动画内容进行交互。在“brave world”例子中没有动态的内容,但是文本是可选的。
图3 由SVGAnimator控制的Canvas
和动画绘制器交互 尽管“brave world”图像不是一个动画,一些程序设计还是可以增加交互的。
JSR-226的DOM支持一个程序改变一个图像的结构。和任何其他的XML文档一样,一个SVGImage可以用一个DOM对象树代表。M2G API允许你使用类似熟悉的XML处理技术来修改图像。树中的每一个节点是一个SVGElement,提供操纵临近的父节点和子节点的方法。你可以通过添加和删除子节点修改节点,或者转换成一个合适的元素类,然后调用那个类的方法进行改变。
SVGEventListener结构使你的应用程序可以从SVGAnimator的Canvas接收用户的输入事件。这个例子是用DOM API来等比例变化和旋转这个图像,用户可以通过箭头键输入:
{
int gameAction = canvas.getGameAction( keyCode );
switch ( gameAction )
{
case Canvas.UP:
scale( 0.10f );
break;
case Canvas.LEFT:
rotate( -10.0f );
break;
case Canvas.DOWN:
scale( -0.10f );
break;
case Canvas.RIGHT:
rotate( 10 );
break;
default:
// leave unchanged
}
}
private void rotate( final float delta )
{
// put ourselves on the animator's thread
animator.invokeLater( new Runnable()
{
public void run()
{
// execute the transformation
Document document = svgImage.getDocument();
SVGSVGElement root = (SVGSVGElement)
document.getDocumentElement();
root.setCurrentRotate( root.getCurrentRotate() + delta );
}
} );
}
private void scale( final float delta )
{
// put ourselves on the animator's thread
animator.invokeLater( new Runnable()
{
public void run()
{
// execute the transformation
Document document = svgImage.getDocument();
SVGSVGElement root = (SVGSVGElement)
document.getDocumentElement();
root.setCurrentScale( root.getCurrentScale() + delta );
}
} );
}
SVGImage.getDocument()提供了动画绘制器渲染的文档的引用。因为这个播放器可能正在运行一个或者更新一个动态的内容,所以你必须小心地将你的变化和动画线程同步,否则将会发生不可确定的错误。SVGAnimator's invokeAndWait() 和invokeLater()方法就像它们的AWT副本一样,可以保证你的代码在动画线程上运行。