knowledge-kitchen

The Processing Framework (in Java)

You’ve baked a really lovely cake, but then you’ve used dog shit for frosting.

―Steve Jobs, critiquing a designer’s work

  1. Overview
  2. Installation
  3. Run a Program
  4. Lifecycle Methods
  5. Animation
  6. Inherited Functions
  7. Adding Sounds
  8. Responding to Events
  9. Conclusions

Overview

Concept

Processing is a code framework for animation. It is also the name of a non-profit foundation that attempts to teach programming and spread software literacy.

Installation

Concept

Processing consists of a few Java ARchive (.jar) files that you can import into your code.

Download Processing

Go to the Processing web site and download the appropriate version for your system.

Install Java SE 8

Processing currently only works with Java 8 (a.k.a 1.8). If you are running a more recent version of Java, you must downgrade to Java SE version 8.

Set Up Visual Studio Code

Processing can be integrated into the popular Visual Studio Code IDE relatively simply.

  "java.configuration.runtimes": [
      {
        "name": "JavaSE-1.8",
        "path": "THE_PATH_TO_JDK_8",
        "default": true
      }
  ],

Set Up Visual Studio Code (continued)

We now install Processing’s core.jar file as a dependency of a new Java project.

{
  "java.project.sourcePaths": ["src", "test"],
  "java.project.outputPath": "bin",
  "java.project.referencedLibraries": ["lib/**/*.jar"]
}

Set Up Visual Studio Code (continued again)

We must now select Java 8 as the Java runtime to use for this new Java project.

At this point, we are ready to write Java code using the Processing library.

Run a Program

What we need to do in code

To use Processing, you must…

Starter code

For example, enter the following starter code within the src/fb1258 directory in a file named MyClass.java.

package fb1258;

import processing.core.*;

public class Circle extends PApplet {
    public void settings() {
  		this.size(600, 400); // open a window that is 600x400, diameter=100
    }
    public void setup() {
    }
    public void draw() {
		  this.ellipse(250, 150, 100, 100); // draw an ellipse at x=250, y=150
    }
    public static void main(String[] args) {
  		PApplet.main("fb1258.Circle"); // this String must match exactly this class's package and class name
    }
}

On syntax

You will note in our starter code that we use the this keyword as a prefix when referring to instance methods and instance properties. This is good code style.

this.ellipse(250, 150, 100, 100);
ellipse(250, 150, 100, 100);

Run it!

Run this program - if it works, you are in good shape!

Lifecycle Methods

Concept

The three methods we added to our code are automatically called by PApplet’s code at certain times in the life of the program.

Animation

Concept

In frame-based animation, objects are redrawn in rapid succession at slightly different locations on the screen in order to give the illusion of movement.

package fb1258;
import processing.core.*;
public class CircleSliding extends PApplet {

  private int x = 250; // starting x position of ellipse
  private int y = 150; // starting y position of ellipse

  public static void main(String[] args) {
    PApplet.main("fb1258.CircleSliding");
  }
  public void settings() {
    this.size(600, 400); /* open a window that is 600x400 */
  }
  public void draw() {
    this.background(0, 0, 0); // fill screen with black (R,G,B = 0,0,0)
    this.fill(255, 255, 255); // paint with white (R,G,B = 255,255,255)
    this.ellipse(this.x, this.y, 100, 100); // draw ellipse with fill color
    this.x++; // next time draw ellipse at slightly different location
    this.y++;
  }
}

Inherited functions

Drawing

PApplet bestows a variety of useful functions upon our custom class, including many functions for drawing shapes to the screen.

Colors

There are several color-related properties that can be set using several appropriately-named functions…

… and much more

These were just the easy functions to get started with.

Adding Sounds

Overview

An additional sound library can be added to a project to provide sophisticated audio functionality.

Playing Sounds (continued)

An example of a program that plays a sound when the user clicks.

package fb1258;

import processing.core.*;
import processing.sound.*; // note this additional import

public class CircleWithSound extends PApplet {
    private SoundFile soundClick; // will refer to a sound file to play
    public void settings() {
  		this.size(600, 400); // open a window that is 600x400, diameter=100
    }
    public void setup() {
      // assuming you have created an audio file named thump.mp3 and placed it within a sounds subdirectory of your project
      this.soundClick = new SoundFile(this, "sounds/thump.mp3"); // if you're on Windows, you may have to change this file path to "sounds\\thump.mp3"
    }
    public void draw() {
		  this.ellipse(250, 150, 100, 100); // draw an ellipse at x=250, y=150
    }
    public void mouseClicked() {
      this.soundClick.play(); // play the sound!
    }
    public static void main(String[] args) {
  		PApplet.main("fb1258.CircleWithSound"); // this String must match exactly this class's package and class name
    }
}

Responding to Events

Mouse clicks

Processing’s code can automatically call a function in your code anytime the user clicks a mouse.

public void mouseClicked() {
  System.out.printf("clicked at %d, %d\n", this.mouseX, this.mouseY);
}

Other mousing around

Processing will also call other functions you define for a variety of other mouse-driven events.

Keyboard events

Processing can respond to various keyboard-driven events if you define functions to handle them.

if (this.keyCode == UP) { /* ... */ }

Multiple Classes

One window, please

When writing programs that use the Processing library, we must have a custom class that inherits from PApplet. But what do we do when we have more than one custom class?

Passing around PApplet

It might be the case that you desire to use one of PApplet’s functions from within a class that does not inherit from PApplet.

Passing around PApplet (continued)

Define one class that inherits from PApplet, and have it pass itself to the other objects.

// ... insert the package and import statements here...
public class App extends PApplet {

  private Circle circle; // a custom class we will define
  private Rectangle rectangle; // a custom class we will define

  // ... insert the main method and settings method go here.

  public void setup() {
    // instantiate the two objects... notice we pass *this*
    this.circle = new Circle(100, 100, this);
    this.rectangle = new Rectangle(100, 100, this);
  }

  public void draw() {
    // have the two objects draw themselves to the screen
    this.circle.draw();
    this.rectangle.draw();
  }
}

Passing around PApplet (continued again)

Within the Circle and Rectangle class constructors, we accept an App object that we caan use to draw to the screen.

// ... insert the package statement and any imports here ...
public class Circle {
  private int x; // the x coordinate of this object
  private int y; // the y coordinate of this object
  private App app; // a property that will hold an App object, which inherits from PApplet

  // notice that we accept an App object into the constructor and store it into this object
  public Circle(int x, int y, App app) {
    this.x = x; // ideally we would use a setter that performs some validation
    this.y = y; // ideally we would use a setter that performs some validation
    this.app = app; // this is the trick - store the App object!
  }

  public void draw() {
    this.x = this.x + 2 // change the x coordinate a bit
    this.app.ellipse(this.x, this.y, 100, 100); // using PApplet's draw method!
  }

}

Conclusions

Hopefully this has been a pleasant foray into creating frame-based animations in Java using the Processing framework.