【问题标题】:Codemane One call Back Command from second Class代号第二类的一个回调命令
【发布时间】:2020-05-09 16:41:25
【问题描述】:

所以,我有一个带有 A 和 B 两个类的 Android 应用程序。返回命令的逻辑在 A 类中设置并按预期工作:按钮操作显示 Form B,而 Escape 按钮带来 Form A返回。

现在,在 B 类中加载表单后,我需要“重新加载”它。我通过创建一个新表单,通过一个按钮再次调用整个类来做到这一点。

在此过程中,后退命令停止工作(命令按钮出现在工具栏中),因为所有组件(工具栏、表单等)都是新创建的,并且缺少 A 类的定义。

我的问题:是否可以在 B 类而不是 A 类中定义后退命令逻辑,以便在重新加载 B 类后后退命令仍然有效,或者以某种方式定义对 A 类的引用以使其工作?

下面是我已经拥有的代码。非常感谢您的任何建议。

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();

    }

}

【问题讨论】:

    标签: codenameone back


    【解决方案1】:

    以下是我使用的机制。你问的是这个吗?

    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);
        }
    }
    

    假设 Toolbar.setGlobalToolbar(true)。实际上我的 setBackCommand 代码更详细一点:

    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);
    

    我假设在 a.showBack() 之后表单 B 有资格进行垃圾收集。如果上述机制不正确,那么我很想知道正确的机制是什么(Shai?)。

    编辑:或不扩展类形式:

    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();
    }
    

    【讨论】:

    • 酷,这正是我的想法......优雅的解决方案与几行代码。谢谢。
    • 还有一个疑问:是否可以在不使用构造函数的情况下添加后退命令?
    • 请参阅我的回答中的编辑。是这个意思吗?
    • 是的,就是这样......非常感谢你的努力......除了CN1之外,这给了我。还对 Java 的工作原理有了新的见解
    【解决方案2】:

    我没有完全遵循逻辑,但是如果您动态更新表单实例,也许您应该将导航逻辑移动到中心类,例如导航管理器,它也可以在必要时调用表单创建的逻辑,例如:

    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;
        }
        // ...
    }
    

    【讨论】:

    • 感谢您发布这个详尽的答案。我发现实现起来有点困难,只是通过调用新类而不是再次调用表单来完全避免丢失返回函数。我不得不删除相关组件,但编写的代码更少。但我会将导航管理器放在手边以备将来使用。
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多