removing apple.jar, modify ThinkDifferent to use Java 9+ Desktop APIs

This commit is contained in:
Ben Fry
2019-10-08 17:51:30 -04:00
parent 2a8ed1ee8a
commit e78f0a0226
6 changed files with 42 additions and 224 deletions
-1
View File
@@ -11,7 +11,6 @@
<classpathentry kind="lib" path="lib/jna-platform.jar"/>
<classpathentry exported="true" kind="lib" path="lib/ant.jar"/>
<classpathentry exported="true" kind="lib" path="lib/ant-launcher.jar"/>
<classpathentry kind="lib" path="/processing4-core/apple.jar"/>
<classpathentry kind="lib" path="/processing4-core/library-test/junit-4.8.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+16 -117
View File
@@ -28,29 +28,16 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import com.apple.eio.FileManager;
import processing.app.Base;
import processing.app.Messages;
import processing.app.platform.DefaultPlatform;
/**
* Platform handler for Mac OS X.
* Platform handler for macOS.
*/
public class MacPlatform extends DefaultPlatform {
// Removing for 2.0b8 because Quaqua doesn't have OS X 10.8 version.
/*
public void setLookAndFeel() throws Exception {
// Use the Quaqua L & F on OS X to make JFileChooser less awful
UIManager.setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel");
// undo quaqua trying to fix the margins, since we've already
// hacked that in, bit by bit, over the years
UIManager.put("Component.visualMargin", new Insets(1, 1, 1, 1));
}
*/
public void saveLanguage(String language) {
String[] cmdarray = new String[]{
"defaults", "write",
@@ -69,33 +56,6 @@ public class MacPlatform extends DefaultPlatform {
super.initBase(base);
System.setProperty("apple.laf.useScreenMenuBar", "true");
ThinkDifferent.init(base);
/*
try {
String name = "processing.app.macosx.ThinkDifferent";
Class osxAdapter = ClassLoader.getSystemClassLoader().loadClass(name);
Class[] defArgs = { Base.class };
Method registerMethod = osxAdapter.getDeclaredMethod("register", defArgs);
if (registerMethod != null) {
Object[] args = { this };
registerMethod.invoke(osxAdapter, args);
}
} catch (NoClassDefFoundError e) {
// This will be thrown first if the OSXAdapter is loaded on a system without the EAWT
// because OSXAdapter extends ApplicationAdapter in its def
System.err.println("This version of Mac OS X does not support the Apple EAWT." +
"Application Menu handling has been disabled (" + e + ")");
} catch (ClassNotFoundException e) {
// This shouldn't be reached; if there's a problem with the OSXAdapter
// we should get the above NoClassDefFoundError first.
System.err.println("This version of Mac OS X does not support the Apple EAWT. " +
"Application Menu handling has been disabled (" + e + ")");
} catch (Exception e) {
System.err.println("Exception while loading BaseOSX:");
e.printStackTrace();
}
*/
}
@@ -106,30 +66,9 @@ public class MacPlatform extends DefaultPlatform {
public File getDefaultSketchbookFolder() throws Exception {
return new File(getDocumentsFolder(), "Processing");
/*
// looking for /Users/blah/Documents/Processing
try {
Class clazz = Class.forName("processing.app.BaseMacOS");
Method m = clazz.getMethod("getDocumentsFolder", new Class[] { });
String documentsPath = (String) m.invoke(null, new Object[] { });
sketchbookFolder = new File(documentsPath, "Processing");
} catch (Exception e) {
sketchbookFolder = promptSketchbookLocation();
}
*/
}
// /**
// * Moves the specified File object (which might be a file or folder)
// * to the trash.
// */
// public boolean deleteFile(File file) throws IOException {
// return FileManager.moveToTrash(file);
// }
public void openURL(String url) throws Exception {
try {
Desktop.getDesktop().browse(new URI(url));
@@ -145,64 +84,23 @@ public class MacPlatform extends DefaultPlatform {
}
/*
public void openURL(String url) throws Exception {
if (PApplet.javaVersion < 1.6f) {
if (url.startsWith("http://")) {
// formerly com.apple.eio.FileManager.openURL(url);
// but due to deprecation, instead loading dynamically
try {
Class<?> eieio = Class.forName("com.apple.eio.FileManager");
Method openMethod =
eieio.getMethod("openURL", new Class[] { String.class });
openMethod.invoke(null, new Object[] { url });
} catch (Exception e) {
e.printStackTrace();
}
} else {
// Assume this is a file instead, and just open it.
// Extension of http://dev.processing.org/bugs/show_bug.cgi?id=1010
processing.core.PApplet.open(url);
}
} else {
try {
Class<?> desktopClass = Class.forName("java.awt.Desktop");
Method getMethod = desktopClass.getMethod("getDesktop");
Object desktop = getMethod.invoke(null, new Object[] { });
// for Java 1.6, replacing with java.awt.Desktop.browse()
// and java.awt.Desktop.open()
if (url.startsWith("http://")) { // browse to a location
Method browseMethod =
desktopClass.getMethod("browse", new Class[] { URI.class });
browseMethod.invoke(desktop, new Object[] { new URI(url) });
} else { // open a file
Method openMethod =
desktopClass.getMethod("open", new Class[] { File.class });
openMethod.invoke(desktop, new Object[] { new File(url) });
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public boolean openFolderAvailable() {
return true;
}
public void openFolder(File file) throws Exception {
//openURL(file.getAbsolutePath()); // handles char replacement, etc
processing.core.PApplet.open(file.getAbsolutePath());
}
*/
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// TODO I suspect this won't work much longer, since access to the user's
// home directory seems verboten on more recent macOS versions [fry 191008]
protected String getLibraryFolder() throws FileNotFoundException {
return System.getProperty("user.home") + "/Library";
}
// see notes on getLibraryFolder()
protected String getDocumentsFolder() throws FileNotFoundException {
return System.getProperty("user.home") + "/Documents";
}
/*
// Some of these are supposedly constants in com.apple.eio.FileManager,
// however they don't seem to link properly from Eclipse.
@@ -237,4 +135,5 @@ public class MacPlatform extends DefaultPlatform {
protected String getDocumentsFolder() throws FileNotFoundException {
return FileManager.findFolder(kUserDomain, kDocumentsFolderType);
}
*/
}
@@ -22,19 +22,17 @@
package processing.app.platform;
import java.awt.event.*;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import javax.swing.*;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import com.apple.eawt.Application;
import processing.app.*;
import processing.app.Base;
import processing.app.Language;
import processing.app.ui.About;
import processing.app.ui.Toolkit;
@@ -52,131 +50,52 @@ import processing.app.ui.Toolkit;
*/
public class ThinkDifferent {
// pseudo-singleton model; no point in making multiple instances
// of the EAWT application or our adapter
private static ThinkDifferent adapter;
// http://developer.apple.com/documentation/Java/Reference/1.4.2/appledoc/api/com/apple/eawt/Application.html
private static Application application;
// reference to the app where the existing quit, about, prefs code is
//private Base base;
static private ThinkDifferent adapter;
static protected void init(final Base base) {
if (application == null) {
application = Application.getApplication();
}
final Desktop desktop = Desktop.getDesktop();
if (adapter == null) {
adapter = new ThinkDifferent(); //base);
adapter = new ThinkDifferent();
}
setHandler(application, "setAboutHandler", (proxy, method, args) -> {
desktop.setAboutHandler((event) -> {
new About(null);
return null;
});
setHandler(application, "setPreferencesHandler", (proxy, method, args) -> {
desktop.setPreferencesHandler((event) -> {
base.handlePrefs();
return null;
});
setHandler(application, "setOpenFileHandler", (proxy, method, args) -> {
Method m = args[0].getClass().getMethod("getFiles");
for (File file : (List<File>) m.invoke(args[0])) {
desktop.setOpenFileHandler((event) -> {
for (File file : event.getFiles()) {
base.handleOpen(file.getAbsolutePath());
}
return null;
});
setHandler(application, "setPrintFileHandler", (proxy, method, args) -> {
desktop.setPrintFileHandler((event) -> {
// TODO not yet implemented
return null;
});
setHandler(application, "setQuitHandler", (proxy, method, args) -> {
desktop.setQuitHandler((event, quitResponse) -> {
if (base.handleQuit()) {
args[1].getClass().getMethod("performQuit").invoke(args[1]);
quitResponse.performQuit();
} else {
args[1].getClass().getMethod("cancelQuit").invoke(args[1]);
quitResponse.cancelQuit();
}
return null;
});
// Set the menubar to be used when nothing else is open.
// Set the menu bar to be used when nothing else is open.
JMenuBar defaultMenuBar = new JMenuBar();
JMenu fileMenu = buildFileMenu(base);
defaultMenuBar.add(fileMenu);
// This is kind of a gross way to do this, but the alternatives? Hrm.
Base.defaultFileMenu = fileMenu;
// if (PApplet.javaVersion <= 1.6f) { // doesn't work on Oracle's Java
try {
application.setDefaultMenuBar(defaultMenuBar);
} catch (Exception e) {
e.printStackTrace(); // oh well, never mind
}
// } else {
// // The douchebags at Oracle didn't feel that a working f*king menubar
// // on OS X was important enough to make it into the 7u40 release.
// //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8007267
// // It languished in the JDK 8 source and has been backported for 7u60:
// //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8022667
//
// JFrame offscreen = new JFrame();
// offscreen.setUndecorated(true);
// offscreen.setJMenuBar(defaultMenuBar);
// Dimension screen = Toolkit.getScreenSize();
// offscreen.setLocation(screen.width, screen.height);
// offscreen.setVisible(true);
// }
desktop.setDefaultMenuBar(defaultMenuBar);
}
// public ThinkDifferent(Base base) {
// this.base = base;
// }
/**
* Sets a handler on an instance of {@link Application}, taking into account JVM version
* differences.
*
* @param app an instance of {@link Application}
* @param name the "set handler" method name
* @param handler the handler
*/
private static void setHandler(Application app, String name, InvocationHandler handler) {
// Determine which version of com.apple.eawt.Application to use and pass it a handler of the
// appropriate type
Method[] methods = app.getClass().getMethods();
for (Method m : methods) {
if (!name.equals(m.getName())) {
continue;
}
if (m.getParameterCount() != 1) {
continue;
}
Class paramType = m.getParameterTypes()[0];
try {
// Allow a null handler
Object proxy = null;
if (handler != null) {
proxy = Proxy.newProxyInstance(
paramType.getClassLoader(), new Class<?>[] { paramType }, handler);
}
m.invoke(app, proxy);
} catch (IllegalArgumentException ex) {
// TODO: Print error?: method doesn't take an interface, etc.
} catch (IllegalAccessException ex) {
// TODO: Print error?: Other method invocation problem
} catch (InvocationTargetException ex) {
ex.getCause().printStackTrace();
// TODO: Print ex.getCause() a different way?
}
break;
}
}
/**
* Gimpy file menu to be used on OS X when no sketches are open.
*/
BIN
View File
Binary file not shown.
-3
View File
@@ -18,8 +18,6 @@
</target>
<path id="classpath.base">
<!-- kinda gross, but if not using the JDT, this just ignored anyway -->
<pathelement location="apple.jar" />
<pathelement location="library/jogl-all.jar" />
<pathelement location="library/gluegen-rt.jar" />
<pathelement location="library/javafx-swt.jar" />
@@ -61,7 +59,6 @@
</or>
</condition>
<!-- link against apple.jar for the ThinkDifferent class -->
<mkdir dir="@{destdir}" />
<javac source="11"
target="11"
+4
View File
@@ -7,6 +7,10 @@ X edit build.xml files and appbundler to preserve more attributes
after the JDK 11 update
X use a new pref for the sketchbook folder location for 4.x
X finish porting ThinkDifferent to use Desktop APIs
X http://openjdk.java.net/jeps/272
_ Implement reliable getLibraryFolder() and getDocumentsFolder() methods in MacPlatform
_ https://github.com/processing/processing4/issues/9
major updates for JDK 11 et al
X https://github.com/processing/processing4/pull/1