October 23, 2009
How to make Processing work from within a Java Application
I was having a hard time getting the Processing graphics environment to work as a Java Application. Basically I wanted to use Processing as a quick way to embed some graphics into my existing java program, but quickly found out it was not trivial. I am programming in Java in the Eclipse environment and the problem that I had was that the Processing window, created in the way that seemed obvious to me, was too small. I couldn't figure out how to resize it from within the code. Even the setup(x,y) command didn't work. When I manually resized it all the drawing functions got screwed up and nothing got rendered. After investigating the "present" mode that is available I looked at the Processing source code and figured out why the "present" mode would create windows fine, but I couldn't create a window that worked for a regular java program. The end result was a java class that works like a normal Processing pde, but can be run from any java program. The way you get it to work is simply to call the constructor. Below I duplicate the source code for a simple processing application that draws white lines on a black background whenever you click the mouse in the window. You can take the source code and add whatever you want to it. Consider it a simple tutorial. |
ProcessingWindow.java |
import java.awt.Color; import java.awt.Frame; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.SystemColor; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import processing.core.PApplet; public class ProcessingWindow extends PApplet { private static final long serialVersionUID = -7463650683050609285L; GraphicsDevice displayDevice = null; public ProcessingWindow() { super(); // Mac OSX only System.setProperty("apple.awt.graphics.UseQuartz", "true"); Color backgroundColor = Color.BLACK; GraphicsDevice displayDevice = null; String folder = null; try { folder = System.getProperty("user.dir"); } catch (Exception e) { } if (displayDevice == null) { GraphicsEnvironment environment = GraphicsEnvironment .getLocalGraphicsEnvironment(); displayDevice = environment.getDefaultScreenDevice(); } Frame frame = new Frame(displayDevice.getDefaultConfiguration()); frame.setResizable(false); frame.setTitle(this.getClass().getCanonicalName()); final PApplet applet = this; applet.frame = frame; applet.sketchPath = folder; frame.setLayout(null); frame.add(applet); frame.pack(); applet.init(); /* Wait for applet to run setup */ while (applet.defaultSize && !applet.finished) { try { Thread.sleep(5); } catch (InterruptedException e) { } } Insets insets = frame.getInsets(); int windowW = Math.max(applet.width, MIN_WINDOW_WIDTH) + insets.left + insets.right; int windowH = Math.max(applet.height, MIN_WINDOW_HEIGHT) + insets.top + insets.bottom; frame.setSize(windowW, windowH); frame.setLocation((applet.screen.width - applet.width) / 2, (applet.screen.height - applet.height) / 2); if (backgroundColor == Color.black) { // BLACK) { // this means no bg color unless specified backgroundColor = SystemColor.control; } frame.setBackground(backgroundColor); int usableWindowH = windowH - insets.top - insets.bottom; applet.setBounds((windowW - applet.width) / 2, insets.top + (usableWindowH - applet.height) / 2, applet.width, applet.height); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); // handle frame resizing events applet.setupFrameResizeListener(); if (applet.displayable()) { frame.setVisible(true); } } public void setup() { size(500, 500); background(0); stroke(255); noLoop(); } public void draw() { color(255, 0, 0); if (mousePressed) { line(mouseX, mouseY, pmouseX, pmouseY); } } public void mousePressed() { redraw(); } public static void main(String[] args) { new ProcessingWindow(); } }