mirror of
https://github.com/processing/processing4.git
synced 2026-02-19 05:15:34 +01:00
Merge remote-tracking branch 'remotes/upstream/master'
This commit is contained in:
@@ -133,7 +133,7 @@ public class AutoFormat implements Formatter {
|
||||
private void writeIndentedLine() {
|
||||
if (buf.length() == 0) {
|
||||
if (s_flag) {
|
||||
s_flag = a_flg = false;
|
||||
s_flag = a_flg = e_flg = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -150,9 +150,26 @@ public class AutoFormat implements Formatter {
|
||||
}
|
||||
a_flg = false;
|
||||
}
|
||||
if (e_flg) {
|
||||
if (lastNonSpaceChar() == '}') {
|
||||
trimRight(result);
|
||||
result.append(" ");
|
||||
}
|
||||
e_flg = 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') continue;
|
||||
else return c_i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private void writeIndentedComment() {
|
||||
@@ -371,16 +388,12 @@ public class AutoFormat implements Formatter {
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (lookup("else")) {
|
||||
e_flg = lookup("else");
|
||||
if (e_flg) {
|
||||
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;
|
||||
break;
|
||||
@@ -418,7 +431,8 @@ public class AutoFormat implements Formatter {
|
||||
break;
|
||||
|
||||
case '{':
|
||||
if (lookup("else")) {
|
||||
e_flg = lookup("else");
|
||||
if (e_flg) {
|
||||
gotelse();
|
||||
}
|
||||
if (s_if_lev.length == c_level) {
|
||||
|
||||
@@ -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) {
|
||||
@@ -1092,32 +1110,36 @@ public class JavaBuild {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
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");
|
||||
@@ -1141,6 +1163,7 @@ public class JavaBuild {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return true; // all good
|
||||
}
|
||||
|
||||
@@ -1182,8 +1205,8 @@ 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 jdkFolderName = null;
|
||||
String jvmRuntime = "";
|
||||
String jdkPath = null;
|
||||
if (exportPlatform == PConstants.MACOSX) {
|
||||
dotAppFolder = new File(destFolder, sketch.getName() + ".app");
|
||||
|
||||
@@ -1193,10 +1216,9 @@ public class JavaBuild {
|
||||
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 dotAppSkeleton = mode.getContentFile("application/template.app");
|
||||
// Base.copyDir(dotAppSkeleton, dotAppFolder);
|
||||
File contentsFolder = new File(dotAppFolder, "Contents");
|
||||
contentsFolder.mkdirs();
|
||||
|
||||
@@ -1270,6 +1292,7 @@ public class JavaBuild {
|
||||
if (!jarFolder.exists()) jarFolder.mkdirs();
|
||||
|
||||
|
||||
/*
|
||||
/// on windows, copy the exe file
|
||||
|
||||
if (exportPlatform == PConstants.WINDOWS) {
|
||||
@@ -1279,7 +1302,7 @@ public class JavaBuild {
|
||||
PrintWriter writer = PApplet.createWriter(batFile);
|
||||
writer.println("@echo off");
|
||||
String javaPath = embedJava ? ".\\java\\bin\\java.exe" : "java";
|
||||
writer.println(javaPath + " -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName());
|
||||
writer.println(javaPath + " -Djna.nosys=true -Djava.ext.dirs=lib -Djava.library.path=lib " + sketch.getName());
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} else {
|
||||
@@ -1287,8 +1310,9 @@ public class JavaBuild {
|
||||
new File(destFolder, sketch.getName() + ".exe"));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// start copying all jar files
|
||||
|
||||
Vector<String> jarListVector = new Vector<String>();
|
||||
@@ -1342,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")) {
|
||||
@@ -1354,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();
|
||||
@@ -1363,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
|
||||
@@ -1384,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
|
||||
@@ -1451,42 +1439,30 @@ public class JavaBuild {
|
||||
|
||||
/// figure out run options for the VM
|
||||
|
||||
// this is too vague. if anyone is using it, we can bring it back
|
||||
// String runOptions = Preferences.get("run.options");
|
||||
List<String> runOptions = new ArrayList<String>();
|
||||
if (Preferences.getBoolean("run.options.memory")) {
|
||||
runOptions.add("-Xms" + Preferences.get("run.options.memory.initial") + "m");
|
||||
runOptions.add("-Xmx" + Preferences.get("run.options.memory.maximum") + "m");
|
||||
}
|
||||
// https://github.com/processing/processing/issues/2239
|
||||
runOptions.add("-Djna.nosys=true");
|
||||
|
||||
StringBuilder jvmOptionsList = new StringBuilder();
|
||||
for (String opt : runOptions) {
|
||||
jvmOptionsList.append(" <string>");
|
||||
jvmOptionsList.append(opt);
|
||||
jvmOptionsList.append("</string>");
|
||||
jvmOptionsList.append('\n');
|
||||
}
|
||||
|
||||
// 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";
|
||||
// }
|
||||
// }
|
||||
|
||||
/// 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/Info.plist.tmpl");
|
||||
plistTemplate = mode.getContentFile("application/" + PLIST_TEMPLATE);
|
||||
}
|
||||
File plistFile = new File(dotAppFolder, "Contents/Info.plist");
|
||||
PrintWriter pw = PApplet.createWriter(plistFile);
|
||||
@@ -1502,31 +1478,16 @@ public class JavaBuild {
|
||||
}
|
||||
while ((index = sb.indexOf("@@jvm_options_list@@")) != -1) {
|
||||
sb.replace(index, index + "@@jvm_options_list@@".length(),
|
||||
jvmOptionsList.toString());
|
||||
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();
|
||||
}
|
||||
@@ -1536,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(PApplet.join(runOptions.toArray(new String[0]), " ") + "\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());
|
||||
@@ -1563,7 +1600,9 @@ public class JavaBuild {
|
||||
// https://github.com/processing/processing/issues/2349
|
||||
pw.print("$APPDIR/java/bin/");
|
||||
}
|
||||
pw.print("java " + Preferences.get("run.options") +
|
||||
String runOptionsStr =
|
||||
PApplet.join(runOptions.toArray(new String[0]), " ");
|
||||
pw.print("java " + runOptionsStr +
|
||||
" -Djava.library.path=\"$APPDIR:$APPDIR/lib\"" +
|
||||
" -cp \"" + exportClassPath + "\"" +
|
||||
" " + sketch.getName() + " \"$@\"\n");
|
||||
@@ -1602,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);
|
||||
|
||||
@@ -251,15 +251,18 @@ 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));
|
||||
|
||||
String line1 = "Export to Application creates double-clickable,";
|
||||
//String line2 = "standalone applications for the selected plaforms.";
|
||||
String line2 = "standalone application for the current plaform.";
|
||||
String line2 = "standalone applications for the selected plaforms.";
|
||||
//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);
|
||||
@@ -267,11 +270,10 @@ public class JavaEditor extends Editor {
|
||||
panel.add(label1);
|
||||
panel.add(label2);
|
||||
// The longer line is different between Windows and OS X.
|
||||
int wide = Math.max(label1.getPreferredSize().width,
|
||||
label2.getPreferredSize().width);
|
||||
// int wide = Math.max(label1.getPreferredSize().width,
|
||||
// label2.getPreferredSize().width);
|
||||
panel.add(Box.createVerticalStrut(12));
|
||||
|
||||
/*
|
||||
final JCheckBox windowsButton = new JCheckBox("Windows");
|
||||
//windowsButton.setMnemonic(KeyEvent.VK_W);
|
||||
windowsButton.setSelected(Preferences.getBoolean("export.application.platform.windows"));
|
||||
@@ -282,7 +284,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) {
|
||||
@@ -309,11 +310,13 @@ public class JavaEditor extends Editor {
|
||||
platformPanel.setBorder(new TitledBorder("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);
|
||||
*/
|
||||
int divWidth = platformPanel.getPreferredSize().width;
|
||||
|
||||
//
|
||||
|
||||
//int indent = new JCheckBox().getPreferredSize().width;
|
||||
int indent = 0;
|
||||
|
||||
@@ -338,13 +341,101 @@ public class JavaEditor extends Editor {
|
||||
});
|
||||
fullScreenButton.setBorder(new EmptyBorder(3, 13, 3, 13));
|
||||
|
||||
boolean embed = Preferences.getBoolean("export.application.embed_java");
|
||||
final String embedWarning = "Embedding Java makes larger applications";
|
||||
final String nopeWarning = "Users will have to install the latest Java 7";
|
||||
final JLabel warningLabel = new JLabel(embed ? embedWarning : nopeWarning);
|
||||
warningLabel.setBorder(new EmptyBorder(3, 13 + indent, 3, 13));
|
||||
JPanel presentPanel = new JPanel();
|
||||
presentPanel.setLayout(new BoxLayout(presentPanel, BoxLayout.Y_AXIS));
|
||||
Box fullScreenBox = Box.createHorizontalBox();
|
||||
fullScreenBox.add(fullScreenButton);
|
||||
|
||||
final JCheckBox embedJavaButton = new JCheckBox("Embed Java");
|
||||
/*
|
||||
//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());
|
||||
|
||||
presentPanel.add(fullScreenBox);
|
||||
|
||||
// presentColorPanel.addMouseListener(new MouseAdapter() {
|
||||
// public void mousePressed(MouseEvent e) {
|
||||
// new ColorListener("run.present.bgcolor");
|
||||
// }
|
||||
// });
|
||||
|
||||
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/> ";
|
||||
//"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) {
|
||||
@@ -359,27 +450,76 @@ public class JavaEditor extends Editor {
|
||||
});
|
||||
embedJavaButton.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(embedJavaButton);
|
||||
optionPanel.add(warningLabel);
|
||||
optionPanel.setBorder(new TitledBorder("Options"));
|
||||
// wide = Math.max(wide, platformPanel.getPreferredSize().width);
|
||||
optionPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
panel.add(optionPanel);
|
||||
|
||||
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);
|
||||
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 = { "Export", "Cancel" };
|
||||
final JOptionPane optionPane = new JOptionPane(panel,
|
||||
@@ -391,7 +531,8 @@ public class JavaEditor extends Editor {
|
||||
|
||||
final JDialog dialog = new JDialog(this, "Export Application", true);
|
||||
dialog.setContentPane(optionPane);
|
||||
|
||||
// System.out.println(optionPane.getLayout());
|
||||
|
||||
optionPane.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
String prop = e.getPropertyName();
|
||||
@@ -406,12 +547,17 @@ public class JavaEditor extends Editor {
|
||||
}
|
||||
});
|
||||
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])) {
|
||||
@@ -423,7 +569,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.
|
||||
|
||||
Reference in New Issue
Block a user