Clone wiki

cp5magic / Home

What is so magic about cp5magic?

This is a little helper library for users of Processing and the popular ControlP5 GUI library (by Andreas Schlegel). Whilst both are great tools for small applications, the design approach of both is not very welcoming for slightly more complex usage scenarios, especially cases where one's data is more distributed and not all part of one large class. ControlP5 is providing some form of automatic GUI controller-to-variable mapping, however this works only for fields (variables) within the given PApplet instance to which the library is directly attached to (This is the standard anti-pattern used by most Processing libraries). Cumbersome boilerplate code is needed, if one wants to create GUI controllers for parameters stored in other classes. Furthermore, the creation of GUI controllers in general is done manually and requires repetitive code and manual placement of elements...

((Very) unfortunate) Disclaimer

It turns out Processing 1.2 isn't fully supporting Java 5 syntax as promised and plainly strips all annotations from code written in the PDE. So dear PDE users, sorry! If you're using Eclipse or another contemporary IDE you should be all set though...


This library is an attempt to remedy all of these above issues by introducing a Java annotations based approach to automatic GUI generation. By simply using a set of simple annotations for all fields desired to have a GUI controller attached to, the actual GUI creation is reduced to 2 lines of code, regardless of how many controllers will be created.

GUIManager gui=new GUIManager(new ControlP5(this));

myDataObject can be any container object with annotated fields as described below.

The GUIManager class is using the builder pattern and an extensible system to map field types to specific builders, which in turn are responsible for creating the actual ControlP5 elements. That way one can specify default mappings for any class and pick a compatible builder. So far the library supports the following types:

TypeDefault builderResulting controller
toxi.util.datatypes.FloatRangeFloatRangeBuilder or FloatRangeMinMaxBuilder1 or 2 sliders
toxi.util.datatypes.IntegerRangeIntRangeBuilder or IntRangeMinMaxBuilder1 or 2 sliders

To create custom builders, simply create a new class implementing the GUIElementBuilder interface.


Unless coordinates for a GUI element are explicitly specified, the element will be automatically positioned below the previously created one. The spacing is done dynamically and provided by the individual builder instances (e.g. a toggle will require more vertical spacing than a slider).

The createControllers() method can also take x & y start coordinates and also supports placing elements in a given ControlP5 UI tab. E.g.

void setup() {
  ControlP5 cp5=new ControlP5(this);
  GUIManager gui=new GUIManager(cp5);
  Tab tab=cp5.addTab("misc");


There're currently 3 annotations used and defined by this system:


This is the main annotation used to indicate that a GUI controller should be generated for this field. The annotation has several optional parameters to customize the default behaviour:

  • label: The label to be used for the GUI controller (if omitted, the variable name is used as label)
  • x: The X position of the GUI controller
  • y: The Y position of the GUI controller
  • builder: A class reference to a specific builder class, responsible for constructing the actual GUI controller. Can be omitted in most cases, but exists merely to provide more flexibility. If specified, it overrides the default mapping for this field type.
// mark this variable as GUI element
// (since no builder is specified the default mapping will be used)
@GUIElement(label = "wireframe mode")
public boolean isWireframe = true;


This annotation is used to define a possible value interval for float or int variables. When using the default builder, this annotation is required in addition to the standard @GUIElement one for variables of these types. The following parameters need to be specified for this annotation:

  • min possible min value
  • max possible max value
/// mark this variable as GUI element and specify value range for slider
@GUIElement(label = "number of columns")
@Range(min = 1, max = 30)
public int cols = 10;


This is a simple class-level annotation to specify the top-left position from which to automatically place GUI elements. Just like the @GUIElement class, it has an x and y parameter...

@GUIConfiguration(x=20, y=200)
public class CityConfig {
	public String btRegenerate

To init a GUI using an annotated data class like this, just use the version of createControllers() not needing x & y start coordinates:

// only specify the context object
gui.createControllers(new CityConfig());

Usage examples

Below are some typical examples how this library might be used:

// a java.util.List is a java.util.Collection and by default mapped to a Radio button group
@GUIElement(label="export format")
public List<String> formats=new ArrayList<String>();

void setup() {


  // now add a listener to this field by giving:
  // the field name,
  // the name of the handler/listener method
  // the instance of the listener (here we use the main PApplet, but could be another class too)

void selectFormat(ControlEvent e) {
  println("format: "+formats.get((int)e.value()));

Some design contexts also require to parameters to be expressed as range only and allow users to manipulate both the min/max values. The toxiclibscore package therefore contains different range types, which can be used with this library to create a pair of sliders.

// the MinMax builder will create 2 sliders: 1 to adjust the min value, the other for the max value
@GUIElement(label="block size", x=20, y=40, builder=toxi.gui.FloatRangeMinMaxBuilder.class)
public FloatRange blockSize=new FloatRange(50,100);

For more examples please see the AnnoTest demo in the repo:


The library depends on the following other projects/libraries (bundled with the source repo, but not with the release jar):

Source checkout

Simply clone this repository to get the full Eclipse project onto your machine (instructions above). Then, in Eclipse, choose:

File > Import... > Existing projects into Workspace

Contact & license

This is a PostSpectacular offering released under the GNU LPGL 2.1 (c) 2010 Karsten Schmidt

Have fun!