創建使用觸摸屏的Java ME 程序
楊建強
摘要: 介紹了Canvas 類中可用于捕獲觸摸屏事件的方法, 創建了一個類似于iPhone 手機上的圖片瀏覽程序。
關鍵詞: Java ME; Canvas
1 Canvas 類
Canvas 類位于javax.microedition.lcdui 包中, 它提供了低級屏幕和圖像操作方法。該類自身是抽象類, 使用的時候需要給出具體的實現。Canvas 中最重要的方法是paint (Graphics g),它完成圖像的實際繪制。當然, 在這里paint () 方法并不是重點, 感興趣的是其他5 個方法, 它們可用于創建使用觸摸屏的Java ME 程序。這些方法包括hasPointerEvents ()、hasPointer-MotionEvents ( ) 、pointerDragged ( int x, int y) 、pointerPressed(int x, int y), 以及pointerReleased (int x, int y)。這5 個方法最初被用于處理具有指點能力的界面———也即用戶能夠使用指點設備與這樣的界面交互。不過, 在具有觸摸功能的非指點設備上, 這些方法工作得一樣好。
當發生指點事件時, 也即按下、釋放和拖動指點設備時,系統會分別調用pointerPressed (int x, int y) 、pointerReleased(int x, int y) 和pointerDragged (int x, int y) 方法, 此時, 參數x、y 中存有指點事件發生時指點所在的坐標。因此, 可以利用這些方法獲得指點所在的位置, 并根據需要完成相應的操作。注意, 系統對這些方法的調用是串行的, 也即系統從不在前一個調用方法返回之前調用另一個方法。方法hasPointerEvents() 檢查設備是否支持指點按下和釋放事件。當has-PointerEvents () 返回true 時, 意味著設備支持pointerPressed(int x, int y) 和pointerReleased (int x, int y) 方法。方法has-PointerMotionEvents () 檢查設備是否支持指點移動事件。當hasPointerMotionEvents () 返回true 時, 意味著設備支持pointerDragged(int x, int y) 方法。
2 利用Canvas 創建觸摸屏圖片瀏覽器
有了前面的基礎, 現在來創建一個類似于iPhone 手機上的觸摸屏圖片瀏覽器。首先, 讓先看一下程序運行時的屏幕截圖, 從而搞清楚要實現的效果是什么。如圖1 顯示Java ME程序啟動后加載的圖片, 以及稍微向左拖動或滑動該圖片后的效果。
圖1 剛加載的圖片(左) 和向左稍微滑動之后的圖片(右)
順便說一下, 使用Java ME SDK 3.0 作為測試平臺, 并選用DefaultFxTouchPhone1 作為目標模擬器。因此, 給出的屏幕截圖來自于電腦上運行的模擬器。當然, 在模擬器只能使用鼠標來代替手指。
選擇的圖片比屏幕的尺寸要寬一些, 為的是創造出圖片滾動的效果。在實際設備上, 當手指在屏幕上左右滑動時, 程序會根據滑動的距離顯示出當前圖片的剩余部分, 或者顯示出前一幅或下一幅圖片。圖片剛加載時剩余部分位于屏幕右側。程序是這樣設置的, 如果水平滑動的距離少有20 個點(像素),將顯示出當前圖片的剩余部分。如果滑動的距離超過20 個點,則顯示前一幅或下一幅圖片(分別對應向左、向右滑動), 如圖2 所示。要達到的效果就是通過手指的滑動來逐個顯示圖片庫中的圖片。
圖2 剛加載的圖片(左) 和向左(或向右)滑動超過20 個點之后的圖片(右)
知道了想要的結果, 現在來看一看完成上述任務的Canvas類的代碼。
public class BrowseImageCanvas extends Canvas {
private boolean scroll = false;
private int currentImage = 0;
private Image[] images; // 存放多個圖片,相當于圖片庫
private int pressX, releaseX, dragX = 0;
public BrowseImageCanvas() {
// 啟動時加載圖片,這里加載3 個圖片
images = new Image[3];
images[0] = Image.createImage("/flower0.jpg");
images[1] = Image.createImage("/flower1.jpg");
images[2] = Image.createImage("/flower2.jpg");
}
protected void paint(Graphics g) {
g.setGrayScale(255);
g.fillRect(0, 0, getWidth(), getHeight()); // 清屏
if (scroll) { // 滾動當前圖片
g.drawImage(images[currentImage], -dragX, 0,
Graphics.LEFT | Graphics.TOP);
scroll = false;
return;
}
if (pressX < releaseX) { // 向右滑動,顯示下一幅圖片
currentImage++;
if (currentImage == images.length) currentImage = 0;
}
if (pressX > releaseX) { // 向左滑動,顯示前一幅圖片
currentImage--;
if (currentImage < 0) currentImage = (images.length - 1);
}
// 繪制新的圖片
g.drawImage (images [currentImage], 0, 0, Graphics.
LEFT | Graphics.TOP);
}
protected void pointerPressed(int x, int y) { // 記下
//開始觸摸的水平位置
pressX = x;
}
// 記下觸摸釋放的水平位置,判斷滑動的距離決定是否加
//載新圖片
protected void pointerReleased(int x, int y) {
if (scroll) return;
releaseX = x;
if (Math.abs(releaseX - pressX) > 20) { // 滑動距離超
//過20 個點加載新圖片
repaint();
}
}
protected void pointerDragged(int x, int y) { //在這里
//決定是否滾動圖片
int deltaX = pressX - x;
if (Math.abs(deltaX) <= 20) { // 滑動距離少于20 個點
//滾動當前圖片
int imageWidth = images[currentImage].getWidth();
if (imageWidth > getWidth()) {
dragX += deltaX;
if (dragX < 0) dragX = 0;
else if (dragX + getWidth() > imageWidth) dragX
= imageWidth - getWidth();
}
scroll = true;
repaint();
}
}
}
程序中, pointerPressed ( ) 、pointerReleased ( ) 、pointer-Dragged () 方法設置各種參數, paint () 利用這些參數來決定是否滾動當前圖片或顯示新圖片。在pointerPressed () 方法中,保存了用戶觸摸位置的x 軸坐標, 然后, 在pointerReleased ()和pointerDragged () 方法中確定用戶手指沿水平方向移動的距離大小(deltaX)。如果移動超過20 點, 則顯示新圖片, 否則就沿x 軸方向卷動圖片。可以左右兩個方向移動。當然, 為了簡化問題, 程序忽略了沿y 軸方向的移動。
3 結語
自Java ME 誕生以來, 它就已經具備了滿足觸摸屏界面的能力, 只是那些提供Java ME 實現的設備制造商沒有跟上步伐。介紹了Canvas 類中的能夠捕獲觸摸屏上指點運動的接口,并以一個類似于iPhone 手機上的圖片瀏覽程序來演示其使用方法。希望能夠起到拋磚引玉的作用, 啟發讀者寫出更加實用的觸摸屏Java 程序。