在Blackberry编写邮件的窗体中加入控件:编写自定义控件

在上一篇文章<<在Blackberry编写邮件的窗体中加入控件>>介绍了如何在Blackberry自带的mail编辑器里加入控件。其中提到了图片预览的控件,我自己花了点时间写了一个.这样BerryMail的附件预览功能基本上大功告成,难吗?不难。

我写的效果如下:

上面只是简单的介绍了一下,目前该代码还不完善,主要表现在:

  1. 图片的缩放问题
  2. 图片属性的完善,例如分辨率等
  3. 一些样式的调整

尽管这样,我的目的也只想起到一个抛砖引玉的目的,如果哪位感兴趣,那就完善一下吧。

上部分代码:

 

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条评论

  1. 博主,您好,我想问个问题.FileConnection能在模拟器上测试吗?
    我每次在模拟器上用FileConnection.create()方法时都会报错.

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注