【问题标题】:Commands sometimes don't work命令有时不起作用
【发布时间】:2011-11-29 17:29:08
【问题描述】:

有一个Canvas 有两个Commands。问题是,当第一次打开画布时,命令起作用,但是当我第二次打开它时,命令不起作用!代码如下:

package view;

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
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;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.StringItem;


public class DetailPhotoClient extends Canvas implements CommandListener {

    private Command delete, back;
    private GaleriePhotos backForm;
    private FileConnection fcFile;
    private Image sourceImage;
    private InputStream is;
    private boolean ok,oom, io;

    public DetailPhotoClient(GaleriePhotos prevForm, String absolutePathphotoName)
    {
        super();

        back = new Command("Retour", Command.SCREEN, 1);
        addCommand(back);

        delete = new Command("Supprimer", Command.SCREEN, 2);
        addCommand(delete);

        setCommandListener(this);

        backForm = prevForm;

        ok = true;
        oom = false;
        io = false;

        try {
            fcFile = (FileConnection) Connector.open(absolutePathphotoName, Connector.READ);
            is = fcFile.openInputStream();
            sourceImage = Image.createImage(is);
            is.close();
            fcFile.close();
        } catch (IOException ex) {
            handleException();
        } catch (OutOfMemoryError oome) {
            handleOOM();
        }
    }
    private void handleException() {
        ok = false;
        io = true;
        repaint();
    }
    private void handleOOM() {
        ok = false;
        oom = true;
        repaint();
    }
    protected void paint(Graphics g) {

        StringItem chp;
        int chpW;
        int x, y = getHeight()/2;

        g.fillRect(0, 0, getWidth(), getHeight());

        if (ok)
            g.drawImage(sourceImage, 0, 0, Graphics.TOP | Graphics.LEFT);

        if (io)
        {
            chp = new StringItem(null,"Erreur média et/ou d'entrée-sortie !");
            chpW = chp.getPreferredWidth();
            x = ( getWidth() - chpW ) / 2 ;
            g.setColor(16711422);
            if (x<0)
                g.drawString("Erreur média et/ou d'entrée-sortie !", 0, y, Graphics.TOP | Graphics.LEFT);
            else
                g.drawString("Erreur média et/ou d'entrée-sortie !", x, y, Graphics.TOP | Graphics.LEFT);
        }

        if (oom)
        {
            chp = new StringItem(null,"Mémoire insuffisante !");
            chpW = chp.getPreferredWidth();
            x = ( getWidth() - chpW ) / 2 ;
            g.setColor(16711422);
            if (x<0)
                g.drawString("Mémoire insuffisante !", 0, y, Graphics.TOP | Graphics.LEFT);
            else
                g.drawString("Mémoire insuffisante !", x, y, Graphics.TOP | Graphics.LEFT);
        }
    }
    public void commandAction(Command c, Displayable d) {
        if (c == back)
            backForm.showBack();
        else
        {
            backForm.showBack();
            backForm.deletePhoto();
        }
    }
}

那么为什么有时命令不起作用?使用阿尔卡特 OT-806D 手机测试应用

【问题讨论】:

  • 我注意到代码backForm.showBack(); 是问题的原因。那么如何将 back 从 Canvas 导航到 LWUIT 表单?
  • 当您从backForm 回到 Canvas 时,您是否将 CommandListener 设置回 Canvas?我注意到您在代码的构造函数中执行此操作。或者,你每次都在破坏DetailPhotoClient
  • backFormactionPerformed 中,这是一个LWUIT 表单,我调用Display.getDisplay(controler).setCurrent(new DetailPhotoClient(this, absolutePathPhotoName));
  • 所以你每次都在创建一个新的画布。尽量不要这样做,有些设备不喜欢每个应用使用多个 Canvas。
  • 你为什么加入 LWUIT?你在使用 LWUIT 吗?

标签: java-me lcdui midp-2.0 cldc


【解决方案1】:

您的代码一开始就广泛暴露于与 CommandListener 相关的威胁。看,你的类“外部”的任何代码都可能使你的命令反应迟钝:

void makeItDeaf(DetailPhotoClient detailPhotoClient) {
    detailPhotoClient.setCommandListener(null);
    // voila! your commands will be still visible but
    // wouldn't respond anymore
}

为确保您不会像上面那样意外破坏命令侦听器,请按如下方式“隐藏”它:

//...    
public class DetailPhotoClient extends Canvas { // no "implements" here

    private Command delete, back;
    private GaleriePhotos backForm;
    private FileConnection fcFile;
    private Image sourceImage;
    private InputStream is;
    private boolean ok,oom, io;

    public DetailPhotoClient(GaleriePhotos prevForm,
            String absolutePathphotoName)
    {
        super();

        back = new Command("Retour", Command.SCREEN, 1);
        addCommand(back);

        delete = new Command("Supprimer", Command.SCREEN, 2);
        addCommand(delete);

        backForm = prevForm;

        setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                if (backForm == null) {
                    System.out.println("backForm is null: ignore command");
                    return;
                }
                if (c == back) {
                    System.out.println("back command");
                    backForm.showBack();
                } else {
                    System.out.println("delete command");
                    backForm.showBack();
                    backForm.deletePhoto();
                }
            }
        });

        ok = true;
        oom = false;
        //...
    }
    //...
}

【讨论】:

  • @pheromix,您是否尝试使用backForm 作为普通 lcdui Displayable 而不是 LWUIT 屏幕来测试您的代码?
  • 我的项目 98% 是用 LWUIT 构建的,只有 2 个 UI 是 javame 的东西。
  • @pheromix 了解。所以,你没有尝试这种方法,第二种形式是普通的 lcdui => 即不能说问题是 LWUIT 还是 lcdui 特定的。实际上,如果命令停止响应,而侦听器按照我的建议被“隐藏”,这可能只是因为设备或 LWUIT 中的错误
  • 现在我找到了问题的原因:它是代码backForm.deletePhoto();,因为它打开了一个与lcdui相反的LWUIT组件和命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 2014-04-01
  • 2012-08-16
  • 2014-09-28
相关资源
最近更新 更多