J2ME 技术的学习与实践者

2008年3月4日 #

j2me如何读取网上资源文件例如文本文件,图形文件,欢迎投稿!

j2me如何读取网上资源文件例如文本文件,图形文件。

例如,读取www.kingdart.cn/jaccount/imobile.png 转换为Image
又例如:读取www.kingdart.cn/jaccount/readme.txt 转换为String

只在模拟器上成功我也会,要求是真机上成功!

posted @ 2008-03-25 22:56 iwinyeah 阅读(615) | 评论 (1)编辑 收藏

[导入]WTK模拟器之RMS(5 还是有可能在手机上做出文件式RMS的)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/174850  发表时间: 2008年03月22日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

我的错!在没有认真阅读FileConnection文档之后就妄下结论.最近下载了fileconnection_spec_1.00文档,发现其中有一个方法
public java.io.OutputStream openOutputStream(long byteOffset)
throws java.io.IOException
该方法在打开输出流时可指定写入的位置,写入的数据将覆盖旧数据,利用这个方法,还是有可能在手机上实现文件式RMS的.

现在我正在做手机理财JAccount的文件备份和恢复,还分不出身来尝试,有兴趣的朋友可以自已试一下如果OK了,别忘了告诉我一声哦!
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/174850

posted @ 2008-03-22 17:01 iwinyeah 阅读(591) | 评论 (3)编辑 收藏

[导入]FileConnection如何使用?


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/174754  发表时间: 2008年03月22日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

由于要为手机理财JAccount增加数据导出到文本文件功能,我为其增加了exportToFile(String fileName)方法,使用Moto模拟器(A630)时发现装入JAR阶段已出错,错误的信息是:
ALERT: Unable to load class javax/microedition/io/file/FileConnection,RAZR_V3则正常.要知道,我从未打算为不同的手机制作不同的JAR,我计划是在代码中检查该手机是否支持FileConnection,若支持的话,菜单项才增加备份和恢复命令项.
如果所有不支持FileConnection的手机都不能装入的话,那不是只能为支持的开发一个版本,不支持的又开发另一个版本?
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/174754

posted @ 2008-03-22 10:55 iwinyeah 阅读(322) | 评论 (0)编辑 收藏

[导入]字段输入流FieldInuptStream


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/174645  发表时间: 2008年03月21日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

/**
 * --------------------------------------------------
 * 字段输入流
 * --------------------------------------------------
 * 从DataInputStream继承
 * 主要增加了从文本格式输入流中读入数据字段的能力
 * --------------------------------------------------
 * 
 * @author iwinyeah 李永超
 * @version 1.0.0
 * */

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FieldInputStream extends DataInputStream {
	public final static int BIN_MODE = 0;

	public final static int TXT_MODE = 1;

	int mode;

	public FieldInputStream(InputStream in, int mode) {
		super(in);
		this.mode = mode;
	}

	public boolean getBoolean() throws IOException {
		if (mode == 0) {
			return readBoolean();
		} else {
			if ("1".equals(next())) {
				return true;
			}
			return false;
		}
	}

	public byte getByte() throws IOException {
		if (mode == 0) {
			return readByte();
		} else {
			return (byte) Integer.parseInt(next());
		}
	}

	public short getShort() throws IOException {
		if (mode == 0) {
			return readShort();
		} else {
			return (short) Integer.parseInt(next());
		}
	}

	public int getInt() throws IOException {
		if (mode == 0) {
			return readInt();
		} else {
			return Integer.parseInt(next());
		}
	}

	public long getLong() throws IOException {
		if (mode == 0) {
			return readLong();
		} else {
			return Long.parseLong(next());
		}
	}

	public String getString() throws IOException {
		if (mode == 0) {
			if (read() == 0) {
				return null;
			} else {
				return readUTF();
			}
		} else {
			return next();
		}
	}

	// 取下一标识符
	private byte[] buffer = new byte[255];

	private int length = 0;

	private boolean eos = false;

	private final static int INITIAL = 0;

	private final static int ESCAPE = 1;

	private final static int COMMENT_START = 2;

	private final static int LINE_COMMENT = 3;

	private final static String WHITESPACE = "\n\r\t";

	public String next() throws IOException {
		length = 0;
		int c = in.read();
		int status = INITIAL;
		READWHILE: while (c != -1) { // 一直读到文件尾

			switch (status) {
			case INITIAL:
				if (c == '\n' || c == '\t') { // 如果是分隔符
					break READWHILE;
				} else if (c == '\\') {
					status = ESCAPE; // 设转义字符标志
				} else if (c == '/') {
					status = COMMENT_START; // 设注释标志
				} else {
					if (WHITESPACE.indexOf(c) < 0) {
						append(c);
					}
				}
				break;

			case ESCAPE: // 处理转义字符
				switch (c) {
				case 'n':
					append('\n');
					break;

				case 'r':
					append('\r');
					break;

				case 't':
					append('\t');
					break;

				case 'b':
					append('\b');
					break;

				case 'f':
					append('\f');
					break;

				default:
					append(c);
					break;
				}
				status = INITIAL; // 设正常情况标志
				break;

			case COMMENT_START: // 处理注释
				if (c == '/') {
					status = LINE_COMMENT; // 是行式注释
				} else {
					status = INITIAL;
					// 如果都不是则把注释起始符和刚读入的字符都加入到标识符中
					append('/');
					append(c);
				}
				break;

			case LINE_COMMENT:
				if (c == '\n') {
					status = INITIAL; // 如果当前为行注释状态则要一直读到行尾才恢复正常情况标志
					break READWHILE;
				}
				break;
			}
			c = in.read(); // 读入下一字符
		}

		if (c == -1) {
			eos = true;
		}

		// 如果读到文件尾时,标识符长度大于零,则返回标识符,否则返回NULL值
		if (length <= 0) {
			return null;
		} else {
			return new String(buffer, 0, length, "UTF-8");
		}
	}

	// 将读入的字符加入缓冲区
	private void append(int c) {
		// 缓冲区不足时自动扩展
		if (length >= buffer.length) {
			byte[] xBuffer = new byte[buffer.length + 16];
			System.arraycopy(buffer, 0, xBuffer, 0, buffer.length);
			buffer = null;
			buffer = xBuffer;
		}

		buffer[length++] = (byte) c;
	}

	public boolean eos() {
		return eos;
	}
}

