读书人

j2me 线程与Command的有关问题

发布时间: 2012-01-20 18:53:53 作者: rapoo

j2me 线程与Command的问题
今天我用j2me实现一个很简单的程序,程序的实现功能是通过每点击一次软键Start,就会在Canvase画板上画一个小球,并且小球会在频幕上走动,碰到墙壁就会反弹.我本来的意思是,点一次软键Start,就创建一个线程处理一个小球行走路线,但在测试的过程,发现当点击一次软键Start第一个线程启动(线程是在commandAction内开始的)以后,软键Start就无效了,再怎么点也没效果,用Println()测试,发现原来commandAction没有被持行.
哪位大虾能给我讲下为什么吗,并且给出解决办法?谢谢.
下面给出未完成的代码,帮我看看.

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;

public class LuckyBollCanvas extends Canvas {

private int x;//球的x坐标
private int y;//球的y坐标
private int offx,offy;//球跳跃的步长
public boolean pause;//控制是否结束

public LuckyBollCanvas() {
// TODO Auto-generated constructor stub

offx=offy=20;
x=(this.getWidth()+offx)/2;
y=(this.getHeight()+offy)/2;
pause=false;

this.addCommand(new Command( "Start ",Command.OK,1));
this.addCommand(new Command( "Stop ",Command.BACK,1));
this.setCommandListener(new CanvasCommand());
}

protected void paint(Graphics arg0) {
// TODO Auto-generated method stub
//刷新画板
arg0.setColor(255, 255, 255);
arg0.fillRect(0, 0, this.getWidth(), this.getHeight());
//画球
arg0.setColor(0, 0, 0);
arg0.fillArc(x, y, 20, 20, 0, 360);
}
//线程内部类
class LuckyBollThread implements Runnable{
public LuckyBollThread() {
super();
// TODO Auto-generated constructor stub
this.run();
}

public void run() {
while (pause) {
// TODO Auto-generated method stub
x+=offx;
y+=offy;
if(x <0)
{
offx=20;
x=0;
}else if(x> getWidth()-offx)
{
x=getWidth()-offx;
offx=-20;
}
if(y <0)
{
offy=20;
y=0;
}else if(y> getHeight()-offy)
{
y=getHeight()-offy;
offy=-20;
}
repaint();
serviceRepaints();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}
//Command内部类
class CanvasCommand implements CommandListener{

public void commandAction(Command arg0, Displayable arg1) {
// TODO Auto-generated method stub
switch(arg0.getCommandType())
{
case Command.OK:
System.out.println( "aaaaaaaaaaaa ");//测试
pause=true;
LuckyBollThread t=new LuckyBollThread();
break;
case Command.BACK:
pause=false;
System.out.println( "bbbbbbbbbb ");//测试
break;
}
}

}
}

[解决办法]
这样写可能简单些:

import java.awt.*;
import java.awt.event.*;

class Ball extends Thread
{
private Canvas c;


private Graphics g;
private int x=0;
private int y=0;
private int x_move=2;
private int y_move=2;
//private java.util.Random r;

private int width;
private int height;

Ball(Canvas c)
{
this.c=c;
width=c.getWidth();
height=c.getHeight();
}
public void draw()
{
g=c.getGraphics();
g.setColor(Color.blue);
g.fillOval(0,0,10,10);
g.dispose();
}
public void move()
{
g=c.getGraphics();
g.setColor(Color.blue);
g.setXORMode(c.getBackground());
g.fillOval(x,y,10,10);

x=x + x_move;
y=y + y_move;

if(x > width)
{
x = width;
x_move = -2;

}
if(x <0)
{
x=0;
x_move=2;
}
if(y> height)
{
y=height;
y_move=-2;

}
if(y <0)
{
y=0;
y_move=2;
}

g.fillOval(x,y,10,10); //画圆
g.dispose(); //后续处理,释放资源


}
public void run()
{
this.draw();
while(true)
{
this.move();
try
{
Thread.sleep(5);
}catch(Exception e){}
}
}
}
class Ballframe extends Frame implements ActionListener
{
private Canvas c;
private Button b;

Ballframe()
{
b=new Button( "new ");
b.addActionListener(this);
c=new Canvas();
this.add(c, "Center ");
this.add(b, "South ");
this.setSize(400,400);
this.setVisible(true);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

}
public void actionPerformed(ActionEvent e)
{
new Ball(this.c).start();
}
public static void main(String args[])
{
Ballframe my=new Ballframe();
}
}
[解决办法]
关键在你的线程启动方法错了,线程启动是不能调用run的
注意你的LuckyBollThread的构造方法
public LuckyBollThread() {
super();
// TODO Auto-generated constructor stub
this.run();
}

应该修改为:
public LuckyBollThread() {
super();
new Thread(this).start();//注意构造Thread并调用start启动线程
}
[解决办法]
LS的眼睛好锐利
this.run(); //这里相当于主线程调用函数,并没有启动子线程,所以主线程就一直在循环中,没法响应事件了。

读书人网 >J2ME开发

热点推荐