首页 > 编程语言 >JavaME 开发体会:线程编程解决手机地图按住方向键不放地图移动问题

JavaME 开发体会:线程编程解决手机地图按住方向键不放地图移动问题

时间:2022-10-21 13:03:49浏览次数:43  
标签:JavaME microedition 键不放 地图 int length Graphics import javax

JavaME 开发体会:线程编程解决手机地图按住方向键不放地图移动问题

初从 JavaEE 开发转入 JavaME 开发,线程编程技术越发显得重要.作者以一个真实项目中的体会,演示了线程编程在 JavaME 开发中的使用,可以巧妙地解决一些看似疑难的问题.
背景:以下代码是作者写的一个 JavaMe 手机地图移动的代码.
ImageMIDlet.java 源码如下:
/**
* 文件名:ImageMIDlet.java
*
* 版本信息:
* 日期:2009-10-17
* Copyright XXX Corporation 2009
* 版权所有
*
*/
package image.downed.move;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
/**
*
* 项目名称:Imagedownedmove
* 类名称:ImageMIDlet
* 类描述:This is the main class of the image downed move.
* 创建人:Defonds
* 创建时间:2009-10-17 上午11:02:17
* 修改人:Defonds
* 修改时间:2009-10-17 上午11:02:17
* 修改备注:
* @version
*
*/
public class ImageMIDlet extends MIDlet implements CommandListener
{
/**
* The canvas is the region of the screen.
*/
ImageCanvas myCanvas;

/**
* The command objects appears as buttons.
*/
private Command exitCommand = new Command("退出",Command.EXIT,99);

/**
* Initialize the canvas and the commands.
*/
public ImageMIDlet()
{
myCanvas = new ImageCanvas(Display.getDisplay(this));
myCanvas.addCommand(exitCommand);
myCanvas.setCommandListener(this);
}
//-------------------------------------
//Implimentation of MIDlet.

/**
* If the MIDlet was usring resources,it should release them in this method.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
*/
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}

/**
* This method is called to notify the MIDlet to enter a paused state.
* The MIDlet should use this opportunity to release shared resources.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#pauseApp()
*/
protected void pauseApp() { }
/**
* Start the application.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#startApp()
*/
protected void startApp() throws MIDletStateChangeException
{
myCanvas.start();
}
//---------------------------------
// implimentation of CommandListener.

/**
* Respond to a command issued on the Canvas.
* (either reset or exit).
*/
/* (non-Javadoc)
* @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
*/
public void commandAction(Command arg0, Displayable arg1)
{
if(arg0 == exitCommand)
{
try
{
destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException e) {}
}
}
}

