Processing
pde sketches get pre-processed to java
Part of the attraction of processing is that it hides a lot of java boilerplate stuff from the user. In vanilla processing all sketches get pre-processed to java prior to compilation:-
So sketch_161005a.pde (an auto-named sketch in the processing ide), gets transformed as follows.
MyClass var; void setup() size(200, 200); var = new MyClass(23); > void draw() background(255, 0, 0); fill(0, 0, 200); ellipse(100, 100, 90, 120); > class MyClass float var; MyClass(float var) this.var = var; > >
See the generated java code below, note all those imports , the class wrapper , and that MyClass becomes a java inner class. Also note that size has moved to settings (the processing guys decided not make this change from processing-2.0 to processing-3.0 explicit, in propane and propane we do expect size to be in settings).
import processing.core.*; import processing.data.*; import processing.event.*; import processing.opengl.*; import java.util.HashMap; import java.util.ArrayList; import java.io.File; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; public class sketch_161005a extends PApplet MyClass var; public void setup() var = new MyClass(23); > public void draw() background(255, 0, 0); fill(0, 0, 200); ellipse(100, 100, 90, 120); > class MyClass float var; MyClass(float var) this.var = var; > > public void settings() size(200, 200); > static public void main(String[] passedArgs) String[] appletArgs = new String[] "sketch_161005a" >; if (passedArgs != null) PApplet.main(concat(appletArgs, passedArgs)); > else PApplet.main(appletArgs); > > >
java reflection gets used a lot in processing
It is an unfortunate truth that java reflection methods are popular with both processing developers and some developers of supporting libraries. It is unfortunate because we have to go through hoops to use these methods in propane (and ruby-processing). The captureEvent and videoEvent are examples of reflection methods from the processing video developers. But we have made these readily available to propane users as a simple library load load_library :video_event . This is what you would do (if we had not created the video_event library):-
- create a java class VideoInterface
- compile the java class (including classpath)
- create a jar (and place it in the same folder as your sketch)
- modify the sketch to both require the jar and to include the interface.
VideoInterface.java
package monkstone.videoevent; import processing.video.Movie; import processing.video.Capture; /** * This interface makes it easier/possible to use the reflection methods * from Movie and Capture classes in Processing::App in propane * @author Martin Prout */ public interface VideoInterface /** * Used to implement reflection method in PApplet * @see processing.video.Movie * @param movie Movie */ public void movieEvent(Movie movie); /** * Used to implement reflection method in PApplet * @see processing.video.Capture * @param capture Capture */ public void captureEvent(Capture capture); >
To match packaging the java file needs to be nested in monkstone/videoevent folders (it is unwise not to have a package) and compile and jar as follows, requires jdk11+.
# NB: classpath needs to be a fully qualified path to jars (not as below) javac -cp video.jar:core.jar monkstone/videoevent/VideoInterface.java jar -cvf video_event.jar monkstone
See below a sketch which using this VideoEvent interface, see the version using the propane provided :video_event library here
black_white_capture.rb
require 'propane' require_relative 'video_event' class BlackAndWhiteCapture Propane::App load_libraries :video include_package 'processing.video' include Java::MonkstoneVideoevent::VideoInterface attr_reader :cam, :my_shader def setup sketch_title 'Black & White Capture' @my_shader = load_shader('bwfrag.glsl') start_capture(width, height) end def start_capture(w, h) @cam = Capture.new(self, w, h) cam.start end def draw image(cam, 0, 0) return if mouse_pressed? filter(my_shader) end # using snake case to match java reflection method def captureEvent(c) c.read end def settings size(960, 544, P2D) end end BlackAndWhiteCapture.new
Now where this knowledge becomes really useful, is when you want to use another library, say the vanilla processing carnivore library whose packetEvent method also depends on java relection. Here is a suitable CarnivoreListener class.
CarnivoreListener.java
package monkstone; /* * Best to use a package to avoid namespace clashes, create your own */ public interface CarnivoreListener /* * @param packet the CarnivorePacket, a reflection method */ public void packetEvent(org.rsg.carnivore.CarnivorePacket packet); >
Which we compile as before
# NB: classpath needs to be a fully qualified path to jar (not as below) javac -cp carnivore.jar monkstone/CarnivoreListener.java jar -cvf carnivore_listener.jar monkstone
Here is an example sketch:-
carnivore1.rb
# A Simple Carnivore Client -- print packets in Processing console # # Note: requires Carnivore Library for Processing (https://r-s-g.org/carnivore) # # + Windows: first install winpcap (https://winpcap.org) # + Mac: first open a Terminal and execute this commmand: sudo chmod 777 /dev/bpf* # you need to do this each time you reboot Mac # + Linux: run with difficulty (run with sudo rights arghh. ) also install libpcap require 'propane' class CarnivoreListener Propane::App load_library :carnivore include_package 'org.rsg.carnivore' java_import 'org.rsg.lib.Log' require_relative 'carnivore_listener' include Java::Monkstone::CarnivoreListener attr_reader :c def settings size(600, 400) end def setup sketch_title 'Carnivore Example' background(255) @c = CarnivoreP5.new(self) Log.setDebug(true) # comment out for quiet mode # c.setVolumeLimit(4) #limit the output volume (optional) # c.setShouldSkipUDP(true) #tcp packets only (optional) end def draw end # Called each time a new packet arrives def packetEvent(p) puts(format('(%s packet) %s > %s', p.strTransportProtocol, p.senderSocket, p.receiverSocket)) # puts(format('Payload: %s', p.ascii)) # puts("---------------------------\n") end end CarnivoreListener.new
Another example of reflection usage the vanilla processing selectInput utility, that enable use of the native file chooser:-
Native File Chooser
What a native file chooser sketch looks like in java, the selectInput callback relies on java reflection under the hood. We have to explicity provide such a signature to use this feature in propane hence FileChooser library.
public class chooser extends PApplet public void setup() selectInput("Select a file to process:", "fileSelected"); > public void fileSelected(File selection) if (selection == null) println("Window was closed or the user hit cancel."); > else println("User selected " + selection.getAbsolutePath()); > > static public void main(String[] passedArgs) String[] appletArgs = new String[] "chooser" >; if (passedArgs != null) PApplet.main(concat(appletArgs, passedArgs)); > else PApplet.main(appletArgs); > > >
Processing pde to java
“Processing is a flexible software sketchbook and a language for learning how to code within the context of the visual arts. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology. There are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning and prototyping.”—from Processing.org
I want to preprocess my sketch directly to .java, so that I can compile the sketch using ‘javac’ in the terminal.
No, I don’t want to compile the sketch from the terminal, I want to view the sketch after is converted into straight java code.
Please and thank you to anyone who has managed this. I’m working from a macosx machine for the record.
Edit: Yes, I could export my sketch since that also creates a java file, but I can’t independently compile it using «javac» since it requires the classpath implied by processing-java export pipeline.
EDIT2: I was not able to accomplish exac tly what I was looking for, but I went with the Eclipse guide provided by the Processing.org, since I need to learn the IDE anyway.
I exported the project for MacOSX, and in the exported package contained the raw Java. The first line «import processing.core.*;» was added, and then literally all my Processing code was contained inside a PApplet(Processing Applet) class. This means the PApplet library itself is where structs like color() live.
Credit to @remy_porter for the recommendation.