预告:j2medev.com将开始整理各个版面的有价值问题,并以PDF格式集结,敬请期待。
出品商
产品名称
产品版本
J2medev.com
版面有价值的问题合集
0.1
j2medev.com之“用户界面和多媒体”版面
有价值问题的整理
历史
Version
Date
Creator
Description
1.0.0.1
2006-4-4
郑昀
草稿
1.0.0.2
2006-4-5
郑昀
第二稿
1 全屏问题
全屏/FullCanvas/setFullScreenMode
关键词
详细描述
SonyEricsson T630
该款手机的参数:索尼爱立信 T630 SonyEricssonT630R401 ProfileMIDP-1.0 ConfigurationCLDC-1.0。
“据我所知,不可以实现全屏显示。”
--- lulei204
SonyEricsson K700c
k700c 直接用nokia的FullCanvas,可以全屏176 x 220。
k700c用midp2.0的那个this.setFullScreenMode(true);也是可以全屏的,176x220。
k700c直接用nokia的FullCanvas全屏好像是176*208,直接拿nokia60上的程序可以直接放进去。键值和60的也是相同的,只是多了一个返回键,我忘了值是多少了。用2.0的GameCanvas大小是176*220。
--- lulei204
不使用FullCanvas实现全屏的方法
为了用标准的SUN WTK2.1开发能兼容各种机型的MIDP2.0游戏,会遇到一个奇怪的全屏问题,在K700上好好的,到了Nokia上居然死活显示一半,费了一番功夫后,终于不用FullCanvas实现了兼容K700和Nokia的全屏显示,方法如下:
在索爱的K700上,实现全屏很简单,如下写法就可以了:
public Canvas1()
{ super(false);
this.setFullScreenMode(true);
this.width=getWidth();
this.height=getHeight();
} 得到的屏幕大小是176*220。
Nokia上就比较奇怪了,这种方式取得的width和height居然是176*144。
需要加以下代码修正一下:
if(width>=176)
{ if(height<208)
{
height=208;
}
} 绘图部分都以width和height为基准。
另外canvas1不能继承系统的GameCanvas,因为系统GameCanvas里的缓冲图还是176*144的,画出来就只能是半屏,我用j2me polish里的GameCanvas修改一下后,放到src里代替系统GameCanvas就OK了。
修正过的GameCanvas代码如下:
http://www.j2medev.com/bbs/dispbbs.asp?
BoardID=19&ID=3218&replyID=&skin=1
---alexhy
FullCanvas和setFullScreenMode()的区别
setFullScreenMode用于MIDP2.0设备上。com.nokia.mid.ui.FullCanvas是Nokia UI API 1.1的包,用于MIDP2.0设备上,SonyEricsson手机也支持。
“FullCanvas是肯定可以实现全屏幕显示的,但是MIDP2.0里面的setFullScreenMode()只是实现为尽量使用最大的屏幕空间,但是不一定是全屏幕,要看各个手机的实现。”
---mingjava
“FullCanvas不能加Command;setFullScreenMode(true)可以加上Command()。只是我加上一个按键时,却不管把它设在哪里,只能是右键响应。”
---风过留痕
FullCanvas和Canvas,GameCanvas分别有什么不同
“FullCanvas是Canvas的子类,实现全屏的功能,而且把按键针对nokia的手机进行了映射。其他没有什么区别。”
---migjava
“GameCanvas也是Canvas的子类,自MIDP2.0起提供,专门针对游戏增加了一些功能。在按键和显示各方面的运用都和Canvas有较大的不同。”
---efei
Motorola的MIDP1.0手机
“motorola如果不支持MIDP2.0,应该就没办法实现全屏了。全屏下的菜单很好实现,不用搞得象Command那么复杂,那个Command用起来就是很不爽,还是自己写最好。”
---海标
Nokia S60全屏后的Canvas高度
“canvas. setFullScreenMode(true)后,一定让他被绘制一次,系统会调用sizechange(int w,int h),w、h肯定是全屏的。仅调用setFullScreenMode (true)则好象各系统有不同处理。”
---atchome
“You can call getWidth() getHeight() after Canvas.showNotify(). Then it will return the correct value. eg. 176*208”
--- okboy001
“系统第一次回调paint()方法时可以获得正确的屏幕尺寸
原因如atchome所说”
--- imshark_jinni
“在Nokia S60真机上这是一个BUG似乎:
setFullScreenMode(true);调用之后,
getHeight()返回的并不是全屏后的高度,比如他本应该返回208,
但是他却返回144,所以,在真机测试时也要小心nokia s60的这个bug,
不要因为屏幕高度获取不正确,导致fillRect与你预想不一致。
以上这个BUG,起码我的Nokia 7610就是这样。
所以我必须在setFullScreenMode(true);全屏之后
通过下面代码来获取真实的canvas高度:
Code:
public abstract class PopupCanvas extends Canvas
{
。。。。
/*
* 针对Nokia全屏情况下getHeight的BUG,此函数出自于
* http://discussion.forum.nokia.com/f...?threadid=48826
*/
public int getHeight(){
try{
if("Nokia".compareTo(
System.getProperty("microedition.platform").substring(0,5))
== 0)
return 208;
else
return super.getHeight();
}
catch(Exception e){
return super.getHeight();
}
}
}”
---zhengyun
2 Image和ByteArray转换问题
Image/byte[]/Convert
关键词
详细描述
Image对象转换为byte[]
“image-(getGraphics)->graphic-(setClip, 对每个象素getColor)->原始byte[]”
--- rypan
“要是在 J2ME 的话, 看来只有 Image.getRGB() 能帮上:
还有做int[] -> byte[] 的动作, 可以考虑用 ByteArrayOutputStream
+ DataOutputStream, 把 int[] 用 dos.writeInt 的方法写在 Byte array 上.
当然可以用最老土的方法, 不知道那种快:
byteArray[i] = intArray[j] & 0xFF;
byteArray[i+1] = (intArray[j] >> 8)& 0xFF;
byteArray[i+2] = (intArray[j] >> 16)& 0xFF;
byteArray[i+3] = (intArray[j] >> 24)& 0xFF;”
--- wapeter
“
public static byte[] getByteArray(Image image)
{
int raw[] = new int[image.getWidth() * image.getHeight()];
image.getRGB(raw, 0, image.getWidth(), 0, 0,
image.getWidth(), image.getHeight());
byte rawByte[] = new byte[image.getWidth() * image.getHeight() * 4];
int n = 0;
for(int i = 0; i < raw.length; i++)
{
int ARGB = raw;
int a = (ARGB & 0xff000000) >> 24;
int r = (ARGB & 0xff0000) >> 16;
int g = (ARGB & 0xff00) >> 8;
int b = ARGB & 0xff;
rawByte[n] = (byte)b;
rawByte[n + 1] = (byte)g;
rawByte[n + 2] = (byte)r;
rawByte[n + 3] = (byte)a;
n += 4;
}
raw = null;
return rawByte;
}
上面代码进一步的解释:
第一步:
如何获得image对象的int数组呢?这个就简单了可以通过获得RGB数组就可以。Image对象中有直接的getRGB方法,不过这里的参数的位置和J2SE中不太一样:
javax.microedition.lcdui.Image.getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)
第一个是目标数组,第二个是偏移量,第三个是扫描的长度,后两个是起始的位置,最后两个是要取得的宽度和高度。其中扫描的长度一般大于等于获取的宽度。
第二步,把得到的Int数组再生成byte数组。
“ byteArray[i+0] = (rgbArray[i/4] >> 24);
byteArray[i+1] = (rgbArray[i/4] >> 16) & 0x000000FF;
byteArray[i+2] = (rgbArray[i/4] >> 8) & 0x000000FF;
byteArray[i+3] = rgbArray[i/4] & 0x000000FF;
”
第一句,alpha channel;
第二句,red channel;
第三句,green channel;
第四句,blue channel。
为什么有这些东西呢?
我们从一篇文章《介绍MIDP2.0新特性Alpha混合》摘要几句:
[quote]
在MIDP2.0中新增了Alpha混合特性...MIDP2.0 java doc中关于Alpha Processing的说明:在可修改图片中的每个像素都必须是完全模糊的,在不可修改图片中的每个像素可以是完全透明的,完全模糊的或者介于两者之间的,也就是半透明...
[/quote]
所以有了上面的Alpha channel。
[quote]
数组中的数值形式为0xAARRGGBB,其中AA代表透明度,后面的代表颜色值。
[/quote]
也就是说,AA就是Alpha,RR就是Red,GG就是Green,BB就是Blue。
还有一句话概括的:
[quote]444,表示图形格式,好像Nokia S40的机器都是采用444格式表示RGB颜色的。就是红,绿,蓝各用4位表示,至于可以表示透明色ARGB的4444格式,应该是机器硬件实现的。[/quote]”
---zhengyun
3 getRGB问题
getRGB/
关键词
详细描述
getRGB的参数意义
“javax.microedition.lcdui.Image.getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)
第一个是目标数组,第二个是偏移量,第三个是扫描的长度,后两个是起始的位置,最后两个是要取得的宽度和高度。其中扫描的长度一般大于等于获取的宽度。”
-- whycloud
“offset 是指要取的RGB值储存在rgbData数组的起始位置,一般为0。如果offset不为0,使用rgbData数组就不方便了,因为要从offset开始的位置使用。而scanlength不对(如:|scanlength|<width)的话,就可能造成所取的rgbData值会有重复。
在API文档里面有一个公式,可以让我们理解地更深刻:
rgbData[offset + (a - x) + (b - y) * scanlength] = P(a, b)
其中P(a, b)表示在IMAGE数组中位置为(a,b)的像素点。
具体的内容可以参考API文档。
其实MIDP2.0的getRGB()跟NOKIA的getPixels()是类似的。
”
--- xpanda
4 字符串换行问题
drawString/Line Wrap/StringLayout
关键词
详细描述
用g.drawString();
要显示的文字很多,那应该如何实现在Canvas上换行呢
“StringLayout类可以自动排版,还能上下翻行。
代码在
http://www.j2medev.com/bbs/dispbbs.asp?BoardID=11
&replyID=20309&id=3997&skin=0可以找到。
”
--- sakaipb
“自动处理字符串折行显示的封装类Line Wrap
代码以及如何使用的例子都可以从
http://fotomica.astrientlabs.com/downloads/textwrap.jsp 找到。
”
--- zhengyun
5 字体问题
Font/setFont/摩托罗拉
关键词
详细描述
moto系列的手机是不是不支持用setFont来修改字体的大小呢?
“motoV360这机器就这德性。
”
--- Lcheer
“好像moto的某些手机里只有一种字体,高度是17x17,而且下面还会被割去几个象素。”
-- lulei204
“MOTO中低端机型都只有一种字体,而且是中号字体。”
-- summoner
SonyEricsson S700c
上用g.drawString()方法绘制的汉字为何很大?
“索爱S700c上面,Canvas 的drawString()方法绘制的汉字为何很大? 一行最多显示10个字左右。
用了Font的SIZE_SMALL还是一样。”
--webgl2005
“有的手机只支持一种字体,用Font的参数都没有效果。”
---magicDragon
怎样为nokia qd设置字体颜色?
“不知道为什么在QD上字体就只有黑色.怎么设置也不行.
Image offImage =
Image.createImage(SCREEN_WIDTH, SCREEN_HEIGHT) ;
Graphics offGraphics = offImage.getGraphics() ;
offGraphics.setColor(0xffff00) ;
offGraphics.drawString(……) ;
这么写的话,字体永远都是黑色的,但在paint()里直接用g.setColor()却是正常的。”
--- 海标
“setColor在非paint中得到的graphics中都无效。这是S60的bug。
”
---蜡笔小刀
moto字体移植问题
“有人说moto字体不好看,大小调整上给移植带来很大麻烦,我以前也这么认为。
现在我觉得moto的字体还行。在没有办法的情况下,我们只好在程序上下功夫,让字排列的更美观、更好看。”
--lulei204
“moto就是这样,移植的时候狠不得把所有文字都去掉”
--topig