Skip to content

Type Representations FAQ

Michael Hoffer edited this page Jul 20, 2016 · 34 revisions

#####How can I make directories (and possibly only directories) selectable in the "load-dialog" representation style?

Use the "load-folder-dialog"style.

#####Is it possible to supply a keyword=value option for the "selection" representation style which will select a specific index of the given selectables, e.g.: options="selected=1"?

No (not yet, anyway).

#####How can I access automatically generated UI elements from the function whose arguments define them? (Examples: Correct unreasonable parameters provided by the user; enable/disable elements depending on a checkbox)

A VRL component can request access to UI elements. Since the current version of VRL (0.4.2.x) uses Swing as UI toolkit one can use everything provided by Swing, e.g., enable/disable UI elements.

NOTE Interacting with the UI directly is not recommended! Only use it if absolutely necessary. Future versions of VRL may use a different UI toolkit (we have plans to migrate from Swing to JavaFX). Compatibility is not guaranteed!

Example 1: (Accessing Object Representations)

@ComponentInfo(name="Object Representation Sample", category="Custom")
class ObjectRepresentationSample implements Serializable {

  private static final long serialVersionUID=1;

    @OutputInfo(name="Object Name")
    public String accessUI(ObjectRequest oReq){
      
      DefaultObjectRepresentation d = oReq.getObject();
      d.setBorder( VSwingUtil.createDebugBorder() )
      return oReq.getObject().getName();
    }
}

[[resources/img/accessing-orep-01.png|alt=
Accessing Object Representations|align=center|width=450px]]

Example 2: (Accessing Method Representations)

@ComponentInfo(name="Method Representation Sample", category="Custom")
class MethodRepresentationSample implements Serializable {

  private static final long serialVersionUID=1;

    @MethodInfo(valueName = "MethodName", hide=false)
    public String accessUI(MethodRequest mReq){

      DefaultMethodRepresentation mRep = mReq.getMethod();
      mRep.setSelected(true)
      
      return mReq.getObject().getName();
    }

    @MethodInfo(hide=false)
    public void anotherMethod() {}
}

[[resources/img/accessing-mrep-01.png|alt=
Accessing Method Representations|align=center|width=450px]]

Example 2: (Accessing Type Representations)

@ComponentInfo(name="Type Representation Sample", category="Custom")
class TypeRepresentationSample implements Serializable {

  private static final long serialVersionUID=1;

    @MethodInfo(valueName="Input Value", hide=false)
    public String accessUI(MethodRequest mReq, 
    @ParamInfo(name="", style="default", options="value=1") int value){

      DefaultMethodRepresentation mRep = mReq.getMethod();

      // param 0 = mReq, param 1 = value
      TypeRepresentationBase tRep = mRep.getParameter(1)
      tRep.setSelected(true)
      
      return tRep.getValue();
    }

    @MethodInfo(hide=false)
    public void anotherMethod() {}
}

[[resources/img/accessing-trep-01.png|alt=
Accessing Type Representations|align=center|width=450px]]

What does the method getValueAsCode() exactly do? Should every custom type representation provide it?

The method getValueAsCode() returns the code fragment that is necessary to create an instance of the represented type that is eqivalent to the visual state of the type representation, e.g., the content of a text field.

This is necessary to allow VRL-Studio to create source code that is equivalent to a visually defined component.

Example: (click here to download the VRL project)

[[resources/img/code-generation-01.png|alt=
Visual Component|align=center|width=450px]]

Here is the corresponding source code that describes the visually defined workflow:

public void run(  ) {
    
    // instances
    eu.mihosoft.vrl.user.AddIntegers obj0 = new eu.mihosoft.vrl.user.AddIntegers();
    eu.mihosoft.vrl.user.SampleClass obj1 = new eu.mihosoft.vrl.user.SampleClass();

    // variable declarations
    java.lang.Integer v0 = null;

    // method calls
    obj1.println( "Hello" );
    v0 = obj0.add( 2, 3 );
    obj0.add( v0, 1 );

}

The getValueAsCode() method is necessary to transform the string and the numbers to a code representation. Even though it looks simple the process is not trivial. For example, the string may contain special characters such as " that need to be escaped.

getValueAsCode() implementation for String values that escapes special characters:

@Override
public String getValueAsCode() {
    return "\""
            + VLangUtils.addEscapesToCode(getValue().toString()) + "\"";
}

For complex types it's necessary to call a constructor or a factory method.

NOTE If the method does not create valid code this will damage the VRL project! Always carefully design and test your implementations of this method!

A complex Example:

Consider the following value class:

public class DataObj {
  private int[] data;

  public DataObj(int[] data) {
    this.data = data;
  }

  public int[] getData() {
      return this.data;
  }

  // ...
}

The getValueAsCode() method might look like this:

@Override
public String getValueAsCode() {
    
    // type checked in getValue() method
    DataObj obj = (DataObj) getValue();

    if(obj==null) {
      return "null";
    }

    StringBuilder sb = new StringBuilder();
    
    sb.append("new DataObj([");
    
    for (int i = 0; i < obj.data.length; i++) {
        if (i > 0) {
            sb.append(", ");
        }
        sb.append(obj.data[i]);
    }
    
    sb.append("] as int[])");
    
    return VLangUtils.addEscapesToCode(sb.toString());
}

NOTE: If the string generation is very complex it is advised to add that functionality to a constructor or factory method, e.g. DataObjFactory.newDataObj("1,2,3") or to create a code generator (if the value object is used by different type representations): String code = CodeGenerator.generateCode(dataObj)

How to get the class a TypeRepresentation represents?

The TypeRepresentation class is annotated with a @TypeInfo. The reflection API gives access to this information. The following example does this for the IntegerType representation.

Class<?> representedType = IntegerType.class.getAnnotation(TypeInfo.class).type()