📄 readingboard.java
字号:
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
public class ReadingBoard extends Canvas implements CommandListener{
private TxtReader bookReader = null; //主程序reference
/***********************文本显示页面****************************/
private static Command autoline = new Command("自动翻转",Command.SCREEN,1);
private static Command autolineStop = new Command("停止翻转", Command.SCREEN, 1);
private static Command turnto = new Command("跳转至",Command.SCREEN,2);
private static Command search = new Command("搜索", Command.SCREEN, 3);
private static Command newmark = new Command("新建书签",Command.SCREEN,4);
private static Command entermark = new Command("书签列表",Command.SCREEN,5);
private static Command newlabel = new Command("新建标注",Command.SCREEN,6);
private static Command enterlabel = new Command("标注列表",Command.SCREEN,7);
private static Command instrument = new Command("使用说明",Command.SCREEN,8);
private static Command back = new Command("返回",Command.BACK,1);
private static Command goSearch = new Command("开始搜索", Command.SCREEN, 1);
private static Command fullScreen = new Command("全屏",Command.SCREEN,1);
/***********************自动翻转页面****************************/
private static Command autostart = new Command("开始翻转", Command.OK, 1);
private static Command next = new Command("下一步", Command.OK, 1);
private static Alert error = new Alert("错误输入","",null,AlertType.ERROR);
private static TextBox tb = null;
private static boolean isEditMode = false;
private boolean isRunning = false;
private Timer timer = new Timer();
private final String[] lineorpage = {"自动翻行","自动翻页"};
private ChoiceGroup autolineorpage = null;
private Form frm = null;
private int selectIndex = 0;
/***********************标注页面****************************/
private Command ok_label = new Command("完成标注", Command.SCREEN, 1);
private NoteRecord[] nr_array = null;
/***********************跳转页面****************************/
private static Command turnstart = new Command("跳转", Command.OK, 1);
private static TextBox turnbox = null;
/***********************说明页面****************************/
private static TextBox instrumentbox = null;
private BookMarkList bml = null; //书签列表
private NoteRecordList nrl = null; //标注列表
private int lines = 1; //总行数
private int[] linecount; //每行字数
private int lineUp = 0; //行页定位器
private String txtPath = null; //文件路径
private String txtName = null; //文件标题
private int colorOfBackground = 0x00FFFFFF; //背景颜色
private int colorOfChar = 0x00000000; //字体颜色
private int sizeOfChar = Font.SIZE_MEDIUM; //字体大小
private int styleOfChar = Font.STYLE_PLAIN; //字体形状
private int clipwidth; //屏宽
private int clipheight; //屏高
private Font font = Font.getDefaultFont();
private int charheight = font.getHeight(); //字高
private int charwidth = font.stringWidth("我"); //字宽
private int pagelines = 0; //页面行数
private String txt; //文本内容
private String encode = "GB2312"; //字符编码
private TextBox strBox = new TextBox("输入搜索内容", "", 256, TextField.ANY);//字串输入框
private boolean isFullMode = false;
//构造方法
public ReadingBoard(TxtReader tr){
bookReader = tr;
//获取手机屏幕尺寸参数
clipwidth = this.getWidth();
clipheight = this.getHeight();
pagelines = clipheight / charheight;
this.addCommand(fullScreen);
this.addCommand(autoline);
this.addCommand(turnto);
this.addCommand(newmark);
this.addCommand(entermark);
this.addCommand(newlabel);
this.addCommand(enterlabel);
this.addCommand(instrument);
this.addCommand(back);
this.addCommand(search);
this.setCommandListener(this);
strBox.addCommand(goSearch);
strBox.addCommand(back);
strBox.setCommandListener(this);
}
public boolean selectFile(String path, boolean isGoByMark){ //打开路径为path的文本文件
this.txtPath = path;
this.txtName = path.substring(path.lastIndexOf('/')+1,path.lastIndexOf('.'));
if(txtName.length() > clipwidth / charwidth / 2){
this.txtName = txtName.substring(0, clipwidth / charwidth / 2 - 4) + ".."
+ txtName.substring(txtName.length()-2,txtName.length());
} //判断标题长度(标题显示问题)
this.setTitle(txtName);
bml = new BookMarkList(txtName,bookReader);
nrl = new NoteRecordList(bookReader, txtName);
charheight = font.getHeight(); //字高
charwidth = font.stringWidth("我");
nr_array = nrl.getAll(); //标注列表
lines = 1;
lineUp = 0;
try{
FileConnection fc = (FileConnection)Connector.open(txtPath);
InputStream open = fc.openInputStream();
if (open.markSupported())
open.mark(Integer.MAX_VALUE);
else
throw new IOException();
long bytesum = open.skip(Integer.MAX_VALUE);
linecount = new int[(int)(bytesum/10)]; //估计每行字符数
open.reset();
byte[] main = new byte[(int)bytesum];
open.read(main,0,(int)bytesum);
txt = new String(main, encode); //根据读取的字节流编码成字符串
open.close();
fc.close();
}catch(SecurityException se){
return false;
}catch(IOException e){
System.out.println(e.getMessage());
return false;
}
//遍历字符串得到每行字符数
int k = clipwidth / charwidth; //预设每行的字符数为默认字宽和接近屏宽
for(int j = 0;j< txt.length();j ++){
char ch = txt.charAt(j);
linecount[lines] ++;
if(ch == '\n'){
lines ++;
}
if(txt.charAt(j) == ' ' && linecount[lines] == 1){
k += 2; //如果行首有空格,该行多读2个字符
}else if(txt.charAt(j) != ' ' && linecount[lines] == 1){
k = clipwidth / charwidth; //否则恢复预设
}
if(linecount[lines] >= k && ch != '\n'){
lines ++;
}
}
if (isGoByMark){
this.goByMark(bml.whenEnter());
}
return true;
}
public void goByMark(int line){ //跳转到书签位置
this.lineUp = line;
repaint();
}
private void nextpage(){ //显示下一页
lineUp += pagelines;
if(lineUp + pagelines > lines) lineUp = lines - pagelines;
repaint();
}
private void nextline(){ //显示下一行
lineUp ++;
if(lineUp + pagelines > lines) lineUp = lines - pagelines;
repaint();
}
private void frontpage(){ //显示上一页
lineUp -= pagelines;
if(lineUp <= 0) lineUp = 0;
repaint();
}
private void frontline(){ //显示上一行
lineUp --;
if(lineUp <= 0) lineUp = 0;
repaint();
}
private void turnTo(int percentage){ //根据百分比跳转页面位置
lineUp = percentage * (lines - pagelines) / 100;
repaint();
}
protected void paint(Graphics g) {
g.setColor(colorOfBackground); // 设置背景颜色
g.fillRect(0, 0, g.getClipWidth(), g.getClipHeight()); // 背景填充
g.setColor(colorOfChar); // 设置字体颜色
g.setFont(font); // 字体属性
int lineleft = 0; // 字符串截取标记
int k = clipwidth / charwidth; // 预设每行的字符数
pagelines = g.getClipHeight() / charheight; // 重新设定该页行数,为全屏准备
String output; // 定义较小字宽的字符处理器
for (int j = 1; j < lineUp; j++) {
lineleft += linecount[j];
} // 画布前将字符串截取标记预设
for (int i = 0; i < pagelines; i++) {
lineleft += linecount[i + lineUp]; // 截取标记划定值
int lineright = lineleft + linecount[i + 1 + lineUp];
String text = txt.substring(lineleft, lineright); // 字符截取
if (Font.getDefaultFont().stringWidth(text) == k * charwidth) {
g.drawString(text, 0, charheight * i, Graphics.TOP
| Graphics.LEFT);// 对满屏宽的直接画出
} else {
double wids = 0; // 空格处理器
for (int j = 0; j < text.length(); j++) {
if (text.charAt(j) == ' ')
wids += 0.5; // 空格视为半个字符
else {
output = text.substring(j, j + 1); // 逐个截取画出
g.drawString(output, (int) (charwidth * wids),
charheight * i, Graphics.TOP | Graphics.LEFT);
wids++;
}
}
}
}
if (isThereNote()) {
this.setTitle(txtName + " " + (lineUp / pagelines + 1) + "/"
+ (lines / pagelines) + " #");
// 设置标题中的页码及标著符
} else {
this.setTitle(txtName + " " + (lineUp / pagelines + 1) + "/"
+ (lines / pagelines));
}
}
protected void keyPressed(int keyCode) { // 响应手机按键
switch(getGameAction(keyCode)){
case Canvas.DOWN: // 对应翻行页功能键
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
nextline();
break;
case Canvas.UP:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
frontline();
break;
case Canvas.LEFT:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
frontpage();
break;
case Canvas.RIGHT:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
nextpage();
break;
case Canvas.GAME_A: //NUM1新建书签
addMark();
break;
case Canvas.GAME_B: //NUM3新建标注
addNote();
break;
case Canvas.GAME_C: //NUM7进入书签列表
Display.getDisplay(bookReader).setCurrent(bml);
break;
case Canvas.GAME_D: //NUM9进入标注列表
nrl.showList();
break;
case 0:
switch (keyCode){ //对应翻行页数字键
case Canvas.KEY_NUM2:
if (isRunning) //翻行页时阻止自动翻页
keyPressed(Canvas.KEY_NUM0);
frontline();
break;
case Canvas.KEY_NUM8:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
nextline();
break;
case Canvas.KEY_NUM4:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
frontpage();
break;
case Canvas.KEY_NUM6:
if (isRunning)
keyPressed(Canvas.KEY_NUM0);
nextpage();
break;
case Canvas.KEY_NUM0: //按键0为自动翻页快捷键
if (!isRunning){ //自动翻页设定
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -