日期:2014-05-20  浏览次数:20681 次

j2me 低级UI控件之文本域

这阵子忙项目,写了个控件,有点像文本域,显示文章用的,带滚动条,有拖拽事件,不过还是有个小问题不咋完美。

?

我承认我的代码不适合阅读,因为注释比较少,并且这个控件的开发难度有点大,主要是拖拽的地方有点复杂,最重要的是,代码还经过一定的优化,合并了许多变量,不过有兴趣的人也可以挑战一下~?

?

设计思路很简单,滚动条的走动依附文本的走动,根据倍数算出各个变量。

?

具体的实现我自己都不愿意回忆了。

?

该代码发布之意在于供人使用,不侧重于供人学习阅读。

?

package com.ctai.items.textarea;

import java.util.Vector;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

import com.ctai.utils.ColorSet;
import com.ctai.utils.DefaultProperties;

public class Textarea
{
	/** 文字颜色 */
	private int i_c_strColor;
	
	/** x, y, 宽, 高*/
	public int x, y, width, hight;

	/** 文字整体高度 */
	private int i_allStrHight;

	/** 整体高度 */
	private int i_strHight;

	private Vector v;

	/** 倍数 */
	private int Multiple;

	/** 滚动条高度 */
	private int scrollHight;

	/** 滚动条的X和Y坐标 */
	private int scrollX, scrollY;

	/** ↑↓按钮方块固定Y */
	private int boxY;

	/** ↑↓按钮方块的宽高 */
	private int boxWH = 16;

	/** 方向键滚屏像素值 */
	private int rollValue;

	/** 方向键滚屏侧滑块移动的偏差像素值 */
	private int rollMoveScrollValue;

	/** 临时变量 */
	private int temp, temp2, temp3, temp4, temp5, temp6, temp7, temp8;

	/** 文字是否超过一篇 */
	private boolean b_isHaveMore = true;

	private int i_dragged[] = new int[2];
	
	/**
	 * 文本域
	 * @param st_strOut 文本域内文字
	 * @param font 当前g的字体
	 * @param i_c_strColor 文字颜色
	 * @param x
	 * @param y
	 * @param width 宽
	 * @param hight 高
	 * @param rollValue 方向键滚屏像素值
	 * */
	public Textarea(String st_strOut, Font font, int i_c_strColor, int x, int y, int width, int hight, int rollValue)
	{
		this.i_c_strColor = i_c_strColor;
		this.x = x;
		this.scrollX = x + width; // 滑块X的坐标初始化
		this.y = y;
		this.temp7 = y;

		this.boxY = y;
		this.scrollY = y + boxWH; // 滑块Y的坐标初始化
		this.width = width;
		this.hight = hight;
		this.rollValue = rollValue;
		v = getSubsection(st_strOut, font, width, "\r\n"); // 赋值vector
		init();
		temp8 = 320 - (boxY + boxWH * 2 + scrollHight + 30);
	}

	public void init()
	{
		Multiple = (temp6 + ((260 / i_strHight) - 1)) / (260 / i_strHight); //倍数 
		if (Multiple == 1)
		{
			b_isHaveMore = false;
		}
		else
		{
			scrollHight = (hight - boxWH * 2) * 260 / (temp6 * i_strHight);
		}
		temp = hight - boxWH;
		temp2 = (boxWH >> 2);
		temp3 = scrollX + (boxWH >> 1);
		temp4 = temp2 * 3;
		temp5 = boxWH * 2;
	}

	public void paint(Graphics g)
	{
		g.setColor(i_c_strColor);
		if (v != null && v.size() > 0)
		{
			for (int i = 0; i < v.size(); i++)
			{
				g.drawString(v.elementAt(i).toString(), x, i * i_strHight + y, 0);
			}
		}

		// 画整个滚动条
		g.setColor(ColorSet.scrollBackColor);
		g.fillRect(scrollX - 1, boxY - 1, boxWH + 2, hight + 2);

		// 画上、下小箭头块边框
		g.setColor(ColorSet.scrollBorderColor);
		g.fillRect(scrollX - 1, boxY - 1, boxWH + 2, boxWH + 2);
		g.fillRect(scrollX - 1, boxY + temp - 1, boxWH + 2, boxWH + 2);

		// 画上、下箭头小块
		g.setColor(ColorSet.scrollFontColor);
		g.fillRect(scrollX, boxY, boxWH, boxWH);
		g.fillRect(scrollX, boxY + temp, boxWH, boxWH);

		// 画箭头
		g.setColor(ColorSet.scrollIcoColor);
		// 画∧
		// 画/
		g.drawLine(temp3, boxY + temp2, scrollX + temp2, boxY + temp4);
		// 画\
		g.drawLine(temp3, boxY + temp2, scrollX + temp4, boxY + temp4);
		// 画∨
		// 画\
		g.drawLine(temp3, boxY + temp + temp4, scrollX + temp2, boxY + temp + temp2);
		// 画/
		g.drawLine(temp3, boxY + temp + temp4, scrollX + temp4, boxY + temp + temp2);

		g.setColor(ColorSet.scrollBorderColor);
		g.fillRect(scrollX, scrollY + rollMoveScrollValue, boxWH, scrollHight);
		g.setColor(ColorSet.scrollFontColor);
		g.fillRect(scrollX + 1, scrollY + rollMoveScrollValue + 1, boxWH - 2, scrollHight - 2);
	}

