If you ever need to execute AppleScript from a Java or Scala application, this code shows how to solve the programming part of this problem.
Given an AppleScript command as a Scala multiline string, like this:
// press the `fn` key twice val asCommand = """ tell application "System Events" key code 63 key code 63 end tell """
you can execute that command by calling this executeAppleScriptCommand
method:
val succeeded = executeAppleScriptCommand(asCommand)
whose source code is shown here:
/** * Executes the AppleScript command you supply as a String. * Returns `true` on success, `false` otherwise. */ def executeAppleScriptCommand(cmd: String): Boolean = { val scriptEngineManager = new ScriptEngineManager val scriptEngine = scriptEngineManager.getEngineByName("AppleScript") try { scriptEngine.eval(cmd) true } catch { case e: Throwable => logger.error("EXCEPTION in AppleScriptUtils::executeAppleScriptCommand") logger.error(e.getStackTrace.mkString("\n")) false } }
Of course there are other/better ways to handle the exceptions that can be thrown, but this gets you pointed in the right direction.
I use this code in my Sarah application, and I’m also using it in a new OS X “iTunes Alarm Clock” application I’m writing.
About the AppleScript command I showed
As the comment in the source code shows, the AppleScript command I shared at the start of this article emulates pressing the fn
key on a Mac keyboard twice. I use this AppleScript code to automatically start the OS X speech recognition software whenever my new Sarah JFrame
gets a WindowFocus
event.
The AppleScript/Java configuration solution
As I mentioned, that covers the “programming side” of this solution. Starting somewhere around Mac OS X 10.7 or 10.8 and Java 7, you also need to add some configuration magic to your application. I describe that magic in this brief article, Configuring AppleScript to work with Java 7 and Mac OS X.
I don’t yet know if that solution works with Java 8 on the Mac platform, but I haven’t read anything that says there is a new approach on Java 8, so at the moment I assume it works there as well.
A more functional approach
As I mentioned, the method shown above isn’t very functional. Its return value depends on things besides its input parameter, and in other ways it can be made better. I fix all of these problems in a blog post titled, “Using functional programming (FP) thinking to make a Scala method better.”