当前位置:  编程技术>移动开发
本页文章导读:
    ▪Practice2- 运用OpenGL ES画点        Practice2- 使用OpenGL ES画点 public void onSurfaceCreated( GL10 gl, EGLConfig config ){    gl.glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); //    gl.glShadeModel( GL10.GL_FLAT ); //        gl.glHint( GL10.GL_POINT_SMOOTH_HINT, GL10.G.........
    ▪ LWUIT 惯用类介绍        LWUIT 常用类介绍 在MIDlet中初始化Lwuit 也是唯一使用原有J2me的东西 可以在startApp方法中定义启动的过程 public void startApp() { //init the LWUIT Display Display.init(this); //加载资源文件 try { Resources r = Resou.........
    ▪ Kuix乱码有关问题       Kuix乱码问题 问题的来源还是前面Kuix国际化的乱码问题,之前没有深究,今天刚好看到了,发现了其中的缘由,先看一篇网上的帖子,讲的就是怎么读取UTF-8: 一、读取Unicode文件    /**    * 读取U.........

[1]Practice2- 运用OpenGL ES画点
    来源: 互联网  发布时间: 2014-02-18
Practice2- 使用OpenGL ES画点
public void onSurfaceCreated( GL10 gl, EGLConfig config ){
    gl.glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); //

    gl.glShadeModel( GL10.GL_FLAT ); //
   
    gl.glHint( GL10.GL_POINT_SMOOTH_HINT, GL10.GL_FASTEST ); //
   
    gl.glEnableClientState( GL10.GL_VERTEX_ARRAY ); //set for  array as vertex
    gl.glEnableClientState( GL10.GL_COLOR_ARRAY ); //set for  array as color
    gl.glDisable( GL10.GL_TEXTURE_2D ); //no 2D texture binded, so we disable it for fast speed
}


    //override method
    public void onDrawFrame( GL10 gl ){
    gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );
   
    int x = 0;
    int y = 0;
    int i = 0,j=0;
    int vertex[] = new int[pointNum * 2];
    int color[] = new int[pointNum * 4];

    //set each dot's position
    for( i=0 ; i<pointNum ; i++ ){
    if( dispWidth != 0 ){
    x = rand.nextInt( dispWidth );
    }
    if( dispHeight != 0 ){
    y = rand.nextInt( dispHeight );
    }
    vertex[i*2] = x * 0x10000;
    vertex[i*2+1] = y * 0x10000;
   
    for( j=0 ; j<4 ; j++ ){
    color[i*4 + j] = one;
    }
    }
drawPoint( gl, vertex, color, 10 );
    try{
    Thread.sleep( 17 );
    } catch ( InterruptedException e ){
    }
    // System.gc(); uncomment this will slow down performance
    }

   
private void drawPoint( GL10 gl, int[] vertex, int[] color, int size ){
gl.glPointSize( size );
gl.glVertexPointer( 2, GL10.GL_FIXED, 0, getIntBuffer( vertex ) );
gl.glColorPointer( 4, GL10.GL_FIXED, 0, getIntBuffer( color ) );
    gl.glDrawArrays( GL10.GL_POINTS, 0, pointNum );
    }

    
[2] LWUIT 惯用类介绍
    来源: 互联网  发布时间: 2014-02-18
LWUIT 常用类介绍

在MIDlet中初始化Lwuit 也是唯一使用原有J2me的东西

可以在startApp方法中定义启动的过程
public void startApp() {
//init the LWUIT Display
Display.init(this);
//加载资源文件
try {
Resources r = Resources.open("/myresources.res");
UIManager.getInstance().setThemeProps(r.getTheme(
r.getThemeResourceNames()[0])
);
} catch (java.io.IOException e) {
}
简单的使用一个内置Form进行显示,而无须使用一个而外的类
Form f = new Form();
f.setTitle("Hello World");
f.setLayout(new BorderLayout());
f.addComponent("Center", new Label("I am a Label"));
f.show();
注意使用show方法进行显示


组件介绍

Component 用于显示到页面上的基础部分,可以理解为DisplayObject,也就是组件部分

Container 用于保存多个Components的容器类型,提供了布局的能力


Form : 提供title和menus,并且提供一个content放置Components,并且提供了content的滚动能力
addComponent,用于添加Components到Content中

提供的一些方法和使用方式

Form mainForm = new Form("Form Title"); //声明一个带标题的Form

mainForm.setLayout(new BorderLayout()); //设置布局管理器

mainForm.addComponent(BorderLayout.CENTER, new Label(“Hello,World”)); //添加Components组件,

mainForm.setTransitionOutAnimator(CommonTransitions.createFade(400)); //设置动画

mainForm.addCommand(new Command("Run", 2)); //添加菜单命令

mainForm.show(); //显示Form

一些技巧
1:可以使用带参数的构造函数,设置标题.也可以不设置标题的构造函数
2:addComponent() 方法提供两个重载,区别在于是否指定布局位置
3:Transition动画用于在forms之间进行切换时候触发
4:Form通过Commands添加菜单,根据添加顺序排序显示,其他使用与普通的J2me一样


Label: 可以同时显示图片和文字,设置align布局,可以通过继承Label实现扩展,如果更复杂,可以使用Button

提供的一些方法和使用方式

Label textLabel = new Label("I am a Label"); //创建一个单行文本

Image icon = Image.createImage("/images/duke.png");
Label imageLabel = new Label(icon); //创建一个带图片的Label

setTextPosition(int alignment); //设置布局方式,CENTER, LEFT, RIGHT,LEFT,TOP, BOTTOM, LEFT, RIGHT,


Button 可以用于触发一个点击的事件Action,使用一个ActionListeners 进行监听

final Button button = new Button("Old Text");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
button.setText("New Text");
}}); //使用匿名的ActionListener接口实现类进行监听

Button继承Label, 所以可以设置不同图文混编的风格,并且提供了三种状态ollover, pressed, and the default
state


RadioButton 单选按钮,继承自Button

RadioButton radioButton = new RadioButton(“Radio Button”);
同样,也会触发action

ButtonGroup 用于保证RadioButton只能选中一项

RadioButton rb1 = new RadioButton("First RadioButton in Group 1");
RadioButton rb2 = new RadioButton("Second RadioButton in Group 1");
ButtonGroup group1 = new ButtonGroup();
group1.add(rb1);
group1.add(rb2);

exampleContainer.addComponent(rb1);
exampleContainer.addComponent(rb2);

这里需要注意,只需要添加addComponent(RadioButton) 到容器中,不需要添加ButtonGroup,只用于后台管理


CheckBox 多选框,不需要添加到group中,同样也触发事件

final CheckBox checkBox = new CheckBox(“Check Box”);

通过checkBox.isSelected() 判断是否被选中

ComboBox 列表,只允许一个被选中,多用于空间有限时候提供多选项的单选功能

创建需要一个数组作为数据源
String[] content = { "Red", "Blue", "Green", "Yellow" };
ComboBox comboBox = new ComboBox(content); //创建一个Combox,在这个构造函数中也是使用List实现

comboBox.setListCellRenderer(new checkBoxRenderer()); //设置renderer 渲染器
也可以使用addActionListener注册事件


通过实现不同的renderer接口可以给组件提供不同的显示效果 implements ListCellRenderer


TextArea

例子
TextArea textArea = new TextArea(5, 20, TextArea.NUMERIC);
textArea.setEditable(false);

构造函数的前两个参数为 总行数和单行长度,第三个参数用于传递到本地文本输入,用于指定限制的类型

可以使用TextArea的常量 ANY,EMAILADDR, NUMERIC, PHONENUMBER, URL, or DECIMAL,PASSWORD, UNEDITABLE, SENSITIVE,NON_PREDICTIVE, INITIAL_CAPS_SENTENCE, INITIAL_CAPS_WORD.也可以使用 | 设置复合约束
默认下可编辑


TabbedPane 通过类似Tab的选项卡方式并排放置一组容器,容器的tab标签可以使用图文混编方式

可以使用addTab or insertTab methods 方法添加容器
removeTabAt(int index) 移除容器
tab的索引由0开始

tab标签可以有四种不同的放置方法 LEFT, RIGHT, TOP or BOTTOM using the setTabPlacement method.

TabbedPane tabbedPane = new TabbedPane(TabbedPane.TOP);
tabbedPane.addTab("Tab 1", new Label("I am a TabbedPane!"));
tabbedPane.addTab("Tab 2", new Label("Tab number 2"));

构造函数使用一个Tab标签布局的常量作为参数

addTab,第一个为tab标签名,第二个参数为直接放置到容器中的内容

Using Lists

List,使用Swing的 MVC模式进行创建
rendered using a ListCellRenderer and are extracted using the ListModel.

使用ListCellRenderer 作为显示的V
使用ListModel. 作为数据源M
其他部分为C进行操作

创建List 有四个构造函数
List()
List(ListModel model) //直接实例化ListModel
List(Object[] items) //Array数组
List(Vector items) //Vector集合

ListModel 也可以分为自定ListModel的实现,以及DefaultListModel

DefaultListModel的使用
String[] items = { "Red", "Blue", "Green", "Yellow" };
DefaultListModel myListModel = new DefaultListModel(items); //使用Array作为数据源

ListCellRenderer 渲染器
同样也可以自定ListCellRenderer的实现,以及DefaultListCellRenderer

自定义的时候,可以通过继承Libel,来节约开发的速度 ,主要实现两个方法
public class MyYesNoRenderer extends Label implements ListCellRenderer{
public Component getListCellRendererComponent(List list,
Object value, int index, boolean isSelected) {
((Boolean)value).booleanValue() 来获取单项的值
}

public Component getListFocusComponent(List list) {
Label label = new label("");
label.getStyle().setBgTransparency(100);
return label;
}}


DefaultListCellRenderer,默认也是使用Label and the ListCellRenderer interface.
实现两个方法,大体和上面相同
getListCellRendererComponent()
getListFocusComponent() //选中风格,可以通过修改透明度来表现


添加或移除item

添加的方法有两种,创建一个ListModel,然后add到list中,重置一个List 使用setModel(ListModel model). 方法

移除的方法有removeItem(int index) or removeAll() methods.

myListModel.addItem(“New Item”); //添加Item
myListModel.removeItem(index); //删除Item
myListModel.removeAll(); //删除所有Item

List 事件 提供了两种事件 ActionEvent and SelectionsListener
addFocusListener(FocusListener l) 区别于常用的Action
SelectionListener 应该会更有用一些

Fixed Selection Feature 应该是只有一行的List,不弹出菜单的模式 //具体还是demo才知道
通过 setFixedSelection(int fixedSelection) 进行设置
通过四个常量属性进行设置
FIXED_NONE //普通的List
FIXED_TRAIL //静态
FIXED_LEAD // ...下面两种都需要用demo看下区别
FIXED_CENTER

setSmoothScrolling(true) //设置这个属性,应该是在移动时增加动画效果,默认为false


Using Dialogs 对话框

也提供一个Content,可以存放其他的Components //对于是否阻塞线程,需要了解一下

Dialog提供了五种不同的类型,默认附加了不同的提示音
ALARM //警告
CONFIRMATION //确认
ERROR //错误
INFO //信息
WARNING //警告提示

当前默认情况下不支持Icon,不过可以自定义Dialog

调用dialog的show()方法进行显示,提供的参数很多,可以选择合适的重载进行显示
1:String title 标题
2:Component body 一个单独的Component
3:String text 用于代替Component body部分
4:Command[] cmds 可以添加Commands
5:int type 设置不同的类型
6:Image icon 添加icon
7:timeout 打开持续时间,设置成0表示为持续打开
8:Transition transition 添加动画
9:String okText 设置Ok按钮的内容
10:String cancelText 设置cancel的内容
11:int top 设置top所在位置
12:int bottom 设置bottom位置
13:int left 同上
14:int right 同上
15:boolean includeTitle //需要了解下

show方法可以返回三个类型 void,Command,boolean
boolean值在点击ok时为true, cancel时为null

使用非静态的方法显示Dialog
dialog.show(90, 90, 10, 10, true);

关闭dialog dispose()
需要先show之前设置timer去关闭dialog

Dialog也可以返回一个Command 区别于点击OK按钮


Using LayoutManagers 使用布局管理器

已经的布局管理器
BorderLayout
BoxLayout
FlowLayout
GridLayout
GroupLayout

BorderLayout 边框布局模式(东西南北中)

如下五个区域
Center
East
North
South
West

在添加Components的时候进行设置
addComponent(BorderLayout.CENTER, component) // preferred
或者直接使用字符串
addComponent(“Center”, component) // valid but error prone 容易出错

BoxLayout 盒子布局
包括了 X_AXIS(横向) Y_AXIS(竖向)的布局,并排的方式

BoxLayout boxLayout = new BoxLayout(BoxLayout.X_AXIS);
BoxLayout boxLayout = new BoxLayout(BoxLayout.Y_AXIS);

FlowLayout 流式布局
这个也是容器默认的布局方式
横向布局,如果长度超出,则自动换行处理

FlowLayout exampleLayout = new FlowLayout();
container.setLayout(exampleLayout);

也可以通过设置构造函数,用于设置布局起始的位置,比如 Left, Right, or Center
FlowLayout exampleLayout = new FlowLayout(Component.RIGHT);

GridLayout 表格式布局,可以用于设置九宫图

可以定制行和列,
GridLayout exampleLayout = new GridLayout(0,2); //2表示每行显示两个单元格cell,0不知道是啥

GroupLayout // GUI builders 的方式进行布局,用于NetBeans中的Swing开发


Using Painters

是一个接口,可以用于绘制一个Components的背景,将绘制在Components限定的范围内

如果要查看painter绘制结果,需要设置对应的transparency //需要查看下

painter可以使用绝对坐标的绘图,所以可以重用在其他组件之上

Painter diagonalPainter = new Painter() {
public void paint(Graphics g, Rectangle rect) {
g.drawLine(rect.getX(),
rect.getY(),
rect.getX() + rect.getSize().getWidth(),
rect.getY() + rect.getSize().getHeight());
}
};

注意查看这里获取位置的方法 x y, size width height

使用时候只要给指定的组件设置Painter即可
myComponent.getStyle().setBgPainter(diagonalPainter);
将会自动应用绘图

记得显示的调用设置透明度 0-255之间
myButton.getStyle().setBgTransparency(100);

Using the Style Object 设置样式对象

The Style object sets colors, fonts, transparency, margin, padding, images, and borders to define the style for a given component.

使用component.getStyle(). 获取该对象,可以在运行时候改变

颜色Style

Foreground color 前景色,主要指文字颜色
Foreground selection color 当组件获取焦点时,字体的颜色
Background color 背景色
Background selection color 获取焦点时候的背景色

这里颜色使用的是RGB(格式为0x000000),不带alpha透明色,有而外的透明设置在Style中

Font 字体

Transparency 透明度
setBgTransparency进行设置 范围是0-255之间

Margin and Padding 外边距和内间距,与css的盒模型一样

设置的方式
setPadding(int top, int bottom, int left, int right)
setPadding(int orientation, int gap)
setMargin(int top, int bottom, int left, int right)
setMargin(int orientation, int gap)

// orientation can be Component.TOP, BOTTOM, LEFT or RIGHT
这两个类型方法的区别在于同时设置一个属性,还是多个属性

Images 背景色,默认为不限制背景色 使用bgImage 可以用于进行设置

Borders边框类型

Style Listener 样式事件
myComponent.getStyle().addStyleListener(new StyleListener() {
public void styleChanged(String propertyName, Style source) {}
}}

Painters也可以用于在Style中设置样式,用于按照要求绘制背景
mycomponent.getStyle().setBgPainter(myPainter);


Theming 皮肤

refreshTheme()方法用于更新所有的样式,不过手动修改的样式元素,并不会被更新

设置样式属性需要注意的地方
Button.font – font for all buttons //将会作用到所有Button组件的字体
font- 将会影响到所有没有定义默认值的组components件
这里不像css那样有特殊的单独样式设置

所有支持的样式属性
fgColor 前景色 16进制的格式
bgColor 背景色 16进制的格式,也可以使用缩写ff
bgSelectionColor 背景选中色 16x
fgSelectionColor 前景选中色 16x
bgImage 背景图片
transparency 设置背景图样式透明色 0-255之间,不过目前对背景图无效

font 分为Bitmap font和System font 定义的方式为Bitmap{myFontName} 和System{face;style;size}
其中系统字体的参数为
face=FACE_SYSTEM,FACE_PROPORTIONALFACE_PROPORTIONAL
/javaTheme.res");//进行加载
使用UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0]));//进行设置
然后可以使用components.refreshTheme 更新组件的样式

LookAndFeel DefaultLookAndFeel 似乎是用来定义一些样式无法修改到的东西,比如滚动条,具体要看API Documention

Resources 资源

LWUIT允许的resource elements的元素包括:
Image Resources //图像资源
Animation Resources //动画资源
Bitmap Fonts //位图字体
Localization (L10N) //本地化
Themes //主题

可以通过专门的编辑器 Resource Editor 或者Ant tasks来创建Resources

Loading a Resource 读取一个资源文件
Resources res = Resources.open(“/myresourceFile.res”);
Image i = res.getImage(“imageName”);

图片可以保存在res文件中,或者直接放置在jar文件中

读取jar中图片的方式
Image image = Image.createImage("/images/duke.png");

image的标签,应该是res配置的时候,可以有三个属性
name //名称,默认为文件名
file //图像文件所在位置
pack //boolean值 ,默认为false ,用于设置是否为Indexed

图像少于256色的时候,可以使用Index image,有利于节约空间

使用indexed image的注意地方
1:因为需要按照像素的去操作图像,所以在显示的时候速度比较慢,不过在现在的手机上并不明显
2:在运行时转换indexed image将会比较慢,而且可能会失败,所以应该在编译时候进行转换
3:Indexed image并没有在res文件中被压缩,所以res文件看起来比较大,不过在jar文件中却能被很好的压缩,而且效果比使用png更好
4:indexed images 创建后将不能被改变,比如getGraphics(),详情看API

Animation Resources
LWUIT支持从Gif文件中得到动画效果,保存的结构类似image structure
StaticAnimation 用于操作动画..派生自Image,所以可以直接使用在icon或者其他地方

Fonts 字体
LWUIT支持bitmap fonts and system fonts.

System Font 包括了三个参数
Face //如FACE_SYSTEM, FACE_PROPORTIONAL and FACE_MONOSPACE.
Style //如STYLE_PLAIN, STYLE_ITALIC, STYLE_BOLD.
Size //如SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE.

在类的内部可以去创建字体引用
Font.createSystemFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font.SIZE_MEDIUM);

同时也可以去创建复合类型的字体(加粗和倾斜)
Font.createSystemFont(Font.FACE_SYSTEM,Font.STYLE_BOLD | Font.STYLE_ITALIC,Font.SIZE_MEDIUM);

Bitmap Fonts
三个属性
name //在res文件中,用于程序加载
charset //就是包含的字符,默认为24个字母,数字和一些符号
src //字体文件TrueType所在位置
size //字体大小
bold //是否加粗,默认为false
trueType //默认为true,根据src属性决定是否生效
antiAliasing //默认为true,如果为false表示别名
logicalName //逻辑名称,表示不同的字体编码类型,类似css中使用的4个大区字体

//这里注意文档中只介绍了使用ant创建Bitmap font,具体还是要查看API文档

Localization (L10N) 本地化
类似Properties文件的使用,使用键值对的方式保存在Resources中,只支持使用USASCII嘛的形式

读取
Hashtable h = bundle.getL10N("localize", "en"); //bundle应该是Resources的实例

UIManager.setResourceBundle(Hashtable) //可以用于替换当前语言

Themes 皮肤
使用ResourceEdit.exe 可以很方便的进行编辑

加载到程序:
UIManager.getInstance().setThemeProps(res.getTheme(“myTheme”));

编辑器创建的默认就是Bitmap font

使用字体需要注意版权问题... 使用编辑器的时候,可以通过设置 Anti-aliasing 达到反锯齿的能力

Localization 的使用

Using Transitions and Animations
使用过度效果以及动画

支持的Transition有,可用于form之间进行的转换
Slide
Fade

Slide Transition
在第一个form中定义
CommonTransitions.createSlide(int type, boolean forward, int speed)

参数
type //定义移动的方向,包括了SLIDE_HORIZONTAL or SLIDE_VERTICAL

forward //用一个boolean值表示,不同方向时,起始位置,比如左到右,不过上到下

speed //用int表示的应该是动画持续的时间,从而在内部计算运行的速度

使用的例子
myForm.setTransitionOutAnimator(CommonTransitions.createSlide(
CommonTransitions.SLIDE_HORIZONTAL, true, 1000));

Fade Transition 渐变效果 (淡入淡出)

CommonTransitions.createFade(int speed)

参数
speed 同样表示动画持续时间,毫秒为单位

例子
themeForm.setTransitionInAnimator(CommonTransitions.createFade(400));


M3G 用于实现3D功能,需要手机的支持 Jsr184

//加载源码.注意需要使用jdk1.4进行编译

调用的方式通过 M3G.Callback内部类接口的实例来创建3d动画对象

class MyCallback implements M3G.Callback {
....
public void paintM3G(Graphics3D g3d) {
g3d.clear(background);
g3d.render(world);
}
...
}

在Components组件上使用的方式为
private M3G.Callback myCallbackInstance = new MyCallback();
public void paint(Graphics g) {
M3G.getInstance().renderM3G(g, true, 0, myCallbackInstance);
// draw some stuff in 2D
...
}

注意这里的区别Graphics3D 和普通的Graphics对象

M3G目前只支持标准的图像文件,而不支持IndexedImage and RGBImage

Logging 日志,可以保存在RMS或者本地文件中

也分为了四种级别
DEBUG //默认级别
INFO
WARNING
ERROR

记录日志的方式
使用static p(String text) or p(String text,int level) methods.

Log.p(“Finish loading images”)

显示日志
Log.showLog();

创建自定义的组件,只要继承Component对象,然后重写paint方法即可,类似Canvas的操作


public class MyComponent extends Component {
public void paint(Graphics g) {
g.setColor(0xffffff);
g.fillRect(getX(), getY(), getWidth(), getHeight());
g.setColor(0);
g.drawString("Hello World", getX(), getY());
}}
在页面上进行使用的时候,就和其他Components一样 add到容器之上

需要注意的地方
这里使用的颜色都是不带alpha的RGB

使用 getX(), getY() 从容器中获取Components所在的位置,也包括了 getWidth(), getHeight()

控制组件的大小适宜,通过重写calcPreferredSize()方法
protected Dimension calcPreferredSize() {
Font fnt = Font.getDefaultFont();
int width = fnt.stringWidth(“99999-9999”)
int height = fnt.getHeight();
return new Dimension(width, height);
}

//这里使用到了获取字体高度和宽度的方法

事件监听

和MIDP原有组件一样,只要重写对应key事件即可
public void keyReleased(int keyCode) {
if(keyCode >= '0' && keyCode <= '9') {
char c = (char)keyCode;
inputString += c;
repaint();
}
}

Focus 焦点

Components组件中的事件,要求当前组件获取焦点后才会触发
setFocusable(true); //使其获取焦点

使用LookAndFeel绘制
UIManager.getInstance().getLookAndFeel().drawBorder(g, this,getStyle().getFgSelectionColor(), 2);

不是很明白的例子,在Components中
public void paint(Graphics g) {
UIManager.getInstance().getLookAndFeel().setFG(g, this);
Style style = getStyle();
g.drawString(inputString, getX() + style.getPadding(LEFT),
getY() + style.getPadding(TOP));
}

不过一些方法不错 以及常量, 可能第一个方法是初始化组件中参数的状态
229136

Background 使用Painter来绘制,允许透明translucent与不透明opaque

对自定义组件添加Animating动画支持
protected void initComponent() {
getComponentForm().registerAnimated(this);
}
不能在构造函数中进行注册

自定义组件的例子

关键方法一
protected Dimension calcPreferredSize() {
Style style = getStyle();
Font fnt = style.getFont();
int width = fnt.stringWidth("99999-9999");
int height = fnt.getHeight();
height += style.getPadding(Component.TOP) +
style.getPadding(Component.BOTTOM);
width += style.getPadding(Component.LEFT) +
style.getPadding(Component.RIGHT);
return new Dimension(width, height);
}

用于在窗口变化时候获取合适的显示效果

主要使用到的方法
1: Style s 的init()方法可以关闭一些占用内存较多的特性

Speed 速度方面


Event Dispatch Thread (EDT) 事件发送线程
Display methods callSerially, callSeriallyAndWait, and invokeAndBlock. 通过这几个方法进行调用特别的线程处


Light Mode 不是很清楚用途
turning off light mode (after Display.init())


    
[3] Kuix乱码有关问题
    来源: 互联网  发布时间: 2014-02-18
Kuix乱码问题

问题的来源还是前面Kuix国际化的乱码问题,之前没有深究,今天刚好看到了,发现了其中的缘由,先看一篇网上的帖子,讲的就是怎么读取UTF-8:

一、读取Unicode文件
   /**
   * 读取Unicode编码文本文件
   * @param resource String - 文件名
   * @return String - Unicode文本
   */
   public static String read_Uni(String resource) {
   byte word_uni[] = new byte[1024];
   String strReturn = null;
   InputStream is;
   try {
   is = instance.getClass().getResourceAsStream(resource);
   is.skip(2); // 跳过两个字节的文件头
   is.read(word_uni);
   is.close();
   StringBuffer stringbuffer = new StringBuffer("");
   for (int j = 0; j < word_uni.length; ) {
   int l = word_uni[j++];
   int h = word_uni[j++];
   char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));
   stringbuffer.append(c);
   }
   strReturn = stringbuffer.toString();
   } catch (IOException ex) {
   System.out.println(ex);
   } finally {
   is = null;
   }
   return strReturn;
  }
  
  二、读取UTF-8文件
   /**
   * 读取UTF-8编码文本文件
   * @param resource String - 文件名
   * @return String - UTF-8文本
   */
   public static String read_UTF(String resource) {
   byte word_utf[] = new byte[1024];
   String strReturn = null;
   InputStream is;
   try {
   is = instance.getClass().getResourceAsStream(resource);
   is.read(word_utf);
   is.close();
   strReturn = new String(word_utf, "UTF-8");
   } catch (IOException ex) {
   System.out.println(ex);
   }
   return strReturn;
   }

 

