Merge remote-tracking branch 'remotes/upstream/master'

This commit is contained in:
Sean McKenna
2014-05-19 09:34:24 -06:00
72 changed files with 1777 additions and 2010 deletions

View File

@@ -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) {

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) {
@@ -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);

View File

@@ -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/>&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) {
@@ -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.