在代号一中,获取给定类型的所有组件的通用方法

In Codename One, generic method to get all Components of a given type

我知道在代号一中我​​可以使用如下递归方法获取给定类型(及其子类型)的所有组件:

recursiveSearch(Display.getInstance().getCurrent());

public void recursiveSearch(Container cnt) {
    for (Component cmp : cnt.getChildrenAsList(true)) {
        if (cmp instanceof Label) {
            // for debugging
            Log.p(cmp.toString());
        } else if (cmp instanceof Container) {
            recursiveSearch((Container) cmp);
        }
    }
}

我的问题是我想概括这种类型的搜索,因为我在开发过程中经常使用它。

这就是为什么我为此目的编写了一个包含两个静态方法的新 class。但我的代码与之前的 recursiveSearch 并不完全相同,因为它没有 return 子类型。例如,如果我要查找所有 Label,我希望也会得到 Button,因为 ButtonLabel。但事实并非如此:使用以下代码,我将仅获得 Label 的实例,而不是 Label 的子 class 实例。

你能帮我解决一下吗?谢谢

我知道这个问题更多的是指通用 Java 而不是 代号一,但是它的用途是特定于代号一的。

public class Selector extends ComponentSelector {

    /**
     * Returns a Set of Components of the given type.
     *
     * @param <T>
     * @param type
     * @return
     */
    public static <T extends Component> Set<T> $(Class<T> type) {
        return Selector.$(type, null);
    }

    /**
     * Returns a Set of Components of the given type, searching for them in the
     * children of the given Container.
     *
     * @param <T>
     * @param type
     * @param root
     * @return
     */
    public static <T extends Component> Set<T> $(Class<T> type, Container root) {
        Set<T> result = new LinkedHashSet<>();
        if (root == null) {
            root = Display.getInstance().getCurrent();
            if (root == null) {
                throw new IllegalStateException("Selector.$(Class<T> type) invoked without a shown Form");
            }
        }
        for (Component cmp : root.getChildrenAsList(true)) {
            if (cmp.getClass().isAssignableFrom(type)) {
                result.add((T) cmp);
            } else if (cmp instanceof Container) {
                result.addAll(Selector.$(type, (Container) cmp));
            }
        }

        return result;
    }

}

测试示例:

Log.p(Selector.$(Label.class).toString());

你不应该转这个:

cmp.getClass().isAssignableFrom(type)

为此:

type.isAssignableFrom(cmp.getClass())

这是我用来做这件事的包装函数。

    /**
     * Find set of specific type of component in subtree rooted at root container.
     * @param <T> The type of the component to find.
     * @param type The class of the component to find.
     * @param root The root from which to search
     * @return A set of components of the given type.
     */
    public static <T> Set<T> select(Class<T> type, Container root) {
        return (Set<T>) $("*", root).filter(c -> {
            return type.isAssignableFrom(c.getClass());
        });
    }

注意,ComponentSelector 的 filter() 方法几乎已经完成了所有工作。用一个有类型参数的方法包装它只会让它使用起来更方便。