如何在持久存储中存储图像

时间:2012-11-27 13:39:02

标签: blackberry persistent persistent-storage

我正在使用具有“图像按钮”的BlackBerry应用程序。每次点击之间,“图像按钮”可以从“开”变为“关”,反之亦然。现在我要做的是,当应用程序关闭并再次加载时,这个“图像按钮”应该作为其最后一个状态加载。如果“图像按钮”设置为“ON”并且应用程序关闭,则在下次加载时它将加载为“ON”。创建图像按钮时,如果该值设置为“true”,则图像加载为“ON”,即使它是作为on-on创建的。我在构造函数外部创建了ImageButton:

LabeledSwitch onImg=new LabeledSwitch(off,on,off,on,true); 

然后在构造函数中,我尝试检查最后一个图像状态,因此再次创建图像按钮。但是,(boolean)((Boolean)persistentHashtable.get(“image”))。booleanValue()抛出一个CastException,即使它编译正常。

persistentObject = PersistentStore.getPersistentObject(KEY);

 if (persistentObject.getContents() == null) 
 {
    persistentHashtable = new Hashtable();
    persistentObject.setContents(persistentHashtable);
 } else {
    persistentHashtable = (Hashtable) persistentObject.getContents();
     }

  if (persistentHashtable.containsKey("image")) 
 {
     boolean booleanVal = (boolean)((Boolean) persistentHashtable.get("image")).booleanValue();
     if (booleanVal==true)
     {
         onImg=new LabeledSwitch(on,off,on,off,true);
     }
     else
     {
         onImg=new LabeledSwitch(off,on,off,on,false);
     }
 }

我在退出时保存图像的状态:

public boolean onClose() 
    {
        int choose=Dialog.ask(Dialog.D_YES_NO, "Are you sure Want to Exit?");
        if(choose==Dialog.YES)
        {
            if(onImg._on)
             persistentHashtable.put("image", Boolean.TRUE);

            else
                persistentHashtable.put("image", Boolean.FALSE); 
            System.exit(0);

        }
        return true;
    }

请指导。作为参考,下面是用于创建图像按钮的LabeledSwitch类:

import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;

public class LabeledSwitch extends Field {
    private String _textOn;
    private String _textOff;

    private int _textWidth;
    private int _textHeight;

    private int _totalWidth;
    private int _totalHeight;

    private Bitmap _imageOn;
    private Bitmap _imageOnFocus;
    private Bitmap _imageOff;
    private Bitmap _imageOffFocus;

    public boolean _on; //chngd
    private boolean _selected;

    private Font _labelFont;

    private static MenuItem _changeOptionsItem = new ChangeOptionMenuItem();

    private int _textColour = 0x888888;
    private int _textColourFocus = 0x000000;

    private int _horizontalTextImageGap;

    private Bitmap _switchImage;  
    private String _labelText;  
    int mHeight;
    int mWidth;

    public LabeledSwitch(){}

    public LabeledSwitch( Bitmap imageOn
                , Bitmap imageOff
                , Bitmap imageOnFocus
                , Bitmap imageOffFocus
                , boolean onByDefault ) {
        super( Field.FIELD_VCENTER );

        //_textOn = textOn ="";
        //_textOff = textOff ="";

        _imageOn = imageOn;
        _imageOff = imageOff;
        _imageOnFocus = imageOnFocus;
        _imageOffFocus = imageOffFocus;
        _on = onByDefault; 
        _selected = false;

        _horizontalTextImageGap = _imageOn.getHeight() / 3;

    }

    public void applyFont() {
        _labelFont = getFont().derive( Font.PLAIN, _imageOn.getHeight()  );
    }

    /**
     * Change the state of the switch
     * @param on - if true, the switch will be set to on state
     */
    public void setOn(boolean on) {
        _on = on;
        invalidate();
    }

    public boolean getOnState() {
        return _on;
    }

    public boolean isFocusable() {
        return true;
    }

    public int getPreferredWidth() {
        return _totalWidth;
    }

    public int getPreferredHeight() {
        return _totalHeight;
    }

    protected void layout( int width, int height ) {
        // 
        _textWidth = Math.max( _labelFont.getAdvance( _textOn + "a" ), _labelFont.getAdvance( _textOff + "a" ) )-36;
        _textHeight = _labelFont.getHeight();

        _totalWidth = _imageOn.getWidth() + _horizontalTextImageGap + _textWidth;
        _totalHeight = _imageOn.getHeight();

        mWidth = getPreferredWidth();
        mHeight = getPreferredHeight();
        setExtent(mWidth, mHeight);

       // setExtent( _totalWidth, _totalHeight );
    }