ImageCanvas.java 源代码如下:
/**
* 文件名:ImageCanvas.java
*
* 版本信息:
* 日期:2009-10-17
* Copyright XXX Corporation 2009
* 版权所有
*
*/
package image.downed.move;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
*
* 项目名称:Imagedownedmove
* 类名称:ImageCanvas
* 类描述:This class represents the region of the screen.
* 实现按住向下键不放,N 张图片一起下移的算法.
* 创建人:Defonds
* 创建时间:2009-10-17 上午11:32:14
* 修改人:Defonds
* 修改时间:2009-10-17 上午11:32:14
* 修改备注:
* @version
*
*/
public class ImageCanvas extends Canvas
{
//-------------------------------
//fields
/**
* A handle to the screen of the device.
*/
Display myDisplay;

/**
* 每按一下向下键,图片向上移动的距离
*/
private final int distance = 5;

/**
* 每按一下向下键,还有多少距离显示空白
*/
private int ydown = 0;

/**
* 手机屏幕中心点坐标
*/
private final int x = getWidth()/2,y = getHeight()/2;

/**
* 下载图片的宽度
*/
private final int imageWidth = 300;

/**
* 判断是否显示第5,6张,停止显示第1,2张
*/
boolean showNew = false;

/**
* 6个图片的初始坐标
*/
private int x1 = x - imageWidth,y1 = y - imageWidth;
private int x2 = x,y2 = y - imageWidth;
private int x3 = x - imageWidth,y3 = y;
private int x4 = x,y4 = y;
private int x5 = x - imageWidth,y5 = getHeight() - 1;
private int x6 = x,y6 = getHeight() - 1;
/**
* 要画的图片
*/
Image image1,image2,image3,image4,image5,image6;

/**
* 要下载的图片的URL(规格:全部是 300 X 300)
*/
String url1 ="http://img1.mapbar.com/maplite/mapbank/baidu/8/116_39/4_7.png";
String url2 ="http://img3.mapbar.com/maplite/mapbank/baidu/8/116_39/5_7.png";
String url3 ="http://img.mapbar.com/maplite/mapbank/baidu/8/116_39/6_6.png";
String url4 ="http://mappng.baidu.com/maplite/mapbank/baidu/5/11_4/3_3.png";
String url5 = "http://img3.mapbar.com/maplite/mapbank/baidu/8/109_42/1_1.png";
String url6 = "http://www.sunyn.com/kmtour/UploadFiles_7357/200706/20070625215831613.png";

/**
* 要下载图片的字节流
*/
byte[] byteofimg1,byteofimg2,byteofimg3,byteofimg4,byteofimg5,byteofimg6;

//-------------------------
//Initialization
/**
* Constructor merely sets the display.
*/
public ImageCanvas(Display d)
{
super();
myDisplay = d;
ydown = imageWidth - getHeight()/2;
try
{
byteofimg1 = loadHttpFile(url1);
System.out.println("byteofimg1.length="+byteofimg1.length);
byteofimg2 = loadHttpFile(url2);
System.out.println("byteofimg2.length="+byteofimg2.length);
byteofimg3 = loadHttpFile(url3);
System.out.println("byteofimg3.length="+byteofimg3.length);
byteofimg4 = loadHttpFile(url4);
System.out.println("byteofimg4.length="+byteofimg4.length);
}
catch (IOException e)
{
e.printStackTrace();
}
}

/**
* This is called as soon as the application begins.
*/
void start()
{
myDisplay.setCurrent(this);
repaint();
}

/**
* 清屏
*/
public void clearScreen(Graphics g)
{
//g.setColor(0, 0, 0);//要设置的底色-黑色
g.setColor(255,255,255); //要设置的底色-白色
g.fillRect(0, 0, this.getWidth(), this.getHeight());
}

/**
* 键盘事件的重写
*/
protected void keyPressed(int keyCode)
{
ydown = ydown - distance;
//如果出现空白,停止显示第1,2张图片,开始显示3,4以及5,6
if(ydown < 0)
{
try
{
byteofimg5 = loadHttpFile(url5);
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("byteofimg5.length="+byteofimg5.length);
try
{
byteofimg6 = loadHttpFile(url6);
} catch (IOException e)
{
e.printStackTrace();
}
System.out.println("byteofimg6.length="+byteofimg6.length);
showNew = !showNew;
//ydown重置
ydown = imageWidth;
System.out.println("byteofimg2.length="+byteofimg2.length);
}
int action = getGameAction(keyCode);
switch(action)
{
case Canvas.DOWN:
y1 = y1 - distance;
y2 = y2 - distance;
y3 = y3 - distance;
y4 = y4 - distance;
if(showNew)
{
y5 = y5 - distance;
y6 = y6 - distance;
}
repaint();
}
}
/**
* 下载图片函数
*/
public byte[] loadHttpFile(String url) throws IOException
{
byte[] byteBuffer;
HttpConnection hc = (HttpConnection) Connector.open(url);
System.out.println("loadHttpFile:"+url);
try
{
hc.setRequestMethod(HttpConnection.GET);
InputStream is = hc.openInputStream();
try
{
int len = (int) hc.getLength();
if (len > 0)
{
byteBuffer = new byte[len];
int done = 0;
while (done < len)
{
done += is.read(byteBuffer, done, len - done);
}
} else
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int count;
while ( (count = is.read(buffer)) >= 0 )
{
bos.write(buffer, 0, count);
}
byteBuffer = bos.toByteArray();
}
} finally
{
is.close();
}
} finally
{
hc.close();
}

return byteBuffer;
}

//-------------------------------------------
//Graphics methods

/**
* Clear the screen and display the image.
*/

/* (non-Javadoc)
* @see javax.microedition.lcdui.Canvas#paint(javax.microedition.lcdui.Graphics)
*/
protected void paint(Graphics arg0)
{
clearScreen(arg0);
if(!showNew)
{
image1 = Image.createImage(byteofimg1,0, byteofimg1.length);
image2 = Image.createImage(byteofimg2,0, byteofimg2.length);
image3 = Image.createImage(byteofimg3,0, byteofimg3.length);
image4 = Image.createImage(byteofimg4,0, byteofimg4.length);
arg0.drawImage(image1, x1, y1, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image2, x2, y2, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image3, x3, y3, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image4, x4, y4, Graphics.TOP|Graphics.LEFT);
}
else
{
image3 = Image.createImage(byteofimg3,0, byteofimg3.length);
image4 = Image.createImage(byteofimg4,0, byteofimg4.length);
image5 = Image.createImage(byteofimg5,0, byteofimg5.length);
image6 = Image.createImage(byteofimg6,0, byteofimg6.length);
arg0.drawImage(image3, x3, y3, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image4, x4, y4, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image3, x5, y5, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image4, x6, y6, Graphics.TOP|Graphics.LEFT);
}
}
}


