2011-04-27 2 views
0

내 문제를 설명하기 위해 간단한 테스트 케이스를 준비했습니다.Blackberry : ListField 내용 및 더티 상태 관리 저장

새로운 프로젝트에 추가 될 때 바로 실행되는 파일은 단지 하나의 파일입니다.

내가 항목의 편집 가능한 목록을 표시하는 MainScreen하고 싶은 :

screenshot

을하고이 화면을 떠날 때, 사용자는 요구한다 - 그녀는 영구 저장소에 수정 된 목록을 저장하고자하는 경우 내 메뉴 항목에

screenshot

내가 추가 한으로 setDirty (참) 표준 대화 상자가 언덕을 올 않습니다, 표준 저장/취소를 제시하여/- 대화 상자를 취소 와이.

내 문제는 다음과 같습니다 내가 저장 한 후 더러운 플래그를 삭제하는 방법을 모른다 - 내 현재 코드 저장/폐기에/취소 - 대화 상자가 또 다시 온다, 난 그냥없이의 ListField을 볼 경우에도 편집.

SRC \ myPackage에 \ MyList.java :

package mypackage; 

import java.util.*; 
import net.rim.device.api.collection.*; 
import net.rim.device.api.collection.util.*; 
import net.rim.device.api.system.*; 
import net.rim.device.api.ui.*; 
import net.rim.device.api.ui.component.*; 
import net.rim.device.api.ui.container.*; 
import net.rim.device.api.ui.decor.*; 
import net.rim.device.api.util.*; 

public class MyList extends UiApplication implements FieldChangeListener { 
    MyScreen myScreen = new MyScreen(); 

    public static void main(String args[]) { 
     MyList app = new MyList(); 
     app.enterEventDispatcher(); 
    } 

    public MyList() { 
     MainScreen titleScreen = new MainScreen(); 
     titleScreen.setTitle("Click the button:"); 

     ButtonField myButton = new ButtonField("Show the list", ButtonField.CONSUME_CLICK) ; 
     myButton.setChangeListener(this); 
     titleScreen.add(myButton); 

     pushScreen(titleScreen); 
    } 

    public void fieldChanged(Field field, int context) { 
     pushScreen(myScreen); 
    } 
} 

class MyScreen extends MainScreen { 
    ObjectListField myList = new ObjectListField(); 
    static PersistentObject myStore; 
    static Vector myData; 

    static { 
     myStore = PersistentStore.getPersistentObject(0xb77f8e453754f37aL); 
     myData = (Vector) myStore.getContents(); 
     if (myData == null) { 
       myData = new Vector(); 
       myData.addElement("String 1"); 
       myData.addElement("String 2"); 
       myData.addElement("String 3"); 
       myStore.setContents(myData); 
     } 
    } 

    public MyScreen() { 
     setTitle("Edit the list below:"); 

     add(myList); 

     addMenuItem(addItem); 
     addMenuItem(editItem); 
     addMenuItem(removeItem); 
    } 

    // load data from persistent store into the ListField 
    private void loadData() { 
     // clear the ListField 
     myList.setSize(0); 
     // copy data from the Vector to the ListField 
     for (int i = myData.size() - 1; i >= 0; i--) 
      myList.insert(0, myData.elementAt(i)); 
    } 

    // save data from the ListField into the persistent store 
    private void saveData() { 
     // clear the Vector 
     myData.removeAllElements(); 
     // copy data from the ListField to the Vector 
     for (int i = myList.getSize() - 1; i >=0; i--) 
      myData.addElement(myList.get(myList, i)); 

     synchronized(PersistentStore.getSynchObject()) { 
      myStore.commit(); 
     } 
    } 

    protected void onUiEngineAttached(boolean attached) { 
     if (attached) { 
      loadData(); 
     } 
    } 

    public void save() { 
     saveData(); 
     // UPDATE: when I call setDirty(false); here, then 
     // the app starts displaying Save/Discard/Cancel dialog 
     // on its exit - so there must be a better way... 
    } 

