示例#1
0
  /**
   * Loads a design for the given root component.
   *
   * <p>This methods assumes that the component class (or a super class) has been marked with an
   * {@link DesignRoot} annotation and will either use the value from the annotation to locate the
   * design file, or will fall back to using a design with the same same as the annotated class file
   * (with an .html extension)
   *
   * <p>Any {@link Component} type fields in the root component which are not assigned (i.e. are
   * null) are mapped to corresponding components in the design. Matching is done based on field
   * name in the component class and id/local id/caption in the design file.
   *
   * <p>The type of the root component must match the root element in the design
   *
   * @param rootComponent The root component of the layout
   * @return The design context used in the load operation
   * @throws DesignException If the design could not be loaded
   */
  public static DesignContext read(Component rootComponent) throws DesignException {
    // Try to find an @DesignRoot annotation on the class or any parent
    // class
    Class<? extends Component> annotatedClass =
        findClassWithAnnotation(rootComponent.getClass(), DesignRoot.class);
    if (annotatedClass == null) {
      throw new IllegalArgumentException(
          "The class "
              + rootComponent.getClass().getName()
              + " or any of its superclasses do not have an @DesignRoot annotation");
    }

    DesignRoot designAnnotation = annotatedClass.getAnnotation(DesignRoot.class);
    String filename = designAnnotation.value();
    if (filename.equals("")) {
      // No value, assume the html file is named as the class
      filename = annotatedClass.getSimpleName() + ".html";
    }

    InputStream stream = annotatedClass.getResourceAsStream(filename);
    if (stream == null) {
      throw new DesignException(
          "Unable to find design file "
              + filename
              + " in "
              + annotatedClass.getPackage().getName());
    }

    Document doc = parse(stream);
    DesignContext context = designToComponentTree(doc, rootComponent, annotatedClass);

    return context;
  }
示例#2
0
 /**
  * Loads a design from the given file name using the given root component.
  *
  * <p>Any {@link Component} type fields in the root component which are not assigned (i.e. are
  * null) are mapped to corresponding components in the design. Matching is done based on field
  * name in the component class and id/local id/caption in the design file.
  *
  * <p>The type of the root component must match the root element in the design.
  *
  * @param filename The file name to load. Loaded from the same package as the root component
  * @param rootComponent The root component of the layout
  * @return The design context used in the load operation
  * @throws DesignException If the design could not be loaded
  */
 public static DesignContext read(String filename, Component rootComponent)
     throws DesignException {
   InputStream stream = rootComponent.getClass().getResourceAsStream(filename);
   if (stream == null) {
     throw new DesignException(
         "File "
             + filename
             + " was not found in the package "
             + rootComponent.getClass().getPackage().getName());
   }
   return read(stream, rootComponent);
 }
示例#3
0
 /**
  * Constructs a component hierarchy from the design specified as an html tree.
  *
  * <p>If a component root is given, the component instances created during reading the design are
  * assigned to its member fields based on their id, local id, and caption
  *
  * @param doc the html tree
  * @param componentRoot optional component root instance. The type must match the type of the root
  *     element in the design. Any member fields whose type is assignable from {@link Component}
  *     are bound to fields in the design based on id/local id/caption
  */
 private static DesignContext designToComponentTree(Document doc, Component componentRoot) {
   if (componentRoot == null) {
     return designToComponentTree(doc, null, null);
   } else {
     return designToComponentTree(doc, componentRoot, componentRoot.getClass());
   }
 }
示例#4
0
  private void bindEventHandler(
      Component componentRoot, Object controller, Method method, UiHandler eventListener) {
    String componentId = eventListener.value();
    Component component = Clara.findComponentById(componentRoot, componentId);
    if (component == null) {
      throw new BinderException("No component found for id: " + componentId + ".");
    }

    Class<?> eventType =
        (method.getParameterTypes().length > 0 ? method.getParameterTypes()[0] : null);
    if (eventType == null) {
      throw new BinderException("Couldn't figure out event type for method " + method + ".");
    }

    Method addListenerMethod = getAddListenerMethod(component.getClass(), eventType);
    if (addListenerMethod != null) {
      try {
        Object listener =
            createListenerProxy(
                addListenerMethod.getParameterTypes()[0], eventType, method, controller);
        addListenerMethod.invoke(component, listener);
        // TODO exception handling
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (IllegalArgumentException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
示例#5
0
    @Override
    public String componentToTag(Component component, DesignContext context) {
      Class<?> componentClass = component.getClass();
      String packageName = componentClass.getPackage().getName();
      String prefix = context.getPackagePrefix(packageName);
      if (prefix == null) {
        prefix = packageName.replace('.', '_');
        context.addPackagePrefix(prefix, packageName);
      }
      prefix = prefix + "-";
      String className = classNameToElementName(componentClass.getSimpleName());
      String tagName = prefix + className;

      return tagName;
    }