我正在使用具有“图像按钮”的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);
}
};
}
答案 0 :(得分:3)
所以,我认为这里可能存在多个问题。我认为Eugen对于commit()
电话是正确的。
但是,我认为LabeledSwitch
类的使用不正确。我猜你猜不上那堂课?我之所以这么说,是因为我在这一类中看到了多种编码约定。
看过这样的多个自定义BlackBerry UI类之后,我相信这就是这个类的工作方式:
该类可以在两个视觉状态之间切换,您可以通过向类传递表示开启状态的PNG图像和关闭状态来定义
通过调用setOn()
方法,可以在这些状态之间切换类,参数值为true
或false
。该参数的值将决定在类的自定义paint()
方法中绘制哪个PNG文件
该班的原作者打算让您使用setOn()
和getOnState()
方法修改和访问交换机的当前状态。你应该改变这个
public boolean _on;
到此:
private boolean _on;
如果您想知道开关是否已打开,请询问onImg.getOnState()
。
顺便说一句,我建议您使用与onImg
不同的名称。这是一个非常令人困惑的名字。它应该类似于onOffSwitch
或toggleSwitch
或fooSwitch
,如果用于关闭和关闭名为 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'之后保留,因为它没有任何意义。