Two years ago I developed a sketch that could be run from PDE or from the command line (processing-java) – optionally with arguments. I wanted the sketch to know which way it had been run (PDE or command line).
That worked up to 3.4 – When run from PDE the output contains “–external” and the flag is set.
processing.core.PApplet --location=1213,185 --external --display=1 --sketch-path=/Users/student/Downloads/Test Test
Now, in 3.5.3, that method isn’t working anymore. When run from PDE, the “external” flag is missing.
processing.core.PApplet --display=1 --sketch-path=/Users/student/Downloads/Test Test
Any idea why / how this might have happened? Is it a bug / regression, or a change in Processing, or the bundled Java? I’m not even sure where to start looking.
A (non) update: I have an issue open on this, but I have never managed to track down which commit changed this behavior, where in the source code. At some point may need to just remove this feature from the JavaDoc documentation if it can’t be fixed…
Thanks for bringing this to the topics!
I will be using processing command-line in the future.
This is my first pass at this and “green” background from command-line launch and “red” from PDE launch:
//https://forum.processing.org/two/discussion/23999/detect-command-line-invocation-of-a-sketch
// 2019-08-25
// Modified to check for external argument only!
/**
* CommandLineDetect
* 2017-09-21 Jeremy Douglass - Processing 3.3.6
* Was a sketch run from PDE, or from the command line?
* If from the command line, what are its arguments and their values?
*
* Invoke it:
* 1. from the command line above the sketch folder, with no arguments:
* processing-java --sketch=`pwd`/CommandLineDetect --run
* 2. ...or with arguments:
* processing-java --sketch=`pwd`/CommandLineDetect --run foo bar=baz lorem="ipsum dolor sit amet, consectetur adipiscing elit" etc
* 3. or form PDE
*
* The sketch relies on the --external flag to detect a PDE launch, as per:
* - processing.github.io/processing-javadocs/core/processing/core/PApplet.html#main-java.lang.String:A-
*
* The command line passes in a String[] of args. If you wish to arguments of the:
* - form foo=bar
* - lorem="ipsum dolor"
*
* Related forum discussions:
* - forum.processing.org/two/discussion/23999/detect-command-line-invocation-of-a-sketch
* - forum.processing.org/two/discussion/23924/handling-command-line-arguments-in-a-sketch
* - forum.processing.org/two/discussion/6457/how-to-use-arguments-with-an-application-built-with-processing
*/
// Some editing by GLV. See original (above) for the complete version.
boolean PDE;
StringDict argDict = new StringDict();
color setBack = 0;
String str1;
void setup()
{
// Local command-line arguments for testing:
// String [] args = {"external", "foo", "bar=baz", "lorem=ipsum dolor sit amet, consectetur adipiscing elit", "etc"};
println(args == null ? "null" : args);
if (args == null)
str1 = "internal";
else
str1 = args[0];
if (str1.equals("external"))
{
PDE=true;
setBack = color(0, 255, 0);
}
else
{
PDE=false;
setBack = color(255, 0, 0);
}
// load command line arguments, load them
if (args != null)
{
for (String arg : args)
{
String[] entry = split(arg, "=");
if (entry.length == 1)
{
argDict.set(entry[0], "");
}
if (entry.length == 2)
{
argDict.set(entry[0], entry[1]);
}
}
}
// set default if specific arg not present
if (!argDict.hasKey("xyzzy")) {
println("Setting default for xyzzy");
// ...do something
}
// demonstrate using arguments
for (String arg : argDict.keyArray()) {
switch(arg) {
case "external":
//arg external
println("mode:", arg);
break;
//case "foo":
// // key only arg
// println("mode:", arg);
// // ...do something
// break;
case "bar":
// key=value arg
println("Setting", arg, "=", argDict.get(arg));
// ...do something
break;
case "lorem":
// parsed value
String parsed = join(sort(argDict.get(arg).split(" ")), " ");
println("Sorting", arg, "=", parsed);
// ...do something
break;
}
}
//exit();
}
void draw()
{
background(setBack);
}
Really glad that this is helpful and useful to you. Looking forward to what you do with it.
When I developed this it was for Edger, a Processing sketch that could be invoked in two ways –
from PDE, where it created a user interface for researchers to processing sparse edglist files into network graphs
from the command line, so a Jekyll static site generator could batch process hundreds of network graphs for a website without launching the graphical interface.
Because the command line was invoking a batch-process mode, I wanted to the PDE version to launch-and-wait (for user input), and the command line version to launch-and-run (with optional command-line arguments). That was the original use case for detecting “how was I launched?” When it could be done automatically, that was elegant. But you are right – explicitly passing it a flag “external” (or perhaps “batch” in my use-case) is a solid workaround.
Just a few minutes ago, I discovered that System.getProperty("sun.java.command").split(" ") returns an array of length one, where the first argument is the sketch class’s name. Only the PDE adds the --display and the --sketch-path flags in. This is perhaps a helpful discovery, since one can now simply check if the other two arguments .contain() those exact flags. We could also add an extra argument for when the sketch runs outside the PDE, and run it only with that argument outside the PDE.