这段代码解决了:手机地图下载,手机地图随方向键的按下而移动.但是还是存在问题:如果用户只按一下方向键,地图移动 5 个象素,而按住住方向键不放同样也是移动 5 个象素.对于这种效果,用户肯定是不会满意的.然而按键事件只是通知按下和松开,仅仅改写按键事件方法,不能起到根据用户按键不放时间进行移动地图的效果.这个时间段怎么计算呢?作者想到了线程编程,问题迎刃而解.解决后的源码如下,读者可以把代码考到自己电脑上,运行一下,体会其中的奥妙.
ImageMIDlet.java 源码如下:
/**
* 文件名:ImageMIDlet.java
*
* 版本信息:
* 日期:2009-10-17
* Copyright XXX Corporation 2009
* 版权所有
*
*/
package image.downed.move;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
/**
*
* 项目名称:Imagedownedmove
* 类名称:ImageMIDlet
* 类描述:This is the main class of the image downed move.
* 创建人:Defonds
* 创建时间:2009-10-17 上午11:02:17
* 修改人:Defonds
* 修改时间:2009-10-17 上午11:02:17
* 修改备注:
* @version
*
*/
public class ImageMIDlet extends MIDlet implements CommandListener
{
/**
* The canvas is the region of the screen.
*/
ImageCanvas3 myCanvas;

/**
* The command objects appears as buttons.
*/
private Command exitCommand = new Command("退出",Command.EXIT,99);

/**
* Initialize the canvas and the commands.
*/
public ImageMIDlet()
{
myCanvas = new ImageCanvas3(Display.getDisplay(this));
myCanvas.addCommand(exitCommand);
myCanvas.setCommandListener(this);
}
//-------------------------------------
//Implimentation of MIDlet.

/**
* If the MIDlet was usring resources,it should release them in this method.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
*/
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}

/**
* This method is called to notify the MIDlet to enter a paused state.
* The MIDlet should use this opportunity to release shared resources.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#pauseApp()
*/
protected void pauseApp() { }
/**
* Start the application.
*/
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#startApp()
*/
protected void startApp() throws MIDletStateChangeException
{
myCanvas.start();
}
//---------------------------------
// implimentation of CommandListener.

/**
* Respond to a command issued on the Canvas.
* (either reset or exit).
*/
/* (non-Javadoc)
* @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
*/
public void commandAction(Command arg0, Displayable arg1)
{
if(arg0 == exitCommand)
{
try
{
destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException e) {}
}
}
}