再看看property文件的内容

YES=\u662F

 这是GBK编码保存的,这里有点混乱,实机上myeclipse的property编辑器有个bug,编辑器里面保存的属性值全部用系统编码保存,也就是GBK码,如果你自己在源文件中写中文,而且文件属性是UTF-8,保存后是这样的:

YES=\u00CA\u00C7

 变成了4个字节,这种情况下Kuix读到的会是乱码,看Kuix.loadMessages

	private static synchronized void loadMessages(InputStream inStream) throws Exception {

		InputStreamReader inputStream = new InputStreamReader(inStream, "UTF-8");
......
					key = convertString(key);
					value = convertString(value);
					messageTable.put(key, value);

 可以看到试图用UTF-8编码读取文件,而实际上property是用十六进制保存的,所以还需要用convertString做一次转换

	private static String convertString(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);

		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					// Read the xxxx
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								value = (value << 4) + aChar - '0';
								break;
							case 'a':
							case 'b':
							case 'c':
							case 'd':
							case 'e':
							case 'f':
								value = (value << 4) + 10 + aChar - 'a';
								break;
							case 'A':
							case 'B':
							case 'C':
							case 'D':
							case 'E':
							case 'F':
								value = (value << 4) + 10 + aChar - 'A';
								break;
							default:
								// return KuixConstants.DEFAULT_UNKNOWN_I18N_MESSAGE STRING if there is any problem
								return "???";
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't') {
						aChar = '\t';
					} else if (aChar == 'r') {
						aChar = '\r';
					} else if (aChar == 'n') {
						aChar = '\n';
					} else if (aChar == 'f') {
						aChar = '\f';
					}
					outBuffer.append(aChar);
				}
			} else {
				outBuffer.append(aChar);
			}
		}
		return outBuffer.toString();
	}

 关键在这一句outBuffer.append((char) value);它用两个字节做一个汉字了,所以出现乱码,实际上应该参考前面的方法:

   int l = word_uni[j++];
   int h = word_uni[j++];
   char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));

 最后摘一段文章说明UTF-8编码的大小.(http://www.iteye.com/topic/113572)

1、UTF-8用几个字节表示一个汉字? 
这各答案你可能了解,但也可能不了解,我敢打保票一半人会不清楚(包括特意查资料之前的我)。 
了解这个对编程有什么影响? 


以下我把对yoolywu的回答,转为帖子发表,以表重视。 


yollywu的问:
引用
系统有两个子系统,一个是BS的,一个是delphi做的CS,中间的数据传输是通过XML进行传输的。在XML传输的功能实现后,要求对XML进行加密解密.加密解密算法是CS端用delphi写的,然后这边用JAVA写个同样的算法。现在碰到的一个问题是: 
用该算法的时候,CS和BS各自都能够加解密,我这边的过程是这样的。。。。[但最后]中文始终是乱码 
Java代码 
   
       StringBuffer strbuf = new StringBuffer();  
try {  
    FileInputStream in = new FileInputStream(file);  
    int size = 0;  
    byte [] buf = new byte[1024];     
    while ((size=in.read(buf)) != -1) {  
        strbuf.append(new String(buf,0,size));  
    }  
      
} catch (FileNotFoundException e) {  
    // TODO Auto-generated catch block  
    e.printStackTrace();  
} catch (IOException e1) {  
    // TODO Auto-generated catch block  
    e1.printStackTrace();  
}  
      return strbuf;  
           





Qieqie的答: 



以下的代码是错误的: 
Java代码 
StringBuffer strbuf = new StringBuffer();     
...  
 strbuf.append(new String(buf,0,size));    


第一、 
你应该使用ByteArrayOutputStream,将InputStream的字节全部读出来,然后转成byte[]数组,最后在根据你和对方协议规定的字符集合(假设你们规定的是UTF-8,如果没有规定,那么就补充上吧),将byte[]变成String: String theString = new String(bytes, "UTF-8")。 
不加"UTF-8"的new String,将使用Java环境设置的字符集,没有特别设置的情况下也就是操作系统的字符集。这是不可靠的。 

第二、 
不能使用byte[]+StringBuffer:StringBuffer是针对char操作的(String也是)。读取byte时可能刚好把一个多字节的char分成前后两批加入StringBuffer。这样就破坏了char的完整性了。而如果你使用UTF-8编码的中文,你就会中招,导致乱码(其实是因为你的读取是由于byte失去原有顺序导致的,跟一般的乱码还不一样) 
-- 
在UTF-8编码集中,每个汉字使用 3个字符表示! 实践证明: 
1、创建一个UTF-8编码的文件:weare.txt 
2、写入三个字:“我们是” 
3、运行以下代码: 
Java代码 
public class UTF8 {  
  
    public static void main(String[] args) throws IOException {  
        String p = "weare.txt";  
        InputStream in = new FileInputStream(p);  
        int read = in.read(new byte[1204]);  
        System.out.println(read);  
          
    }  
}  

4、你会发现打印出来的是 9 ! 

所以,byte[]+StringBuffer的使用方式是错误的! 

不过可以使用StringBuffer + bufferedReader.readLine(),读出一行行后再加入StringBuffer。 
或者第2楼说的stringbuffer+reader.read(char[])的形式(毕竟错误是由于byte[]导致的,而非StringBuffer) 




参考资料: 

zh.wikipedia.org 写道

UTF-8 使用一至四个字节为每个字符编码。128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。 

 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3