| [ Web Proxy ] |
| Viewing: https://raw.githubusercontent.com/botbit/processing/master/app/src/processing/app/Base.java | [Back] [Original] |
Closing the last open sketch will quit Processing.";
int result = JOptionPane.showOptionDialog(editor,
prompt,
"Quit",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (result == JOptionPane.NO_OPTION ||
result == JOptionPane.CLOSED_OPTION) {
return false;
}
}
}
Preferences.unset("server.port"); //$NON-NLS-1$
Preferences.unset("server.key"); //$NON-NLS-1$
// This will store the sketch count as zero
editors.remove(editor);
// System.out.println("editors size now " + editors.size());
// storeSketches();
// Save out the current prefs state
Preferences.save();
if (defaultFileMenu == null) {
if (modeSwitch) {
// need to close this editor, ever so temporarily
editor.setVisible(false);
editor.dispose();
activeEditor = null;
editors.remove(editor);
} else {
// Since this wasn't an actual Quit event, call System.exit()
System.exit(0);
}
} else { // on OS X, update the default file menu
editor.setVisible(false);
editor.dispose();
defaultFileMenu.insert(getRecentMenu(), 2);
activeEditor = null;
editors.remove(editor);
}
} else {
// More than one editor window open,
// proceed with closing the current window.
editor.setVisible(false);
editor.dispose();
editors.remove(editor);
}
return true;
}
/**
* Handler for File → Quit.
* @return false if canceled, true otherwise.
*/
public boolean handleQuit() {
// If quit is canceled, this will be replaced anyway
// by a later handleQuit() that is not canceled.
// storeSketches();
if (handleQuitEach()) {
// make sure running sketches close before quitting
for (Editor editor : editors) {
editor.internalCloseRunner();
}
// Save out the current prefs state
Preferences.save();
if (!Base.isMacOS()) {
// If this was fired from the menu or an AppleEvent (the Finder),
// then Mac OS X will send the terminate signal itself.
System.exit(0);
}
return true;
}
return false;
}
/**
* Attempt to close each open sketch in preparation for quitting.
* @return false if canceled along the way
*/
protected boolean handleQuitEach() {
// int index = 0;
for (Editor editor : editors) {
// if (editor.checkModified()) {
// // Update to the new/final sketch path for this fella
// storeSketchPath(editor, index);
// index++;
//
// } else {
// return false;
// }
if (!editor.checkModified()) {
return false;
}
}
return true;
}
// .................................................................
/**
* Asynchronous version of menu rebuild to be used on save and rename
* to prevent the interface from locking up until the menus are done.
*/
protected void rebuildSketchbookMenusAsync() {
//System.out.println("async enter");
//new Exception().printStackTrace();
EventQueue.invokeLater(new Runnable() {
public void run() {
rebuildSketchbookMenus();
}
});
}
public void thinkDifferentExamples() {
nextMode.showExamplesFrame();
}
/**
* Synchronous version of rebuild, used when the sketchbook folder has
* changed, so that the libraries are properly re-scanned before those menus
* (and the examples window) are rebuilt.
*/
protected void rebuildSketchbookMenus() {
// rebuildSketchbookMenu(); // no need to rebuild sketchbook post 3.0
for (Mode mode : getModeList()) {
//mode.rebuildLibraryList();
mode.rebuildImportMenu(); // calls rebuildLibraryList
mode.rebuildToolbarMenu();
mode.resetExamples();
}
}
protected void rebuildSketchbookMenu() {
// System.err.println("sketchbook: " + sketchbookFolder);
sketchbookMenu.removeAll();
populateSketchbookMenu(sketchbookMenu);
// boolean found = false;
// try {
// found = addSketches(sketchbookMenu, sketchbookFolder, false);
// } catch (IOException e) {
// Base.showWarning("Sketchbook Menu Error",
// "An error occurred while trying to list the sketchbook.", e);
// }
// if (!found) {
// JMenuItem empty = new JMenuItem("(empty)");
// empty.setEnabled(false);
// sketchbookMenu.add(empty);
// }
}
public void populateSketchbookMenu(JMenu menu) {
boolean found = false;
try {
found = addSketches(menu, sketchbookFolder, false);
} catch (IOException e) {
Base.showWarning("Sketchbook Menu Error",
"An error occurred while trying to list the sketchbook.", e);
}
if (!found) {
JMenuItem empty = new JMenuItem(Language.text("menu.file.sketchbook.empty"));
empty.setEnabled(false);
menu.add(empty);
}
}
// public JMenu getSketchbookMenu() {
// if (sketchbookMenu == null) {
// sketchbookMenu = new JMenu(Language.text("menu.file.sketchbook"));
// rebuildSketchbookMenu();
// }
// return sketchbookMenu;
// }
// public JMenu getRecentMenu() {
// if (recentMenu == null) {
// recentMenu = recent.createMenu();
// } else {
// recent.updateMenu(recentMenu);
// }
// return recentMenu;
// }
public JMenu getRecentMenu() {
return recent.getMenu();
}
public JMenu getToolbarRecentMenu() {
return recent.getToolbarMenu();
}
public void handleRecent(Editor editor) {
recent.handle(editor);
}
public void handleRecentRename(Editor editor,String oldPath){
recent.handleRename(editor,oldPath);
}
/**
* Called before a sketch is renamed so that its old name is
* no longer in the menu.
*/
public void removeRecent(Editor editor) {
recent.remove(editor);
}
/**
* Scan a folder recursively, and add any sketches found to the menu
* specified. Set the openReplaces parameter to true when opening the sketch
* should replace the sketch in the current window, or false when the
* sketch should open in a new window.
*/
protected boolean addSketches(JMenu menu, File folder,
final boolean replaceExisting) throws IOException {
// skip .DS_Store files, etc (this shouldn't actually be necessary)
if (!folder.isDirectory()) {
return false;
}
if (folder.getName().equals("libraries")) {
return false; // let's not go there
}
String[] list = folder.list();
// If a bad folder or unreadable or whatever, this will come back null
if (list == null) {
return false;
}
// Alphabetize the list, since it's not always alpha order
Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String path = e.getActionCommand();
if (new File(path).exists()) {
boolean replace = replaceExisting;
if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) {
replace = !replace;
}
// if (replace) {
// handleOpenReplace(path);
// } else {
handleOpen(path);
// }
} else {
showWarning("Sketch Disappeared",
"The selected sketch no longer exists.\n" +
"You may need to restart Processing to update\n" +
"the sketchbook menu.", null);
}
}
};
// offers no speed improvement
//menu.addActionListener(listener);
boolean found = false;
// for (int i = 0; i < list.length; i++) {
// if ((list[i].charAt(0) == '.') ||
// list[i].equals("CVS")) continue;
for (String name : list) {
if (name.charAt(0) == '.') {
continue;
}
File subfolder = new File(folder, name);
if (subfolder.isDirectory()) {
File entry = checkSketchFolder(subfolder, name);
if (entry != null) {
JMenuItem item = new JMenuItem(name);
item.addActionListener(listener);
item.setActionCommand(entry.getAbsolutePath());
menu.add(item);
found = true;
} else {
// not a sketch folder, but maybe a subfolder containing sketches
JMenu submenu = new JMenu(name);
// needs to be separate var otherwise would set ifound to false
boolean anything = addSketches(submenu, subfolder, replaceExisting);
if (anything && !name.equals("old")) { //Don't add old contributions
menu.add(submenu);
found = true;
}
}
}
}
return found;
}
protected boolean addSketches(DefaultMutableTreeNode node, File folder) throws IOException {
// skip .DS_Store files, etc (this shouldn't actually be necessary)
if (!folder.isDirectory()) {
return false;
}
if (folder.getName().equals("libraries")) {
return false; // let's not go there
}
String[] fileList = folder.list();
// If a bad folder or unreadable or whatever, this will come back null
if (fileList == null) {
return false;
}
// Alphabetize the list, since it's not always alpha order
Arrays.sort(fileList, String.CASE_INSENSITIVE_ORDER);
// ActionListener listener = new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// String path = e.getActionCommand();
// if (new File(path).exists()) {
// handleOpen(path);
// } else {
// showWarning("Sketch Disappeared",
// "The selected sketch no longer exists.\n" +
// "You may need to restart Processing to update\n" +
// "the sketchbook menu.", null);
// }
// }
// };
// offers no speed improvement
//menu.addActionListener(listener);
boolean found = false;
for (String name : fileList) {
//Skip hidden files
if (name.charAt(0) == '.') {
continue;
}
// JTree tree = null;
// TreePath[] a = tree.getSelectionPaths();
// for (TreePath path : a) {
// Object[] o = path.getPath();
// }
File subfolder = new File(folder, name);
if (subfolder.isDirectory()) {
File entry = checkSketchFolder(subfolder, name);
if (entry != null) {
DefaultMutableTreeNode item =
new DefaultMutableTreeNode(new SketchReference(name, entry));
node.add(item);
found = true;
} else {
// not a sketch folder, but maybe a subfolder containing sketches
DefaultMutableTreeNode subnode = new DefaultMutableTreeNode(name);
// needs to be separate var otherwise would set ifound to false
boolean anything = addSketches(subnode, subfolder);
if (anything) {
node.add(subnode);
found = true;
}
}
}
}
return found;
}
/**
* Check through the various modes and see if this is a legit sketch.
* Because the default mode will be the first in the list, this will always
* prefer that one over the others.
*/
File checkSketchFolder(File subfolder, String item) {
for (Mode mode : getModeList()) {
File entry = new File(subfolder, item + "." + mode.getDefaultExtension()); //$NON-NLS-1$
// if a .pde file of the same prefix as the folder exists..
if (entry.exists()) {
return entry;
}
}
return null;
}
// .................................................................
// /**
// * Show the About box.
// */
// static public void handleAbout() {
// new About(activeEditor);
// }
/**
* Show the Preferences window.
*/
public void handlePrefs() {
if (preferencesFrame == null) {
preferencesFrame = new PreferencesFrame(this);
}
preferencesFrame.showFrame();
}
/**
* Show the library installer window.
*/
public void handleOpenLibraryManager() {
libraryManagerFrame.showFrame(activeEditor);
}
/**
* Show the tool installer window.
*/
public void handleOpenToolManager() {
toolManagerFrame.showFrame(activeEditor);
}
/**
* Show the mode installer window.
*/
public void handleOpenModeManager() {
modeManagerFrame.showFrame(activeEditor);
}
/**
* Show the examples installer window.
*/
public void handleOpenExampleManager() {
exampleManagerFrame.showFrame(activeEditor);
}
public void handleShowUpdates() {
updateManagerFrame.showFrame(activeEditor);
}
// ...................................................................
static public int getRevision() {
return REVISION;
}
/**
* Return the version name, something like 1.5 or 2.0b8 or 0213 if it's not
* a release version.
*/
static public String getVersionName() {
return VERSION_NAME;
}
//...................................................................
static public Platform getPlatform() {
return platform;
}
static public String getPlatformName() {
return PConstants.platformNames[PApplet.platform];
}
// Because the Oracle JDK is 64-bit only, we lose this ability, feature,
// edge case, headache.
// /**
// * Return whether sketches will run as 32- or 64-bits. On Linux and Windows,
// * this is the bit depth of the machine, while on OS X it's determined by the
// * setting from preferences, since both 32- and 64-bit are supported.
// */
// static public int getNativeBits() {
// if (Base.isMacOS()) {
// return Preferences.getInteger("run.options.bits"); //$NON-NLS-1$
// }
// return nativeBits;
// }
/**
* Return whether sketches will run as 32- or 64-bits based
* on the JVM that's in use.
*/
static public int getNativeBits() {
return nativeBits;
}
/*
static public String getPlatformName() {
String osname = System.getProperty("os.name");
if (osname.indexOf("Mac") != -1) {
return "macosx";
} else if (osname.indexOf("Windows") != -1) {
return "windows";
} else if (osname.equals("Linux")) { // true for the ibm vm
return "linux";
} else {
return "other";
}
}
*/
/**
* Map a platform constant to its name.
* @param which PConstants.WINDOWS, PConstants.MACOSX, PConstants.LINUX
* @return one of "windows", "macosx", or "linux"
*/
static public String getPlatformName(int which) {
return platformNames.get(which);
}
static public int getPlatformIndex(String what) {
Integer entry = platformIndices.get(what);
return (entry == null) ? -1 : entry.intValue();
}
// These were changed to no longer rely on PApplet and PConstants because
// of conflicts that could happen with older versions of core.jar, where
// the MACOSX constant would instead read as the LINUX constant.
/**
* returns true if Processing is running on a Mac OS X machine.
*/
static public boolean isMacOS() {
//return PApplet.platform == PConstants.MACOSX;
return System.getProperty("os.name").indexOf("Mac") != -1; //$NON-NLS-1$ //$NON-NLS-2$
}
/*
static private Boolean usableOracleJava;
// Make sure this is Oracle Java 7u40 or later. This is temporary.
static public boolean isUsableOracleJava() {
if (usableOracleJava == null) {
usableOracleJava = false;
if (Base.isMacOS() &&
System.getProperty("java.vendor").contains("Oracle")) {
String version = System.getProperty("java.version"); // 1.7.0_40
String[] m = PApplet.match(version, "1.(\\d).*_(\\d+)");
if (m != null &&
PApplet.parseInt(m[1]) >= 7 &&
PApplet.parseInt(m[2]) >= 40) {
usableOracleJava = true;
}
}
}
return usableOracleJava;
}
*/
/**
* returns true if running on windows.
*/
static public boolean isWindows() {
//return PApplet.platform == PConstants.WINDOWS;
return System.getProperty("os.name").indexOf("Windows") != -1; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* true if running on linux.
*/
static public boolean isLinux() {
//return PApplet.platform == PConstants.LINUX;
return System.getProperty("os.name").indexOf("Linux") != -1; //$NON-NLS-1$ //$NON-NLS-2$
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/**
* Get the directory that can store settings. (Library on OS X, App Data or
* something similar on Windows, a dot folder on Linux.) Removed this as a
* preference for 3.0a3 because we need this to be stable.
*/
static public File getSettingsFolder() {
File settingsFolder = null;
// String preferencesPath = Preferences.get("settings.path"); //$NON-NLS-1$
// if (preferencesPath != null) {
// settingsFolder = new File(preferencesPath);
//
// } else {
try {
settingsFolder = platform.getSettingsFolder();
} catch (Exception e) {
showError("Problem getting the settings folder",
"Error getting the Processing the settings folder.", e);
}
// }
// create the folder if it doesn't exist already
if (!settingsFolder.exists()) {
if (!settingsFolder.mkdirs()) {
showError("Settings issues",
"Processing cannot run because it could not\n" +
"create a folder to store your settings.", null);
}
}
return settingsFolder;
}
/**
* Convenience method to get a File object for the specified filename inside
* the settings folder. Used to get preferences and recent sketch files.
* @param filename A file inside the settings folder.
* @return filename wrapped as a File object inside the settings folder
*/
static public File getSettingsFile(String filename) {
return new File(getSettingsFolder(), filename);
}
/*
static public File getBuildFolder() {
if (buildFolder == null) {
String buildPath = Preferences.get("build.path");
if (buildPath != null) {
buildFolder = new File(buildPath);
} else {
//File folder = new File(getTempFolder(), "build");
//if (!folder.exists()) folder.mkdirs();
buildFolder = createTempFolder("build");
buildFolder.deleteOnExit();
}
}
return buildFolder;
}
*/
/**
* Create a temporary folder by using the createTempFile() mechanism,
* deleting the file it creates, and making a folder using the location
* that was provided.
*
* Unlike createTempFile(), there is no minimum size for prefix. If
* prefix is less than 3 characters, the remaining characters will be
* filled with underscores
*/
static public File createTempFolder(String prefix, String suffix, File directory) throws IOException {
int fillChars = 3 - prefix.length();
for (int i = 0; i < fillChars; i++) {
prefix += '_';
}
File folder = File.createTempFile(prefix, suffix, directory);
// Now delete that file and create a folder in its place
folder.delete();
folder.mkdirs();
// And send the folder back to your friends
return folder;
}
static public File getToolsFolder() {
return getContentFile("tools");
}
static public void locateSketchbookFolder() {
// If a value is at least set, first check to see if the folder exists.
// If it doesn't, warn the user that the sketchbook folder is being reset.
String sketchbookPath = Preferences.getSketchbookPath();
if (sketchbookPath != null) {
sketchbookFolder = new File(sketchbookPath);
if (!sketchbookFolder.exists()) {
Base.showWarning("Sketchbook folder disappeared",
"The sketchbook folder no longer exists.\n" +
"Processing will switch to the default sketchbook\n" +
"location, and create a new sketchbook folder if\n" +
"necessary. Processing will then stop talking\n" +
"about himself in the third person.", null);
sketchbookFolder = null;
}
}
// If no path is set, get the default sketchbook folder for this platform
if (sketchbookFolder == null) {
sketchbookFolder = getDefaultSketchbookFolder();
Preferences.setSketchbookPath(sketchbookFolder.getAbsolutePath());
if (!sketchbookFolder.exists()) {
sketchbookFolder.mkdirs();
}
}
getSketchbookLibrariesFolder().mkdir();
getSketchbookToolsFolder().mkdir();
getSketchbookModesFolder().mkdir();
getSketchbookExamplesFolder().mkdir();
// System.err.println("sketchbook: " + sketchbookFolder);
}
public void setSketchbookFolder(File folder) {
sketchbookFolder = folder;
Preferences.setSketchbookPath(folder.getAbsolutePath());
rebuildSketchbookMenus();
}
static public File getSketchbookFolder() {
return sketchbookFolder;
}
static public File getSketchbookLibrariesFolder() {
return new File(sketchbookFolder, "libraries");
}
static public File getSketchbookToolsFolder() {
return new File(sketchbookFolder, "tools");
}
static public File getSketchbookModesFolder() {
return new File(sketchbookFolder, "modes");
}
static public File getSketchbookExamplesFolder() {
return new File(sketchbookFolder, "examples");
}
static protected File getDefaultSketchbookFolder() {
File sketchbookFolder = null;
try {
sketchbookFolder = platform.getDefaultSketchbookFolder();
} catch (Exception e) { }
if (sketchbookFolder == null) {
showError("No sketchbook",
"Problem while trying to get the sketchbook", null);
}
// create the folder if it doesn't exist already
boolean result = true;
if (!sketchbookFolder.exists()) {
result = sketchbookFolder.mkdirs();
}
if (!result) {
showError("You forgot your sketchbook",
"Processing cannot run because it could not\n" +
"create a folder to store your sketchbook.", null);
}
return sketchbookFolder;
}
// /**
// * Check for a new sketchbook location.
// */
// static protected File promptSketchbookLocation() {
// // Most often this will happen on Linux, so default to their home dir.
// File folder = new File(System.getProperty("user.home"), "sketchbook");
// String prompt = "Select a folder to place sketches...";
//
//// FolderSelector fs = new FolderSelector(prompt, folder, new Frame());
//// folder = fs.getFolder();
// folder = Base.selectFolder(prompt, folder, new Frame());
//
//// folder = Base.selectFolder(prompt, folder, null);
//// PApplet.selectFolder(prompt,
//// "promptSketchbookCallback", dflt,
//// Preferences.this, dialog);
//
// if (folder == null) {
// System.exit(0);
// }
// // Create the folder if it doesn't exist already
// if (!folder.exists()) {
// folder.mkdirs();
// return folder;
// }
// return folder;
// }
// .................................................................
/**
* Implements the cross-platform headache of opening URLs.
*
* For 2.0a8 and later, this requires the parameter to be an actual URL,
* meaning that you can't send it a file:// path without a prefix. It also
* just calls into Platform, which now uses java.awt.Desktop (where
* possible, meaning not on Linux) now that we're requiring Java 6.
* As it happens the URL must also be properly URL-encoded.
*/
static public void openURL(String url) {
try {
platform.openURL(url);
} catch (Exception e) {
showWarning("Problem Opening URL",
"Could not open the URL\n" + url, e);
}
}
/**
* Used to determine whether to disable the "Show Sketch Folder" option.
* @return true If a means of opening a folder is known to be available.
*/
static protected boolean openFolderAvailable() {
return platform.openFolderAvailable();
}
/**
* Implements the other cross-platform headache of opening
* a folder in the machine's native file browser.
*/
static public void openFolder(File file) {
try {
platform.openFolder(file);
} catch (Exception e) {
showWarning("Problem Opening Folder",
"Could not open the folder\n" + file.getAbsolutePath(), e);
}
}
// .................................................................
// /**
// * Prompt for a folder and return it as a File object (or null).
// * Implementation for choosing directories that handles both the
// * Mac OS X hack to allow the native AWT file dialog, or uses
// * the JFileChooser on other platforms. Mac AWT trick obtained from
// * this post
// * on the OS X Java dev archive which explains the cryptic note in
// * Apple's Java 1.4 release docs about the special System property.
// */
// static public File selectFolder(String prompt, File folder, Frame frame) {
// if (Base.isMacOS()) {
// if (frame == null) frame = new Frame(); //.pack();
// FileDialog fd = new FileDialog(frame, prompt, FileDialog.LOAD);
// if (folder != null) {
// fd.setDirectory(folder.getParent());
// //fd.setFile(folder.getName());
// }
// System.setProperty("apple.awt.fileDialogForDirectories", "true");
// fd.setVisible(true);
// System.setProperty("apple.awt.fileDialogForDirectories", "false");
// if (fd.getFile() == null) {
// return null;
// }
// return new File(fd.getDirectory(), fd.getFile());
//
// } else {
// JFileChooser fc = new JFileChooser();
// fc.setDialogTitle(prompt);
// if (folder != null) {
// fc.setSelectedFile(folder);
// }
// fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//
// int returned = fc.showOpenDialog(new JDialog());
// if (returned == JFileChooser.APPROVE_OPTION) {
// return fc.getSelectedFile();
// }
// }
// return null;
// }
// static class FolderSelector {
// File folder;
// boolean ready;
//
// FolderSelector(String prompt, File defaultFile, Frame parentFrame) {
// PApplet.selectFolder(prompt, "callback", defaultFile, this, parentFrame);
// }
//
// public void callback(File folder) {
// this.folder = folder;
// ready = true;
// }
//
// boolean isReady() {
// return ready;
// }
//
// /** block until the folder is available */
// File getFolder() {
// while (!ready) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) { }
// }
// return folder;
// }
// }
//
//
// /**
// * Blocking version of folder selection. Runs and sleeps until an answer
// * comes back. Avoid using: try to make things work with the async
// * selectFolder inside PApplet instead.
// */
// static public File selectFolder(String prompt, File folder, Frame frame) {
// return new FolderSelector(prompt, folder, frame).getFolder();
// }
// .................................................................
/**
* "No cookie for you" type messages. Nothing fatal or all that
* much of a bummer, but something to notify the user about.
*/
static public void showMessage(String title, String message) {
if (title == null) title = "Message";
if (commandLine) {
System.out.println(title + ": " + message);
} else {
JOptionPane.showMessageDialog(new Frame(), message, title,
JOptionPane.INFORMATION_MESSAGE);
}
}
/**
* Non-fatal error message.
*/
static public void showWarning(String title, String message) {
showWarning(title, message, null);
}
/**
* Non-fatal error message with optional stack trace side dish.
*/
static public void showWarning(String title, String message, Throwable e) {
if (title == null) title = "Warning";
if (commandLine) {
System.out.println(title + ": " + message);
} else {
JOptionPane.showMessageDialog(new Frame(), message, title,
JOptionPane.WARNING_MESSAGE);
}
if (e != null) e.printStackTrace();
}
/**
* Non-fatal error message with optional stack trace side dish.
*/
static public void showWarningTiered(String title,
String primary, String secondary,
Throwable e) {
if (title == null) title = "Warning";
final String message = primary + "\n" + secondary;
if (commandLine) {
System.out.println(title + ": " + message);
} else {
// JOptionPane.showMessageDialog(new Frame(), message,
// title, JOptionPane.WARNING_MESSAGE);
if (!Base.isMacOS()) {
JOptionPane.showMessageDialog(new JFrame(),
"" +
"" + primary + "" +
"
" + secondary, title,
JOptionPane.WARNING_MESSAGE);
} else {
// Pane formatting adapted from the Quaqua guide
// http://www.randelshofer.ch/quaqua/guide/joptionpane.html
JOptionPane pane =
new JOptionPane(" " +
" " +
"" + primary + "" +
"
" + secondary + "
", JOptionPane.WARNING_MESSAGE); // String[] options = new String[] { // "Yes", "No" // }; // pane.setOptions(options); // highlight the safest option ala apple hig // pane.setInitialValue(options[0]); JDialog dialog = pane.createDialog(new JFrame(), null); dialog.setVisible(true); // Object result = pane.getValue(); // if (result == options[0]) { // return JOptionPane.YES_OPTION; // } else if (result == options[1]) { // return JOptionPane.NO_OPTION; // } else { // return JOptionPane.CLOSED_OPTION; // } } } if (e != null) e.printStackTrace(); } /** * Show an error message that's actually fatal to the program. * This is an error that can't be recovered. Use showWarning() * for errors that allow P5 to continue running. */ static public void showError(String title, String message, Throwable e) { if (title == null) title = "Error"; if (commandLine) { System.err.println(title + ": " + message); } else { JOptionPane.showMessageDialog(new Frame(), message, title, JOptionPane.ERROR_MESSAGE); } if (e != null) e.printStackTrace(); System.exit(1); } /** * Testing a new warning window that includes the stack trace. */ static private void showBadnessTrace(String title, String message, Throwable t, boolean fatal) { if (title == null) title = fatal ? "Error" : "Warning"; if (commandLine) { System.err.println(title + ": " + message); if (t != null) { t.printStackTrace(); } } else { StringWriter sw = new StringWriter(); t.printStackTrace(new PrintWriter(sw)); // Necessary to replace \n with" + Language.text("save.hint") + "
", JOptionPane.QUESTION_MESSAGE); String[] options = new String[] { Language.text("save.btn.save"), Language.text("prompt.cancel"), Language.text("save.btn.dont_save") }; pane.setOptions(options); // highlight the safest option ala apple hig pane.setInitialValue(options[0]); // on macosx, setting the destructive property places this option // away from the others at the lefthand side pane.putClientProperty("Quaqua.OptionPane.destructiveOption", Integer.valueOf(2)); JDialog dialog = pane.createDialog(editor, null); dialog.setVisible(true); Object result = pane.getValue(); if (result == options[0]) { return JOptionPane.YES_OPTION; } else if (result == options[1]) { return JOptionPane.CANCEL_OPTION; } else if (result == options[2]) { return JOptionPane.NO_OPTION; } else { return JOptionPane.CLOSED_OPTION; } } } static public int showYesNoQuestion(Frame editor, String title, String primary, String secondary) { if (!Base.isMacOS()) { return JOptionPane.showConfirmDialog(editor, "" + "" + primary + "" + "" + secondary + "
", JOptionPane.QUESTION_MESSAGE); String[] options = new String[] { "Yes", "No" }; pane.setOptions(options); // highlight the safest option ala apple hig pane.setInitialValue(options[0]); JDialog dialog = pane.createDialog(editor, null); dialog.setVisible(true); Object result = pane.getValue(); if (result == options[0]) { return JOptionPane.YES_OPTION; } else if (result == options[1]) { return JOptionPane.NO_OPTION; } else { return JOptionPane.CLOSED_OPTION; } } } static protected File processingRoot; /** * Get reference to a file adjacent to the executable on Windows and Linux, * or inside Contents/Resources/Java on Mac OS X. */ static public File getContentFile(String name) { if (processingRoot == null) { // Get the path to the .jar file that contains Base.class String path = Base.class.getProtectionDomain().getCodeSource().getLocation().getPath(); // Path may have URL encoding, so remove it String decodedPath = PApplet.urlDecode(path); if (decodedPath.contains("/app/bin")) { // This means we're in Eclipse if (Base.isMacOS()) { processingRoot = new File(path, "../../build/macosx/work/Processing.app/Contents/Java"); } else if (Base.isWindows()) { processingRoot = new File(path, "../../build/windows/work"); } else if (Base.isLinux()) { processingRoot = new File(path, "../../build/linux/work"); } } else { // The .jar file will be in the lib folder File jarFolder = new File(decodedPath).getParentFile(); if (jarFolder.getName().equals("lib")) { // The main Processing installation directory. // This works for Windows, Linux, and Apple's Java 6 on OS X. processingRoot = jarFolder.getParentFile(); } else if (Base.isMacOS()) { // This works for Java 8 on OS X. We don't have things inside a 'lib' // folder on OS X. Adding it caused more problems than it was worth. processingRoot = jarFolder; } if (processingRoot == null || !processingRoot.exists()) { // Try working directory instead (user.dir, different from user.home) System.err.println("Could not find lib folder via " + jarFolder.getAbsolutePath() + ", switching to user.dir"); processingRoot = new File(System.getProperty("user.dir")); } } } return new File(processingRoot, name); } static public File getJavaHome() { if (isMacOS()) { //return "Contents/PlugIns/jdk1.7.0_40.jdk/Contents/Home/jre/bin/java"; File[] plugins = getContentFile("../PlugIns").listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return dir.isDirectory() && name.endsWith(".jdk") && !name.startsWith("."); } }); return new File(plugins[0], "Contents/Home/jre"); } // On all other platforms, it's the 'java' folder adjacent to Processing return getContentFile("java"); } /** Get the path to the embedded Java executable. */ static public String getJavaPath() { String javaPath = "bin/java" + (isWindows() ? ".exe" : ""); File javaFile = new File(getJavaHome(), javaPath); try { return javaFile.getCanonicalPath(); } catch (IOException e) { return javaFile.getAbsolutePath(); } } /** * Return a File from inside the Processing 'lib' folder. */ static public File getLibFile(String filename) throws IOException { return new File(getContentFile("lib"), filename); } /** * Return an InputStream for a file inside the Processing lib folder. */ static public InputStream getLibStream(String filename) throws IOException { return new FileInputStream(getLibFile(filename)); } // Note: getLibImage() has moved to Toolkit // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . /** * Get the number of lines in a file by counting the number of newline * characters inside a String (and adding 1). */ static public int countLines(String what) { int count = 1; for (char c : what.toCharArray()) { if (c == '\n') count++; } return count; } /** * Same as PApplet.loadBytes(), however never does gzip decoding. */ static public byte[] loadBytesRaw(File file) throws IOException { int size = (int) file.length(); FileInputStream input = new FileInputStream(file); byte buffer[] = new byte[size]; int offset = 0; int bytesRead; while ((bytesRead = input.read(buffer, offset, size-offset)) != -1) { offset += bytesRead; if (bytesRead == 0) break; } input.close(); // weren't properly being closed input = null; return buffer; } /** * Read from a file with a bunch of attribute/value pairs * that are separated by = and ignore comments with #. * Changed in 3.0a6 to return null (rather than empty hash) if no file, * and changed return type to Map instead of HashMap. */ static public Map readSettings(File inputFile) { if (!inputFile.exists()) { if (DEBUG) System.err.println(inputFile + " does not exist."); return null; } String lines[] = PApplet.loadStrings(inputFile); if (lines == null) { System.err.println("Could not read " + inputFile); return null; } return readSettings(inputFile.toString(), lines); } /** * Parse a String array that contains attribute/value pairs separated * by = (the equals sign). The # (hash) symbol is used to denote comments. * Comments can be anywhere on a line. Blank lines are ignored. * In 3.0a6, no longer taking a blank HahMap as param; no cases in the main * PDE code of adding to a (Hash)Map. Also returning the Map instead of void. * Both changes modify the method signature, but this was only used by the * contrib classes. */ static public Map readSettings(String filename, String[] lines) { Map settings = new HashMap(); for (String line : lines) { // Remove comments int commentMarker = line.indexOf('#'); if (commentMarker != -1) { line = line.substring(0, commentMarker); } // Remove extra whitespace line = line.trim(); if (line.length() != 0) { int equals = line.indexOf('='); if (equals == -1) { if (filename != null) { System.err.println("Ignoring illegal line in " + filename); System.err.println(" " + line); } } else { String attr = line.substring(0, equals).trim(); String valu = line.substring(equals + 1).trim(); settings.put(attr, valu); } } } return settings; } static public void copyFile(File sourceFile, File targetFile) throws IOException { BufferedInputStream from = new BufferedInputStream(new FileInputStream(sourceFile)); BufferedOutputStream to = new BufferedOutputStream(new FileOutputStream(targetFile)); byte[] buffer = new byte[16 * 1024]; int bytesRead; while ((bytesRead = from.read(buffer)) != -1) { to.write(buffer, 0, bytesRead); } from.close(); from = null; to.flush(); to.close(); to = null; targetFile.setLastModified(sourceFile.lastModified()); targetFile.setExecutable(sourceFile.canExecute()); } /** * Grab the contents of a file as a string. */ static public String loadFile(File file) throws IOException { String[] contents = PApplet.loadStrings(file); if (contents == null) return null; return PApplet.join(contents, "\n"); } /** * Spew the contents of a String object out to a file. */ static public void saveFile(String str, File file) throws IOException { File temp = File.createTempFile(file.getName(), null, file.getParentFile()); try { // fix from cjwant to prevent symlinks from being destroyed. File canon = file.getCanonicalFile(); // assign the var as second step since previous line may throw exception file = canon; } catch (IOException e) { throw new IOException("Could not resolve canonical representation of " + file.getAbsolutePath()); } // Can't use saveStrings() here b/c Windows will add a ^M to the file PrintWriter writer = PApplet.createWriter(temp); writer.print(str); boolean error = writer.checkError(); // calls flush() writer.close(); // attempt to close regardless if (error) { throw new IOException("Error while trying to save " + file); } // remove the old file before renaming the temp file if (file.exists()) { boolean result = file.delete(); if (!result) { throw new IOException("Could not remove old version of " + file.getAbsolutePath()); } } boolean result = temp.renameTo(file); if (!result) { throw new IOException("Could not replace " + file.getAbsolutePath() + " with " + temp.getAbsolutePath()); } } /** * Copy a folder from one place to another. This ignores all dot files and * folders found in the source directory, to avoid copying silly .DS_Store * files and potentially troublesome .svn folders. */ static public void copyDir(File sourceDir, File targetDir) throws IOException { if (sourceDir.equals(targetDir)) { final String urDum = "source and target directories are identical"; throw new IllegalArgumentException(urDum); } targetDir.mkdirs(); String files[] = sourceDir.list(); for (int i = 0; i < files.length; i++) { // Ignore dot files (.DS_Store), dot folders (.svn) while copying if (files[i].charAt(0) == '.') continue; //if (files[i].equals(".") || files[i].equals("..")) continue; File source = new File(sourceDir, files[i]); File target = new File(targetDir, files[i]); if (source.isDirectory()) { //target.mkdirs(); copyDir(source, target); target.setLastModified(source.lastModified()); } else { copyFile(source, target); } } } static public void copyDirNative(File sourceDir, File targetDir) throws IOException { Process process = null; if (Base.isMacOS() || Base.isLinux()) { process = Runtime.getRuntime().exec(new String[] { "cp", "-a", sourceDir.getAbsolutePath(), targetDir.getAbsolutePath() }); } else { // TODO implement version that uses XCOPY here on Windows throw new RuntimeException("Not yet implemented on Windows"); } try { int result = process.waitFor(); if (result != 0) { throw new IOException("Error while copying (result " + result + ")"); } } catch (InterruptedException e) { e.printStackTrace(); } } /** * Delete a file or directory in a platform-specific manner. Removes a File * object (a file or directory) from the system by placing it in the Trash * or Recycle Bin (if available) or simply deleting it (if not). * * When the file/folder is on another file system, it may simply be removed * immediately, without additional warning. So only use this if you want to, * you know, "delete" the subject in question. * * NOTE: Not yet tested nor ready for prime-time. * * @param file the victim (a directory or individual file) * @return true if all ends well * @throws IOException what went wrong */ static public boolean platformDelete(File file) throws IOException { return platform.deleteFile(file); } /** * Remove all files in a directory and the directory itself. */ static public void removeDir(File dir) { if (dir.exists()) { removeDescendants(dir); if (!dir.delete()) { System.err.println("Could not delete " + dir); } } } /** * Recursively remove all files within a directory, * used with removeDir(), or when the contents of a dir * should be removed, but not the directory itself. * (i.e. when cleaning temp files from lib/build) */ static public void removeDescendants(File dir) { if (!dir.exists()) return; String files[] = dir.list(); for (int i = 0; i < files.length; i++) { if (files[i].equals(".") || files[i].equals("..")) continue; File dead = new File(dir, files[i]); if (!dead.isDirectory()) { if (!Preferences.getBoolean("compiler.save_build_files")) { if (!dead.delete()) { // temporarily disabled System.err.println("Could not delete " + dead); } } } else { removeDir(dead); //dead.delete(); } } } /** * Calculate the size of the contents of a folder. * Used to determine whether sketches are empty or not. * Note that the function calls itself recursively. */ static public int calcFolderSize(File folder) { int size = 0; String files[] = folder.list(); // null if folder doesn't exist, happens when deleting sketch if (files == null) return -1; for (int i = 0; i < files.length; i++) { if (files[i].equals(".") || files[i].equals("..") || files[i].equals(".DS_Store")) continue; File fella = new File(folder, files[i]); if (fella.isDirectory()) { size += calcFolderSize(fella); } else { size += (int) fella.length(); } } return size; } /** * Recursively creates a list of all files within the specified folder, * and returns a list of their relative paths. * Ignores any files/folders prefixed with a dot. */ // static public String[] listFiles(String path, boolean relative) { // return listFiles(new File(path), relative); // } static public String[] listFiles(File folder, boolean relative) { String path = folder.getAbsolutePath(); Vector vector = new Vector(); listFiles(relative ? (path + File.separator) : "", path, null, vector); String outgoing[] = new String[vector.size()]; vector.copyInto(outgoing); return outgoing; } static public String[] listFiles(File folder, boolean relative, String extension) { String path = folder.getAbsolutePath(); Vector vector = new Vector(); if (extension != null) { if (!extension.startsWith(".")) { extension = "." + extension; } } listFiles(relative ? (path + File.separator) : "", path, extension, vector); String outgoing[] = new String[vector.size()]; vector.copyInto(outgoing); return outgoing; } static protected void listFiles(String basePath, String path, String extension, Vector vector) { File folder = new File(path); String[] list = folder.list(); if (list != null) { for (String item : list) { if (item.charAt(0) == '.') continue; if (extension == null || item.toLowerCase().endsWith(extension)) { File file = new File(path, item); String newPath = file.getAbsolutePath(); if (newPath.startsWith(basePath)) { newPath = newPath.substring(basePath.length()); } // only add if no ext or match if (extension == null || item.toLowerCase().endsWith(extension)) { vector.add(newPath); } if (file.isDirectory()) { // use absolute path listFiles(basePath, file.getAbsolutePath(), extension, vector); } } } } } /** * @param folder source folder to search * @return a list of .jar and .zip files in that folder */ static public File[] listJarFiles(File folder) { return folder.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return (!name.startsWith(".") && (name.toLowerCase().endsWith(".jar") || name.toLowerCase().endsWith(".zip"))); } }); } ///////////////////////////////////////////////////////////////////////////// /** * Given a folder, return a list of absolute paths to all jar or zip files * inside that folder, separated by pathSeparatorChar. * * This will prepend a colon (or whatever the path separator is) * so that it can be directly appended to another path string. * * As of 0136, this will no longer add the root folder as well. * * This function doesn't bother checking to see if there are any .class * files in the folder or within a subfolder. */ static public String contentsToClassPath(File folder) { if (folder == null) return ""; StringBuilder sb = new StringBuilder(); String sep = System.getProperty("path.separator"); try { String path = folder.getCanonicalPath(); // When getting the name of this folder, make sure it has a slash // after it, so that the names of sub-items can be added. if (!path.endsWith(File.separator)) { path += File.separator; } String list[] = folder.list(); for (int i = 0; i < list.length; i++) { // Skip . and ._ files. Prior to 0125p3, .jar files that had // OS X AppleDouble files associated would cause trouble. if (list[i].startsWith(".")) continue; if (list[i].toLowerCase().endsWith(".jar") || list[i].toLowerCase().endsWith(".zip")) { sb.append(sep); sb.append(path); sb.append(list[i]); } } } catch (IOException e) { e.printStackTrace(); // this would be odd } return sb.toString(); } /** * A classpath, separated by the path separator, will contain * a series of .jar/.zip files or directories containing .class * files, or containing subdirectories that have .class files. * * @param path the input classpath * @return array of possible package names */ static public String[] packageListFromClassPath(String path) { Map map = new HashMap(); String pieces[] = PApplet.split(path, File.pathSeparatorChar); for (int i = 0; i < pieces.length; i++) { //System.out.println("checking piece '" + pieces[i] + "'"); if (pieces[i].length() == 0) continue; if (pieces[i].toLowerCase().endsWith(".jar") || pieces[i].toLowerCase().endsWith(".zip")) { //System.out.println("checking " + pieces[i]); packageListFromZip(pieces[i], map); } else { // it's another type of file or directory File dir = new File(pieces[i]); if (dir.exists() && dir.isDirectory()) { packageListFromFolder(dir, null, map); //importCount = magicImportsRecursive(dir, null, // map); //imports, importCount); } } } int mapCount = map.size(); String output[] = new String[mapCount]; int index = 0; Set set = map.keySet(); for (String s : set) { output[index++] = s.replace('/', '.'); } //System.arraycopy(imports, 0, output, 0, importCount); //PApplet.printarr(output); return output; } static private void packageListFromZip(String filename, Map map) { try { ZipFile file = new ZipFile(filename); Enumeration entries = file.entries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); if (!entry.isDirectory()) { String name = entry.getName(); if (name.endsWith(".class")) { int slash = name.lastIndexOf('/'); if (slash == -1) continue; String pname = name.substring(0, slash); if (map.get(pname) == null) { map.put(pname, new Object()); } } } } file.close(); } catch (IOException e) { System.err.println("Ignoring " + filename + " (" + e.getMessage() + ")"); //e.printStackTrace(); } } /** * Make list of package names by traversing a directory hierarchy. * Each time a class is found in a folder, add its containing set * of folders to the package list. If another folder is found, * walk down into that folder and continue. */ static private void packageListFromFolder(File dir, String sofar, Map map) { //String imports[], //int importCount) { //System.err.println("checking dir '" + dir + "'"); boolean foundClass = false; String files[] = dir.list(); for (int i = 0; i < files.length; i++) { if (files[i].equals(".") || files[i].equals("..")) continue; File sub = new File(dir, files[i]); if (sub.isDirectory()) { String nowfar = (sofar == null) ? files[i] : (sofar + "." + files[i]); packageListFromFolder(sub, nowfar, map); //System.out.println(nowfar); //imports[importCount++] = nowfar; //importCount = magicImportsRecursive(sub, nowfar, // imports, importCount); } else if (!foundClass) { // if no classes found in this folder yet if (files[i].endsWith(".class")) { //System.out.println("unique class: " + files[i] + " for " + sofar); map.put(sofar, new Object()); foundClass = true; } } } } static public void unzip(File zipFile, File dest) { try { FileInputStream fis = new FileInputStream(zipFile); CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32()); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum)); ZipEntry next = null; while ((next = zis.getNextEntry()) != null) { File currentFile = new File(dest, next.getName()); if (next.isDirectory()) { currentFile.mkdirs(); } else { File parentDir = currentFile.getParentFile(); // Sometimes the directory entries aren't already created if (!parentDir.exists()) { parentDir.mkdirs(); } currentFile.createNewFile(); unzipEntry(zis, currentFile); } } } catch (Exception e) { e.printStackTrace(); } } static protected void unzipEntry(ZipInputStream zin, File f) throws IOException { FileOutputStream out = new FileOutputStream(f); byte[] b = new byte[512]; int len = 0; while ((len = zin.read(b)) != -1) { out.write(b, 0, len); } out.flush(); out.close(); } static public void log(Object from, String message) { if (DEBUG) { System.out.println(from.getClass().getName() + ": " + message); } } static public void log(String message) { if (DEBUG) { System.out.println(message); } } static public void logf(String message, Object... args) { if (DEBUG) { System.out.println(String.format(message, args)); } } static public void loge(String message, Throwable e) { if (DEBUG) { System.err.println(message); e.printStackTrace(); } } static public void loge(String message) { if (DEBUG) { System.out.println(message); } } }| Web Proxy Viewer | New URL | Original Page |