	public void pointerDragged(int x, int y)
	{
		if(b_isHaveMore)
		{
			i_dragged[1] = i_dragged[0];
			i_dragged[0] = y;

			if(x < scrollX && y > boxY && y < 290)
			{
				this.y -= i_dragged[0] - i_dragged[1];
				if (this.y - this.temp7 <= i_allStrHight)
				{
					this.y = i_allStrHight + this.temp7;
				}
				else if (this.y >= boxY)
				{
					this.y = boxY;
				}

				rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
				if (rollMoveScrollValue < 0)
				{
					rollMoveScrollValue = 0;
				}
			}
			if(x > scrollX && x < 239 && y > scrollY + rollMoveScrollValue && y < scrollY + rollMoveScrollValue + scrollHight)
			{
				this.y += (i_dragged[0] - i_dragged[1]) * (i_allStrHight / (hight - (boxWH * 2) - scrollHight));
				if (this.y - this.temp7 <= i_allStrHight)
				{
					this.y = i_allStrHight + this.temp7;
				}
				else if (this.y >= boxY)
				{
					this.y = boxY;
				}

				rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
				if (rollMoveScrollValue < 0)
				{
					rollMoveScrollValue = 0;
				}
			}
		}
	}
	public void keyPressed(int keyCode)
	{
		if (b_isHaveMore)
		{
			if (keyCode == DefaultProperties.KEY_DOWN)
			{
				this.y -= rollValue;
				if (this.y - this.temp7 <= i_allStrHight)
				{
					this.y = i_allStrHight + this.temp7 + 2;
				}
			}
			if (keyCode == DefaultProperties.KEY_UP)
			{
				this.y += rollValue;
				if (this.y >= boxY)
				{
					this.y = boxY;
				}
			}
			rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
			if (rollMoveScrollValue < 0)
			{
				rollMoveScrollValue = 0;
			}
		}
	}

	public void pointerPressed(int x, int y)
	{
		if (b_isHaveMore)
		{
			i_dragged[1] = y;
			i_dragged[0] = y;
			if (x > scrollX && x < scrollX + boxWH && y > scrollY && y < scrollY + hight - temp5) // 在滑块内点击时间的捕捉
			{
				if (y < scrollY + rollMoveScrollValue)
				{
					this.y += hight;
					if (this.y >= boxY)
					{
						this.y = boxY;
					}
				} 
				else if (y > scrollY + rollMoveScrollValue + scrollHight)
				{
					this.y -= hight;
					if (this.y - this.temp7 <= i_allStrHight)
					{
						this.y = i_allStrHight + this.temp7 + 2;
					}
				}
				rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
				if (rollMoveScrollValue < 0)
				{
					rollMoveScrollValue = 0;
				}
			}
			else if (x > scrollX && x < scrollX + boxWH && y > boxY && y < boxY + boxWH)
			{
				this.y += rollValue;
				if (this.y >= boxY)
				{
					this.y = boxY;
				}
				rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
				if (rollMoveScrollValue < 0)
				{
					rollMoveScrollValue = 0;
				}
			} 
			else if (x > scrollX && x < scrollX + boxWH && y > boxY + temp && y < boxY + hight)
			{
				this.y -= rollValue;
				if (this.y - this.temp7 <= i_allStrHight)
				{
					this.y = i_allStrHight + this.temp7 + 2;
				}
				rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight);
			}
		}
	}

	private final int getXY(int w, int x, int Exp)
	{
		return (int) (((long) (x * w) * 1000000) / ((long) Exp * 1000000));
	}

	/** 此方法会根据文字内容自动返回长度适应给定width的vector */
	public Vector getSubsection(String strSource, Font font, int width, String strSplit)
	{
		Vector vector = new Vector();
		String temp = strSource;
		int i, j;
		int LastLength = 1;
		int step = 0;
		try {
			while (!temp.equals(""))
			{
				i = temp.indexOf("\n");
				if (i > 0)
				{
					if (font.stringWidth(temp.substring(0, i - 1)) >= width)
					{
						i = -1;
					}
				}
				if (i == -1)
				{
					if (LastLength > temp.length())
					{
						i = temp.length();
					}
					else
					{
						i = LastLength;
						step = font.stringWidth(temp.substring(0, i)) > width ? -1 : 1;
						if (i < temp.length())
						{
							while (!(font.stringWidth(temp.substring(0, i)) <= width && font.stringWidth(temp.substring(0, i + 1)) > width))
							{
								i = i + step;
								if (i == temp.length())
								{
									break;
								}
							}
						}
					}
					if (!strSplit.equals(""))
					{
						j = i;
						if (i < temp.length())
						{
							while (strSplit.indexOf(temp.substring(i - 1, i)) == -1)
							{
								i--;
								if (i == 0)
								{
									i = j;
									break;
								}
							}
						}
					}
				}
				LastLength = i;
				vector.addElement(temp.substring(0, i));
				if (i == temp.length())
				{
					temp = "";
				}
				else
				{
					temp = temp.substring(i);
					if (temp.substring(0, 1).equals("\n"))
					{
						temp = temp.substring(1);
					}
				}
			}
		}
		catch (Exception e)
		{
			System.out.println("getSubsection:" + e);
		}
		temp6 = vector.size();
		i_strHight = font.getHeight();
		i_allStrHight = 320 - boxY - 30 - vector.size() * i_strHight;
		return vector;
	}
}

?

?

有些颜色的静态变量是另一个颜色管理类的,使用时替换成你想要的颜色即可。

?

此控件支持的触屏事件:文字域的拖拽,滚动条的拖拽,上下按钮的点击,滚动条底色区域的翻屏事件

此控件支持的按键事件:手机键盘上下按钮文字像素滚动。

?

?

?

附件有这个类的源码。