1
votes

So, I have an Android App with two classes, A and B. The logic for the back-command is set up in class A and works as expected: the button action shows Form B and the the Escape button brings Form A back.

Now, after loading the form in Class B, I need to "reload" it. I do this by creating a new Form, calling the whole class again, via a button.

In the process, the back-command ceases to work (and the command button to appear in the toolbar), since all the components (toolbar, form, etc.) are newly created, and lack the definitions from Class A.

My question: is it possible to define the back-command logic inside Class B, instead of in Class A, so that the back-command still works after reloading Class B, or somehow define references to Class A to make it work?

Below is the code I already have. Many thanks in advance fro any kind suggestions.

public class ClassA {

    private Command back; 
    private ClassB classB;
    private Form current;
    private Resources theme;
    private  Form formA;
    private Button button = new Button("Go forward");

    public void loadA() {

        showBack();

        formA = new Form("Old Form", BoxLayout.y());            
        classB = new ClassB();

        button.addActionListener(l -> {

            classB = new ClassB();
            classB.formB.getToolbar().setBackCommand(back);
            classB.formB.setBackCommand(back);

            classB.goBack();

            Button buttonToolbar = classB.formB.getToolbar().findCommandComponent(back);

            FontImage image = FontImage.createMaterial(FontImage.MATERIAL_10K, "test", 4);
            buttonToolbar.setIcon(image);


        });

        formA.add(button);
        formA.show();
    }

    public void showBack() {

        back = new Command("Back") {
                @Override
                public void actionPerformed(ActionEvent evt) {
                        formA.showBack();
                }
        };
    }

}

public class ClassB {

    public ClassA classA = new ClassA();
    public Form formB = new Form("New Form", BoxLayout.y());
    private Button buttonReload = new Button("Reload");

    public void reload () {

        buttonReload.addActionListener(l -> {

            ClassB classB = new ClassB();
            classB.reload();

            // I want to recreate the back-command logic here in Class B. 
            // The below doesn't work. 

            formB.getToolbar().setBackCommand(new Command("back"));

        });

        formB.add(buttonReload);
        formB.show();

    }

}
2

2 Answers

1
votes

I don't follow the logic exactly but if you dynamically update form instances maybe you should just move the navigation logic to a central class e.g. navigation manager which can also invoke the logic of the form creation when necessary e.g.:

interface DynamicForm {
    public String getFormName();
    public Form createFormInstance();
}


public class NavigationManager {
    // ...
    public void register(DynamicForm df) {
        formRegistryMap.put(df.getFormName(), df);
    }

    public void clearFormCache() {
        formCache.clear();
    }

    public Form getFormInstance(String formName) {
        Form formCache = formCache.get(formName);
        if(formCache != null) {
            return formCache;
        }
        formCache = formRegistryMap.get(formName).createFormInstance();
        formCache.put(formName, formCache);
        return formCache;
    }
    // ...
}
1
votes

Below is the mechanism that I use. Is that what you are asking?

public class A extends Form {
    public A() {
        super("A"); // set title
        Button b = new Button("B");
        b.addActionListener((ActionListener) (ActionEvent evt) -> {
            new B(this).show();
        });
        add(b);
    }
}

public class B extends Form {
    public B(Form a) {
        super("B"); // set title
        Command back = new Command("A") {
            @Override
            public void actionPerformed(ActionEvent evt) {
                a.showBack();
            }
        };
        getToolbar().setBackCommand(back);
    }
}

Assuming Toolbar.setGlobalToolbar(true). Actually my code for setBackCommand is a bit more elaborate:

getToolbar().setBackCommand(back,
    Toolbar.BackCommandPolicy.WHEN_USES_TITLE_OTHERWISE_ARROW); 
Button backButton = getToolbar().findCommandComponent(back); 
FontImage.setMaterialIcon(backButton,
    ios() ? FontImage.MATERIAL_ARROW_BACK_IOS
          : FontImage.MATERIAL_ARROW_BACK);

I assume that after a.showBack() form B is eligible for garbage collection. If the above mechanism is not correct then I am very interested to learn what the correct mechanism is (Shai?).

Edit: Or without extending class Form:

void showA() {
    Form a = new Form("A");
    Button b = new Button("B");
    b.addActionListener((ActionListener) (ActionEvent evt) -> {
        showB(a);
    });
    a.add(b);
    a.show();
}

void showB(Form a) {
    Form b = new Form("B");
    Command back = new Command("A") {
        @Override
        public void actionPerformed(ActionEvent evt) {
            a.showBack();
        }
    };
    b.getToolbar().setBackCommand(back);
    b.show();
}