    public void paint( Graphics g ){
        Font oldFont = g.getFont();
        int oldColor = g.getColor();

        try { 

            if( _on ) {
                _switchImage = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? _imageOnFocus : _imageOn;
            } else {
                _switchImage = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? _imageOffFocus : _imageOff;
            }

            g.setFont( _labelFont );

            // Determine Label Colour
            g.setColor( g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? _textColourFocus : _textColour );

            // Label
            g.drawText( _on ? _textOn : _textOff, 0, ( getHeight() - _textHeight ) / 2, DrawStyle.RIGHT, _textWidth ); 

            // Image
            //g.drawBitmap( _textWidth + _horizontalTextImageGap, 0, _switchImage.getWidth(), _switchImage.getHeight(), _switchImage, 0, 0 );
            g.drawBitmap(0, 5, mWidth, mHeight, _switchImage, 0, 0);
        } finally {
            g.setFont( oldFont );
            g.setColor( oldColor );
        }
    }

    public void paintBackground( Graphics g ) {}

    protected void drawFocus( Graphics g, boolean on ){
        // Paint() handles it all
        g.setDrawingStyle( Graphics.DRAWSTYLE_FOCUS, true );
        paint( g );
    }

    protected boolean keyChar( char key, int status, int time ){
        if( key == Characters.SPACE || key == Characters.ENTER ) {
            toggle();            
            return true;
        }
        return false;
    }

    protected boolean navigationClick(int status, int time){
        toggle();            
        return true;    
    }

    protected boolean invokeAction(int action){
        switch( action ) {
            case ACTION_INVOKE: {
                toggle(); 
                return true;
            }
        }
        return super.invokeAction( action );
    }

    protected boolean trackwheelClick( int status, int time ){        
        if( isEditable() ) {
            toggle();            
            return true;
        }
        return super.trackwheelClick(status, time);
    }

    /**
     * Toggles the state of the switch
     */
    private void toggle(){
        _on = !_on;
        invalidate();
        fieldChangeNotify( 0 );
    }

    public void setDirty( boolean dirty ){
        // We never want to be dirty or muddy
    }

    public void setMuddy( boolean muddy ){
        // We never want to be dirty or muddy
    }    

    protected void makeContextMenu(ContextMenu contextMenu){
        super.makeContextMenu(contextMenu);
        if((Ui.getMode() < Ui.MODE_ADVANCED) && isEditable()) {
            contextMenu.addItem(_changeOptionsItem);
        }
    }

    /**
     * @category Internal InnerClass
     */
    static class ChangeOptionMenuItem extends MenuItem {
        ChangeOptionMenuItem() {
            super("Toggle", 30270, 10);
        }

        ChangeOptionMenuItem(String text) {
            super(text, 30270, 10);
        }

        public void run() {
            LabeledSwitch theSwitch = (LabeledSwitch)getTarget();
            theSwitch.toggle();
        }

        public int getPriority() {
            return 100 + (getTarget().isMuddy() ? 1000 : 0);
        }
    };
}

2 个答案:

答案 0 :(得分:3)

所以,我认为这里可能存在多个问题。我认为Eugen对于commit()电话是正确的。

但是,我认为LabeledSwitch类的使用不正确。我猜你猜不上那堂课?我之所以这么说,是因为我在这一类中看到了多种编码约定。

看过这样的多个自定义BlackBerry UI类之后,我相信这就是这个类的工作方式:

  1. 该类可以在两个视觉状态之间切换,您可以通过向类传递表示开启状态的PNG图像和关闭状态来定义

  2. 通过调用setOn()方法,可以在这些状态之间切换类,参数值为truefalse。该参数的值将决定在类的自定义paint()方法中绘制哪个PNG文件

  3. 该班的原作者打算让您使用setOn()getOnState()方法修改和访问交换机的当前状态。你应该改变这个

  4. public boolean _on;
    

    到此:

    private boolean _on;
    

    如果您想知道开关是否已打开,请询问onImg.getOnState()

    顺便说一句,我建议您使用与onImg不同的名称。这是一个非常令人困惑的名字。它应该类似于onOffSwitchtoggleSwitchfooSwitch,如果用于关闭和关闭名为 foo 的内容。在成员变量onImg的上下文中将其命名为_imageOn令人困惑,始终应表示当开关显示的图像>

    总而言之,而不是:

     if (booleanVal==true)
     {
         onImg=new LabeledSwitch(on,off,on,off,true);
     }
     else
     {
         onImg=new LabeledSwitch(off,on,off,on,false);
     }
    

    使用类似的东西:

     onOffSwitch = new LabeledSwitch(on, off, on, off, true);
     onOffSwitch.setOn(booleanValue);        
    

     onOffSwitch = new LabeledSwitch(on, off, on, off, booleanValue);
    

答案 1 :(得分:1)

首先,我没有看到以下必需的代码来存储持久对象:

persistentObject.commit();

我希望这只是你代码中的一些额外内容,否则你总是在读取之前重写值,这可能不是预期的。所以'read'代码不应该在'write'之后保留,因为它没有任何意义。