Processing in BlueJ/Greenfoot

I know this gets asked from time to time and I’ve gone through all the instructions I can find (this did work once upon a time but …)

Some background: I teach a high school CS2 course in object oriented design and we start out with Processing. At some point, BlueJ becomes a better environment for what I want to accomplish but I also want to leverage all the cool graphics we have done up to that point. So, we switch to BlueJ.

I know about importing the various Processing libraries and where to find them (I’m on OS X) and I know about extend PApplet and using settings() instead of just setup().

However when I have the following:

import processing.core.PApplet;

public class P3Test extends PApplet
{

public void settings() {
    size(800, 600, P3D);
}

}

I still get the error telling me to put size() inside of settings. This happens immediately upon creating a P3Test object and invoking the settings() method as per typical BlueJ use. This is occurring based on the most recent BlueJ v5.0 and Processing 3.5.4.

Any guidance would be greatly appreciated.

PcF

If that is really happening it suggests there is a bug. As you may know the only way processing managed to keep size inside setup in a pde file, is to pre-process the pde file as in settings_demo.pde

void setup() {
  size(200, 200);
}

void draw() {
  background(255, 0, 0);
}

gets pre-processed to

/* autogenerated by Processing revision 1272 on 2021-03-23 */
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 settings_demo extends PApplet {

 public void setup() {
  /* size commented out by preprocessor */;
}

 public void draw() {
  background(255, 0, 0);
}


  public void settings() { size(200, 200); }

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "settings_demo" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

So you should be able to run the java sketch from BlueJ (providing you set up CLASSPATH)

Yeah, I thought this should work. The full version of source in BlueJ that I am attempting to run is:

/**

  • Write a description of class P3Test here.
  • @author (your name)
  • @version (a version number or a date)
    */
    import processing.core.PApplet;

public class P3Test extends PApplet
{

public void settings() {
    size(800, 600);
}

public void setup() {
    
    background(0);
    
}

public void draw() {
    background(64);
    ellipse(mouseX, mouseY, 20, 20);
}

public static void main(String[] args) {
    String[] processingArgs = {"MySketch" };
    P3Test p3Test = new P3Test();
    PApplet.runSketch(args, p3Test);
}

}

I get the error whether I invoke settings(), setup or run main without first creating the P3Test object manually.

I haven’t tried to do this for a couple of years and there have been a few updates of Processing, BlueJ and Java.

I guess my first question is: given that I have imported the core, gluegen, jna. jogl, pde and ant libraries from Processing, this should work, right?

I’m not too familiar with BlueJ but somehow you need the relevant jars on your classpath (possibly that’s what the libraries folder is for in settings?). I can auto-magically do this sort of thing with my ruby-processing projects, java is not as convenient.

In BlueJ you add the libraries rather then adding locations to a CLASSPATH (well, I’m sure it is just internally maintaining a CLASSPATH).

The issue I’m having does not seem to be in ability to find the libraries but the error seems to be internal to Processing.

The actual error text is (note, the error implies no problem finding the library):

When not using the PDE, size() can only be used inside settings().
Remove the size() method from setup(), and add the following:
public void settings() {
size(800, 600);
}
java.lang.IllegalStateException: size() cannot be used here, see size() \ Language (API) \ Processing 3+
at processing.core.PApplet.insideSettings(PApplet.java:949)
at processing.core.PApplet.size(PApplet.java:2018)
at P3Test.settings(P3Test.java:26)

I guess I need to try this in something like Eclipse and see if this is something strange in the interaction with BlueJ or something that has changed inside Processing.

In the source for PApplet.java there is a function insideSettings that checks if the use of size() was done inside an override of the settings() function when not using the PDE.

settings() is an empty public void that the user needs to override.

So far so good.

But how does the boolean insideSettings ever get set to true? It isn’t a public variable. It seems to be set to true by the function handleSettings() but that is also private. Basically it seems like the boolean intended to ensure a user is using settings() when external to the PDE is not, and can’t be, set too true.

At least, that’s my reading of the source.

Should the abstract version of settings() have

public void settings() {
insideSettings = true;
}
and then the proper use outside of the PDE would be to override settings:

public void settings() {
super.settings();
size(800, 600);
}

PcF

/**

  • param method “size” or “fullScreen”

  • param args parameters passed to the function so we can show the user

  • return true if safely inside the settings() method
    */
    boolean insideSettings(String method, Object… args) {
    if (insideSettings) {
    return true;
    }
    final String url = “Language Reference (API) \ Processing 3+” + method + “_.html”;
    if (!external) { // post a warning for users of Eclipse and other IDEs
    StringList argList = new StringList(args);
    System.err.println(“When not using the PDE, " + method + “() can only be used inside settings().”);
    System.err.println(“Remove the " + method + “() method from setup(), and add the following:”);
    System.err.println(“public void settings() {”);
    System.err.println(” " + method + “(” + argList.join(”, “) + “);”);
    System.err.println(”}");
    }
    throw new IllegalStateException(method + "() cannot be used here, see " + url);
    }

  • Override this method to call size() when not using the PDE.

*/
public void settings() {
// is this necessary? (doesn’t appear to be, so removing)
//size(DEFAULT_WIDTH, DEFAULT_HEIGHT, JAVA2D);
}

Do you have to use bluej because there are other ide with development capability which work with processing ie vs code and eclipse and intellij

I’ve got bluej installed on my RaspberryPI (albeit version 4.2.1) and I got it to run OK with processing-3.5.3 jars.

Is it me or is that BlueJ is a bit cookie in that you need to click on the class diagram, then on the main method to get it to run? Also when I checked possibility of installing BlueJ 5.0 on the RaspberryPI that’s a no go, because of javafx requirement which is only available for 32 bit so I can’t install right version on ManjaroArm (64 bit), and BlueJ 5.0 is only available for 64 bit. I have zero interest in installing BlueJ on my linux box, where I use netbeans and atom to develop ruby-processing and processing projects.

handleSettings() wraps the call to the settings() hook method - eg. processing/core/src/processing/core/PApplet.java at master · processing/processing · GitHub This ensures that the boolean is set correctly around a valid call to settings(). This is a common design pattern for this. It suggests something is calling settings() at the wrong time?

Unlikely perhaps, but does changing "MySketch" to "P3Test" in processingArgs make any difference? Processing does expect that to be the class name.

Glad to see someone appreciates the IDE I put too much of my spare time into (looks at @paulgoux ! :smile:) There was code to work directly with BlueJ projects inside NetBeans - looks like that might have gone astray in the Apache transition for now.

Monk, you don’t have to but that is the way one normally invokes methods. You can also simply invoke main() if you have one (which isn’t necessary). That’s actually the answer to paulgoux. I use BlueJ as a teaching environment to explore object oriented design process not as an efficient development environment to get to the end result. It serves a real purpose with high school students in making all the bits and pieces of OOP more concrete and less abstract, magical, incantations. It is particularly helpful with the whole coupling/cohesion topic and abstract classes and inheritance. I can also use the Greenfoot version to explore agent based modeling. It’s all part of a course sequence that uses Racket, Java, Python, Matlab and systems dynamics programming. There is a twisted logic. Twisted, but it’s there.

This did work with earlier versions of Processing/BlueJ so it is possible … must be doing something wrong (COVID threw all my courses off their stride and trying to get things back in sync is proving … difficult)

Thanks all.

PcF

p.s. Monk, I need to inspect handleSettings more carefully because I didn’t see how that was getting invoked. I did download the source free so I can try to understand how this is meant to work under the hood. That may take me a bit …

2 Likes

Monk,

Could you share your exact main()? I’m doing something wrong in how I wrote it and I’m just not seeing what it is.

public static void main(String[] args){
String[] processingArgs = {“MySketch”};
MySketch mySketch = new MySketch();
PApplet.runSketch(processingArgs, mySketch);
}

I dropped back to BlueJ4.2.2 and Processing 3.5.3 but still no joy so I’m being stupid somewhere here.

public static void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "settings_test" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }

Just to close out this thread: after some months of frustration, using the libraries from the Processing 4 Beta did the trick. No fuss, no muss. All you need is add the core.jar, pde.jar and the various jog libraries from Processing to your BlueJ Prefs->Libraries

Use monkstone’s example static main above and be sure to use both a void settings() to hold size() and void setup as you normally would.

Works a charm.

Thanks to all for the dialog some months back!

2 Likes