Development patterns are few rules that Zebra widely “employes”.

Declaration pattern

Zebra UI engine often makes an assumption a class can (but not necessary) implements dedicated methods with the given parameters list. The approach is actively used in event handling where you have to implement an appropriate method to start handling the given events there:

// create UI panel that handles mouse pressed events
var myComp = new zebra.ui.Panel([
    // declare mouse pressed events handler method
    function mousePressed(e) {
       ...
    }
]);

Another example is zebra UI component rendering where any component can declare “paint(…)” method to customize its “face”:

var myComp = new zebra.ui.Panel([
    // the method is invoked every time a content of the component has to 
    // be re-rendered
    function paint(g) {
        g.setColor("blue"); // set color
        g.drawLine(0,0, this.width, this.height); // draw blue diagonal 
    }
]);

Property

Zebra UI engine configures default properties value with a JSON configuration. Every time a property value has to be set Zebra tries to find the property setter method. If such method exists it is executed to populate the given property value, otherwise a field assignment is used. To detect setter method existence Zebra uses simple rule:

  • “Setter method name has to satisfy the following name convention: setPropertyname.

For instance, let’s declare class that has setter for “name” property:

var A = zebra.Class([
     // declare "name" property setter  
     function setName(name) { this.name = name; }
]);

// create "A" class instance
var a = new A();

// find and call setter to setup "name" property value 
zebra.properties( { "name" : "Test" } );
zebra.name // "Test"

One more example is an initiization of an UI component:

 
    var lab = new zebra.ui.Label("Test");
     
    // setup components properties
    lab.properties({
        color: "red",      // setColor setter will be called 
        padding: 6,        // setPadding method will be called 
        background: "gray" // setBackground method will be called
    });

Interfaces as an intention

In most cases Zebra classes implements interfaces to express an intention to be a participant in some activity or as the class indicator. For instance to make all children UI components event transparent the parent UI component has to implement “zebra.ui.Composite” interface:

// create an instance of "zebra.ui.Panel" anonymous class that implements 
// "zebra.ui.Composite" interface to make all its child component event 
//  transparent
var compositePan = new zebra.ui.Panel(zebra.ui.Composite, []);

var childPane = new zebra.ui.Panel([
     function mousePressed(e) {
         // the method will be never called if the component 
         // is inserted into compositePan
     }
]);

compositePan.add(childPane);

Interfaces itself don’t issue any extra requirements to a class that implements the interfaces. Interface is sort of marker that pitch a class. Declaration of an own interface is very simple:

var MyInterface = zebra.Interface();

You also can easily create an instance of the class that implements the given interface:

// create an instance that implements the given interface
var instance = new MyInterface();

// create an instance that implements the given interface
// and add "calculate()" class method
var instance = new MyInterface([
    function calculate() { ... }
]);

zebra.instanceOf(instance, MyInterface) // return true

// call the instance "calculate" method
instance.calculate();