请参看我的另一篇文章:字段输出流FieldOutputStreamhttp://iwinyeah.javaeye.com/admin/blogs/174644
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/174645

posted @ 2008-03-21 22:19 iwinyeah 阅读(164) | 评论 (0)编辑 收藏

[导入]字段输出流FieldOutputStream


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/174644  发表时间: 2008年03月21日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

我的FieldOutputStream继承了DataOutputStream,这样就可以只更改很少量的代码就实现了既支持原生格式又支持文本方式输出了,稍候一段时间手机理财将可以实现备份和恢复(文本格式)功能了.
package util;
/**
 * --------------------------------------------------
 * 字段输出流
 * --------------------------------------------------
 * 从DataOutputStream继承
 * 主要增加了向输出流写入文本格式的数据字段的能力
 * 文本格式流将由TAB分隔字段,回车换行符分隔记录
 * --------------------------------------------------
 * 
 * @author iwinyeah 李永超
 * @version 1.0.0
 * */

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FieldOutputStream extends DataOutputStream {
	public final static int BIN_MODE = 0;

	public final static int TXT_MODE = 1;

	private final static byte[] fieldSplit = {'\t'};

	private final static byte[] recordSplit = {'\r','\n'};

	private int mode;
	
	private boolean nextEnd = false;

	public FieldOutputStream(OutputStream out, int mode) {
		super(out);
		this.mode = mode;
	}

	// 接着写入的是否最后一个字段
	// 写第一个字段前以参数false调用它
	// 写最后一个字段前以参数false调用它
	public void setNextEnd(boolean end){
		nextEnd = end;
	}
	
	public void putBoolean(boolean value) throws IOException {
		if (mode == 0) {
			writeBoolean(value);
		} else {
			out.write(value ? '1' : '0');
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

	public void putByte(byte value) throws IOException {
		if (mode == 0) {
			writeByte(value);
		} else {
			out.write(String.valueOf(value).getBytes("UTF-8"));
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

	public void putShort(short value) throws IOException {
		if (mode == 0) {
			writeShort(value);
		} else {
			out.write(String.valueOf(value).getBytes("UTF-8"));
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

	public void putInt(int value) throws IOException {
		if (mode == 0) {
			writeInt(value);
		} else {
			out.write(String.valueOf(value).getBytes("UTF-8"));
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

	public void putLong(long value) throws IOException {
		if (mode == 0) {
			writeLong(value);
		} else {
			out.write(String.valueOf(value).getBytes("UTF-8"));
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

	public void putString(String value) throws IOException {
		if (mode == 0) {
			if (value == null) {
				writeByte(0);
			} else {
				writeByte(1);
				writeUTF(value);
			}
		} else {
			if(value != null){
				byte[] b = value.getBytes("UTF-8");
				for(int i = 0; i < b.length; i++){
					if(b[i] == '\n'){
						out.write('\\');
						out.write('n');
					}
					else if(b[i] == '\r'){
						out.write('\\');
						out.write('r');
					}
					else if(b[i] == '\t'){
						out.write('\\');
						out.write('t');}
					else if(b[i] == '\b'){
						out.write('\\');
						out.write('b');}
					else if(b[i] == '\f'){
						out.write('\\');
						out.write('f');
					}else{
						out.write(b[i]);
					}
				}				
			}
			out.write(nextEnd ? recordSplit : fieldSplit);
		}
	}

}


读回请参看另一篇:字段输入流FieldInputStream.http://iwinyeah.javaeye.com/admin/blogs/174645
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/174644

posted @ 2008-03-21 22:16 iwinyeah 阅读(201) | 评论 (0)编辑 收藏

[导入]日期处理类(忽略时间)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/173704  发表时间: 2008年03月19日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

我的一个日期处理类,解决了时区问题,给有需要的人。
package util;

/**
 * --------------------------------------------------
 * 日期转换对象
 * --------------------------------------------------
 * 主要提供日期与1970-01-01后的天数的转换和到字符串的转换
 * --------------------------------------------------
 * 
 * @author iwinyeah 李永超
 * @version 1.0.0
 * */

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateUtil {
	private static Calendar _calendar = Calendar.getInstance(); // 用于日期计算

	private static long MSEC_EVERYDAY = 86400000L; // 一天的微秒数

	private static int rawOffset = TimeZone.getDefault().getRawOffset();

	/**
	 * 将日期转换为1970-01-01后的天数
	 * 
	 * @param Date
	 *            theDate 要计算天数的日期
	 * @return int 所传入日期与1970-01-01相差的天数
	 */
	public static int dateToDay(Date theDate) {
		return (int) ((theDate.getTime() + rawOffset) / MSEC_EVERYDAY);
	}

	/**
	 * 将1970-01-01后的天数转换为日期
	 * 
	 * @param int
	 *            要取的日期与1970-01-01相差的天数
	 * @return Date theDate 与1970-01-01相差相应天数的日期
	 */
	public static Date dayToDate(int day) {
		return new Date(day * MSEC_EVERYDAY);
	}

	/**
	 * 取今天与1970-01-01相差的天数
	 * 
	 * @return int 取今天与1970-01-01相差的天数
	 */
	public static int toDay() {
		return (int) ((System.currentTimeMillis() + rawOffset) / MSEC_EVERYDAY);
	}

	/**
	 * 将日期转换为年月日字符串
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return String 对应日期年月日形式的字符串
	 */
	public static String getYMD(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		return _calendar.get(Calendar.YEAR) % 100 + "/"
				+ (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
				+ (_calendar.get(Calendar.MONTH) + 1) + "/"
				+ (_calendar.get(Calendar.DATE) > 9 ? "" : "0")
				+ _calendar.get(Calendar.DATE);
	}

	/**
	 * 将日期转换为年月字符串
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return String 对应日期年月形式的字符串
	 */
	public static String getYM(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		return _calendar.get(Calendar.YEAR) + "/"
				+ (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
				+ (_calendar.get(Calendar.MONTH) + 1);
	}

	/**
	 * 将日期转换为月日字符串
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return String 对应日期月日形式的字符串
	 */
	public static String getMD(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		return (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
				+ (_calendar.get(Calendar.MONTH) + 1) + "/"
				+ (_calendar.get(Calendar.DATE) > 9 ? "" : "0")
				+ _calendar.get(Calendar.DATE);
	}

	/**
	 * 将日期转换为当月一号
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return int 对应日期所在月份第一天与1970-01-01相差的天数
	 */
	public static int getMonthFirstDay(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		_calendar.set(Calendar.DAY_OF_MONTH, 1);
		return (int) (dateToDay(_calendar.getTime()));
	}

	/**
	 * 取日期所在年份
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return int 对应日期所在年份
	 */
	public static int getYear(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		return _calendar.get(Calendar.YEAR);
	}

	/**
	 * 取日期所在月份
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return int 对应日期所在月份
	 */
	public static int getMonth(int theDay) {
		_calendar.setTime(dayToDate(theDay));
		return _calendar.get(Calendar.MONTH);
	}

	/**
	 * 取日期所在周次
	 * 
	 * @param int
	 *            theDay 与1970-01-01相差的天数
	 * @return int 对应日期所在周次
	 */
	public static int getWeek(int theDay) {
		// 1971-01-03是星期日,从该日开始计算周次
		_calendar.setTime(dayToDate(theDay));
		return (int) ((_calendar.getTime().getTime() - 172800000L) / 604800000L);
	}

}

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/173704

posted @ 2008-03-19 12:32 iwinyeah 阅读(212) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil Action <--> View <--> Controller


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/172974  发表时间: 2008年03月17日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

Action: 规定了与用户交互的View可以触发的动作,在某个View新建之后显示之前,应先为其指定具体的Action,当用户按下了相应的Command按钮之后,View将该Command对应的Action发送到该View的Controller进行处理。
//
public class Action{
    String name; // 名称 
    Command command; // 命令 
    int code; // 代码 (将由该View的传递到其Controller使用)
    Item item; // 数据项 
    boolean defaultAction; // 是否是默认的Action 
    //...省略
}


请看View的基类的代码节选
public abstract class AbstractView{

    //...省略

    // 为该View增加Action
    public void addAction( final Action action, final boolean active )
    {
        if( !actions.containsKey( action.getName() ) )
        {
            // 将Action存入Actions表中
            actions.put( action.getName(), action );
            if( active )
            {
                activateAction( action );
            }
        }
    }

    // 使Action生效可用
    private void activateAction( final Action action )
    {
        final Command command = action.getCommand();
        activeActions.put( command, action );
        final Item item = action.getItem();
        if( item == null )
        {
            addCommand( command ); // 该Action是屏幕相关的命令
        }
        else
        {
            item.addCommand( command ); // 该Action是数据项相关的命令
            if( action.isDefaultAction() )
            {
                item.setDefaultCommand( command );
            }
        }
    }

    //...省略

    // 用户按下相应的命令键后,触发执行与其关联的Action
    public void commandAction(
            final Command       command,
            final Displayable   displayable
    )
    {
        if( !handleAction( command ) )
        {
            if( displayable instanceof Choice )
            {
                AbstractController.commandAction(
                        this,
                        command,
                        (Choice) displayable
                );
            }
            else
            {
                AbstractController.commandAction( this, command );
            }
        }
    }

    // 用户在某个指定了命令的Item按下了命令按钮时触发执行与其关联的Action
    public void commandAction( final Command command, final Item item )
    {
        if( !handleAction( command ) )
        {
            AbstractController.commandAction( this, command );
        }
    }

    // 根据所触发的命令查找关联的Action,并新它发送到Controller进行处理
    public boolean handleAction( final Command command )
    {
        if( activeActions.containsKey( command ) )
        {
            final Action action = (Action) activeActions.get( command );
            // 以Action代码为参数生成ControllerEvent并传递到controller处理
            final ControllerEvent event = new ControllerEvent(
                    action.getCode(),
                    this
            );
            controller.handle( event );
            return true;
        }
        else
        {
            return false;
        }
    }

    //...省略

}

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/172974

posted @ 2008-03-17 14:06 iwinyeah 阅读(343) | 评论 (0)编辑 收藏

[导入]Nokia 6070 报表问题解决


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/172237  发表时间: 2008年03月15日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

经过多次的尝试,终于解决了手机理财JAccount在Nokia 6070反复统计收支表和余额表时出错的问题.
原来我有两个报表上分别使用了incomeVector 和balanceVector来保存所生成的统计资料,每次统计前检查Vector是否为null,否则先置空,再重新new一个.
我尝试过new之后加了runtime.gc(),未能解决问题;
我又尝试过不置空Vector,而使用vector.removeallelements(),也不行;
我又尝试过两个报表共用一个Vector也不行;

最后,我使用两个报表共用数组来保存结果,才解决了问题,有点开心.
类似Nokia6070这种机器的JVM的内存管理的确存在很大的问题,明明有内存也用不得,真郁闷!
不过还是有点开心,毕竟解决了一个问题!
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/172237

posted @ 2008-03-15 21:43 iwinyeah 阅读(143) | 评论 (0)编辑 收藏

[导入]我在J2ME中用过的几种后台线程方法(如何选择?)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/172200  发表时间: 2008年03月15日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

我以前在其他地方发过的贴子,这几种方式都没问题,哪种较好或者说在什么情况下用哪种方法较好呢?
// 方法一
public class firstManager implements Runnable {
  public void runTask() {
   (new Thread(this)).start();
  }
  public void run() {
   System.out.println("\nfirst thread method!");
   // Do some thing ...
  }
}
// 方法二
public class secondManager {
  private BackTask backTask;
  private Timer timer;
  public secondManager() {
   backTask = new BackTask();
   timer = new Timer();
  }
  public void runTask() {
   timer.schedule(backTask, 0);
  }
  private class BackTask extends TimerTask {
   public void run() {
    System.out.println("\nsecond thread method!");
    // Do some thing ...
   }
  }
}
// 方法三
public class thirdManager {
  private BackTask backTask;
  private int cmd = 0;
  public thirdManager() {
   backTask = new BackTask();
   backTask.start();
  }
  public void runTask() {
   synchronized (backTask) {
    cmd = 1;
    backTask.notify();
   }
  }
  private class BackTask extends Thread {
   public void run() {
    while (true) {
     try {
      if (cmd == 0) {
       synchronized (this) {
        wait();
       }
       continue;
      }
      System.out.println("\nthird thread method!");
      // Do some thing ...
     } catch (Exception e) {
     }
     cmd = 0;
    }
   }
  }
}

// 用例
public void main(){
  firstManager man1 = new firstManager();
  secondManager man2 = new secondManager();
  thirdManager man3 = new thirdManager();
  man1.runTask();
  man2.runTask();
  man3.runTask();
}

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/172200

posted @ 2008-03-15 17:47 iwinyeah 阅读(192) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil StreamParser 流标识符分段器


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/170335  发表时间: 2008年03月12日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

在处理资源文件时,我以前的做法是一次性读入资源文件,然后再进行处理,在处理大文件时,这种方法对由于对机器内存消耗较大而存在隐患,刚想将它改为逐字读入的方式,在OpenBaseMovil中发现了这个类,很符合我的要求。关键代码如下:
//... 省略
	public static final String WHITESPACE = "\r\n\t ";
	public String next(final String delimiters, final boolean keepWhitespace,
			final boolean allowComments, final boolean reuseDelimiter,
			final boolean processEscape) throws IOException {
		try {
			final StringBuffer token = new StringBuffer();
			startLine = endLine;
			startChar = endChar;
			int c = in.read();
			endChar++;
			int status = INITIAL;
			while (c != -1) { // 若还未读到文件尾
				if (c == '\n') {
					endLine++;
					endChar = 0;
				}
				switch (status) {
				case INITIAL:
					if (delimiters.indexOf(c) > -1) { // 如果是分隔符
						lastDelimiter = (char) c;
						if (isWhiteSpace(c)) {
							// 如果同时也是空白符并且标识符长度大于零则返回标识符
							if (token.length() > 0) {
								if (reuseDelimiter) { // 如果要重用分隔符则将它推回输入流中
									in.revert((char) c);
								}
								return token.toString();
							}
							// 如果还未有数据,还要继续往下读
						} else { // 如果不是空白符则无论标识符长度是否为零,都要返回
							if (reuseDelimiter) {
								in.revert((char) c);
							}
							return token.toString();
						}
					} else if (processEscape && c == '\\') {
						status = ESCAPE; // 设转义字符标志
					} else if (allowComments && c == '/') {
						status = COMMENT_START; // 设注释标志
					} else if (isWhiteSpace(c)) {
						if (keepWhitespace) { // 如果空白符也要用,把它加入标识符中
							token.append((char) c);
						}
					} else {
						token.append((char) c);
					}
					break;

				case ESCAPE: // 处理转义字符
					switch (c) {
					case 'n':
						token.append('\n');
						break;

					case 'r':
						token.append('\r');
						break;

					case 't':
						token.append('\t');
						break;

					case 'b':
						token.append('\b');
						break;

					case 'f':
						token.append('\f');
						break;

					default:
						token.append((char) c);
						break;
					}
					status = INITIAL; // 设正常情况标志
					break;

				case COMMENT_START: // 处理注释
					if (c == '/') {
						status = LINE_COMMENT; // 是行式注释
					} else if (c == '*') {
						status = BLOCK_COMMENT; // 是块式注释
					} else {
						status = INITIAL;
						// 如果都不是则把注释起始符和刚读入的字符都加入到标识符中
						token.append('/').append((char) c);
					}
					break;

				case LINE_COMMENT:
					if (c == '\n') {
						status = INITIAL; // 如果当前为行注释状态则要一直读到行尾才恢复正常情况标志
					}
					break;

				case BLOCK_COMMENT:
					if (c == '*') {
						status = COMMENT_END; // 如果当前为块注释状态则要一直读到*号设为块注释结束状态
					}
					break;

				case COMMENT_END:
					if (c == '/') {
						status = INITIAL; // 在块结束状态下读到/则为块结束
					} else {
						status = BLOCK_COMMENT; // 否则块注释还未结束,恢复为块注释状态
					}
					break;

				}
				c = in.read(); // 读入下一字符
			}
			// 如果读到文件尾时,标识符长度大于零,则返回标识符,否则返回NULL值
			return token.length() > 0 ? token.toString() : null;
		} catch (IOException e) {
			throw new IOException("Error reading input L=" + startLine + " C="
					+ startChar);
		}
	}
//... 省略


不过从代码可以看出,它并不支持非Ascii编码格式的文件,还要进行进一步的改造。
我的计划是StringBuffer 用byte[]代替,增加setEncode(String encode)方法,返回字符串时使用 new String(byte[], encode)
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/170335

posted @ 2008-03-12 07:03 iwinyeah 阅读(212) | 评论 (0)编辑 收藏

[导入]兼容性对J2ME程序设计的确是一个主要的问题!


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/170016  发表时间: 2008年03月11日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

对于手机理财JAcount,我在SE K750, SE P990,Philips768, Nokia2630上进行过完整的测试,都没有什么问题.最近,在移动那里一元购机了一台Nokia6070,原以为与Nokia2630一样是S40的机器,应该没什么问题,结果余额表和收支表重复算两次后出现了"应用程序错误",详情是Array Index out of bounds,我估计是内存不足,于是在重新开启程序,打开了第一次收支表后检查了内存,还有300多K,再次打开收支表,又出错了,还未搞清楚是什么原因,真有点失败的感觉,前一段时间在聊天时借了别人的Nokia N73,结果安装时候就死机了,还没机会检查是什么问题,现在先弄好Nokia 6070的问题吧.唉!兼容性!
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/170016

posted @ 2008-03-11 06:36 iwinyeah 阅读(99) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil 设备检测(2)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/169545  发表时间: 2008年03月09日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

唉,有贴代码骗粮票的嫌疑呢,至少大家可以在这里看到各种设备的规格方法了.
    public static boolean isBlackBerry()
    {
        return checkPlatform( "RIM" );
    }

    public static boolean checkPlatform( final String key )
    {
        final String platform = System.getProperty( "microedition.platform" );
        return platform != null && platform.toUpperCase().indexOf(
                key.toUpperCase()
        ) > -1;
    }

    public static boolean checkUserAgent( final String key )
    {
        final String userAgent = Application.getManager().getProperty(
                "user-agent"
        );
        return userAgent != null && userAgent.toUpperCase().indexOf(
                key.toUpperCase()
        ) > -1;
    }

    public static boolean checkPlatform( final String[] keys )
    {
        final int length = keys.length;
        for( int i = 0; i < length; i++ )
        {
            if( checkPlatform( keys[i] ) )
            {
                return true;
            }
        }
        return false;
    }

    public static boolean isNokia()
    {
        return checkPlatform( "Nokia" );
    }

    public static boolean isEmulator()
    {
        return checkPlatform( new String[] { "j2me", "SunMicrosystems_wtk" } );
    }

    public static boolean isSonyEricsson()
    {
        return checkPlatform( "SonyEricsson" );
    }

    public static boolean isSonyEricssonJP7()
    {
        return isSonyEricsson() && checkPlatform( JP7 );
    }

    public static boolean isSymbian()
    {
        return checkUserAgent( "SymbianOS" );
    }

    public static boolean isSeries60()
    {
        return checkUserAgent( "Series60" );
    }

    public static boolean isSeries60_2nd()
    {
        return checkUserAgent( "Series60/2" );
    }

    public static boolean isSeries60_3rd()
    {
        return checkUserAgent( "Series60/3" );
    }

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/169545

posted @ 2008-03-09 18:55 iwinyeah 阅读(55) | 评论 (0)编辑 收藏

[导入]Java 初学者应对以下代码问个为什么


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/169280  发表时间: 2008年03月08日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

public void main(){
	Integer nullInt = null;
	tryChangeInteger(nullInt);
	if(nullInt == null){
		System.out.println("\nThe Object nullInt not be changed.");
	}else{
		System.out.println("\nThe Object nullInt now is " + nullInt);
	}
}	

private void tryChangeInteger(Integer theInt){
	theInt = new Integer(100); 
}

// 控制台应打印出什么呢?(The Object nullInt not be changed.)
//
// 关键要理解好Java的参数传递是传值而不是传引用,因而在tryChangeInteger方法
// 里得到的theInt不是main方法里的nullInt,而是nullInt的副本,nullInt值并没有被改变。

// 再请看以下代码

public void main() {
	char[] initChars = new char[10];
	initChars[0] = 'a';
	tryChangeCharArray(initChars);
	if(initChars[0] == 'a'){
		System.out.println("\nThe Object initChars[0] not be changed.");
	}else{
		System.out.println("\nThe Object initChars[0] now is " + initChars[0]);
	}
}		

private void tryChangeCharArray(char[] theChars){
	if(theChars != null && theChars.length > 0){
		theChars[0] = 'b';
	}
}
	
// 控制台应打印出什么呢?(The Object initChars[0] now is b")
// Why?
// 弄明白了这个,JAVA引用基本就明白了。

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/169280

posted @ 2008-03-08 07:16 iwinyeah 阅读(57) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil 设备检测(1)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/168955  发表时间: 2008年03月07日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

以下代码由bm.core.tools.DeviceInfo.java抽出,详见该文件
    private void testFontListBug()
    {
        if( isNokia() )
        {
            // 就算是Nokia的设备也要进行一下测试来确定是否有这个Bug
            final Font font = Font.getFont(
                    Font.FACE_PROPORTIONAL,
                    Font.STYLE_PLAIN,
                    Font.SIZE_SMALL
            );
            final List list = new List( "", List.IMPLICIT );
            for( int i = 0; i < 3; i++ )
            {
                list.append( "", null );
            }
            for( int i = 0; i < 3; i++ )
            {
                list.setFont( i, font );
            }
            list.deleteAll();
            try
            {
            for( int i = 0; i < 4; i++ )
                {
                    list.append( "", null );
                }
                listFontBug = false;
            }
            catch( Throwable e )
            {
                listFontBug = true;
            }
        }
        else
        {
            // 除Nokia设备外,其它设备都假定它有这个Bug
            // 不知道实际上是不是这样呢?我估计大部分的手机都有这个问题
              // 不然他不会这么做
            listFontBug = true;
        }
    }


那么这个Bug是什么呢?
我在bm.mvc.ListBrowserView中找到如下代码:
    if( !DeviceInfo.getDeviceInfo().hasListFontBug() )
    {
        final int itemCount = list.size();
        for( int i = 0; i < itemCount; i++ )
        {
            list.setFont( i, Util.SMALL_FONT );
        }
    }

也就是说,有这个Bug的设备不能将List的项的字体更改为SMALL_FONT
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/168955

posted @ 2008-03-07 09:46 iwinyeah 阅读(73) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil Nokia s60, 6670,e71,e61问题?


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/168522  发表时间: 2008年03月06日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

   private void doShow()
    {
        // This delays minimze the chance that a Nokia 6670 or Nokia S60 3rd
        // edition device (might apply to other nokias) freez when showing a
        // view. The total delay of 600ms, with this distribution seems to
        // make it stable on E70 and E61. The delay is only applied to Nokia
        // phones at this moment
        if( displayable != null )
        {
            final Display display = Application.getManager().getDisplay();
            delay();
            delay();
            display.setCurrent( displayable );
            if( !DeviceInfo.isNokia() && focusedItem != null )
            {
                delay();
                delay();
                display.setCurrentItem( focusedItem );
            }
            setCurrent( this );
            delay();
            delay();
        }
    }

    private void delay()
    {
        if( delay )
        {
            // Under some strange circumstances the Nokia 6670 crashes whitout this delay
            try
            {
                Thread.sleep( 100 );
            }
            catch( InterruptedException e )
            {
            }
        }
    }



是否的确是这样?天啊,谁可以使用以上环境的设备给我测试一下我的手机理财JAccount呢?
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/168522

posted @ 2008-03-06 07:54 iwinyeah 阅读(111) | 评论 (0)编辑 收藏

[导入]强烈建议安装Jode Decompiler


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/168521  发表时间: 2008年03月06日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

如果你用Eclipse开发java应用的话,我强烈建议你安装它,这样,你随时可解开jar文件浏其他人特别是SUN公司的源代码了(SUN的JAR没有经过混淆),对于学习java是十分有益而高效的.
Eclipse/软件更新/查找与安装/新建远程站点/地址为:http://www.technoetic.com/eclipse/update

安装完成后,要使用时,在包资源管理器上列出你要查看的class,双击该文件,会出现错误提示,不理它,再双击一次就可以在编辑器上出现源代码了!超方便!
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/168521

posted @ 2008-03-06 06:36 iwinyeah 阅读(798) | 评论 (0)编辑 收藏

[导入]OpenBaseMovil 的高速对象缓存机制


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/168482  发表时间: 2008年03月05日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

一个简单的高速对象缓存
public class SimpleCache
{
    private static long wideHits;
    private static long wideMisses;

    private Hashtable   cache;
    private Vector      stamps;
    private int         maxSize;
    private long        hits;
    private long        misses;

    // ...部分省略

    // 构建函数,根据SIZE构建Cache和命中表
    public SimpleCache( final int size )
    {
        this.maxSize = size;
        cache = new Hashtable( size );
        stamps = new Vector( size );
    }

    // ...部分省略

    public void add( final Object key, final Object object )
    {
        // 为什么不直接使用cache而要使用另一个引用?
        final Hashtable cache = this.cache;

        if( !cache.containsKey( key ) )
        {
            if( cache.size() == maxSize )
            {
                discard(); // 如果Cache超过容量,按策略丢弃过时的对象
            }
            // 在Cache中加入这个对象
            cache.put( key, object );
            // 相应也插入命中表第一位
            stamps.insertElementAt( key, 0 );
        }
        else
        {
            // 更新Cache
            cache.put( key, object );
            // 也算命中一次
            touch( key );
        }
    }

    // ...部分省略

    public synchronized Object get( final Object key )
    {
        final Object o = cache.get( key );
        if( o != null )
        {
            hits++;
            wideHits++;
            // 算命中一次
            touch( key );
        }
        else
        {
            misses++;
            wideMisses++;
        }
        return o;
    }

    // ...部分省略

    // 总是丢弃最后一个对象,
    private void discard()
    {
        final Object key = stamps.lastElement();
        stamps.removeElement( key );
        cache.remove( key );
    }

   // 每次从Cache取用某key对象,都将它插到第一位
    // 这样不常用的对象将很快会被推至最后一位
    private void touch( final Object key )
    {
        stamps.removeElement( key );
        stamps.insertElementAt( key, 0 );
    }
}

本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/168482

posted @ 2008-03-05 22:29 iwinyeah 阅读(64) | 评论 (0)编辑 收藏

[导入]WTK模拟器之RMS文件(4 完结篇)


网站: JavaEye  作者: iwinyeah  链接:http://iwinyeah.javaeye.com/blog/167866  发表时间: 2008年03月04日

声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

感谢Cavaj!在Eclipse在包资源管理器上查到RecordStore.class在midpapi10.jar中
将C:\WTK22\lib\midpapi10.jar解开,然后用Cavaj!反编译RecordStore.class,得到了两个类,果然有些料到,不仅有记录链表,还有自由链表,自由空间重用与分裂...,用代码说话(个人做了一些修改和注释)!

------------------------
写在最后:原来研究它的目的是在利用J2me可选包FileConnection方式来实现手机理财JAccounthttp://iwinyeah.javaeye.com/admin/categories/27410,但经分析后,FileConnection没有实现skip()方法,换言之,不能对文件进行自由读写,因而该计划也落了空.

在此也感谢无花http://wuhua.javaeye.com/的提醒,的确,手机实现的FileConnection的安全检查太多了,严重影响用户体验,不太合适用于这种方式的应用.

新计划是手机理财JAccount上增加备份与恢复功能(read和append方式是FileConnection所支持的)由于备份和恢复无须经常地使用,用户也可接受.
本文的讨论也很精彩,浏览讨论>>


JavaEye推荐




文章来源:http://iwinyeah.javaeye.com/blog/167866

posted @ 2008-03-04 21:41 iwinyeah 阅读(343) | 评论 (0)编辑 收藏