在 Kuix 框架下绘制自己定义的画布

在 Kuix 框架下绘制自己定义的画布

        本文详细介绍了如何在以低级界面实现的 Kuix 框架下绘制自定义画布,以及自定义画布用户事件的加入。
        我们知道,Kuix 的实现全部是低级界面,也就是说你看到的每一个按钮,每一个输入框,等等貌似 JavaME 高级界面的东西,实际上都是利用 JavaME 的低级界面,也就是 Canvas 绘制而成。org.kalmeo.kuix.core.KuixCanvas 继承自 JavaME 的 javax.microedition.lcdui.game.GameCanvas,担当了绘制 Kuix 所有界面的重任。
        这样就给我们绘制自己的低级界面带来了难度,有种把两只脚绑在一块走路的感觉。既然所有的界面都是用继承了 Canvas 的 KuixCanvas 来绘制,怎么可以再自定义一个 Canvas 的子类呢?除非脱离 Kuix 框架。但是有时候还必须得绘制自定义的低级界面。怎么办呢?——利用 Widget。                org.kalmeo.kuix.widget.Widget 是所有的 Kuix 下 widget 的基类,其作用和地位类似于 Qt 编程中的 QWidget。查看 org.kalmeo.kuix.widget.Widget 的 API,会发现它是有一个 public void paint(Graphics arg0) 方法的。原来 Kuix 的设计者们已经考虑到了我们的需求,并且给我们保留了一个进行自定义界面的接口。说做就做。写一个继承自 Widget 的类,画一个我们熟悉的绘制的低级界面:一个字符串“Hello,Kuix”和一个图片。源代码如下:

        调用的时候,只需要写一个继承自这个类的子类即可。

        效果图如下:

低级界面效果图
        这时候我们会发现,虽然按照我们的意图绘制出了我们的低级界面,但是却只能显示,这不是我们想要的。我们要的是可以随我们的键盘/鼠标事件随意改变的低级界面。于是我们想到了 Canvas 的 keyPressed()/keyRepeated()/keyReleased()/pointerPressed()/pointerDragged()/pointerReleased() 方法。但是 widget 并非继承自 Canvas,如果非要加上这些方法,除非 PmapWidget 也继承 Canvas。我们知道:Java 所有的类只能有一个父类。也就是说这是不可行的。那么怎么样才可以加入这些方法来实现我们的功能呢。这时候有的朋友可能会想到:让 Widget 继承 Canvas!好主意。但是不可行。作者曾尝试过修改 Kuix 源码,也就是让 Widget 继承 Canvas,然后在 PmapWidget 中加入上面事件处理方法。但是事实证明:这样是不可行的,keyPressed 根本就不会起作用。读者如果感兴趣的话可以自己去试试。
        那么为什么我们让 Widget 继承 Canvas,我们的按键事件处理方法还不起作用呢?这个问题就要从 Kuix 的事件处理机制谈起。关于 Kuix 的事件处理,网上相关文献很丰富,而且这里限于篇幅,作者不再详细介绍。我们只需要知道:Kuix 并没有在回调 Canvas 的系统主线程中处理事件,而是采取了将事件记录下来,使用工作线程处理和分发事件的方法。查看 org.kalmeo.kuix.core.KuixCanvas 的源代码,我们会发现,KuixCanvas 拦截了所有的用户事件(包括按键和指针)。比如拦截 keyPressed() 的源代码如下:

        也就是说如果我们想相应用户事件,必须遵守 Kuix 的游戏规则,按照它的套路出招。Kuix 给我们提供了一个继承自 Widget 的 org.kalmeo.kuix.widget.ActionWidget
 类,来进行自定义事件处理。于是我们的 PmapWidget 得到了改进:


        再次运行程序,发现向上键按下的时候,屏幕已经开始作出相应了,效果图如下:
事件处理效果图

posted @ 2009-12-20 10:57  Defonds  阅读(32)  评论(0编辑  收藏  举报