Search code examples
javacodenameone

Codename One: i want to send a JsonArray to the server using a Hashtable in connection request


I am building an app that will be submitting the details of your siblings to the database. MY idea is since i dont know number of your children, i just have a floating button that am using to call a class that adds a contaner with some textFields to be filled.

so I have like a Form here....

private Button btnSubmit;
    private Container cnt_box;
public class ChildrenForm extends Form
    {
        private List<Child> listofchildren;
        
        public ChildrenForm()
        {
            super("CHILDREN DETAILS",BoxLayout.y());
            FloatingActionButton fab=FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);
            fab.bindFabToContainer(this);
            fab.addActionListener((e) -> addNewChild());
            getToolbar().addMaterialCommandToRightBar("", FontImage.MATERIAL_CLEAR_ALL, (e) -> 


          clearAll());
         btnSubmit=new Button("Submit");
         cnt_box = new Container(new BoxLayout(BoxLayout.Y_AXIS));
            cnt_box.add(btnSubmit);
            add(cnt_box);
        }
    //....here i have some other methods...
}

i have a method to enable the editing here....

public void edit()
            {
                txtname.startEditingAsync();
                txtname3.startEditingAsync();
                txtbirth.startEditingAsync();
                txtdbirth.startEditingAsync();
            }

the floatingAction Button calls this method here....

public void addNewChild()
        {
            Childdetails td=new Childdetails("","","","",false);
            add(td);
            revalidate();
            td.edit();
        }

that method now called this class which i want to take the details showing this container.....

public class Childdetails extends Container
        {
            private TextField txtname;
            private TextField txtname3;
            private TextField txtbirth;
            private TextField txtdbirth;
            private CheckBox done=new CheckBox();
            private Container cnt_child;

            public Childdetails(String name,String name3,String birthcertno,String dateofbirth ,boolean checked)
            {
                super(new BorderLayout());

                 cnt_child=new Container();

                        cnt_child.addComponent(new Label("First Name"));
                        txtname = new TextField(name);
                        txtname.setHint("First Name");
                        cnt_child.addComponent(txtname);

                        cnt_child.addComponent(new Label("Surname"));
                        txtname3 = new TextField(name3);
                        txtname3.setHint("Surname");
                        cnt_child.addComponent(txtname3);

                        cnt_child.addComponent(new Label("Birth Certificate/Notification No"));
                        txtbirth = new TextField(birthcertno);
                        txtbirth.setHint("Birth Certificate No:");
                        cnt_child.addComponent(txtbirth);

                        cnt_child.addComponent(new Label("Date of Birth"));
                        txtdbirth = new TextField(dateofbirth);
                        txtdbirth.setHint("dd/MM/yyyy");
                        cnt_child.addComponent(txtdbirth);

                add(CENTER,cnt_child);
                add(LEFT,done);
                done.setSelected(checked);
            }
            public void edit()
            {
                txtname.startEditingAsync();
                txtname3.startEditingAsync();
                txtbirth.startEditingAsync();
                txtdbirth.startEditingAsync();
            }
            public boolean isChecked(){
               return done.isSelected();
            }
            public String getText(){
               return txtname.getText();
            }
        }

this is the method which am using to delate any selected container....but i understand its because of that save method......

private void clearAll()
        {
            int cc=getContentPane().getComponentCount();
            for(int i=cc-1; i>=0; i--)
            {
                Childdetails t=(Childdetails)getContentPane().getComponentAt(i);
                if(t.isChecked())
                {
                    t.remove();
                }
            }
            save();
            getContentPane().animateLayout(300);
        }

the save method....which after following some tutorial i believe its saving the taken data.... here

private void save()
        {
            listofchildren = new ArrayList<>();
            Childdetails detail=new Childdetails("","","","",false);
            Child child=new Child()
                    .name.set(detail.getText())
                        .name3.set(detail.getText())
                        .birthcertno.set(detail.getText())
                        .dateofbirth.set(detail.getText())
                        .checked.set(detail.isChecked());
            listofchildren.add(child);
            
            PropertyIndex.storeJSONList("child.json", listofchildren);
        }

