📄 txtreadercanvas.java
字号:
package com.ismyway.anyview;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.util.Vector;
//import java.util.Stack;
import java.util.Calendar;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.*;
/**
* <p>Title: AnyView</p>
*
* <p>Description: E680(I) Reader</p>
*
* <p>Copyright: Copyright (c) 2005</p>
*
* <p>Company: www.ismyway.com</p>
*
* @author ZhangJian
* @version 1.0
*/
public class TXTReaderCanvas extends Canvas {
private int ANCHOR = Graphics.LEFT | Graphics.TOP;
private int srcW, srcH;
private String filename;
private boolean rotate = false;
private FileSystemReader fsa;
private Image background = null;
private int txtLenght = 0; //当前文件文件的长度
int lineOfPage = 0; //当前视图情况下可以显示的行数
int viewWidth, viewHeight; //可视区域的高与宽
Image bufferImage; //缓冲区图像
int currentLine = 0; //当前起始行
private int currentOffset = 0; //当前视图内首行的偏移
//private int bufferStartOffset = 0; //当前缓冲区的开始在文件中的位置
Vector mylines = new Vector(); //保存每行的起始偏移
private int BufferLenght = 65536; //64K的缓冲长度
private byte[] bufferTxt; //文件缓冲
private byte[] bufferbuffer = new byte[0]; //保存缓冲区尾部数据的缓冲
private boolean eof = false; //是否是文档的最后一页
private boolean bof = true; //是否是文档的最前一页
//private Vector history = new Vector(); //当前阅读文档的返回点
//private int historyIndex = -1; //返回点的索引
private BookMark[] allBookMarks = null; //所有的书签
private Vector currentMarks = new Vector(); //当前书签中的所有书签项
private int currentBookMarkIndex = -1; //当前的书签
private int pressedx, pressedy, releasex, releasey;
private Vector finds = new Vector();
private Menu menu = null;
private boolean showMenu = false;
private AbstractWindow currentWindow = null;
private Selector selector = null;
private String[] menuitems = {"阅读信息", "选择书签", "添加书签", "删除书签", "自由跳转",
"分享片断", "搜 索", "返回菜单", "退出程序"};
Message message = new Message(); //提示消息
Image serachImage = null;
private boolean needsearch = false;
private String searchStr = "";
private int searchStrLenght = 0;
/*public final static int GB2312 = 0;
public final static int UTF8 = 1;
public final static int UNICODE = 2;
//private int txtCharSet = GB2312;*/
protected TXTReaderCanvas(String filename) {
this.filename = filename;
this.setFullScreenMode(true);
srcW = getWidth();
srcH = getHeight();
AnyView.cf.setColor(ColorSelector.colors[AnyView.frontColor]);
rotate = AnyView.readType == 1;
prepareBackGround();
rotate(rotate);
fsa = new FileSystemReader(filename);
/*byte[] b = fsa.read(4);
if (null != b || b.length > 2) {
if (b[0] == -17 && b[1] == -69 && b[2] == -65) {
txtCharSet = UTF8;
} else if (b[0] == -1 && b[1] == -2 || b[0] == 72 && b[1] == 66) {
txtCharSet = UNICODE;
}
}
fsa.close();
fsa.open();*/
txtLenght = (int) fsa.fileSize();
openRec(); //读取老的记录
bof = currentOffset == 0;
fsa.skip(currentOffset);
readNextBuffer();
analysisBuffer();
prepareNextImage();
}
private void prepareBackGround() {
FileSystemReader fsr = new FileSystemReader(AnyView.Root +
"anyview/bg.png");
if (fsr.exists()) {
int len = (int) fsr.fileSize();
byte[] b = fsr.read(len);
/*
//创建半透明背景,在真机上失败
Image temp = Image.createImage(b, 0, b.length);
b = null;
if (temp != null) {
int w = temp.getWidth();
int h = temp.getHeight();
int[] v = new int[w * h];
temp.getRGB(v, 0, w, 0, 0, w, h);
for (int i = 0; i < v.length; i++) {
v[i] = 0x3F000000 | (v[i] >>> 8);
}
background = Image.createRGBImage(v, w, h, false);
v = null;
temp = null;
}*/
try {
background = Image.createImage(b, 0, b.length);
} catch (Exception ex) {
background = null;
}
/*b = null;
int w = background.getWidth();
int h = background.getHeight();
int[] v = new int[w * h];
int color = 0xAAFFFFFF; // | ColorSelector.colors[AnyView.backColor];
for (int i = 0; i < v.length; i++) {
v[i] = color;
}
Image temp = Image.createRGBImage(v, w, h, true);
Image mutable = Image.createImage(w, h);
Graphics g = mutable.getGraphics();
g.drawImage(background, 0, 0, ANCHOR);
g.drawImage(temp, 0, 0, ANCHOR);
v = null;
temp = null;
background = mutable;*/
}
fsr.close();
System.gc();
}
void readNextBuffer() {
needsearch = false;
int start = 0;
if (null != bufferbuffer) { //查看缓冲区尾部数据的缓冲中是否有数据
start = bufferbuffer.length;
}
byte[] b = fsa.read(BufferLenght);
if (b.length != BufferLenght) { //已读到了文章的尾部
eof = true;
bufferTxt = new byte[b.length + start];
//将缓冲区尾部数据的缓冲中的数据COPY至缓冲区中
System.arraycopy(bufferbuffer, 0, bufferTxt, 0, start);
System.arraycopy(b, 0, bufferTxt, start, b.length);
bufferbuffer = new byte[0]; //缓冲的缓冲为空
b = null;
System.gc();
return;
}
//删除缓冲区中最后一个回车以后的字符
eof = false;
int end = b.length;
if (end > 0) {
while (true) {
int v = b[end - 1] & 0xff;
if (v == 10) { //\n 换行
break;
}
end--;
}
}
if (0 == end) { //遇上了严重的错误,居然16K数据中没有一个回车符,不合情理
System.exit( -1);
}
bufferTxt = new byte[end + start];
int rest = BufferLenght - end;
System.arraycopy(bufferbuffer, 0, bufferTxt, 0, start);
System.arraycopy(b, 0, bufferTxt, start, end);
bufferbuffer = new byte[rest];
System.arraycopy(b, end, bufferbuffer, 0, rest);
b = null;
System.gc();
//是否需要进行编码转换
/*if (txtCharSet == UTF8) {
//ByteArrayInputStream bais = new ByteArrayInputStream(bufferTxt);
//DataInputStream dis = new DataInputStream(bais);
StringBuffer sb = new StringBuffer();
try {
sb.append(new String(bufferTxt, "UTF-8"));
bufferTxt
} catch (UnsupportedEncodingException ex) {
}
} else if (txtCharSet == UNICODE) {
}*/
}
void readPreviousBuffer() {
/*int start = currentOffset - 1 - BufferLenght;
start = start < 0 ? 0 : start;
int len = currentOffset - 1 - start; //计算缓冲需要的实际长度
bufferbuffer = new byte[0]; //不需要保存缓冲区尾部数据的缓冲
fsa.locate(start);
byte[] b = fsa.read(len);
//寻找第一个回车以后的文字
start = 0;
while (start < len) {
int v = b[start++] & 0xff;
if (v == 10) { //\n 换行
break;
}
}
if (start >= len - 1) { //居然数据中没有一个回车符,那是不是意味着到了头?
start = 0;
}
bufferTxt = new byte[len - start];
System.arraycopy(b, start, bufferTxt, 0, len);
b = null;
System.gc();*/
}
synchronized void analysisBuffer() {
if (null == bufferTxt) {
return;
}
mylines.removeAllElements();
int c = 0;
int w = 0;
int l = 0;
//Vector test = new Vector();
//mylines.addElement(new Integer(currentOffset));
while (c < bufferTxt.length - 1) {
int b = bufferTxt[c] & 0xff;
if (b == 10) { //\r 换行
c++;
l++;
//mylines.addElement(new Integer(c + currentOffset));
mylines.addElement(new TxtLine(currentOffset + c - l, l));
w = 0;
l = 0;
continue;
}
//字符处理
if (b > 0x7f) { //汉字
if (w + AnyView.cf.GBWidth > viewWidth) { //当前行无法显示完整
//mylines.addElement(new Integer(c + currentOffset));
mylines.addElement(new TxtLine(currentOffset + c - l, l));
w = 0;
l = 0;
continue;
} else {
c += 2;
l += 2;
w += AnyView.cf.GBWidth;
}
} else { //英文
if (w + AnyView.cf.AsciiWidth > viewWidth) { //当前行无法显示完整
//mylines.addElement(new Integer(c + currentOffset));
mylines.addElement(new TxtLine(currentOffset + c - l, l));
w = 0;
l = 0;
continue;
} else {
c++;
l++;
w += AnyView.cf.AsciiWidth;
}
}
}
mylines.addElement(new TxtLine(currentOffset + c - l, l));
/*for (int i = 0; i < mylines.size(); i++) {
TxtLine tl = (TxtLine) mylines.elementAt(i);
System.out.println(tl.offset + ", " + tl.lenght);
}
System.out.println(bufferTxt.length);*/
//System.out.println(mylines.size());
currentLine = 0;
//定位到正确的行
if (currentOffset != 0) {
int i = 0;
while (i < mylines.size()) {
if (((TxtLine) mylines.elementAt(i)).offset >=
currentOffset) {
break;
}
i++;
}
i--;
currentLine = i < 0 ? 0 : i;
}
}
void prepareNextImage() {
if (currentLine == mylines.size()) {
currentOffset = ((TxtLine) mylines.elementAt(0)).offset +
bufferTxt.length;
} else {
currentOffset = ((TxtLine) mylines.elementAt(currentLine)).
offset;
}
bof = ((TxtLine) mylines.elementAt(0)).offset == 0;
//判断当前缓冲区的内容是否够显示
if (currentLine + lineOfPage >= mylines.size() && !eof) {
int offset = currentOffset -
((TxtLine) mylines.elementAt(0)).offset;
int rest = bufferTxt.length - offset;
byte[] b = new byte[rest + bufferbuffer.length];
System.arraycopy(bufferTxt, offset, b, 0, rest);
System.arraycopy(bufferbuffer, 0, b, rest, bufferbuffer.length);
bufferbuffer = new byte[b.length];
System.arraycopy(b, 0, bufferbuffer, 0, b.length);
b = null;
System.gc();
readNextBuffer();
analysisBuffer();
bof = false;
}
//创建缓冲图像
bufferImage = null;
bufferImage = Image.createImage(viewWidth, viewHeight);
Graphics g = bufferImage.getGraphics();
g.setColor(ColorSelector.colors[AnyView.backColor]);
g.fillRect(0, 0, viewWidth, viewHeight);
if (background != null) {
if (rotate) {
g.drawRegion(background, 0, 0, background.getWidth(),
background.getHeight()
, Sprite.TRANS_ROT90, 0, 0,
ANCHOR);
} else {
g.drawImage(background, 0, 0, ANCHOR);
}
}
int line = 0;
int yOff = 0;
int temp = currentLine;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -