Processing: Sketches – Your Multi-Programs

When you start Processing, you get an editor with a sketch name. You will probably want another name for your program, a name that means something. So, to change the name generated by the tool, you choose file->save as. Choose a name, and the tool will create a folder with that name, and a file named <name>.pde.

When you run your sketch – by clicking the button with the triange or selecting ‘sketch->Run …’ (Run In Browser, Run on Device, Run In Emulator, Run, etc. Depending on the mode) – Processing will parse the ‘.pde’ files and the program used for running will create an instance each time you run it.

Setup and Draw

If you want have things to do upon initiation of your program, define a function named ‘void setup()‘.  To size your canvas call size(width, height). It is recommended to use ‘size’ only once in the setup function, and the whole sketch. A setup command is not called in run time. It is recommended to set the frame rate inside the setup function by calling ‘frameRate(rate)‘, the rate is the number of time the function ‘draw()‘ is supposed to be call every second. If you want an action to take place each time a frame changes, write a “draw” function in one of  your ‘.pde’ files.

More Than Just Pure Processing

Sometimes, pure Processing is not enough for your application. For example, sound functions do not exist in pure Processing. There are libraries, such as Maxim,  that extend Processing.

Another reason to use more than pure Processing is will to use native widgets (HTML elements, Android Menus & Dialogs, etc.). In pure Processing, you would have to draw the button and detect in the ‘mouseClicked‘ function if the mouse pointer is inside the button.

Here’s a little video example of using the android menu to change the number of polygon sides:

In addition, I’ve created a Javascript module, and added buttons to the HTML page displayed when running in Javascript mode.

The following sections will explain how to do it.

 The Common Part: Just Draw a Polygon

The sommon part that draws the polygon is found in a ‘.pde’ file in the ‘polygon’ sketch directory. The function ‘draw’ detects changes in the global variable n, the number of sides.

The functions ‘translate’ and ‘rotate’ make drawing rotated shapes and lines easier.

In addition, the module contains a call to a function named ‘alert’. This function exists in Javascript, so I’ve made another in the Android module using Toasts.

Following is the code:

// This program draws a regular polygon with n sides.
int n;
float halfVertexAngle; // Will be used for moving from the center
                      // of the sreen to a vertex of the polygon.
                                          
float rotateAngle;     

void set_no_of_sides(int inputN){
  if (inputN < 3){
    alert("Polygons must have at least 3 sides. Try again");
    return;
  }
  n=inputN;
  halfVertexAngle = radians(180) / n; 
  rotateAngle = radians(360./n);
}

void setup(){
  //size(640,480);
  set_no_of_sides(8);
  background(0xffffff00);
  strokeWeight(1);
}

void draw(){
    background(0xffffff00);

  // Center coordinates of the screen and circumbscribed circle.

  int centerX = width / 2;
  int centerY = height / 2;
  
  
  float radius = min(width / 2, height/2);  // The radius of the circumscribed circle.
 
  // Use the cosine theorem to find the length of a side. 
  float side = sqrt(2 * radius * radius * (1 - cos(2 * halfVertexAngle)));
  
  translate(centerX, centerY);  // Move the origin of axes to the center of the screen.
  rotate (-halfVertexAngle);    // Rotate the axes to find the first vertex without
                                // dealing with trigonometry.
  translate(0, radius);
  rotate(halfVertexAngle);      // Rotate back to make the first side horizontal.
  
  for (int i=0; i<n; i ++){
    line(0,0,-side,0);
    translate(-side,0);
    rotate(rotateAngle);
  }
}

The Android Module

I found that in my Linux system Android files are created in the ‘/tmp’ directory. Processing Android mode generates an extension of the class PApplet from your pde files. The good news is that PApplet extends the android Activity class, which makes adding event handlers easy.

Additional functions to a class extending PApplet should be written in a separate pde file. Following is the extension’s code:

import android.os.Bundle;
import android.widget.Toast;
import android.view.Menu;
import android.view.MenuItem;
import android.app.AlertDialog;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.content.DialogInterface;

AlertDialog.Builder alertDialog=null;

public void alert(String text){
  Toast toast=Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
  toast.show();
}

public void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  
}

 public boolean onCreateOptionsMenu (Menu menu){
   super.onCreateOptionsMenu (menu);
   menu.add(Menu.NONE, 37, Menu.NONE, "Change Number of sides");
   return true;
 }
 
 private void createAlertDialog(){
     // Create a dialog to change the number of polygon sides.
  alertDialog = new AlertDialog.Builder(this);
  alertDialog.setTitle("Polygon Settings");
  alertDialog.setMessage("Enter number of polygon sides:");
  final EditText input = new EditText(polygon.this);
  LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.MATCH_PARENT,
                                    LinearLayout.LayoutParams.MATCH_PARENT);
  input.setLayoutParams(lp);
  alertDialog.setView(input);
  alertDialog.setPositiveButton("Accept",
    new DialogInterface.OnClickListener(){
      public void onClick(DialogInterface dialog, int which){
        int numberParsed;
        try {
          numberParsed = Integer.parseInt(input.getText().toString());
          set_no_of_sides(numberParsed);
        } catch (NumberFormatException ex){
          alert("Not an integer. Try again.");
        }
      }
    });

  alertDialog.setNegativeButton("Cancel",
    new DialogInterface.OnClickListener(){
      public void onClick(DialogInterface dialog, int which){
      }
    });

 }
 
 public boolean onMenuItemSelected(int featureId, MenuItem menuitem){
   super.onMenuItemSelected(featureId, menuitem);
   switch (menuitem.getItemId()){
     case 37:
       createAlertDialog();
       alertDialog.show();
       break;
     default:
       break;
   }
   return true;
 }

Notes:

  • If you have an Android module, but you want to run in another mode, renaming the Android mode’s pde file with a ‘.bak’ extension is recommended.
  • If the Android module is not installed, you can install it from a Processing editor window, by selecting <mode button> -> Add more…

Javascript Functions & Changes to the HTML Page

You can change the appearance of your output HTML page by editing the file <sketch-name>/template/template.html . If the file and directory do not exist yet, you can create them by choosing “Javascript->Start Custom Template”. If they do exist use “Javascript-.Show Custom Template”.

For example, I’ve added a button in the HTML template as follows:

<input type="button" value="Change Number of Sides" onclick="get_no_of_sides(this);" />

In addition, I’ve added an ‘onload’ event to change the size of the canvas after the polygon object is created. This function works fine in my favorite browser, Firefox. Fortunately, from ‘.js’ module one can call ‘size’ to resize the canvas:

    <body onload="new_size(640, 480);">

From this page you can learn about accessing Processing from Javascript.

Following is my javascript code defined in ‘js_functions.js’:

function new_size(w, h){
  var divElement=document.getElementById('content');
  divElement.addEventListener("DOMSubtreeModified", function(event, func){
    if (window.Processing.getInstanceById("polygon")){
      divElement.removeEventListener("DOMSubtreeModified", arguments.callee);
      divElement.style.width = w + "px";
      window.Processing.getInstanceById("polygon").size(w,h);
    }
  });

function get_no_of_sides(obj){

  var k=prompt("How many sides?");
  var num=Number(k);
  if (isNaN(num) || num != parseInt(k)){
    alert("Please type an integer");
    return;
  }

  this.Processing.getInstanceById('polygon').set_no_of_sides(num);
}

Now, when you run your application, the product will be found in ‘<sketch-name>/web-export’.
Learn more about Javascript modules here.

JSON, The New XML

When you write for the web, you may want to send data to another server or to a client. A common way to transfer that data is in XML format. The data will then be processed using SAX, DOM or XPath. Every language support it.

If what you want is to define a variable, an object or an array in Javascript, you can use the JSON extension. JSON is an acronym for ‘Java Script Object Notation’. In Javascript you can use it as follows:

var myObject=<?php echo json_encode($php_object); >;

Here no parsers are required.

Here’s an example of using it in PHP:

<?
class my_class {
  public $prop1;
  public $prop2;

  function __construct(){
    $this->prop1='a';
    $this->prop2=400;
  }
}

$obj=new my_class();
echo json_encode($obj);
?>

The output looks like:
{“prop1″:”a”,”prop2″:400}

In addition to encoding, a JSON string can be decoded into an object in a language other than Javascript. Thus, you can pass data in the JSON format to any program supporting JSON, and, as you can see in www.json.org, most languages used today support it.

The ability to encode varibles into JSON and decode it back in any language is not the only reason why JSON can replace XML. If you go to www.json.org, you can see links in the bottom referring to other sites. For example, JSONPath, that allows you to access a member just like XPath. JSONPath is available in PHP and Javascript.