i also have a class i constructed following certain tutorial to save the data.....here

public class Child implements PropertyBusinessObject
        {
            public final Property<String,Child> name=new Property<>("firstname","");
            public final Property<String,Child> name3=new Property<>("Surname","");
            public final Property<String,Child> birthcertno=new Property<>("BirthCertNo","");
            public final Property<String,Child> dateofbirth=new Property<>("dateofbirth","");
            public final BooleanProperty<Child> checked=new BooleanProperty<>("checked", false);

            private final PropertyIndex idx=new PropertyIndex(this,"Todo", name, name3, birthcertno, dateofbirth, checked);

            @Override
            public PropertyIndex getPropertyIndex(){
                return idx;
            }

now my main main problem... i just want when that submit button is pressed, to send the filled details..... i tried this,,,

btnSubmit.addActionListener(new ActionListener() 
            {
                @Override
                public void actionPerformed(ActionEvent evt) 
                {
                    Log.p("Button pressed", 1);
                     save();
                     Log.p("data saved...", 1);
                    if(existsInStorage("child.json"))
                    {
                        Log.p("loading data ...", 1);
                        
                        listofchildren=new Child().getPropertyIndex().loadJSONList("child.json");
                        
                        String NationalID=Storage.getInstance().readObject("NationalID").toString();
                        String UserName=Storage.getInstance().readObject("UserName").toString();
                        
                        Hashtable hash=new Hashtable();
                        hash.put("ChildDet", listofchildren);
                        
                        hash.put("ReadIdCopy", NationalID);
                        hash.put("UserName",UserName);

                        final Result res=Result.fromContent(hash);
                        final String checkthis=res.toString();
                            //--------check url......
                        String myUrl="http://localhost:50111/AddChildren";
                        String Reply="";
                        
                        requestclass c=new requestclass(); 
                        try {
                            Reply=c.checking(checkthis,myUrl);
                            } catch (IOException ex) {
    //                            Logger.getLogger(AddChildren.class.getName()).log(Level.SEVERE, null, ex);
                            } catch (requestclass.JSONException ex) {
    //                            Logger.getLogger(AddChildren.class.getName()).log(Level.SEVERE, null, ex);
                            }
                         if(Reply.equals("SuccesfullyRecieved"))
                        {
                            Dialog.show("SuccesfullyRecieved", "Details Succesfuly Recieved", "OK", null);
                             /*----redirect---*/
                            nextofkin nkin=new nextofkin();
                            nkin.nxtofkscreen();
                        }
                        else if(Reply.equals("sorry"))
                        {
                            Dialog.show("SORRY!!!", "Seems their is a problem updating Next of kin details... try again", "OK", null);
                        }
                        else
                        {
                            Dialog.show("Error", "Something went wrong, try checking your connection and try again later.", "OK", null);
                        } 
                    }
                    else
                    {
                        ToastBar.showErrorMessage("Sorry, no data to submit....");
                    }
                }
            });

i dont know how to do it,,,, also my save method has some errors...please help me out, thanks in advance


Solution

  • This is caused by this line:

    Childdetails t=(Childdetails)getContentPane().getComponentAt(i);
    

    What you are doing here is looping over all the components in the content pane and downcasting them to Childdetails.

    This is bad. You don't check instanceof which would be helpful. You might have other problems but this line:

    add(cnt_box);
    

    Specifically adds a non Childdetails component to the content pane (doing add without a context on a Form implicitly adds to the content pane).

    Also about startEditingAsync. This is wrong.

    This isn't the way to make them visible.

    Notice your code adds a lot of components before the form is shown and uses animateLayout on these instances. This is probably why things aren't visible since you do that on a Form that isn't shown yet (from the constructor) and so the animation "runs" without any effect. The components are probably in the wrong area.

    I suggest removing that whole block of startEditingAsync and also try:

    if(getContentPane().isInitialized()) {
        getContentPane().animateLayout(300);
    }