Skip to content

Additional annotations

These additional annotations can be used alongside primary annotations to provide additional configuration for a field or method.


@interface ID {
  String value();

Override the default ID for a port or control.


// default id would be screen-width
@P(1) @ID("width") int screenWidth; 


@interface OnChange {
  String value();

Specify a method to run when a property value changes. Especially useful for knowing when a background loading resource is ready. The method should take no arguments and return void.


@P(1) @OnChange("reconfigure") double scale;

void reconfigure() {
  // do something when scale changes


@interface OnError {
  String value();

Specify a method to run when setting a property fails. Especially useful for situations where background loading a resource fails. The method should take no arguments and return void.


@P(1) @OnError("imgError") PImage img;
@AuxOut(2) Output error;

void imgError() {


@interface Port {
  boolean value();

Control the creation of a port. Currently only used to suppress the creation of ports for properties and triggers.


@P(1) @Config.Port(false) PImage img;
@T(1) @Config.Port(false) void reset() {
  // reset stuff


@interface ReadOnly {}

Specify a property is read only. No port will be created. Attempts to set the property via its control will fail. The field can still be set in code and read via the control.


@P(5) @ReadOnly int length;


@interface Transient {}

Mark a property as transient, meaning the current value will not be saved in the project. Useful for continuously changing values (eg. media position)


@P(2) @Type.Number(min = 0, max = 1) @Transient
double position;


@interface Type {
  Class<? extends Value> value() default Value.class;
  String[] properties() default {};
  String def() default "";

Specify a property as any sub-type of Value. Arbitrary info properties can also be provided, and the default value as its String representation.


@P(4) @Type(ControlAddress.class) Property to;


@interface Type.Boolean {
  boolean def() default false;

Specify a property is a boolean, with optional default value.


@P(4) @Type.Boolean(def = true) render;


@interface Type.Integer {
  int min() default PNumber.MIN_VALUE;
  int max() default PNumber.MAX_VALUE;
  int def() default 0;
  int[] suggested() default {};

Specify a property is an integer with optional range and default value. An array of suggested values can be provided, providing a select box in the editor.


@P(2) @Type.Integer(min = 1, max = 10, def = 1)
int count;


@interface Type.Number {
  double min() default PNumber.MIN_VALUE;
  double max() default PNumber.MAX_VALUE;
  double def() default 0;
  double skew() default 1;

Specify a property is numeric (double) with optional range and default value. Ranged numeric properties will show as a slider in the property editor.

The skew value is used to alter the behaviour of sliders - eg. use a value of 2 or 4 to make the slider more suitable for frequency or volume. Technically the normalised range of the slider (0..1) is raised to the power of skew.


@P(1) @Type.Number(min = 0, max = 360) Property rotation;
@P(2) @Type.Number(min = 0, max = 1, def = 0.5) double position;


@interface Type.String {
  String[] allowed() default {};
  boolean emptyIsDefault() default false;
  String mime() default "";
  String def() default "";
  String template() default "";

Specify a property is a string, with optional default value. The emptyIsDefault parameter will cause the word default to show in the editor when the value is an empty string.

If the allowed array is not empty, the property will act like an enumeration, providing a select box in the editor.

The mime type may be set to control editing / syntax highlighting, and the template may be used to specify text to use in the editor when the value is empty.


@P(1) @Type.String(allowed = {"Blend", "Add", "Multiply"})
String blendMode;
@P(1) @Type.String(mime = GLSL_FRAGMENT_MIME, template = DEFAULT_FRAGMENT_SHADER)
String fragment;