在Blackberry编写邮件的窗体中加入控件:编写自定义控件
Taigoo 发表于 December 5, 2008 2:02 am
版权信息 :严禁转载, 若想推荐或收藏,请用链接的形式.
网址:http://www.inblackberry.com/web/development/implements-custome-image-previiew-field.html
在上一篇文章<<在Blackberry编写邮件的窗体中加入控件>>介绍了如何在Blackberry自带的mail编辑器里加入控件。其中提到了图片预览的控件,我自己花了点时间写了一个.这样BerryMail的附件预览功能基本上大功告成,难吗?不难。
我写的效果如下:
上面只是简单的介绍了一下,目前该代码还不完善,主要表现在:
- 图片的缩放问题
- 图片属性的完善,例如分辨率等
- 一些样式的调整
尽管这样,我的目的也只想起到一个抛砖引玉的目的,如果哪位感兴趣,那就完善一下吧。
上部分代码:
package com.taigoo.eie.gui.component;
/**
* it can make image preview, and shows the attributes of the image.
* such as name, size,image type.
* @author taigoo zhang
*
*/
public class ImagePreviewField extends Field {
public final static int IMAGE_ATTRIB_NAME = 0 ; //image name attribute
public final static int IMAGE_ATTRIB_PATH = 1 ; //image path
public final static int IMAGE_ATTRIB_SIZE = 2 ;
public final static int IMAGE_ATTRIB_RESOLUTION = 3 ;
public final static int IMAGE_ATTRIB_TYPE = 4 ;
//The field's width
private int width ;
//the field's height
private int height ;
//the image height to render
private int imageHeight = 80 ;
//the image width to render
private int imageWidth = 80;
//image path
private String imagePath;
//font
private Font font;
private IntHashtable attributes = new IntHashtable();
private EncodedImage encodeImage ;
//the space between 2 lines in Y direction
private int heightOffset = 2 ;
//the space between 2 lines in X direction
private int widthOffset = 2 ;
//the vertical line top/bottom/left/right margin.
private int lineOffsetTop = 10 ;
private int lineOffsetBottom = 10 ;
private int lineOffsetLeft = 5;
private int lineOffsetRight = 5 ;
//arch height and width
private int arcHeight = 15 ;
private int arcWidth = 15 ;
//the margin between the fields in it.
private int marginTop = 10 ;
private int marginBottom = 10 ;
private int marginLeft = 10 ;
private int marginRight = 10;
/**
* Constructor
* @param path image path
*/
public ImagePreviewField(String path) {
font = this.getFont();
imagePath = path;
this.width = this.getPreferredWidth();
this.height = this.getPreferredHeight();
//read data
readImage();
}
/**
* @see net.rim.device.api.ui.Field#paint(Graphics)
*/
protected void paint(Graphics g) {
//firstly, draw a round rectangle.
g.drawRoundRect(0, 0, width, height, arcWidth, arcHeight);
//draw image
int imageX = this.marginLeft ;
int imageY = this.marginTop ;
//so complex here
float ratio = this.getScaleRatio() ; //get the ratio in format of Fiexed32 type.
int divisor = Fixed32.toFP(100) ;
int multiplier = Fixed32.toFP(400 - new Float(ratio*100).intValue()) ;
int scaleWidth = Fixed32.toFP(1);
scaleWidth = Fixed32.div(scaleWidth,divisor);/** First, divide the image scale by 100. */
scaleWidth = Fixed32.mul(scaleWidth,multiplier); /** Now, multiply the image scale by the multiplier. */
int scaleHeight = Fixed32.toFP(1);
scaleHeight = Fixed32.div(scaleHeight,divisor);/** First, divide the image scale by 100. */
scaleHeight = Fixed32.mul(scaleHeight,multiplier); /** Now, multiply the image scale by the multiplier. */
int drawImageWidth = new Float(this.encodeImage.getWidth() * ratio).intValue();
int drawImageHeight = new Float(this.encodeImage.getHeight() * ratio).intValue();
g.drawImage(imageX, imageY, drawImageWidth, drawImageHeight
, this.encodeImage.scaleImage32(scaleWidth ,scaleHeight), 0, 0, 0);
//draw vertical line
int lineX = imageX + imageWidth + lineOffsetLeft ;
int lineY = imageY ;
g.drawLine(lineX, lineY, lineX, lineY + imageHeight);
//draw text
//name
int textX1 = lineX + lineOffsetRight ;
int textY1 = lineY ;
g.drawText(this.attributes.get(ImagePreviewField.IMAGE_ATTRIB_NAME).toString(), textX1, textY1 ,
(int)( getStyle() & DrawStyle.ELLIPSIS | DrawStyle.HALIGN_MASK ), this.getPreferredWidth() - textX1);
//size
int textX2 = textX1;
int textY2 = textY1 + font.getHeight() + this.heightOffset ;
long fileSize = Long.parseLong(this.attributes.get(ImagePreviewField.IMAGE_ATTRIB_SIZE).toString());
g.drawText("Size: " +new Long(fileSize/1024).toString()+"K" , textX2, textY2 ,
(int)( getStyle() & DrawStyle.ELLIPSIS | DrawStyle.HALIGN_MASK ), this.getPreferredWidth() - textX2);
//type
int textX3 = textX2 ;
int textY3 = textY2 + font.getHeight() + this.heightOffset ;
g.drawText("Type: " + convertImageTypeToString(Integer.parseInt(attributes.get(ImagePreviewField.IMAGE_ATTRIB_TYPE).toString()))
, textX3, textY3 , (int)( getStyle() & DrawStyle.ELLIPSIS | DrawStyle.HALIGN_MASK )
, this.getPreferredWidth() - textX3);
}
/**
* Read the image to byte stream.
* @return
*/
private byte[] readImage(){
byte[] data ;
try {
FileConnection fileConnection = (FileConnection)Connector.open(imagePath);
if (fileConnection.exists()) {
InputStream input = fileConnection.openInputStream();
int size = input.available();
data = new byte[size];
input.read(data, 0, size);
//read image attributes
this.readAttributes(fileConnection) ;
encodeImage = EncodedImage.createEncodedImage(data,0,data.length) ;
this.attributes.put(ImagePreviewField.IMAGE_ATTRIB_TYPE,new Integer(encodeImage.getImageType())) ;
} else {
throw new Exception("File is not found.");
}
fileConnection.close();
} catch(Exception ioe) {
throw new IllegalArgumentException(ioe.getMessage());
}
return data;
}
/**
* Gets the image type.
* @return
*/
private void readAttributes(FileConnection fc) {
if(fc != null) {
this.attributes.put(ImagePreviewField.IMAGE_ATTRIB_PATH, fc.getPath());
//image name
String name = fc.getName();
this.attributes.put(ImagePreviewField.IMAGE_ATTRIB_NAME, name);
try{
this.attributes.put(ImagePreviewField.IMAGE_ATTRIB_SIZE, new Long(fc.fileSize()));
} catch(IOException ioe){
this.attributes.put(ImagePreviewField.IMAGE_ATTRIB_SIZE, new Long(0));
}
}
}
/**
* Converts the image type from int to string.
* @param type
* @return
*/
private String convertImageTypeToString(int type) {
String typeString = "IMAGE/UNKNOWN" ;
switch(type){
case EncodedImage.IMAGE_TYPE_BMP :
typeString = "IMAGE/BMP" ;
break;
case EncodedImage.IMAGE_TYPE_GIF :
typeString = "IMAGE/GIF";
break;
........
default:
typeString = "IMAGE/UNKNOWN" ;
}
return typeString;
}
private float getScaleRatio() {
int w = this.encodeImage.getWidth() ;
int h = this.encodeImage.getHeight() ;
float ratioWidth = 1.0f *imageWidth/w ;
float ratioHeight = 1.0f * imageHeight/ h;
return (ratioWidth < ratioHeight) ? ratioWidth : ratioHeight ;
}
}
上面只显示了一些关键代码,提供以下思路而已啦。
若索要全代码,和我联系即可。

1. nathaniel 发表于 May 30,2009 22:37:18
博主,您好,我想问个问题.FileConnection能在模拟器上测试吗?
我每次在模拟器上用FileConnection.create()方法时都会报错.