ImageCanvas3.java 源代码如下:
/**
* 文件名:ImageCanvas3.java
*
* 版本信息:
* 日期:2009-10-18
* Copyright XXX Corporation 2009
* 版权所有
*
*/
package image.downed.move;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
*
* 项目名称:Imagedownedmove
* 类名称:ImageCanvas3
* 类描述:This class represents the region of the screen.
* 利用 按键方法重写 + 线程 + 计时器 解决按住向下键不放手机地图移动的距离问题.
* 创建人:Defonds
* 创建时间:2009-10-18 上午10:33:03
* 修改人:Defonds
* 修改时间:2009-10-18 上午10:33:03
* 修改备注:
* @version
*
*/
public class ImageCanvas3 extends Canvas implements Runnable
{
//----------------------------
//fields

/**
* A handle to the screen of the device.
*/
Display myDisplay;

/**
* A handle to the run method.
*/
private Thread myThread = null;

/**
* 按住向下建的单位时间内,图片向上移动的距离.
*/
private final int yspeed = 5;

/**
* 手机屏幕中心点坐标.
*/
private final int x = getWidth()/2,y = getHeight()/2;

/**
* 下载图片的宽度(假想全部为正方形图片).
*/
private final int imageWidth = 300;

/**
* 按键处理代码需要变量:
* keyDown:Canvas.DOWN 按下为 true,反之为 false;
* action:GameAction
*/
private boolean keyDown = false;
private int action = 0;

/**
* 6 个图片的初始坐标.
*/
private int x1 = x - imageWidth,y1 = y - imageWidth;
private int x2 = x,y2 = y - imageWidth;
private int x3 = x - imageWidth,y3 = y;
private int x4 = x,y4 = y;
private int x5 = x - imageWidth,y5 = y + imageWidth;
private int x6 = x,y6 = y + imageWidth;

/**
* 要画的图片.
*/
Image image1,image2,image3,image4,image5,image6;

/**
* 要下载的图片的 URL(规格: 300 X 300).
*/
String url1 = "http://img1.mapbar.com/maplite/mapbank/baidu/8/116_39/4_7.png";
String url2 = "http://img3.mapbar.com/maplite/mapbank/baidu/8/116_39/5_7.png";
String url3 = "http://img.mapbar.com/maplite/mapbank/baidu/8/116_39/6_6.png";
String url4 = "http://mappng.baidu.com/maplite/mapbank/baidu/5/11_4/3_3.png";
String url5 = "http://img3.mapbar.com/maplite/mapbank/baidu/8/109_42/1_1.png";
String url6 = "http://www.sunyn.com/kmtour/UploadFiles_7357/200706/20070625215831613.png";

/**
* 要下载的图片的字节流.
*/
byte[] byteofimg1,byteofimg2,byteofimg3,byteofimg4,byteofimg5,byteofimg6,byteofimg7;

//---------------------------------------
//Initialization.
/**
* Constructor merely sets the display.
*/
public ImageCanvas3(Display d)
{
super();
myDisplay = d;
try
{
byteofimg1 = loadHttpFile(url1);
System.out.println("byteofimg1.length="+byteofimg1.length);
byteofimg2 = loadHttpFile(url2);
System.out.println("byteofimg2.length="+byteofimg2.length);
byteofimg3 = loadHttpFile(url3);
System.out.println("byteofimg3.length="+byteofimg3.length);
byteofimg4 = loadHttpFile(url4);
System.out.println("byteofimg4.length="+byteofimg4.length);
byteofimg5 = loadHttpFile(url5);
System.out.println("byteofimg5.length="+byteofimg5.length);
byteofimg6 = loadHttpFile(url6);
System.out.println("byteofimg6.length="+byteofimg6.length);
}
catch (IOException e)
{
e.printStackTrace();
}
}

/**
* This is called as soon as the application begins.
*/
public void start()
{
if(myThread == null)
{
myThread = new Thread(this);
myThread.start();
}
myDisplay.setCurrent(this);
repaint();
}

/**
* This is called as soon as the application ends.
*/
public void stop()
{
if(myThread != null)
{
myThread = null;
}
}

/**
* 清屏.
*/
public void clearScreen(Graphics g)
{
g.setColor(255,255,255);//要设置的底色:白色
g.fillRect(0, 0, getWidth(), getHeight());
}

/**
* 键盘事件函数 keyPressed 的重写
*/
protected void keyPressed(int keyCode)
{
action = getGameAction(keyCode);
switch(action)
{
case Canvas.DOWN:keyDown = true;
}
}

/**
* 键盘事件函数 keyReleased 的重写
*/
protected void keyReleased(int keyCode)
{
action = getGameAction(keyCode);
switch(action)
{
case Canvas.DOWN:
keyDown = false;//keyDown 复位.
}
}

/**
* http 下载图片函数.
*/
public byte[] loadHttpFile(String url) throws IOException
{
byte[] byteBuffer;
HttpConnection hc = (HttpConnection) Connector.open(url);
System.out.println("loadHttpFile:"+url);
try
{
hc.setRequestMethod(HttpConnection.GET);
InputStream is = hc.openInputStream();
try
{
int len = (int) hc.getLength();
if (len > 0)
{
byteBuffer = new byte[len];
int done = 0;
while (done < len)
{
done += is.read(byteBuffer, done, len - done);
}
} else
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int count;
while ( (count = is.read(buffer)) >= 0 )
{
bos.write(buffer, 0, count);
}
byteBuffer = bos.toByteArray();
}
} finally
{
is.close();
}
} finally
{
hc.close();
}

return byteBuffer;
}

//-----------------------
//Graphics method.

/**
* Clear the screen and display the image.
*/
/* (non-Javadoc)
* @see javax.microedition.lcdui.Canvas#paint(javax.microedition.lcdui.Graphics)
*/
protected void paint(Graphics arg0)
{
clearScreen(arg0);
image1 = Image.createImage(byteofimg1,0, byteofimg1.length);
image2 = Image.createImage(byteofimg2,0, byteofimg2.length);
image3 = Image.createImage(byteofimg3,0, byteofimg3.length);
image4 = Image.createImage(byteofimg4,0, byteofimg4.length);
image5 = Image.createImage(byteofimg5,0, byteofimg5.length);
image6 = Image.createImage(byteofimg6,0, byteofimg6.length);
arg0.drawImage(image1, x1, y1, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image2, x2, y2, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image3, x3, y3, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image4, x4, y4, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image5, x5, y5, Graphics.TOP|Graphics.LEFT);
arg0.drawImage(image6, x6, y6, Graphics.TOP|Graphics.LEFT);
}
//---------------------------------
//implimentation of Runnable.

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run()
{
while(true)
{
if(keyDown)
{
try
{
Thread.sleep(200);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("向下键被按下,屏幕开始重绘!");
y1 = y1 - yspeed;
y2 = y2 - yspeed;
y3 = y3 - yspeed;
y4 = y4 - yspeed;
y5 = y5 - yspeed;
y6 = y6 - yspeed;
repaint();
}
}
}
}

标签:JavaME,microedition,键不放,地图,int,length,Graphics,import,javax
From: https://blog.51cto.com/defonds/5782402

相关文章