    private final MenuItem addItem = new MenuItem("Add Item", 0, 0) { 
     public void run() { 
      String[] buttons = {"Add", "Cancel"}; 
      Dialog myDialog = new Dialog("Add Item", buttons, null, 0, null); 

      EditField myEdit = new EditField("Item: ", ""); 
      myDialog.add(myEdit); 

      if (myDialog.doModal() == 0) { 
       myList.insert(0, myEdit.getText()); 
       setDirty(true); 
      } 
     } 
    }; 

    private final MenuItem editItem = new MenuItem("Edit Item", 0, 0) { 
     public void run() { 
      String[] buttons = {"Save", "Cancel"}; 
      Dialog myDialog = new Dialog("Edit Item", buttons, null, 0, null); 

      int index = myList.getSelectedIndex(); 
      if (index == -1) { 
       return; 
      } 

      String selectedItem = (String) myList.get(myList, index); 
      EditField myEdit = new EditField("Item: ", selectedItem); 
      myDialog.add(myEdit); 

      if (myDialog.doModal() == 0) { 
       myList.set(index, myEdit.getText()); 
       setDirty(true); 
      } 
     } 
    }; 

    private final MenuItem removeItem = new MenuItem("Remove Item", 0, 0) { 
     public void run() { 
      String[] buttons = {"Delete", "Cancel"}; 
      Dialog myDialog = new Dialog("Remove Item", buttons, null, 0, null); 

      int index = myList.getSelectedIndex(); 
      if (index == -1) { 
       return; 
      } 

      String selectedItem = (String) myList.get(myList, index); 
      LabelField myLabel = new LabelField("Really delete " + selectedItem + "?"); 
      myDialog.add(myLabel); 

      if (myDialog.doModal() == 0) { 
       myList.delete(index); 
       setDirty(true); 
      } 
     } 
    }; 
} 

블랙 베리 6의 경험을 공유하십시오, 영구 저장소에 관해서 조언도 환영합니다.

실제 프로그램에서는 KeywordFilterField for viewing a SortedReadableList을 사용하고 있습니다. Blackberry 문서를 읽는 것으로부터는 항상 SortedReadableList와 Vector간에 데이터를 복사해야합니다. 왜냐하면 후자는 지속 가능하고 전자는 그렇지 않기 때문입니다.

+0

저장 호출이 모두 기록되지 않는 문제가 있습니까? – jprofitt

+0

죄송합니다. 질문을 명확하게 업데이트했습니다. 내 문제는 (코드는 대부분 괜찮아 지지만) Save/Discard/Cancel 대화 상자는 반복적으로 나온다. 목록을 편집하지 않아도 마찬가지다. –

+0

음 ... 나는 이것을 재현하지 않습니다. 'onUiEngineAttached'에서 내용을로드하는 것뿐만 아니라 화면 생성자에 목록을 추가한다고해서 화면이 더러워지는 것은 아닙니다. 그래서 종료시 화면이 더러워지지 않기 때문에 Save/Discard/Cancel 대화 상자가 표시되지 않습니다. 그리고 대화 상자를 얻지 못하기 때문에'save()'가 호출되지 않기 때문에'save()'에서 더티 상태를 바꿀 지 여부는 중요하지 않습니다. 따라서 질문은 "목록을 편집하지 않을 때 화면을 더러워지게 만드는 이유는 무엇입니까?" –

답변

0

setDirty (false)는 사용자가 나중에있는 경우 더티 플래그를 지 웁니다.

+0

감사합니다.하지만 setDirty (false)를 saveData()에 넣으면 앱이 종료시 저장/취소/취소 대화 상자를 표시하기 시작합니다. –

+0

그 이유는 아마도 저장 데이터가 호출 될 때까지 프로그램이 이미 저장을 결정하는 논리를 거치고 사용자에게 메시지를 표시하기 때문일 수 있습니다. 팝업을 피하려면 사용자가 화면을 종료하기 전에 플래그를 지워야합니다. – Richard

+0

감사합니다. 내 실제 문제를 알아 냈습니다. MainScreen 제목 영역에 KeywordFilterField가 있으며, 이로 인해 더티 비트가 Screen.onClose()가 보이면 더티 비트가 무시됩니다. 내 자신의 _dirty 변수를 소개하고이 문제를 해결하기 위해 내 자신의 onClose() 처리기를 작성했습니다. –