October 23, 2009

How to make Processing work from within a Java Application

ProcessingWindowScreenSnapz001.png

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.

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();
    }

}
Posted by djp3 at 9:10 AM | Comments (0) | TrackBack (0)