updated for processing 2.1.2

This commit is contained in:
Darius Morawiec
2014-05-21 12:56:42 +02:00
388 changed files with 20570 additions and 24933 deletions

View File

@@ -38,56 +38,62 @@ import processing.core.PApplet;
* <p/>
* After some further digging, this code in fact appears to be a modified
* version of Jason Pell's GPLed "Java Beautifier" class found
* <a href="http://www.geocities.com/jasonpell/programs.html">here</a>.
* Which is itself based on code from Van Di-Han Ho from
* <a href="http://www.geocities.com/~starkville/vancbj_idx.html">here</a>.
* <a href="http://web.archive.org/web/20091018220353/http://geocities.com/jasonpell/programs.html">here</a>,
* which is itself based on code from Van Di-Han Ho from
* <a href="http://web.archive.org/web/20091027043013/http://www.geocities.com/~starkville/vancbj_idx.html">here</a>.
* [Ben Fry, August 2009]
*/
public class AutoFormat implements Formatter {
private char[] chars;
private final StringBuilder buf = new StringBuilder();
private final StringBuilder result = new StringBuilder();
private int indentValue;
private boolean EOF;
private boolean a_flg, e_flg, if_flg, s_flag, q_flg;
private boolean s_if_flg[];
private boolean a_flg, if_flg, s_flag, elseFlag;
/** Number of ? entered without exiting at : of a?b:c structures. */
private int conditionalLevel;
private int pos;
// private int lineNumber;
private int s_level[];
private int c_level;
private int sp_flg[][];
private int s_ind[][];
private int s_if_lev[];
private int if_lev, level;
private int ind[];
private int paren;
private int p_flg[];
private int[][] sp_flg;
private int[][] s_ind;
private int if_lev;
/** Number of curly brackets entered and not exited. */
private int level;
/** Number of parentheses entered and not exited. */
private int parenLevel;
private int[] ind;
private int[] p_flg;
private char l_char;
private int ct;
private int s_tabs[][];
private int[][] s_tabs;
private boolean jdoc_flag;
private char cc;
private int tabs;
private char c;
private char lastNonWhitespace = 0;
private final Stack<Boolean> castFlags = new Stack<Boolean>();
private void comment() {
final boolean save_s_flg = s_flag;
private void handleMultiLineComment() {
final boolean saved_s_flag = s_flag;
buf.append(c = next()); // extra char
char ch;
buf.append(ch = nextChar()); // extra char
while (true) {
buf.append(c = next());
while ((c != '/')) {
if (c == '\n') {
// lineNumber++;
buf.append(ch = nextChar());
while (ch != '/') {
if (ch == '\n') {
// lineNumber++;
writeIndentedComment();
s_flag = true;
}
buf.append(c = next());
buf.append(ch = nextChar());
}
if (buf.length() >= 2 && buf.charAt(buf.length() - 2) == '*') {
jdoc_flag = false;
@@ -96,50 +102,65 @@ public class AutoFormat implements Formatter {
}
writeIndentedComment();
s_flag = save_s_flg;
s_flag = saved_s_flag;
jdoc_flag = false;
return;
}
private char get_string() {
char ch;
while (true) {
buf.append(ch = next());
if (ch == '\\') {
buf.append(next());
continue;
}
if (ch == '\'' || ch == '"') {
buf.append(cc = next());
while (!EOF && cc != ch) {
if (cc == '\\') {
buf.append(next());
}
buf.append(cc = next());
}
continue;
}
if (ch == '\n') {
writeIndentedLine();
a_flg = true;
continue;
}
return ch;
private void handleSingleLineComment() {
char ch = nextChar();
while (ch != '\n') {
buf.append(ch);
ch = nextChar();
}
// lineNumber++;
writeIndentedLine();
s_flag = true;
}
// /**
// * Transfers buf to result until a character is reached that
// * is neither \, \n, or in a string. \n is not written, but
// * writeIndentedLine is called on finding it.
// * @return The first character not listed above.
// */
// private char get_string() {
// char ch1, ch2;
// while (true) {
// buf.append(ch1 = nextChar());
// if (ch1 == '\\') {
// buf.append(nextChar());
// } else if (ch1 == '\'' || ch1 == '\"') {
// buf.append(ch2 = nextChar());
// while (!EOF && ch2 != ch1) {
// if (ch2 == '\\') {
// // Next char is escaped, ignore.
// buf.append(nextChar());
// }
// buf.append(ch2 = nextChar());
// }
// } else if (ch1 == '\n') {
// writeIndentedLine();
// a_flg = true;
// } else {
// return ch1;
// }
// }
// }
private void writeIndentedLine() {
if (buf.length() == 0) {
if (s_flag) {
s_flag = a_flg = false;
s_flag = a_flg = elseFlag = false;
}
return;
}
if (s_flag) {
final boolean shouldIndent = (tabs > 0) && (buf.charAt(0) != '{')
&& a_flg;
final boolean shouldIndent =
(tabs > 0) && (buf.charAt(0) != '{') && a_flg;
if (shouldIndent) {
tabs++;
}
@@ -150,9 +171,25 @@ public class AutoFormat implements Formatter {
}
a_flg = false;
}
if (elseFlag) {
if (lastNonSpaceChar() == '}') {
trimRight(result);
result.append(' ');
}
elseFlag = false;
}
result.append(buf);
buf.setLength(0);
}
private char lastNonSpaceChar() {
for (int i = result.length() - 1; i >= 0; i--) {
char c_i = result.charAt(i);
if (c_i != ' ' && c_i != '\n') return c_i;
}
return 0;
}
private void writeIndentedComment() {
@@ -170,7 +207,7 @@ public class AutoFormat implements Formatter {
jdoc_flag = true;
}
if (buf.charAt(i) == '/' && buf.charAt(i + 1) == '*') {
if (saved_s_flag && prev() != ';') {
if (saved_s_flag && getLastNonWhitespace() != ';') {
result.append(buf.substring(i));
} else {
result.append(buf);
@@ -187,18 +224,6 @@ public class AutoFormat implements Formatter {
}
private void handleSingleLineComment() {
c = next();
while (c != '\n') {
buf.append(c);
c = next();
}
// lineNumber++;
writeIndentedLine();
s_flag = true;
}
private void printIndentation() {
if (tabs < 0) {
tabs = 0;
@@ -208,7 +233,7 @@ public class AutoFormat implements Formatter {
}
final int spaces = tabs * indentValue;
for (int k = 0; k < spaces; k++) {
result.append(" ");
result.append(' ');
}
}
@@ -221,10 +246,7 @@ public class AutoFormat implements Formatter {
}
private char lastNonWhitespace = 0;
private int prev() {
private int getLastNonWhitespace() {
return lastNonWhitespace;
}
@@ -239,33 +261,32 @@ public class AutoFormat implements Formatter {
if (pos == chars.length - 1) {
EOF = true;
} else {
pos--; // reset for next()
pos--; // reset for nextChar()
}
}
private char next() {
private char nextChar() {
if (EOF) {
return 0;
return '\0';
}
pos++;
final char c;
char retVal;
if (pos < chars.length) {
c = chars[pos];
if (!Character.isWhitespace(c))
lastNonWhitespace = c;
retVal = chars[pos];
if (!Character.isWhitespace(retVal))
lastNonWhitespace = retVal;
} else {
c = 0;
retVal = '\0';
}
if (pos == chars.length - 1) {
if (pos == chars.length-1) {
EOF = true;
}
return c;
return retVal;
}
/* else processing */
private void gotelse() {
private void gotElse() {
tabs = s_tabs[c_level][if_lev];
p_flg[level] = sp_flg[c_level][if_lev];
ind[level] = s_ind[c_level][if_lev];
@@ -273,23 +294,22 @@ public class AutoFormat implements Formatter {
}
/* read to new_line */
private boolean getnl() {
private boolean readUntilNewLine() {
final int savedTabs = tabs;
char c = peek();
while (!EOF && (c == '\t' || c == ' ')) {
buf.append(next());
buf.append(nextChar());
c = peek();
}
if (c == '/') {
buf.append(next());
buf.append(nextChar());
c = peek();
if (c == '*') {
buf.append(next());
comment();
buf.append(nextChar());
handleMultiLineComment();
} else if (c == '/') {
buf.append(next());
buf.append(nextChar());
handleSingleLineComment();
return true;
}
@@ -298,7 +318,7 @@ public class AutoFormat implements Formatter {
c = peek();
if (c == '\n') {
// eat it
next();
nextChar();
// lineNumber++;
tabs = savedTabs;
return true;
@@ -327,24 +347,25 @@ public class AutoFormat implements Formatter {
public String format(final String source) {
final String normalizedText = source.replaceAll("\r", "");
final String cleanText = normalizedText
+ (normalizedText.endsWith("\n") ? "" : "\n");
final String cleanText =
normalizedText + (normalizedText.endsWith("\n") ? "" : "\n");
result.setLength(0);
indentValue = Preferences.getInteger("editor.tabs.size");
// lineNumber = 0;
q_flg = e_flg = a_flg = if_flg = false;
// lineNumber = 0;
boolean forFlag = a_flg = if_flg = false;
s_flag = true;
c_level = if_lev = level = paren = 0;
int forParenthLevel = 0;
conditionalLevel = parenLevel = c_level = if_lev = level = 0;
tabs = 0;
jdoc_flag = false;
s_level = new int[10];
int[] s_level = new int[10];
sp_flg = new int[20][10];
s_ind = new int[20][10];
s_if_lev = new int[10];
s_if_flg = new boolean[10];
int[] s_if_lev = new int[10];
boolean[] s_if_flg = new boolean[10];
ind = new int[10];
p_flg = new int[10];
s_tabs = new int[20][10];
@@ -352,10 +373,10 @@ public class AutoFormat implements Formatter {
chars = cleanText.toCharArray();
// lineNumber = 1;
EOF = false; // set in next() when EOF
EOF = false; // set in nextChar() when EOF
while (!EOF) {
c = next();
c = nextChar();
switch (c) {
default:
buf.append(c);
@@ -371,15 +392,12 @@ public class AutoFormat implements Formatter {
case ' ':
case '\t':
if (lookup("else")) {
gotelse();
elseFlag = lookup("else");
if (elseFlag) {
gotElse();
if ((!s_flag) || buf.length() > 0) {
buf.append(c);
}
// // issue https://github.com/processing/processing/issues/364
// s_flag = false;
// trimRight(result);
// result.append(" ");
writeIndentedLine();
s_flag = false;
@@ -395,9 +413,9 @@ public class AutoFormat implements Formatter {
if (EOF) {
break;
}
e_flg = lookup("else");
if (e_flg) {
gotelse();
elseFlag = lookup("else");
if (elseFlag) {
gotElse();
}
if (lookup_com("//")) {
final char lastChar = buf.charAt(buf.length() - 1);
@@ -409,18 +427,18 @@ public class AutoFormat implements Formatter {
writeIndentedLine();
result.append("\n");
s_flag = true;
if (e_flg) {
if (elseFlag) {
p_flg[level]++;
tabs++;
} else if (prev() == l_char) {
} else if (getLastNonWhitespace() == l_char) {
a_flg = true;
}
break;
case '{':
if (lookup("else")) {
gotelse();
}
elseFlag = lookup("else");
if (elseFlag) gotElse();
if (s_if_lev.length == c_level) {
s_if_lev = PApplet.expand(s_if_lev);
s_if_flg = PApplet.expand(s_if_flg);
@@ -440,9 +458,9 @@ public class AutoFormat implements Formatter {
buf.append(" ");
buf.append(c);
writeIndentedLine();
getnl();
readUntilNewLine();
writeIndentedLine();
//fprintf(outfil,"\n");
result.append("\n");
tabs++;
s_flag = true;
@@ -475,11 +493,12 @@ public class AutoFormat implements Formatter {
printIndentation();
result.append(c);
if (peek() == ';') {
result.append(next());
result.append(nextChar());
}
getnl();
readUntilNewLine();
writeIndentedLine();
result.append("\n");
result.append('\n');
s_flag = true;
if (c_level < s_level[level]) {
if (level > 0) {
@@ -497,21 +516,21 @@ public class AutoFormat implements Formatter {
case '"':
case '\'':
buf.append(c);
cc = next();
cc = nextChar();
while (!EOF && cc != c) {
buf.append(cc);
if (cc == '\\') {
buf.append(cc = next());
buf.append(cc = nextChar());
}
if (cc == '\n') {
// lineNumber++;
writeIndentedLine();
s_flag = true;
}
cc = next();
cc = nextChar();
}
buf.append(cc);
if (getnl()) {
if (readUntilNewLine()) {
l_char = cc;
// push a newline into the stream
chars[pos--] = '\n';
@@ -519,13 +538,21 @@ public class AutoFormat implements Formatter {
break;
case ';':
if (forFlag) {
// This is like a comma.
trimRight(buf);
buf.append("; ");
// Not non-whitespace: allow \n.
advanceToNonSpace();
break;
}
buf.append(c);
writeIndentedLine();
if (p_flg[level] > 0 && ind[level] == 0) {
tabs -= p_flg[level];
p_flg[level] = 0;
}
getnl();
readUntilNewLine();
writeIndentedLine();
result.append("\n");
s_flag = true;
@@ -541,26 +568,39 @@ public class AutoFormat implements Formatter {
case '\\':
buf.append(c);
buf.append(next());
buf.append(nextChar());
break;
case '?':
q_flg = true;
conditionalLevel++;
buf.append(c);
break;
case ':':
buf.append(c);
// Java 8 :: operator.
if (peek() == ':') {
writeIndentedLine();
result.append(next());
result.append(c).append(nextChar());
break;
}
if (q_flg) {
q_flg = false;
// End a?b:c structures.
else if (conditionalLevel>0) {
conditionalLevel--;
buf.append(c);
break;
}
else if (forFlag) {
trimRight(buf);
buf.append(" : ");
// Not to non-whitespace: allow \n.
advanceToNonSpace();
break;
}
buf.append(c);
if (!lookup("default") && !lookup("case")) {
s_flag = false;
writeIndentedLine();
@@ -570,26 +610,27 @@ public class AutoFormat implements Formatter {
tabs++;
}
if (peek() == ';') {
result.append(next());
result.append(nextChar());
}
getnl();
readUntilNewLine();
writeIndentedLine();
result.append("\n");
result.append('\n');
s_flag = true;
break;
case '/':
final char la = peek();
if (la == '/') {
buf.append(c).append(next());
final char next = peek();
if (next == '/') {
// call nextChar to move on.
buf.append(c).append(nextChar());
handleSingleLineComment();
result.append("\n");
} else if (la == '*') {
} else if (next == '*') {
if (buf.length() > 0) {
writeIndentedLine();
}
buf.append(c).append(next());
comment();
buf.append(c).append(nextChar());
handleMultiLineComment();
} else {
buf.append(c);
}
@@ -599,15 +640,23 @@ public class AutoFormat implements Formatter {
final boolean isCast = castFlags.isEmpty() ? false : castFlags.pop();
paren--;
if (paren < 0) {
paren = 0;
parenLevel--;
// If we're further back than the start of a for loop, we've
// left it.
if (forFlag && forParenthLevel > parenLevel) {
forFlag = false;
}
if (parenLevel < 0) {
parenLevel = 0;
}
buf.append(c);
writeIndentedLine();
if (getnl()) {
if (readUntilNewLine()) {
chars[pos--] = '\n';
if (paren != 0) {
if (parenLevel != 0) {
a_flg = true;
} else if (tabs > 0 && !isCast) {
p_flg[level]++;
@@ -630,42 +679,16 @@ public class AutoFormat implements Formatter {
}
buf.append(c);
paren++;
parenLevel++;
// isFor says "is it the start of a for?". If it is, we set forFlag and
// forParenthLevel. If it is not parenth_lvl was incremented above and
// that's it.
if (isFor) {
// TODO(feinberg): handle new-style for loops
c = get_string();
while (c != ';' && c != ':') {
c = get_string();
if (!forFlag) {
forParenthLevel = parenLevel;
forFlag = true;
}
ct = 0;
int for_done = 0;
while (for_done == 0) {
c = get_string();
while (c != ')') {
if (c == '(') {
ct++;
}
c = get_string();
}
if (ct != 0) {
ct--;
} else {
for_done = 1;
}
} // endwhile for_done
paren--;
if (paren < 0) {
paren = 0;
}
writeIndentedLine();
if (getnl()) {
chars[pos--] = '\n';
p_flg[level]++;
tabs++;
ind[level] = 0;
}
break;
} else if (isIf) {
writeIndentedLine();
s_tabs[c_level][if_lev] = tabs;

View File

@@ -48,6 +48,7 @@ public class Commander implements RunnerListener {
static final String forceArg = "--force";
static final String outputArg = "--output=";
static final String exportApplicationArg = "--export";
static final String noJavaArg = "--no-java";
static final String platformArg = "--platform=";
static final String bitsArg = "--bits=";
// static final String preferencesArg = "--preferences=";
@@ -61,38 +62,19 @@ public class Commander implements RunnerListener {
static final int EXPORT = 4;
Sketch sketch;
PrintStream systemOut;
PrintStream systemErr;
static public void main(String[] args) {
/*
if (args == null || args.length == 0) {
// System.out.println(System.getProperty("user.dir"));
args = new String[] {
"--export",
// "--build",
// "--run",
// "--present",
"--force",
// "--platform=windows",
"--platform=macosx",
"--bits=64",
"--sketch=/Users/fry/coconut/processing/java/examples/Basics/Lights/Directional",
// "--sketch=/Users/fry/coconut/sketchbook/sketchbook_libraries_test",
"--output=/Users/fry/Desktop/test-build"
};
}
*/
// Do this early so that error messages go to the console
Base.setCommandLine();
// init the platform so that prefs and other native code is ready to go
Base.initPlatform();
// make sure a full JDK is installed
Base.initRequirements();
// launch command line handler
new Commander(args);
}
@@ -107,20 +89,25 @@ public class Commander implements RunnerListener {
boolean force = false; // replace that no good output folder
// String preferencesPath = null;
int platform = PApplet.platform; // default to this platform
int platformBits = 0;
// int platformBits = 0;
int platformBits = Base.getNativeBits();
int task = HELP;
boolean embedJava = true;
// Turns out the output goes as MacRoman or something else useless.
// http://code.google.com/p/processing/issues/detail?id=1418
try {
systemOut = new PrintStream(System.out, true, "UTF-8");
systemErr = new PrintStream(System.err, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(1);
}
// File preferencesFile = Base.getSettingsFile("preferences.txt");
// System.out.println("Preferences file at " + preferencesFile.getAbsolutePath());
for (String arg : args) {
if (arg.length() == 0) {
// ignore it, just the crappy shell script
@@ -146,23 +133,28 @@ public class Commander implements RunnerListener {
} else if (arg.equals(exportApplicationArg)) {
task = EXPORT;
} else if (arg.equals(noJavaArg)) {
embedJava = false;
} else if (arg.startsWith(platformArg)) {
String platformStr = arg.substring(platformArg.length());
platform = Base.getPlatformIndex(platformStr);
if (platform == -1) {
complainAndQuit(platformStr + " should instead be " +
"'windows', 'macosx', or 'linux'.", true);
}
complainAndQuit("The --platform option has been removed from Processing 2.1.", false);
// String platformStr = arg.substring(platformArg.length());
// platform = Base.getPlatformIndex(platformStr);
// if (platform == -1) {
// complainAndQuit(platformStr + " should instead be " +
// "'windows', 'macosx', or 'linux'.", true);
// }
} else if (arg.startsWith(bitsArg)) {
String bitsStr = arg.substring(bitsArg.length());
if (bitsStr.equals("32")) {
platformBits = 32;
} else if (bitsStr.equals("64")) {
platformBits = 64;
} else {
complainAndQuit("Bits should be either 32 or 64, not " + bitsStr, true);
}
complainAndQuit("The --bits option has been removed from Processing 2.1.", false);
// String bitsStr = arg.substring(bitsArg.length());
// if (bitsStr.equals("32")) {
// platformBits = 32;
// } else if (bitsStr.equals("64")) {
// platformBits = 64;
// } else {
// complainAndQuit("Bits should be either 32 or 64, not " + bitsStr, true);
// }
} else if (arg.startsWith(sketchArg)) {
sketchPath = arg.substring(sketchArg.length());
@@ -212,7 +204,7 @@ public class Commander implements RunnerListener {
Base.removeDir(outputFolder);
} else {
complainAndQuit("The output folder already exists. " +
"Use --force to remove it.", false);
"Use --force to remove it.", false);
}
}
@@ -273,11 +265,11 @@ public class Commander implements RunnerListener {
// if (platformBits == 0) {
// platformBits = Base.getNativeBits();
// }
if (platformBits == 0 &&
Library.hasMultipleArch(platform, build.getImportedLibraries())) {
complainAndQuit("This sketch can be exported for 32- or 64-bit, please specify one.", true);
}
success = build.exportApplication(outputFolder, platform, platformBits);
// if (platformBits == 0 &&
// Library.hasMultipleArch(platform, build.getImportedLibraries())) {
// complainAndQuit("This sketch can be exported for 32- or 64-bit, please specify one.", true);
// }
success = build.exportApplication(outputFolder, platform, platformBits, embedJava);
}
}
}
@@ -289,6 +281,7 @@ public class Commander implements RunnerListener {
} catch (SketchException re) {
statusError(re);
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
@@ -316,15 +309,18 @@ public class Commander implements RunnerListener {
if (codeIndex != -1) {
// format the runner exception like emacs
//blah.java:2:10:2:13: Syntax Error: This is a big error message
// Emacs doesn't like the double line thing coming from Java
// https://github.com/processing/processing/issues/2158
String filename = sketch.getCode(codeIndex).getFileName();
int line = re.getCodeLine() + 1;
int column = re.getCodeColumn() + 1;
//if (column == -1) column = 0;
// TODO if column not specified, should just select the whole line.
// But what's the correct syntax for that?
systemErr.println(filename + ":" +
line + ":" + column + ":" +
line + ":" + column + ":" + " " + re.getMessage());
} else { // no line number, pass the trace along to the user
exception.printStackTrace();
}
@@ -363,11 +359,12 @@ public class Commander implements RunnerListener {
out.println("--present Preprocess, compile, and run a sketch full screen.");
out.println();
out.println("--export Export an application.");
out.println("--platform Specify the platform (export to application only).");
out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
out.println("--bits Must be specified if libraries are used that are");
out.println(" 32- or 64-bit specific such as the OpenGL library.");
out.println(" Otherwise specify 0 or leave it out.");
out.println("--no-java Do not embed Java. Use at your own risk!");
// out.println("--platform Specify the platform (export to application only).");
// out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
// out.println("--bits Must be specified if libraries are used that are");
// out.println(" 32- or 64-bit specific such as the OpenGL library.");
// out.println(" Otherwise specify 0 or leave it out.");
out.println();
}
@@ -391,4 +388,4 @@ public class Commander implements RunnerListener {
public boolean isHalted() {
return false;
}
}
}

View File

@@ -26,8 +26,15 @@ import java.io.*;
import java.util.*;
import java.util.zip.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import processing.app.*;
import processing.app.exec.ProcessHelper;
import processing.core.*;
import processing.data.XML;
import processing.mode.java.preproc.*;
// Would you believe there's a java.lang.Compiler class? I wouldn't.
@@ -397,7 +404,7 @@ public class JavaBuild {
throw new SketchException(ex.toString());
}
// grab the imports from the code just preproc'd
// grab the imports from the code just preprocessed
importedLibraries = new ArrayList<Library>();
Library core = mode.getCoreLibrary();
@@ -408,10 +415,21 @@ public class JavaBuild {
// System.out.println("extra imports: " + result.extraImports);
for (String item : result.extraImports) {
// System.out.println("item = '" + item + "'");
// remove things up to the last dot
int dot = item.lastIndexOf('.');
// http://dev.processing.org/bugs/show_bug.cgi?id=1145
String entry = (dot == -1) ? item : item.substring(0, dot);
// System.out.print(entry + " => ");
if (item.startsWith("static ")) {
// import static - https://github.com/processing/processing/issues/8
// Remove more stuff.
int dot2 = item.lastIndexOf('.');
entry = entry.substring(7, (dot2 == -1) ? entry.length() : dot2);
// System.out.println(entry);
}
// System.out.println("library searching for " + entry);
Library library = mode.getLibrary(entry);
// System.out.println(" found " + library);
@@ -427,7 +445,7 @@ public class JavaBuild {
// If someone insists on unnecessarily repeating the code folder
// import, don't show an error for it.
if (codeFolderPackages != null) {
String itemPkg = item.substring(0, item.lastIndexOf('.'));
String itemPkg = entry;
for (String pkg : codeFolderPackages) {
if (pkg.equals(itemPkg)) {
found = true;
@@ -435,7 +453,7 @@ public class JavaBuild {
}
}
}
if (ignorableImport(item)) {
if (ignorableImport(entry + '.')) {
found = true;
}
if (!found) {
@@ -531,6 +549,8 @@ public class JavaBuild {
if (pkg.startsWith("processing.data.")) return true;
if (pkg.startsWith("processing.event.")) return true;
if (pkg.startsWith("processing.opengl.")) return true;
// if (pkg.startsWith("com.jogamp.")) return true;
// // ignore core, data, and opengl packages
// String[] coreImports = preprocessor.getCoreImports();
@@ -1093,43 +1113,68 @@ public class JavaBuild {
File folder = null;
for (String platformName : PConstants.platformNames) {
int platform = Base.getPlatformIndex(platformName);
// Can only embed Java on the native platform
boolean embedJava = (platform == PApplet.platform) &&
Preferences.getBoolean("export.application.embed_java");
if (Preferences.getBoolean("export.application.platform." + platformName)) {
if (Library.hasMultipleArch(platform, importedLibraries)) {
// export the 32-bit version
folder = new File(sketch.getFolder(), "application." + platformName + "32");
if (!exportApplication(folder, platform, 32)) {
if (!exportApplication(folder, platform, 32, embedJava && Base.getNativeBits() == 32)) {
return false;
}
// export the 64-bit version
folder = new File(sketch.getFolder(), "application." + platformName + "64");
if (!exportApplication(folder, platform, 64)) {
if (!exportApplication(folder, platform, 64, embedJava && Base.getNativeBits() == 64)) {
return false;
}
} else { // just make a single one for this platform
folder = new File(sketch.getFolder(), "application." + platformName);
if (!exportApplication(folder, platform, 0)) {
if (!exportApplication(folder, platform, 0, embedJava)) {
return false;
}
}
}
}
/*
File folder = null;
String platformName = Base.getPlatformName();
boolean embedJava = Preferences.getBoolean("export.application.embed_java");
if (Library.hasMultipleArch(PApplet.platform, importedLibraries)) {
if (Base.getNativeBits() == 32) {
// export the 32-bit version
folder = new File(sketch.getFolder(), "application." + platformName + "32");
if (!exportApplication(folder, PApplet.platform, 32, embedJava)) {
return false;
}
} else if (Base.getNativeBits() == 64) {
// export the 64-bit version
folder = new File(sketch.getFolder(), "application." + platformName + "64");
if (!exportApplication(folder, PApplet.platform, 64, embedJava)) {
return false;
}
}
} else { // just make a single one for this platform
folder = new File(sketch.getFolder(), "application." + platformName);
if (!exportApplication(folder, PApplet.platform, 0, embedJava)) {
return false;
}
}
*/
return true; // all good
}
// public boolean exportApplication(String destPath,
// String platformName,
// int exportBits) throws IOException, RunnerException {
// return exportApplication(destPath, Base.getPlatformIndex(platformName), exportBits);
// }
/**
* Export to application without GUI. Also called by the Commander.
*/
protected boolean exportApplication(File destFolder,
int exportPlatform,
int exportBits) throws IOException, SketchException {
int exportBits,
boolean embedJava) throws IOException, SketchException {
// TODO this should probably be a dialog box instead of a warning
// on the terminal. And the message should be written better than this.
// http://code.google.com/p/processing/issues/detail?id=884
@@ -1160,13 +1205,53 @@ public class JavaBuild {
/// on macosx, need to copy .app skeleton since that's
/// also where the jar files will be placed
File dotAppFolder = null;
String jvmRuntime = "";
String jdkPath = null;
if (exportPlatform == PConstants.MACOSX) {
dotAppFolder = new File(destFolder, sketch.getName() + ".app");
// String APP_SKELETON = "skeleton.app";
//File dotAppSkeleton = new File(folder, APP_SKELETON);
File dotAppSkeleton = mode.getContentFile("application/template.app");
Base.copyDir(dotAppSkeleton, dotAppFolder);
File contentsOrig = new File(Base.getJavaHome(), "../../../../..");
if (embedJava) {
File jdkFolder = new File(Base.getJavaHome(), "../../..");
String jdkFolderName = jdkFolder.getCanonicalFile().getName();
jvmRuntime = "<key>JVMRuntime</key>\n <string>" + jdkFolderName + "</string>";
jdkPath = new File(dotAppFolder, "Contents/PlugIns/" + jdkFolderName + ".jdk").getAbsolutePath();
}
File contentsFolder = new File(dotAppFolder, "Contents");
contentsFolder.mkdirs();
// Info.plist will be written later
// set the jar folder to a different location than windows/linux
//jarFolder = new File(dotAppFolder, "Contents/Resources/Java");
jarFolder = new File(contentsFolder, "Java");
File macosFolder = new File(contentsFolder, "MacOS");
macosFolder.mkdirs();
Base.copyFile(new File(contentsOrig, "MacOS/Processing"),
new File(contentsFolder, "MacOS/" + sketch.getName()));
File pkgInfo = new File(contentsFolder, "PkgInfo");
PrintWriter writer = PApplet.createWriter(pkgInfo);
writer.println("APPL????");
writer.flush();
writer.close();
// Use faster(?) native copy here (also to do sym links)
if (embedJava) {
Base.copyDirNative(new File(contentsOrig, "PlugIns"),
new File(contentsFolder, "PlugIns"));
}
File resourcesFolder = new File(contentsFolder, "Resources");
Base.copyDir(new File(contentsOrig, "Resources/en.lproj"),
new File(resourcesFolder, "en.lproj"));
Base.copyFile(mode.getContentFile("application/sketch.icns"),
new File(resourcesFolder, "sketch.icns"));
/*
String stubName = "Contents/MacOS/JavaApplicationStub";
// need to set the stub to executable
// will work on osx or *nix, but just dies on windows, oh well..
@@ -1189,17 +1274,25 @@ public class JavaBuild {
String stubPath = stubFile.getAbsolutePath();
Runtime.getRuntime().exec(new String[] { "chmod", "+x", stubPath });
}
// set the jar folder to a different location than windows/linux
jarFolder = new File(dotAppFolder, "Contents/Resources/Java");
*/
} else if (exportPlatform == PConstants.LINUX) {
if (embedJava) {
Base.copyDirNative(Base.getJavaHome(), new File(destFolder, "java"));
}
} else if (exportPlatform == PConstants.WINDOWS) {
if (embedJava) {
Base.copyDir(Base.getJavaHome(), new File(destFolder, "java"));
}
}
/// make the jar folder (windows and linux)
/// make the jar folder (all platforms)
if (!jarFolder.exists()) jarFolder.mkdirs();
/*
/// on windows, copy the exe file
if (exportPlatform == PConstants.WINDOWS) {
@@ -1208,7 +1301,8 @@ public class JavaBuild {
File batFile = new File(destFolder, sketch.getName() + ".bat");
PrintWriter writer = PApplet.createWriter(batFile);
writer.println("@echo off");
writer.println("java -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName());
String javaPath = embedJava ? ".\\java\\bin\\java.exe" : "java";
writer.println(javaPath + " -Djna.nosys=true -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName());
writer.flush();
writer.close();
} else {
@@ -1216,8 +1310,9 @@ public class JavaBuild {
new File(destFolder, sketch.getName() + ".exe"));
}
}
*/
/// start copying all jar files
Vector<String> jarListVector = new Vector<String>();
@@ -1271,7 +1366,6 @@ public class JavaBuild {
String includes = Base.contentsToClassPath(sketch.getCodeFolder());
// Use tokens to get rid of extra blanks, which causes huge exports
String[] codeList = PApplet.splitTokens(includes, File.pathSeparator);
// String cp = "";
for (int i = 0; i < codeList.length; i++) {
if (codeList[i].toLowerCase().endsWith(".jar") ||
codeList[i].toLowerCase().endsWith(".zip")) {
@@ -1283,7 +1377,6 @@ public class JavaBuild {
// cp += codeList[i] + File.pathSeparator;
}
}
// packClassPathIntoZipFile(cp, zos, zipFileContents); // this was double adding the code folder prior to 2.0a2
}
zos.flush();
@@ -1292,15 +1385,6 @@ public class JavaBuild {
jarListVector.add(sketch.getName() + ".jar");
// /// add core.jar to the jar destination folder
//
// File bagelJar = Base.isMacOS() ?
// Base.getContentFile("core.jar") :
// Base.getContentFile("lib/core.jar");
// Base.copyFile(bagelJar, new File(jarFolder, "core.jar"));
// jarListVector.add("core.jar");
/// add contents of 'library' folders to the export
for (Library library : importedLibraries) {
// add each item from the library folder / export list to the output
@@ -1313,38 +1397,13 @@ public class JavaBuild {
"a big fat lie and does not exist.");
} else if (exportFile.isDirectory()) {
//System.err.println("Ignoring sub-folder \"" + exportList[i] + "\"");
// if (exportPlatform == PConstants.MACOSX) {
// // For OS X, copy subfolders to Contents/Resources/Java
Base.copyDir(exportFile, new File(jarFolder, exportName));
// } else {
// // For other platforms, just copy the folder to the same directory
// // as the application.
// Base.copyDir(exportFile, new File(destFolder, exportName));
// }
} else if (exportName.toLowerCase().endsWith(".zip") ||
exportName.toLowerCase().endsWith(".jar")) {
Base.copyFile(exportFile, new File(jarFolder, exportName));
jarListVector.add(exportName);
// old style, prior to 2.0a2
// } else if ((exportPlatform == PConstants.MACOSX) &&
// (exportFile.getName().toLowerCase().endsWith(".jnilib"))) {
// // jnilib files can be placed in Contents/Resources/Java
// Base.copyFile(exportFile, new File(jarFolder, exportName));
//
// } else {
// // copy the file to the main directory.. prolly a .dll or something
// Base.copyFile(exportFile, new File(destFolder, exportName));
// }
// first 2.0a2 attempt, until below...
// } else if (exportPlatform == PConstants.MACOSX) {
// Base.copyFile(exportFile, new File(jarFolder, exportName));
//
// } else {
// Base.copyFile(exportFile, new File(destFolder, exportName));
} else {
// Starting with 2.0a2 put extra export files (DLLs, plugins folder,
// anything else for libraries) inside lib or Contents/Resources/Java
@@ -1380,31 +1439,30 @@ public class JavaBuild {
/// figure out run options for the VM
String runOptions = Preferences.get("run.options");
List<String> runOptions = new ArrayList<String>();
if (Preferences.getBoolean("run.options.memory")) {
runOptions += " -Xms" +
Preferences.get("run.options.memory.initial") + "m";
runOptions += " -Xmx" +
Preferences.get("run.options.memory.maximum") + "m";
runOptions.add("-Xms" + Preferences.get("run.options.memory.initial") + "m");
runOptions.add("-Xmx" + Preferences.get("run.options.memory.maximum") + "m");
}
// if (exportPlatform == PConstants.MACOSX) {
// // If no bits specified (libs are all universal, or no native libs)
// // then exportBits will be 0, and can be controlled via "Get Info".
// // Otherwise, need to specify the bits as a VM option.
// if (exportBits == 32) {
// runOptions += " -d32";
// } else if (exportBits == 64) {
// runOptions += " -d64";
// }
// }
// https://github.com/processing/processing/issues/2239
runOptions.add("-Djna.nosys=true");
/// macosx: write out Info.plist (template for classpath, etc)
if (exportPlatform == PConstants.MACOSX) {
String PLIST_TEMPLATE = "template.plist";
StringBuilder runOptionsXML = new StringBuilder();
for (String opt : runOptions) {
runOptionsXML.append(" <string>");
runOptionsXML.append(opt);
runOptionsXML.append("</string>");
runOptionsXML.append('\n');
}
String PLIST_TEMPLATE = "Info.plist.tmpl";
File plistTemplate = new File(sketch.getFolder(), PLIST_TEMPLATE);
if (!plistTemplate.exists()) {
plistTemplate = mode.getContentFile("application/template.plist");
plistTemplate = mode.getContentFile("application/" + PLIST_TEMPLATE);
}
File plistFile = new File(dotAppFolder, "Contents/Info.plist");
PrintWriter pw = PApplet.createWriter(plistFile);
@@ -1414,33 +1472,22 @@ public class JavaBuild {
if (lines[i].indexOf("@@") != -1) {
StringBuffer sb = new StringBuffer(lines[i]);
int index = 0;
while ((index = sb.indexOf("@@vmoptions@@")) != -1) {
sb.replace(index, index + "@@vmoptions@@".length(),
runOptions);
while ((index = sb.indexOf("@@jvm_runtime@@")) != -1) {
sb.replace(index, index + "@@jvm_runtime@@".length(),
jvmRuntime);
}
while ((index = sb.indexOf("@@jvm_options_list@@")) != -1) {
sb.replace(index, index + "@@jvm_options_list@@".length(),
runOptionsXML.toString());
}
while ((index = sb.indexOf("@@sketch@@")) != -1) {
sb.replace(index, index + "@@sketch@@".length(),
sketch.getName());
}
while ((index = sb.indexOf("@@classpath@@")) != -1) {
sb.replace(index, index + "@@classpath@@".length(),
exportClassPath.toString());
}
while ((index = sb.indexOf("@@lsuipresentationmode@@")) != -1) {
sb.replace(index, index + "@@lsuipresentationmode@@".length(),
Preferences.getBoolean("export.application.fullscreen") ? "4" : "0");
}
while ((index = sb.indexOf("@@lsarchitecturepriority@@")) != -1) {
// More about this mess: http://support.apple.com/kb/TS2827
// First default to exportBits == 0 case
String arch = "<string>x86_64</string>\n <string>i386</string>";
if (exportBits == 32) {
arch = "<string>i386</string>";
} else if (exportBits == 64) {
arch = "<string>x86_64</string>";
}
sb.replace(index, index + "@@lsarchitecturepriority@@".length(), arch);
}
lines[i] = sb.toString();
}
@@ -1450,17 +1497,93 @@ public class JavaBuild {
pw.flush();
pw.close();
// attempt to code sign if the Xcode tools appear to be installed
if (Base.isMacOS() && new File("/usr/bin/codesign_allocate").exists()) {
if (embedJava) {
ProcessHelper.ffs("codesign", "--force", "--sign", "-", jdkPath);
}
String appPath = dotAppFolder.getAbsolutePath();
ProcessHelper.ffs("codesign", "--force", "--sign", "-", appPath);
}
} else if (exportPlatform == PConstants.WINDOWS) {
File argsFile = new File(destFolder + "/lib/args.txt");
PrintWriter pw = PApplet.createWriter(argsFile);
File buildFile = new File(destFolder, "launch4j-build.xml");
File configFile = new File(destFolder, "launch4j-config.xml");
// Since this is only on Windows, make sure we use Windows CRLF
pw.print(runOptions + "\r\n");
pw.print(sketch.getName() + "\r\n");
pw.print(exportClassPath);
XML project = new XML("project");
XML target = project.addChild("target");
target.setString("name", "windows");
XML taskdef = target.addChild("taskdef");
taskdef.setString("name", "launch4j");
taskdef.setString("classname", "net.sf.launch4j.ant.Launch4jTask");
String launchPath = mode.getContentFile("application/launch4j").getAbsolutePath();
taskdef.setString("classpath", launchPath + "/launch4j.jar:" + launchPath + "/lib/xstream.jar");
XML launch4j = target.addChild("launch4j");
// not all launch4j options are available when embedded inside the ant
// build file (i.e. the icon param doesn't work), so use a config file
//<launch4j configFile="windows/work/config.xml" />
launch4j.setString("configFile", configFile.getAbsolutePath());
XML config = new XML("launch4jConfig");
config.addChild("headerType").setContent("gui");
config.addChild("dontWrapJar").setContent("true");
config.addChild("downloadUrl").setContent("http://java.com/download");
File exeFile = new File(destFolder, sketch.getName() + ".exe");
config.addChild("outfile").setContent(exeFile.getAbsolutePath());
File iconFile = mode.getContentFile("application/sketch.ico");
config.addChild("icon").setContent(iconFile.getAbsolutePath());
pw.flush();
pw.close();
XML clazzPath = config.addChild("classPath");
clazzPath.addChild("mainClass").setContent(sketch.getName());
for (String jarName : jarList) {
clazzPath.addChild("cp").setContent("lib/" + jarName);
}
XML jre = config.addChild("jre");
if (embedJava) {
jre.addChild("path").setContent("java");
}
jre.addChild("minVersion").setContent("1.7.0_40");
for (String opt : runOptions) {
jre.addChild("opt").setContent(opt);
}
/*
XML config = launch4j.addChild("config");
config.setString("headerType", "gui");
File exeFile = new File(destFolder, sketch.getName() + ".exe");
config.setString("outfile", exeFile.getAbsolutePath());
config.setString("dontWrapJar", "true");
config.setString("jarPath", "lib\\" + jarList[0]);
File iconFile = mode.getContentFile("application/sketch.ico");
config.addChild("icon").setContent(iconFile.getAbsolutePath());
XML clazzPath = config.addChild("classPath");
clazzPath.setString("mainClass", sketch.getName());
for (int i = 1; i < jarList.length; i++) {
String jarName = jarList[i];
clazzPath.addChild("cp").setContent("lib\\" + jarName);
}
XML jre = config.addChild("jre");
jre.setString("minVersion", "1.7.0_40");
//PApplet.join(runOptions.toArray(new String[0]), " ")
for (String opt : runOptions) {
jre.addChild("opt").setContent(opt);
}
*/
config.save(configFile);
project.save(buildFile);
if (!buildWindowsLauncher(buildFile, "windows")) {
// don't delete the build file, might be useful for debugging
return false;
}
configFile.delete();
buildFile.delete();
} else {
File shellScript = new File(destFolder, sketch.getName());
@@ -1473,7 +1596,13 @@ public class JavaBuild {
pw.print("APPDIR=$(dirname \"$0\")\n"); // more posix compliant
// another fix for bug #234, LD_LIBRARY_PATH ignored on some platforms
//ps.print("LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$APPDIR\n");
pw.print("java " + Preferences.get("run.options") +
if (embedJava) {
// https://github.com/processing/processing/issues/2349
pw.print("$APPDIR/java/bin/");
}
String runOptionsStr =
PApplet.join(runOptions.toArray(new String[0]), " ");
pw.print("java " + runOptionsStr +
" -Djava.library.path=\"$APPDIR:$APPDIR/lib\"" +
" -cp \"" + exportClassPath + "\"" +
" " + sketch.getName() + " \"$@\"\n");
@@ -1512,23 +1641,66 @@ public class JavaBuild {
}
/// remove the .class files from the export folder.
// for (File file : classFiles) {
// if (!file.delete()) {
// Base.showWarning("Could not delete",
// file.getName() + " could not \n" +
// "be deleted from the applet folder. \n" +
// "You'll need to remove it by hand.", null);
// }
// }
// these will now be removed automatically via the temp folder deleteOnExit()
/// goodbye
return true;
}
/**
* Run the launch4j build.xml file through ant to create the exe.
* Most of this code was lifted from Android mode.
*/
protected boolean buildWindowsLauncher(File buildFile, String target) {
Project p = new Project();
String path = buildFile.getAbsolutePath().replace('\\', '/');
p.setUserProperty("ant.file", path);
// deals with a problem where javac error messages weren't coming through
p.setUserProperty("build.compiler", "extJavac");
// too chatty
/*
// try to spew something useful to the console
final DefaultLogger consoleLogger = new DefaultLogger();
consoleLogger.setErrorPrintStream(System.err);
consoleLogger.setOutputPrintStream(System.out);
// WARN, INFO, VERBOSE, DEBUG
consoleLogger.setMessageOutputLevel(Project.MSG_ERR);
p.addBuildListener(consoleLogger);
*/
DefaultLogger errorLogger = new DefaultLogger();
ByteArrayOutputStream errb = new ByteArrayOutputStream();
PrintStream errp = new PrintStream(errb);
errorLogger.setErrorPrintStream(errp);
ByteArrayOutputStream outb = new ByteArrayOutputStream();
PrintStream outp = new PrintStream(outb);
errorLogger.setOutputPrintStream(outp);
errorLogger.setMessageOutputLevel(Project.MSG_INFO);
p.addBuildListener(errorLogger);
try {
p.fireBuildStarted();
p.init();
final ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.executeTarget(target);
return true;
} catch (final BuildException e) {
// Send a "build finished" event to the build listeners for this project.
p.fireBuildFinished(e);
String out = new String(outb.toByteArray());
String err = new String(errb.toByteArray());
System.out.println(out);
System.err.println(err);
}
return false;
}
protected void addManifest(ZipOutputStream zos) throws IOException {
ZipEntry entry = new ZipEntry("META-INF/MANIFEST.MF");
zos.putNextEntry(entry);

View File

@@ -251,31 +251,33 @@ public class JavaEditor extends Editor {
toolbar.deactivate(JavaToolbar.EXPORT);
}
// JPanel presentColorPanel;
// JTextField presentColorPanel;
protected boolean exportApplicationPrompt() throws IOException, SketchException {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(Box.createVerticalStrut(6));
//Box panel = Box.createVerticalBox();
//Box labelBox = Box.createHorizontalBox();
// Box panel = Box.createVerticalBox();
// Box labelBox = Box.createHorizontalBox();
// String msg = "<html>Click Export to Application to create a standalone, " +
// "double-clickable application for the selected plaforms.";
// String msg = "Export to Application creates a standalone, \n" +
// "double-clickable application for the selected plaforms.";
String line1 = Language.text("export.description.line1");
String line2 = Language.text("export.description.line2");
//String line2 = "standalone application for the current plaform.";
JLabel label1 = new JLabel(line1, SwingConstants.CENTER);
JLabel label2 = new JLabel(line2, SwingConstants.CENTER);
label1.setAlignmentX(Component.LEFT_ALIGNMENT);
label2.setAlignmentX(Component.LEFT_ALIGNMENT);
// label1.setAlignmentX();
// label2.setAlignmentX(0);
panel.add(label1);
panel.add(label2);
int wide = label2.getPreferredSize().width;
// The longer line is different between Windows and OS X.
// int wide = Math.max(label1.getPreferredSize().width,
// label2.getPreferredSize().width);
panel.add(Box.createVerticalStrut(12));
final JCheckBox windowsButton = new JCheckBox("Windows");
@@ -288,7 +290,6 @@ public class JavaEditor extends Editor {
});
final JCheckBox macosxButton = new JCheckBox("Mac OS X");
//macosxButton.setMnemonic(KeyEvent.VK_M);
macosxButton.setSelected(Preferences.getBoolean("export.application.platform.macosx"));
macosxButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
@@ -315,14 +316,15 @@ public class JavaEditor extends Editor {
platformPanel.setBorder(new TitledBorder(Language.text("export.platforms")));
//Dimension goodIdea = new Dimension(wide, platformPanel.getPreferredSize().height);
//platformPanel.setMaximumSize(goodIdea);
wide = Math.max(wide, platformPanel.getPreferredSize().width);
// wide = Math.max(wide, platformPanel.getPreferredSize().width);
platformPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.add(platformPanel);
// Box indentPanel = Box.createHorizontalBox();
// indentPanel.add(Box.createHorizontalStrut(new JCheckBox().getPreferredSize().width));
int divWidth = platformPanel.getPreferredSize().width;
//int indent = new JCheckBox().getPreferredSize().width;
int indent = 0;
final JCheckBox showStopButton = new JCheckBox(Language.text("export.options.show_stop_button"));
//showStopButton.setMnemonic(KeyEvent.VK_S);
showStopButton.setSelected(Preferences.getBoolean("export.application.stop"));
showStopButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
@@ -330,9 +332,7 @@ public class JavaEditor extends Editor {
}
});
showStopButton.setEnabled(Preferences.getBoolean("export.application.fullscreen"));
showStopButton.setBorder(new EmptyBorder(3, 13, 6, 13));
// indentPanel.add(showStopButton);
// indentPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
showStopButton.setBorder(new EmptyBorder(3, 13 + indent, 6, 13));
final JCheckBox fullScreenButton = new JCheckBox(Language.text("export.options.fullscreen"));
//fullscreenButton.setMnemonic(KeyEvent.VK_F);
@@ -346,63 +346,200 @@ public class JavaEditor extends Editor {
});
fullScreenButton.setBorder(new EmptyBorder(3, 13, 3, 13));
JPanel optionPanel = new JPanel();
optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.Y_AXIS));
optionPanel.add(fullScreenButton);
optionPanel.add(showStopButton);
// optionPanel.add(indentPanel);
optionPanel.setBorder(new TitledBorder(Language.text("export.options")));
wide = Math.max(wide, platformPanel.getPreferredSize().width);
//goodIdea = new Dimension(wide, optionPanel.getPreferredSize().height);
optionPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
//optionPanel.setMaximumSize(goodIdea);
panel.add(optionPanel);
JPanel presentPanel = new JPanel();
presentPanel.setLayout(new BoxLayout(presentPanel, BoxLayout.Y_AXIS));
Box fullScreenBox = Box.createHorizontalBox();
fullScreenBox.add(fullScreenButton);
/*
//run.present.stop.color
// presentColorPanel = new JTextField();
// presentColorPanel.setFocusable(false);
// presentColorPanel.setEnabled(false);
presentColorPanel = new JPanel() {
public void paintComponent(Graphics g) {
g.setColor(Preferences.getColor("run.present.bgcolor"));
Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height);
}
};
presentColorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
// presentColorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
presentColorPanel.setMaximumSize(new Dimension(30, 20));
fullScreenBox.add(presentColorPanel);
*/
fullScreenBox.add(new ColorPreference("run.present.bgcolor"));
//presentPanel.add(fullScreenButton);
fullScreenBox.add(Box.createHorizontalStrut(10));
fullScreenBox.add(Box.createHorizontalGlue());
Dimension good;
//label1, label2, platformPanel, optionPanel
good = new Dimension(wide, label1.getPreferredSize().height);
label1.setMaximumSize(good);
good = new Dimension(wide, label2.getPreferredSize().height);
label2.setMaximumSize(good);
good = new Dimension(wide, platformPanel.getPreferredSize().height);
platformPanel.setMaximumSize(good);
good = new Dimension(wide, optionPanel.getPreferredSize().height);
optionPanel.setMaximumSize(good);
// JPanel actionPanel = new JPanel();
// optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.X_AXIS));
// optionPanel.add(Box.createHorizontalGlue());
// final JDialog frame = new JDialog(editor, "Export to Application");
// JButton cancelButton = new JButton("Cancel");
// cancelButton.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// frame.dispose();
// return false;
presentPanel.add(fullScreenBox);
// presentColorPanel.addMouseListener(new MouseAdapter() {
// public void mousePressed(MouseEvent e) {
// new ColorListener("run.present.bgcolor");
// }
// });
// Add the buttons in platform-specific order
// if (PApplet.platform == PConstants.MACOSX) {
// optionPanel.add(cancelButton);
// optionPanel.add(exportButton);
// } else {
// optionPanel.add(exportButton);
// optionPanel.add(cancelButton);
// }
Box showStopBox = Box.createHorizontalBox();
showStopBox.add(showStopButton);
showStopBox.add(new ColorPreference("run.present.stop.color"));
showStopBox.add(Box.createHorizontalStrut(10));
showStopBox.add(Box.createHorizontalGlue());
presentPanel.add(showStopBox);
//presentPanel.add(showStopButton);
// presentPanel.add(Box.createHorizontalStrut(10));
// presentPanel.add(Box.createHorizontalGlue());
presentPanel.setBorder(new TitledBorder("Full Screen"));
// wide = Math.max(wide, platformPanel.getPreferredSize().width);
presentPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.add(presentPanel);
// Dimension good;
// good = new Dimension(wide, label1.getPreferredSize().height);
// label1.setMaximumSize(good);
// good = new Dimension(wide, label2.getPreferredSize().height);
// label2.setMaximumSize(good);
// good = new Dimension(wide, presentPanel.getPreferredSize().height);
//
JPanel embedPanel = new JPanel();
embedPanel.setLayout(new BoxLayout(embedPanel, BoxLayout.Y_AXIS));
String platformName = null;
if (Base.isMacOS()) {
platformName = "Mac OS X";
} else if (Base.isWindows()) {
platformName = "Windows (" + Base.getNativeBits() + "-bit)";
} else if (Base.isLinux()) {
platformName = "Linux (" + Base.getNativeBits() + "-bit)";
}
boolean embed = Preferences.getBoolean("export.application.embed_java");
final String embedWarning =
"<html><div width=\"" + divWidth + "\"><font size=\"2\">" +
// "<html><body><font size=2>" +
"Embedding Java will make the " + platformName + " application " +
"larger, but it will be far more likely to work. " +
"Users on other platforms will need to <a href=\"\">install Java 7</a>.";
final String nopeWarning =
"<html><div width=\"" + divWidth + "\"><font size=\"2\">" +
// "<html><body><font size=2>" +
"Users on all platforms will have to install the latest " +
"version of Java 7 from <a href=\"\">http://java.com/download</a>. " +
"<br/>&nbsp;";
//"from <a href=\"http://java.com/download\">java.com/download</a>.";
final JLabel warningLabel = new JLabel(embed ? embedWarning : nopeWarning);
warningLabel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
Base.openURL("http://java.com/download");
}
});
warningLabel.setBorder(new EmptyBorder(3, 13 + indent, 3, 13));
final JCheckBox embedJavaButton =
new JCheckBox("Embed Java for " + platformName);
embedJavaButton.setSelected(embed);
embedJavaButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
boolean selected = embedJavaButton.isSelected();
Preferences.setBoolean("export.application.embed_java", selected);
if (selected) {
warningLabel.setText(embedWarning);
} else {
warningLabel.setText(nopeWarning);
}
}
});
embedJavaButton.setBorder(new EmptyBorder(3, 13, 3, 13));
embedPanel.add(embedJavaButton);
embedPanel.add(warningLabel);
embedPanel.setBorder(new TitledBorder("Embed Java"));
panel.add(embedPanel);
//
if (Base.isMacOS()) {
JPanel signPanel = new JPanel();
signPanel.setLayout(new BoxLayout(signPanel, BoxLayout.Y_AXIS));
signPanel.setBorder(new TitledBorder("Code Signing"));
// gatekeeper: http://support.apple.com/kb/ht5290
// for developers: https://developer.apple.com/developer-id/
String thePain =
//"<html><body><font size=2>" +
"In recent versions of OS X, Apple has introduced the \u201CGatekeeper\u201D system, " +
"which makes it more difficult to run applications like those exported from Processing. ";
if (new File("/usr/bin/codesign_allocate").exists()) {
thePain +=
"This application will be \u201Cself-signed\u201D which means that Finder may report that the " +
"application is from an \u201Cunidentified developer\u201D. If the application will not " +
"run, try right-clicking the app and selecting Open from the pop-up menu. Or you can visit " +
"System Preferences \u2192 Security & Privacy and select Allow apps downloaded from: anywhere. ";
} else {
thePain +=
"Gatekeeper requires applications to be \u201Csigned\u201D, or they will be reported as damaged. " +
"To prevent this message, install Xcode (and the Command Line Tools) from the App Store, or visit " +
"System Preferences \u2192 Security & Privacy and select Allow apps downloaded from: anywhere. ";
}
thePain +=
"To avoid the messages entirely, manually code sign your app. " +
"For more information: <a href=\"\">https://developer.apple.com/developer-id/</a>";
// xattr -d com.apple.quarantine thesketch.app
//signPanel.add(new JLabel(thePain));
//JEditorPane area = new JEditorPane("text/html", thePain);
//JTextPane area = new JEditorPane("text/html", thePain);
// JTextArea area = new JTextArea(thePain);
// area.setBackground(null);
// area.setFont(new Font("Dialog", Font.PLAIN, 10));
// area.setLineWrap(true);
// area.setWrapStyleWord(true);
// Are you f-king serious, Java API developers?
JLabel area = new JLabel("<html><div width=\"" + divWidth + "\"><font size=\"2\">" + thePain + "</div></html>");
area.setBorder(new EmptyBorder(3, 13, 3, 13));
// area.setPreferredSize(new Dimension(embedPanel.getPreferredSize().width, 100));
// area.setPreferredSize(new Dimension(300, 200));
signPanel.add(area);
// signPanel.add(Box.createHorizontalGlue());
signPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
area.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
Base.openURL("https://developer.apple.com/developer-id/");
}
});
panel.add(signPanel);
}
//System.out.println(panel.getPreferredSize());
// panel.setMinimumSize(new Dimension(316, 461));
// panel.setPreferredSize(new Dimension(316, 461));
// panel.setMaximumSize(new Dimension(316, 461));
//
String[] options = { Language.text("prompt.export"), Language.text("prompt.cancel") };
final JOptionPane optionPane = new JOptionPane(panel,
JOptionPane.PLAIN_MESSAGE,
//JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION,
null,
options,
options[0]);
final JDialog dialog = new JDialog(this, Language.text("export"), true);
dialog.setContentPane(optionPane);
// System.out.println(optionPane.getLayout());
optionPane.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
@@ -410,20 +547,24 @@ public class JavaEditor extends Editor {
if (dialog.isVisible() &&
(e.getSource() == optionPane) &&
(prop.equals(JOptionPane.VALUE_PROPERTY))) {
//If you were going to check something
//before closing the window, you'd do
//it here.
// If you were going to check something before
// closing the window, you'd do it here.
dialog.setVisible(false);
}
}
});
dialog.pack();
// System.out.println("after pack: " + panel.getPreferredSize());
// dialog.setSize(optionPane.getPreferredSize());
dialog.setResizable(false);
// Center the window in the middle of the editor
Rectangle bounds = getBounds();
dialog.setLocation(bounds.x + (bounds.width - dialog.getSize().width) / 2,
bounds.y + (bounds.height - dialog.getSize().height) / 2);
dialog.setVisible(true);
//System.out.println(panel.getSize());
Object value = optionPane.getValue();
if (value.equals(options[0])) {
@@ -435,7 +576,90 @@ public class JavaEditor extends Editor {
return false;
}
/*
Color bgcolor = Preferences.getColor("run.present.bgcolor");
final ColorChooser c = new ColorChooser(JavaEditor.this, true, bgcolor,
"Select", new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Preferences.setColor("run.present.bgcolor", c.getColor());
}
});
*/
/*
class ColorListener implements ActionListener {
ColorChooser chooser;
String prefName;
public ColorListener(String prefName) {
this.prefName = prefName;
Color color = Preferences.getColor(prefName);
chooser = new ColorChooser(JavaEditor.this, true, color, "Select", this);
chooser.show();
}
@Override
public void actionPerformed(ActionEvent e) {
Color color = chooser.getColor();
Preferences.setColor(prefName, color);
// presentColorPanel.setBackground(color);
presentColorPanel.repaint();
chooser.hide();
}
}
*/
class ColorPreference extends JPanel implements ActionListener {
ColorChooser chooser;
String prefName;
public ColorPreference(String pref) {
prefName = pref;
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
setPreferredSize(new Dimension(30, 20));
setMaximumSize(new Dimension(30, 20));
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
Color color = Preferences.getColor(prefName);
chooser = new ColorChooser(JavaEditor.this, true, color, "Select", ColorPreference.this);
chooser.show();
}
});
}
public void paintComponent(Graphics g) {
g.setColor(Preferences.getColor(prefName));
Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height);
}
public void actionPerformed(ActionEvent e) {
Color color = chooser.getColor();
Preferences.setColor(prefName, color);
//presentColorPanel.repaint();
repaint();
chooser.hide();
}
}
// protected void selectColor(String prefName) {
// Color color = Preferences.getColor(prefName);
// final ColorChooser chooser = new ColorChooser(JavaEditor.this, true, color,
// "Select", new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// Preferences.setColor(prefName, c.getColor());
// }
// });
// }
/**
* Checks to see if the sketch has been modified, and if so,
* asks the user to save the sketch or cancel the export.

View File

@@ -123,11 +123,7 @@ public class Runner implements MessageConsumer {
}
// public void launch(String appletClassName, boolean presenting) {
// this.appletClassName = appletClassName;
public boolean launchVirtualMachine(boolean presenting) {
// this.presenting = presenting;
String[] vmParams = getMachineParams();
String[] sketchParams = getSketchParams(presenting);
int port = 8000 + (int) (Math.random() * 1000);
@@ -139,10 +135,15 @@ public class Runner implements MessageConsumer {
// Newer (Java 1.5+) version that uses JVMTI
String jdwpArg = "-agentlib:jdwp=transport=dt_socket,address=" + portStr + ",server=y,suspend=y";
// Everyone works the same under Java 7 (also on OS X)
String[] commandArgs = new String[] { Base.getJavaPath(), jdwpArg };
/*
String[] commandArgs = null;
if (!Base.isMacOS()) {
commandArgs = new String[] {
"java", jdwpArg
Base.getJavaPath(),
jdwpArg
};
} else {
// Decided to just set this to 1.6 only, because otherwise it's gonna
@@ -160,7 +161,7 @@ public class Runner implements MessageConsumer {
// OS X at this point, because we require 10.6.8 and higher. That also
// means we don't need to check for any other OS versions, the user is
// a douchebag and modifies Info.plist to get around the restriction.
if (true) {
if (false) {
if (System.getProperty("os.version").startsWith("10.6")) {
commandArgs = new String[] {
"/usr/libexec/java_home",
@@ -183,41 +184,19 @@ public class Runner implements MessageConsumer {
} else {
// testing jdk-7u40
commandArgs = new String[] {
"/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/java",
//"/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/java",
Base.getJavaPath(),
jdwpArg
};
}
}
*/
commandArgs = PApplet.concat(commandArgs, vmParams);
commandArgs = PApplet.concat(commandArgs, sketchParams);
// PApplet.println(commandArgs);
// commandArg.setValue(commandArgs);
launchJava(commandArgs);
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// boolean available = false;
// while (!available) {
// try {
// Socket socket = new Socket((String) null, port);
//// socket.close();
// // this should mean we're all set?
// available = true;
//
// } catch (IOException e) {
// System.out.println("waiting");
// //e.printStackTrace();
// try {
// Thread.sleep(100);
// } catch (InterruptedException e1) {
// e1.printStackTrace();
// }
// }
// }
AttachingConnector connector = (AttachingConnector)
findConnector("com.sun.jdi.SocketAttach");
@@ -467,7 +446,7 @@ public class Runner implements MessageConsumer {
// PApplet.println("launchJava stderr:");
// PApplet.println(errorStrings);
// PApplet.println("launchJava stdout:");
PApplet.println(inputStrings);
PApplet.printArray(inputStrings);
if (errorStrings != null && errorStrings.length > 1) {
if (errorStrings[0].indexOf("Invalid maximum heap size") != -1) {
@@ -699,7 +678,9 @@ public class Runner implements MessageConsumer {
for (Event event : eventSet) {
// System.out.println("EventThread.handleEvent -> " + event);
if (event instanceof ExceptionEvent) {
if (event instanceof VMStartEvent) {
vm.resume();
} else if (event instanceof ExceptionEvent) {
// for (ThreadReference thread : vm.allThreads()) {
// System.out.println("thread : " + thread);
//// thread.suspend();
@@ -731,8 +712,6 @@ public class Runner implements MessageConsumer {
errThread.start();
outThread.start();
vm.resume();
// Shutdown begins when event thread terminates
try {
if (eventThread != null) eventThread.join(); // is this the problem?
@@ -944,7 +923,7 @@ public class Runner implements MessageConsumer {
ObjectReference ref = (ObjectReference)val;
method = ((ClassType) ref.referenceType()).concreteMethodByName("getFileName", "()Ljava/lang/String;");
StringReference strref = (StringReference) ref.invokeMethod(thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
String filename = strref.value();
String filename = strref == null ? "Unknown Source" : strref.value();
method = ((ClassType) ref.referenceType()).concreteMethodByName("getLineNumber", "()I");
IntegerValue intval = (IntegerValue) ref.invokeMethod(thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
int lineNumber = intval.intValue() - 1;