📄 uibase.java
字号:
package com.podome.ui;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import com.podome.log.Logger;
import com.podome.style.IStyle;
import com.podome.style.Style;
import com.podome.tool.Config;
import com.podome.tool.EffectHelper;
import com.podome.ui.Effect;
public abstract class UIBase implements Paint,Effect,IStyle {
//public static int LAYOUT_LEFT = 1;
UIContainer owner; //控件所在的容父容器。
String string = null; //显示的内容
int strLength = 0; //字符个数
int strWidth = 0; //字符总长度和
boolean enable = true; //是否可以获取焦点
boolean visble = false; //是否显示在屏幕上
boolean marked = false; //是否被标记
boolean editAble = false; //可以接受输入
boolean hasFocus = false; //是否获得了焦点
boolean isNewLine = false; //是否需要重新起一行
int offset = 0; //内容偏移量(跑马灯类型的文字用到)
int[][] bonds = new int[2][2]; //开始点坐标,和最后一个点坐标
/************************自动换行的文本该参数才有用*************************/
int lineHeight = 0; //行的绝对高度,包括空白边和框高
int lineNum = 1; // 字符占的总行数(换行后)
int[] lineCharNum; // 每一行的字符个数(是为了只计算一次)
boolean autoLineWrap = false; // 自动换行
/***************************************************/
int layout = 0; //布局方式
int firstStopCnt = Config.FIRST_STOPCOUNT;
int lastStopCnt = Config.LAST_STOPCOUNT;
boolean overflow = false; // 内容是否溢出
int overflowWidth = 0; //溢出长度
Style style; //样式
/**
* 构造函数
*/
public UIBase(){
super();
}
/**
* 构造函数
* @param s
*/
public UIBase(String s){
this();
this.setString(s);
}
/**
* 设置是否新行标志
* @param newline
*/
public void setNewLine(boolean newline){
this.isNewLine = newline;
}
/**
* 获取换行标志
* @return
*/
public boolean isNewLine(){
return this.isNewLine;
}
/**
* 设置是否自动换行,默认不换行。
* @param autoWrap
*/
public void setAutoWrap(boolean autoWrap){
this.autoLineWrap = autoWrap;
}
/**
* 获取自动换行标志
* @return
*/
public boolean isAutoWrap(){
return this.autoLineWrap;
}
/**
* 设置控件的文字内容,改变文字内容默认不改变控件的布局,也就是
* 控件的可见区域不会改变。
*/
public void setString(String str){
if(string == str ) return;
//计算内容的宽度和字符个数
if(str == null || str.equals("")){
strLength = 0;
}
else{
strLength = str.length();
}
this.string = str;
//需要重画缓冲区
//offImageRepaint = true;
}
/**
* 获取控件的内容
* @return
*/
public String getString(){
return this.string;
}
public void setEditAble(boolean able){
this.editAble = able;
}
public boolean getEidtAble(){
return this.editAble;
}
public void setEnable(boolean enable){
this.enable = enable;
}
public boolean getEnable(){
return this.enable;
}
public void setVisble(boolean visble){
this.visble = visble;
}
public boolean getVisble(){
return this.visble;
}
public void setMarked(boolean mark){
this.marked = mark;
}
public boolean getMarked(){
return this.marked;
}
public void setFocus(boolean focus){
if( !this.enable ) return;
if( this.hasFocus != focus ){
this.hasFocus = focus;
if( this.isInViewer() ){
if( focus && this.overflow && !this.autoLineWrap ){
EffectHelper.addToRepaint(this);
}
else if( !focus && this.overflow && !this.autoLineWrap ){
this.offset = 0;
EffectHelper.removeRepaint(this);
}
Stage.getInstance().notifyRepaint(this);
}
}
}
public boolean hasFocus(){
if( !this.enable )
return false;
return this.hasFocus;
}
/**
* 设置控件的内容自适应容器,使用该方法前提是
* 属性 autoLineWrap=true
* @param x 相对容器的X轴坐标
* @param y 相对容器的Y轴坐标
* @param maxWidth 容器的最大可用空间
*/
protected void setAutoArea(int x, int y,int maxWidth){
if( this.owner == null ) return;
Style selfStyle = this.getStyle();
Style pareStyle = owner.getStyle();
this.setX(x);
this.setY(y);
//计算字符长度
this.strWidth = selfStyle.dfont.stringWidth(string);
int factLineHeight = selfStyle.dfont.getHeight();
//+ selfStyle.paddingTop
//+ selfStyle.paddingBottom;
//设置行高
if(this.lineHeight < factLineHeight) {
this.lineHeight = factLineHeight;
}
int usedWidth = maxWidth + pareStyle.paddingLeft - x;
//实际宽度
int factWidth = this.strWidth + selfStyle.paddingLeft + selfStyle.paddingRight;
//
if( factWidth <= usedWidth ){
bonds[1][0] = bonds[0][0] + factWidth;
bonds[1][1] = bonds[0][1] + this.lineHeight + selfStyle.paddingTop + selfStyle.paddingBottom;
lineCharNum = new int[1];
lineCharNum[0] = strLength;
}
else if( !this.autoLineWrap ){
bonds[1][0] = bonds[0][0] + usedWidth;
bonds[1][1] = bonds[0][1] + this.lineHeight + selfStyle.paddingTop + selfStyle.paddingBottom;
lineCharNum = new int[1];
lineCharNum[0] = strLength;
this.overflow = true;
this.overflowWidth = this.strWidth + selfStyle.paddingLeft + selfStyle.paddingRight- maxWidth;
}
else{
this.lineNum += (this.strWidth-usedWidth) /( maxWidth - selfStyle.wCharCH -5 );
int lastW = (this.strWidth-usedWidth) % maxWidth;
if (lastW > 0) {
this.lineNum++;
}
this.lineCharNum = new int[this.lineNum];
//计算每行可以容纳多少个字符,把计算结果保存到int[] lineCharNum;
int startIndex = 0;
int lastIndex = 0;
factWidth = maxWidth + pareStyle.paddingLeft - x - selfStyle.paddingLeft -selfStyle.paddingRight;
lastIndex = this.serach(startIndex, factWidth, selfStyle);
if(lastIndex != -1){
this.lineCharNum[0] = lastIndex - startIndex + 1;
startIndex = lastIndex + 1;
}
factWidth = maxWidth - selfStyle.paddingLeft -selfStyle.paddingRight;
int factLine = 1;
for (; factLine < this.lineNum; factLine++) {
lastIndex = this.serach(startIndex, factWidth, selfStyle);
if (lastIndex != -1) {
this.lineCharNum[factLine] = lastIndex - startIndex + 1;
startIndex = lastIndex + 1;
}
else{
break;
}
}
this.lineNum = factLine;
//最后一行的字符个数,修正行数和计算最后一行的宽度
factWidth = selfStyle.dfont.stringWidth(this.string.substring( startIndex-lineCharNum[lineNum-1]));
factWidth = factWidth + selfStyle.paddingLeft + selfStyle.paddingRight + 5;
bonds[1][0] = factWidth;
if(this.lineNum == 1 ){
bonds[1][0] = bonds[0][0] + factWidth;
}
bonds[1][1] = bonds[0][1] +
lineHeight* this.lineNum +
selfStyle.paddingBottom +
selfStyle.paddingTop +
selfStyle.marginTop;
}
}
/**
* @param startIndex 开始下标
* @param width 计算长度
* @param wChar 每个字符的计算宽度
* @return
*/
private int serach(int startIndex, int width ,Style style) {
if( this.string == null ||
this.string.equals("") ||
width < style.wCharCH ) {
return -1;
}
if(startIndex >= this.strLength - 1) {
return -1;
}
// 估算字符个数,并以这个数字作为基准前后移动计算
int charCnt = width / style.wCharCH;
int endIndex = startIndex + charCnt;
// 如果长度超过源字符长度,则以最后一个可计算长度为结束下标。
if( endIndex > this.strLength - 1 ) {
endIndex = this.strLength - 1;
charCnt = this.strLength - startIndex;
}
if (endIndex < startIndex) {
return -1;
}
// 默认情况估算字符个数总长度
int iBase = style.dfont.substringWidth(this.string, startIndex, charCnt);
if (iBase > width) {
//Logger.info("Here----------> 1");
while (iBase > width) {
//iBase -= style.dfont.charWidth(this.string.charAt(endIndex));
charCnt--;
endIndex--;
iBase = style.dfont.substringWidth(this.string, startIndex, charCnt);
if (iBase <= width) {
endIndex--;
break;
}
else if (endIndex <= startIndex){
break;
}
}
}
else if( iBase < width ){
//Logger.info("Here----------> 2");
while (iBase < width) {
if ( endIndex == this.strLength - 1 )
break;
endIndex++;
charCnt++;
//Logger.info("Length:" + iBase + ",CharCount:" + charCnt );
iBase = style.dfont.substringWidth(this.string, startIndex, charCnt);
if( iBase >= width){
endIndex -=2;
break;
}
}
}
//Logger.info("S=" + startIndex + ",E=" + endIndex + ",W=" + width + ",FW=" + iBase);
//return endIndex;
return splitToWord(this.string, endIndex );
}
/**
* 对英文单词进行分词处理
* @param s
* @param idx
* @return
*/
private int splitToWord(String s,int idx){
int index = idx;
if( isLetter( s.charAt(idx) ) ){
for( int i=1; i< 15; i++ ){
char ch = s.charAt(idx - i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -