在Codename One中,这是获取给定类型的所有Components的通用方法

时间:2019-05-07 13:46:02

标签: codenameone

我知道在Codename One中,我可以使用如下递归方法获得给定类型(及其子类型)的所有组件:

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

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

这就是为什么我为此编写了一个带有两个静态方法的新类的原因。但是我的代码与先前的recursiveSearch并不完全等效,因为它不返回子类型。例如,如果我正在寻找所有的Label,那么我期望也能得到Button,因为ButtonLabel。但是事实并非如此:通过以下代码,我将仅获得Label的实例,而这些实例不是Label的子类的实例。

您能帮我解决吗?谢谢

我知道这个问题所指的是泛型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());

2 个答案:

答案 0 :(得分:1)

你不应该转动这个吗?

cmp.getClass().isAssignableFrom(type)

对此:

type.isAssignableFrom(cmp.getClass())

答案 1 :(得分:1)

这是我用来完成此操作的包装函数。

    /**
     * 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()方法几乎可以完成所有操作。用具有类型参数的方法将其包装起来,使用起来更加方便。