Java Development Guide For Mac OS X: Tools & Languages: Other Languages
Java Development Guide For Mac OS X: Tools & Languages: Other Languages
2010-10-20
Apple Inc. 2003, 2010 Apple Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer for personal use only and to print copies of documentation for personal use provided that the documentation contains Apples copyright notice. The Apple logo is a trademark of Apple Inc. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-labeled computers. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010 .Mac is a registered service mark of Apple Inc. Apple, the Apple logo, AppleScript, Aqua, Cocoa, eMac, Finder, Keychain, Leopard, Mac, Mac OS, Macintosh, Objective-C, Quartz, QuickTime, Safari, Snow Leopard, and Xcode are trademarks of Apple Inc., registered in the United States and other countries. Intel and Intel Core are registered trademarks of Intel Corportation or its subsidiaries in the United States and other countries. Java is a registered trademark of Oracle and/or its affiliates. UNIX is a registered trademark of The Open Group
Even though Apple has reviewed this document, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED AS IS, AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY
DEFECT OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty. Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.
Contents
Introduction 7
Who Should Read This Document? 7 Organization of This Document 7 See Also 8 Filing and Tracking Bugs 8
3
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
4
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
5
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
6
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Introduction
Note: As of the release of Java for Mac OS X 10.6 Update 3, the Java runtime ported by Apple and that ships with Mac OS X is deprecated. Developers should not rely on the Apple-supplied Java runtime being present in future versions of Mac OS X. The Java runtime shipping in Mac OS X 10.6 Snow Leopard, and Mac OS X 10.5 Leopard, will continue to be supported and maintained through the standard support cycles of those products. The Java Platform, Standard Edition for Mac OS X provides a Java environment that is highly integrated with Mac OS X. This integration brings together the Java platforms versatility and Mac OS Xs advanced technologies to offer users a wider selection of applications and developers a first-class development and deployment platform. Mac OS X version 10.6 includes both 32-bit and 64-bit versions of Java SE 6 out of the box. This opens up the entire Mac user base to Java application and applet developers, and conversely, the world of Java applications to Mac OS X users. While Java's promise of write once, run anywhere is true on Mac OS X, there are a number of things you should do to ensure that your application's user experience adheres to conventions and behaviors that Mac users have come to expect from their applications. This document seeks to highlight these methods so you can spend your time writing applications instead of troubleshooting.
Overview of Java for Mac OS X (page 9) describes the Java platforms available on Mac OS X. Apple Developer Tools for Java (page 15) introduces you to the Apple suite of developer tools, along with recommended tools from other manufacturers.
Introduction
Java Deployment Options for Mac OS X (page 21) discusses how you can distribute your Java application on Mac OS X. Mac OS X Integration for Java (page 29) provides you with some handy tips for making your Java application act and feel more like a native Mac OS X application. User Interface Toolkits for Java (page 39) shows you the different user interface elements common in Mac OS X. Core Java APIs and the Java Runtime on Mac OS X (page 47) discusses the how core Java APIs vary on Mac OS X.
See Also
General information about Mac OS X, including more on many of the topics discussed in this document can be found in Mac OS X Technology Overview. Answers to frequently asked questions about Java for Mac OS X are addressed in the Java FAQ. General information on previous versions of Java for Mac OS X can be found in the Release Notes > Java. This document and other Java documentation for Mac OS X, including the Javadoc API reference, are available in the Java Reference Library. A subset of this documentation is installed in /Developer/Documentation/DocSets/ on a Mac OS X system with the Mac OS X Developer Tools. You can view this documentation through a web browser or through Xcode (from Xcodes Help menu, choose Documentation and then click Java). The main Apple website for Java technology, http://developer.apple.com/java/, contains links to information about Java development in Mac OS X. The java-dev mailing list is a great source of information on a wide range of Java development topics in Mac OS X. You can sign up for this list at http://lists.apple.com/. Suns Java website, http://java.sun.com/ is the essential reference point for Java development in general.
See Also
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
This article provides a broad overview of how Java fits into Mac OS X. It is suggested background information for anyone new to Java development for Mac OS X.
Java, Built In
Write once, run anywhere is true only if Java is everywhere. With Mac OS X, you know the Java Runtime is there for your applications, because it is built into the operating system. This means that when developing Java applications for deployment on Mac OS X, you know that Java is already installed and configured to work with your customers Mac. Java is the only high-level framework on Mac OS X besides Cocoa that provides a graphical toolkit for building applications. With just a little work on your part, Java applications can be nearly indistinguishable from native applications. Information on how to achieve this is provided in Mac OS X Integration for Java (page 29). Users dont need to learn different behaviors for Java applicationsin fact, they shouldnt even know that applications are Java applications. When developing with Java in Mac OS X, you are encouraged to create applications that target the oldest possible Java version but launch with the newest available version. In this way, you accommodate the largest possible audience, and at the same time take advantage of the speedups and operating system integration that later versions afford.
Note: There is no redistribution license for the Java technology built into Mac OS X. If your customers need a specific update of the Java runtime and they do not have it, they should get it directly from Apple via Software Update or the Apple Support page at http://www.apple.com/support/.
10
Figure 1
Apples Aqua look and feel and the standard Java cross-platform look and feel in Mac OS X
By default, Swing applications in Mac OS X use the Aqua look and feel (LAF). Although this is the default LAF, it is not required; the standard Java cross-platform LAF is also available. While the use of the Aqua LAF is encouraged for Swing applications, different design philosophies inherent in an application might make the Aqua LAF inappropriate. To use the cross-platform LAF, modify your code to include UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassname()). Further details on the Aqua LAF are provided in User Interface Toolkits for Java (page 39).
11
Java Extensions
Java can be extended by adding custom.jar, .zip, and .class files, as well as native JNI libraries, into an extensions directory. On some platforms this is designated by the java.ext.dir system property. In Mac OS X, put your extensions in /Library/Java/Extensions/. Java automatically looks in this directory as it is starting up the Java Virtual Machine. Putting extensions in /Library/Java/Extensions/ loads those extensions for every user on that particular computer. It is preferable to limit which users can use certain extensions by putting them in the ~/Library/Java/Extensions/ directory inside the appropriate users home directories. By default, that folder does not exist, so you may need to make it. Try to include all of your dependent libraries in your application rather than relying on the Java Extensions directory, because its contents are unversioned and cannot accommodate for multiple versions of the same library.
12
13
14
This article provides a broad overview of recommended tools for Java development. It covers integrated development environments (IDEs) from other manufacturers, Apples own Xcode IDE, the Jar Bundler application, and methods for obtaining and viewing documentation.
The installed location of the JDK command-line tools is different in Mac OS X. These tools are installed with the rest of JavaVM.framework in /System. The Java tools provided in the default path in /usr/bin/ will execute the version of Java the user has selected as their preferred version for applications in Java Preferences. For more on Java Preferences, see Other Tools (page 18). For more information on overall differences in where Java components are in Mac OS X, see Finding Your Way Around (page 12).
tools.jar does not exist. Classes usually located here are instead included in classes.jar. Scripts that rely on the existence of tools.jar need to be rewritten accordingly.
Java IDEs
Java development on any platform often benefits from the use of an Integrated Development Environment (IDE), which provides a more fluid workflow between writing, compiling, running, debugging, and packaging Java code than a simple text editor and the command line. Different IDEs offer unique features and are often suited for different kinds of Java development. These IDEs are industry leaders and offer substantial support for Mac OS X:
Eclipse IDE for Java Developers (http://www.eclipse.org) is a free download. Netbeans IDE (http://www.netbeans.org) is a free download. Jetbrains IntelliJ IDEA (http://www.jetbrains.com/idea/) requires a license for continued use after a trial period. Xcode (http://developer.apple.com/tools/xcode/) is a free download with a free account from the Apple Developer Connection.
15
If you are developing a JNI library or intend to have your application communicate with Cocoa, you should plan to use the Xcode Tools for those portions of your development. For more information on JNI development, see JNI (page 47).
Xcode Tools
Apple provides a full suite of general developer tools with Mac OS X. This suite of tools, the Xcode Tools, is free but not installed by default. The tools are available for download at the Apple Developer Connection (ADC) Member Site http://connect.apple.com/. If you do not have an ADC membership, you can enroll for various levels of membership, including a free online membership that allows you access to the member site, at http://developer.apple.com/products/.
Command-line tools, installed in /Developer/Tools/ Graphical tools, installed in /Developer/Applications/ Sample code, installed in /Developer/Extras/Java/
Xcode
The core component of the Mac OS X development environment is Xcode. Xcode is a complete IDE that allows you to edit, compile, debug, and package Mac OS X applications written in multiple languages. Even if you do not intend to use it for your primary Java development, it is helpful to become familiar with Xcode. Downloadable sample code and the sample code installed in /Developer/Extras/Java/ are both usually provided as Xcode projects. Additionally, there are some elements of documentation viewing that are available only through Xcode. For more on using Xcode for Java development, see the Xcode Help menu.
16
Xcode Tools
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Figure 1
The Organizer shows your project exactly as it is laid out in the file system. This is in contrast to the main Xcode project windows, which allow you to arrange files arbitrarily without altering their location on disk. The Organizers direct reflection of the file system better serves Java development and is similar to other Java IDEs. To create a new Java project in Xcode, choose New From Template from the New menu in the bottom-left corner of the Organizer.
Xcode Tools
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
17
Jar Bundler
Jar Bundler is an application that takes Java applications deployed as standalone Jar files and turns them into applications that can be launched just like native Mac OS X applications. Although the Terminal application is a part of every installation of Mac OS X, many Mac OS X users never use it. To prevent your users from having to use Terminal for your Java applications, you should wrap your application as a Mac OS X application bundle (see Mac OS X Application Bundles (page 22)). Jar Bundler allows you to do this very easily. It also provides a simple interface for you to set system properties that make your applications perform their best in Mac OS X. Jar Bundler is available in /Developer/Applications/Utilities/. More information on Jar Bundler is available in Jar Bundler User Guide.
Applet Launcher
Applet Launcher (in /Developer/Applications/Utilities/) provides a graphical interface to Suns Java Plug-in. Applet Launcher loads an applet from an HTML page. For example, entering the following URL launches the ArcTest applet:
file:///Developer/Extras/Java/Applets/ArcTest/example1.html
Applet Launcher is useful for testing your applets in Mac OS X. Performance and behavior settings for applets may be adjusted in the Java Preferences application installed in /Applications/Utilities/.
Other Tools
In addition to containing Xcode and Jar Bundler, /Developer/Applications/Utilities/ contains some applications that you can use for Java development though they are not Java-specific:
Package Maker helps you create an installer PKG for your application. File Merge provides a graphical interface for comparing and merging source files. Icon Composer helps you create an ICNS file for your application bundle.
Additional development tools for Java and other languages can be found in /usr/share/. Of particular use for Java development are:
18
Other Tools
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Apache Ant, a tool for automating builds. The Ant executable can also be found in /usr/bin/. Apache Maven, a tool for consolidating multiple elements of development, including dependency management and release management. Derby, a lightweight database.
Developer Documentation
Documentation for Java development in Mac OS X is provided both online and as a download from Apple Developer Connection. The most current version of the documentation is available from the Java Reference Library on the Apple Developer Connection website. A snapshot of this documentation is also installed on your computer when you install the Java documentation package. This documentation is easily accessible in Xcode by selecting Documentation from the Help menu. Man pages for the command-line tools are accessible from the command line man program and through the Xcode Help menu. Suns Java SE 6 API documentation is available in
/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/docs.jar. Documentation for Apples Java extensions is available in appledocs.jar in the same directory.
Note that Apple does not attempt to provide a full Java documentation suite online or with the Xcode Tools. Sun supplies very thorough documentation available online at http://java.sun.com/reference/docs/. Apples documentation only aims to augment Suns documentation for Java development issues specific to Mac OS X and to document Mac OS Xspecific features of Java. Your primary source for Java platform documentation is Suns Java documentation website.
Developer Documentation
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
19
20
Developer Documentation
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
When deploying Java applications in Mac OS X, you can use Java Web Start and web browser applets as you can on other platforms. You may also deploy Java applications as native Mac OS X application bundles. This article discusses these deployment technologies. Make sure you know whether you are using a 32-bit or a 64-bit version of Java to ensure that your application is compatible with the architectures you are writing for.
<?xml version="1.0" encoding="UTF-8"?> <jnlp spec="1.0+" codebase="http://developer.apple.com/java/javawebstart/apps/welcome" href="JWS_Demo.jnlp"> <information> <title>Welcome to Web Start!</title> <vendor>Apple Computer, Inc.</vendor> <homepage href="http://developer.apple.com/java/javawebstart" /> <offline-allowed /> </information> <resources> <j2se version="1.5+" /> <jar href="WebStartDemo.jar" /> </resources> <application-desc main-class="apple.dts.javawebstart.DemoMain" /> </jnlp>
Mac OS Xs desktop integration with Java Web Start lets users can create a local application bundle from any Java Web Start application. The Shortcut Creation setting in Java Preferences controls whether the user is prompted to create an application bundle when opening a Java Web Start application. Bundled Java Web Start applications have all of the benefits of native application bundles, which are described in Mac OS X Application Bundles. You need to be aware of only a few details about how the Mac OS X implementation of Java Web Start differs from the Windows and Solaris versions:
21
Java Web Start on the Mac does not support downloading of additional Java Runtime Environments (JREs). New Java versions are provided by Apple via Software Update to all current Mac OS X customers. Valid version keys for Mac OS X application bundles are the same as those of Java Web Start. A list of these keys can be found in Java Dictionary Info.plist Keys. It is not necessary to set up proxy information explicitly in the Web Start application. Java Web Start in Mac OS X automatically picks up the proxy settings from the Network pane in System Preferences. Java Web Start caches its data in the users ~/Library/Caches/Java/ directory.
Users can simply double-click the application to launch it. They can also drag it to the Trash to delete it. Users can add your application to their Dock. This is not possible without a complete Mac OS X application bundle. If you add an appropriate icon, it shows the application icon in the Dock, clearly identifying your application. (Otherwise, a default Java coffee cup icon appears in the Dock.) You can easily set Mac OS Xspecific system properties that can make your Java application look more like a native application. You can associate specific document types with your application. This lets users launch your application by double-clicking a document created by your application.
22
Figure 1
Applications bundles for Java applications should have the following components:
An Info.plist file in the Contents folder. This contains important information that Mac OS X uses to set up the Java runtime environment for your application. More information about these property lists is in Java Dictionary Info.plist Keys. A file named PkgInfo should also be in the Contents folder. This is a simple text file that contains the string APPL optionally concatenated with a four letter creator code. If an application does not have a registered creator code, the string APPL???? should be used. You may register your application with Apples creator code database on the ADC Creator Code Registration site at http://developer.apple.com/datatype/. The applications icon that is displayed in the Dock and the Finder should be in the Resources folder. There is a Mac OS Xspecific file type designated by the .icns suffix, but most common image types work. To make an icon (.icns) file from your images, use the Icon Composer application installed in /Developer/Applications/Utilities/. The Java code itself, in either .jar or .class files, in the Resources folder. A native executable stub in the MacOS folder that launches the Java VM. This stub should only contain the architectures your application supports. Typically, pure Java applications should use the default ppc, i386, and x86_64 Universal stub in order to launch in as many Java VMs and as many versions of Mac OS X as possible. Images (PNG, ICNS, PDF, and so on) used in your application should be in the Resources folder. These images can be accessed in you application with the AWT Toolkit by calling java.awt.Toolkit.getDefaultToolkit().getImage("NSImage://your-image-name"). Optional localized versions of strings may be included in folders designated by the .lproj suffix. If your application contains localized strings, you must include corresponding .lproj folders in your bundle, even if the strings are in .properties files in a Jar. See Localizing Java Applications (page 25) for more information on localized application bundles.
There are other files in the application bundle, but these are the ones that you should have in a Java application bundle. You can learn more about the other files in an application bundle, as well as more information about some of these items, in Framework Programming Guide.
23
If you build a new Java Swing application using one of the Xcode Organizers templates, Xcode automatically generates an application bundle complete with a default Info.plist file. You can fine-tune the Info.plist file directly in Xcode or with Property List Editor. For more information on using Xcode for Java development, see Xcode Help (available from the Help menu in Xcode). If you want to turn your existing Java application into a Mac OS X Java application, use the Jar Bundler application available in /Developer/Applications/Utilities. It allows you to take existing .class or .jar files and wrap them as application bundles. Information about Jar Bundler, including a tutorial, is provided in Jar Bundler User Guide. To build a valid application bundle from the command-line, for example, in a shell script or an Ant file, you need to follow these steps: 1. Set up the correct directory hierarchy. The top level directory should be named with the name of your application with the suffix .app.
24
There should be a Contents directory at the root of the application bundle. It should contain a MacOS directory and a Resources directory. A Java directory should be inside of the Resources directory. The directory layout should look like this:
YourApplicationName.app/ Contents/ MacOS/ Resources/ Java/
2.
3.
Make an Info.plist file in the Contents directory of your application bundle. You can start with an example from an existing Java application (such as Jar Bundler) and modify it or generate a completely new one from scratch. Note that the application bundle does not launch unless you have set the correct attributes in this property list, especially the MainClass key. Make a PkgInfo file in the Contents directory. It should be a plain text file. If you have not registered a creator code with ADC, the contents should be APPL????. If you have registered a creator code replace the ???? with your creator code. Put your applications icon file into the Contents/Resources/ directory. Use Icon Composer in Developer/Applications/Utilities for help creating your icon file. Copy your Java .jar or .class files into Contents/Resources/Java/. Set the bundle bit Finder attribute with SetFile, found in /Developer/Tools/. For example, /Developer/Tools/SetFile -a B YourApplicationName.app. For more information on SetFile, see the man page.
4.
5.
6. 7.
After these steps, you should have a double-clickable application bundle that contains your Java application.
25
26
For use in Safari, the <APPLET> tag is preferred over the <OBJECT> and <EMBED> tags. To ensure that your applet launches correctly in all browsers, see Suns Java Web App Deployment Advice.
27
28
The more your application fits in with the native environment, the less users have to learn unique behaviors to use your application. A great application looks and feels like an extension of the platform it runs on. This article discusses a few details that can help you make your application look and feel like it is an integral part of Mac OS X.
29
List File (page 24). According to the Aqua guidelines, the name you specify for the application menu should be the simplest name of the application (generally no more than 16 characters) and should not include extraneous information like a company name. Figure 1 shows an application menu. Figure 1 Application menu for a Java application in Mac OS X
The next step to customizing your application menu is to have your own handling code called when certain items in the application menu are chosen. Apple provides functionality for this in the com.apple.eawt.* Java classes. The Application and ApplicationAdaptor classes provide a way to handle the Preferences, About, and Quit items. For more information see J2SE 5.0 Apple Extensions Reference. Examples of how to use these can also be found in a default Java application project in Xcode. Just open a new project in Xcode by selecting Java Application from the Organizer window. The resulting project uses all of these handlers. For more on the Xcode Organizer, see The Xcode Organizer (page 16). If your application is to be deployed on other platforms, where Preferences, Quit, and About are elsewhere on the menu bar (in a File or Edit menu, for example), you should make this placement conditional based on the host platforms operating system. Conditional placement is preferable to just adding a second instance of each of these menu items for Mac OS X. This minor modification can go a long way to making your Java application feel more like a native application in Mac OS X. An in-depth example of conditional menu and UI handling is provided in the Xcode JNI Library project template.
30
When calling this method, the current platforms Toolkit implementation returns the proper mask. For example, in the case of adding a Copy item to a menu, using getMenuShortcutKeyMask means that you can replace the complexity of Listing 1 with the simplicity of Listing 2. Listing 1 Explicitly setting accelerators based on the host platform
JMenuItem jmi = new JMenuItem("Copy"); String vers = System.getProperty("os.name").toLowerCase(); if (s.indexOf("windows") != -1) { jmi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.CTRL_MASK)); } else if (s.indexOf("mac") != -1) { jmi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.META_MASK)); }
Listing 2
The default modifier key in Mac OS X is the Command key. There may be additional modifier keys like Shift, Option, or Control, but the Command key is the primary key that alerts an application that a command, not regular input follows. When assigning keyboard shortcuts to items for menu items, make sure that you are not overriding any of the keyboard commands that Mac users are accustomed to. See Apple Human Interface Guidelines for the definitive list of the most common and reserved keyboard shortcuts (keyboard equivalents). You should make your keyboard shortcuts conditional based on the current platform, because standard shortcuts vary across platforms.
Mnemonics
The JMenuItem class inherits the concept of mnemonics from the JAbstractButton class. In the context of menus, mnemonics are shortcuts to menus and their contents, which are executed by using a modifier key in conjunction with a single letter. When you set a mnemonic in a menu item, Java underscores the mnemonic letter in the title of the JMenuItem or JMenu component when the Option key is held down. Using mnemonics is discouraged in Mac OS X, because mnemonics violate the principles of Apple Human Interface Guidelines. If you are developing a Java application for multiple platforms and some of those platforms recommend the use of mnemonics, just include a single setMnemonics() method that is conditionally called (based on the platform) when constructing your interface. How then do you get the functionality of mnemonics without using Javas mnemonics? If you have defined a keystroke sequence in the setAccelerator() method for a menu item, that key sequence is automatically entered into your menus. For example, Listing 3 sets an accelerator of Command-Shift-S for a Save As menu. Listing 3 Setting an accelerator
JMenuItem saveAsItem = new JMenuItem("Save As..."); saveAsItem.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_S, (java.awt.event.InputEvent.SHIFT_MASK | (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())))); saveAsItem.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent e) { System.out.println("Save As...") ; } });
31
fileMenu.add(saveAsItem);
Figure 2 shows the result of this code, along with similar settings for the other items. Note that the symbols representing the Command and Shift keys are automatically included. Figure 2 A File menu
In addition to accelerators, Mac OS X provides keyboard and assistive-device navigation to the menus. Preferences for these features are set in the Keyboard and Universal Access panes of System Preferences. Note: Since the ALT_MASK modifier is the Option key in Mac OS X, Control-Alt masks set for Windows become Command-Option masks if you use getMenuShortcutKeyMask() in conjunction with ALT_MASK.
Contextual Menus
Contextual menus, which are called pop-up menus in Java, are fully supported. In Mac OS X, they are triggered by a Control-click or a right-click on mouse down. Even though both clicks trigger a contextual menu, they are not the same mouse event. In Windows, the right mouse button-up is the standard trigger for contextual menus. The different triggers present in Mac OS X could result in fragmented and conditional code. One important aspect of both triggers is sharedthe mouse click. To ensure that your program is interpreting the proper contextualmenu trigger, it is again a good idea to ask the AWT to do the interpreting for you, with java.awt.event.MouseEvent.isPopupTrigger().
32
The method is defined in java.awt.event.MouseEvent because you need to activate the contextual menu through a java.awt.event.MouseListener on a given component when a mouse event on that component is detected. The important thing to determine is how and when to detect the proper event. In Mac OS X, the pop-up trigger is set on MOUSE_PRESSED. In Windows it is set on MOUSE_RELEASED. For portability, both cases should be considered. Listing 4 Detecting contextual-menu activation
JLabel label = new JLabel("I have a pop-up menu!"); label.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e) { evaluatePopup(e); } public void mouseReleased(MouseEvent e) { evaluatePopup(e); } private void evaluatePopup(MouseEvent e) { if (e.isPopupTrigger()) { // show the pop-up menu... } } });
Like the application menu, contextual menus can differ between platforms. You should make the layout of your contextual menus conditional based on the platform. When designing contextual menus, keep in mind that a contextual menu should never be the only way a user can access something. Contextual menus provide convenient access to often-used commands associated with an item, not the primary or sole access.
The Dock
The com.apple.eawt.Application class includes the following methods for managing your Java applications Dock icon:
public java.awt.Image getDockIconImage() public void setDockIconImage(java.awt.Image) public java.awt.PopupMenu getDockMenu() public void setDockMenu(java.awt.PopupMenu) public void setDockIconBadge(String)
33
Coloring Components
Because a given look and feel tends to have universal coloring and styling for most, if not all of its controls, you may be tempted to create custom components that match the look and feel of standard user interface classes. This approach adds maintenance and portability costs that may not be apparent until Apple or the Java platform changes the default appearance. It is easy to set an explicit color that you think works well with the current look and feel. Changing to a different look and feel, though, may surprise you with an occasional nonstandard component. To ensure that your custom control matches standard components, query the UIManager class for the desired colors. One example is a custom window object that contains some standard lightweight components but wants to paint its uncovered background to match that of the rest of the applications containers and windows. To do this, you can call
myPanel.setBackground(UIManager.getColor("window"))
This call returns the color appropriate for the current look and feel. There are also a number of Mac OS X-specific colors installed in the UIManager that are used in different contexts. The following colors stay in sync with the user's color selections in the Appearance system preference pane:
There are also a number of borders installed in the UIManager that can be used to draw alternative backgrounds for certain kinds of lists. The following borders dynamically adjust to the active state of the parent window of the component they are painting:
UIManager.getBorder("List.sourceListBackgroundPainter") UIManager.getBorder("List.sourceListSelectionBackgroundPainter")
34
When you are using a host platform other than Mac OS X, you may find that the JScrollBar default policy, AS_NEEDED, more closely resembles its native behavior.
35
File-Choosing Dialogs
File-choosing dialogs in Java applications are of two main types: dialogs created with java.awt.FileDialog and those created with javax.swing.JFileChooser. Although each has its advantages, java.awt.FileDialog makes your applications behave more like a native Mac OS X application. This dialog, shown in Figure 3, looks much like a Finder window in Mac OS X. Figure 3 Dialog created with java.awt.FileDialog
The Swing dialog, shown in Figure 4, looks much less like a Mac OS X dialog.
36
Figure 4
Unless you need a functional advantage of JFileChooser, use FileDialog instead. When using FileDialog, you may want a user to select a directory instead of a file. In this case, use the apple.awt.fileDialogForDirectories property with the setProperty.invoke() method on your FileDialog instance.
Window-Modified Indicator
In Mac OS X, when a document has unsaved changes, the windows close button displays a dot. Adopting this same approach, that is, using a window-modified indicator, in your application makes it look more like a Mac OS X native application and so conform to user expectations. To display an indicator that a window was modified, you need to use the Swing property Window.documentModified. It can be set on any subclass of JComponent that implements a top-level window using the putClientProperty() method. The value of the property is either Boolean.TRUE or Boolean.FALSE. For more on using the window-modified indicator in your application, review New Control Styles available within J2SE 5.0 on Mac OS X 10.5.
37
public static void main(String[] args) throws Throwable { String script = "say \"Hello from Java\""; ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("AppleScript"); engine.eval(script); }
System Properties
There are many Mac OS Xspecific system properties you can set to modify the behavior of your Java application. A complete list of supported Mac OS X system properties, including how to use them, is available in Java System Property Reference for Mac OS X.
38
This article discusses how the Mac OS X implementation of the user interface toolkits Swing, AWT, accessibility, and sound differ from the toolkits on other platforms. Although there is some additional functionality in Mac OS X, for the most part these toolkits work as you would expect them to on other platforms. This article does not discuss user interface design issues that you should consider in Mac OS X. For that information, see Making User Interface Decisions (page 29).
Swing
In Mac OS X, Swing uses the Aqua Look and Feel as the default look and feel (LAF). Swing attempts to be platform neutral, but some aspects of it are an impedance mismatch with the Aqua user interface. Apple attempts to bridge the gap with a common ground that provides both developers and users an experience that is not foreign. This section discusses where the Aqua LAF differs from the default implementation on other platforms. Note: While testing your application, you should test it on the standard Java cross-platform LAF as well as Aqua. To do this, add UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()) to your code.
This property can have a value of true or false. By default, it is false, which means menus are in the window instead of the menu bar. When this property is set to true, the Java runtime moves the menu bar of any Java frame to the top of the screen, where Macintosh users expect it. Since this is just a simple runtime property that only the Mac OS X Java VM looks for, there is no harm in putting it into your cross-platform code base. Note that this setting does not work for Java dialogs having menus. A dialog should be informational or present the user with a simple decision, not provide complex choices. If users are performing actions in a dialog, it is not really a dialog and you should consider using a JFrame object instead of a JDialog object.
Swing
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
39
One other thing to keep in mind about JTabbedPane objects in Mac OS X is that they have a standard size. If you put an image in a tab, the image is scaled to fit the tab instead of the tab to the image. This standard size applies to several other Swing components as well.
Component Sizing
Aqua has very well-defined guidelines for the size of its controls. Swing, on the other hand, does not. The Aqua LAF tries to find a common ground. For example, since any combo box larger than twenty pixels would look out of place in Mac OS X, that is all that is displayed, even if the actual size of the combo box is bigger. Figure 2 shows a very large JComboBox component in Windows XP. Note that the drop-down scrolling list appears at the bottom of the button.
40
Swing
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Figure 2
The same code yields quite a different look in Mac OS X, as can be seen in Figure 3. The visible button is sized to that of a standard Aqua combo box. The drop-down list appears at the bottom of the visible button. The entire area that is active on other platforms is still active, but the button itself doesnt appear as large. Figure 3 An oversize JComboBox component in the Aqua LAF
Note that some other components have similar sizing adjustments to align with the standards set in Apple Human Interface Guidelines for example, scroller and sliders. The JComboBox example is an extreme example. Most are not as large, but this gives you an idea of how the Aqua LAF handles this type of situation.
Buttons
There are basically three button types in Mac OS X:
Swing
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
41
Push buttons, which are rounded rectangles with text labels on them. Radio buttons, which are in sets of two to seven circular buttons. They are for making mutually exclusive, but related choices. Bevel buttons, which can display text, an icon, or a picture that can be either a standard push button or have a menu attached. Bevel buttons normally have rounded corners. When displayed in a toolbar or when sizing constraints are tight, the corners are squared off.
To be consistent with these button types and their defined use in Mac OS X, there are some nuances of Swing buttons that you should be aware of:
JButton components with images in them are rendered as bevel buttons by default.
A default JButton component that contains only text is usually rendered as a push button. (Over a certain height, it is rendered as a bevel button, since Aqua push buttons are limited in their height.)
In addition to these default characteristics which are dependent on height and the contents of the button, you can also explicitly set the type of button with JButton.buttontype, which accepts the following values:
square gives you square bevel button. bevel gives you a rounded bevel button. texturedRound gives you a metal button.
Keep Apples human interface guidelines in mind if you explicitly set a button type. For many more button styles available in the Aqua LAF in Swing, see New Control Styles available within J2SE 5.0 on Mac OS X 10.5.
Mac OS X does not specify a default minimum size for windows. To avoid a 0 by 0 (0x0) pixel window being opened, top-level frames have a minimum size of 128 points wide by 37 points high. Mac OS X does not allow visible windows to have a location that is completely off-screen. In order to set the location of a window to a value that is off-screen, make the window invisible with the setVisible() method and make it undecorated with the setUndecorated() method.
42
Dragging the mouse following a control-click or a right click in a window produces a MOUSE_MOVED event instead of a MOUSE_DRAGGED event. This is because control-clicks and right clicks trigger a contextual menu on mouse down, which does not initiate a drag.
java.awt.GraphicsDevice includes methods for controlling the full screen of a client computer
through Java. In addition to these standard tools, Mac OS X provides a few system properties that may be useful for development of full-screen Java applications. These are discussed in Java System Property Reference for Mac OS X.
Character Encoding
The default character encoding in Java for Mac OS X is MacRoman. The default font encoding on some other platforms is ISO-Latin-1 or WinLatin-1; unlike MacRoman, these encodings are subsets of UTF-8. Programs that assume that filenames can be turned into UTF-8 by just turning a byte into a char will cause problems in Mac OS X. The simplest way to work around this problem is to specify a font encoding explicitly rather than assuming one. Specifying a font encoding besides UTF-8 and UTF-16 is not recommended. If you do not specify a font encoding explicitly, recognize that:
In the conversion from a Unicode subset to MacRoman you may lose information. Filenames are not stored on disk in the default font encoding, but in UTF-8. Usually this isnt a problem, because most files are handled in Java as java.io.Files, though it is good to be aware of. Although filenames are stored on disk as UTF-8, they are stored decomposed. This means that certain charactersfor example, e-acute ()are stored as two characters, e followed by (acute accent). , The default HFS+ filesystem of Mac OS X enforces this behavior. SMB enforces composed Unicode characters. UFS and NFS do not specify whether filenames are stored composed or decomposed, so they can do either.
Accessibility
With some platforms, to use the Java Accessibility API, you must use a native bridge. This is not necessary in Mac OS X because the bridging code is built in. Users can configure the accessibility features of Mac OS X through the Universal Access pane of System Preferences. As a result, if you are using the Accessibility API, your application can use devices that the user has configured there. Beginning with Mac OS X v10.4, a screen reader called VoiceOver is included with the operating system. Your Java application automatically uses this technology.
Character Encoding
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
43
Security
In Mac OS X v10.5 and later, Java applications that use the Kerberos computer network authentication protocol automatically access the system credentials cache and tickets. Apple also includes a cryptographic service provider based on the Java Cryptography Architecture. Currently, the following algorithms are supported:
Mac: MD5, SHA1 Message Digest: MD5, SHA1 Secure Random: YarrowPRNG
Java on Mac OS X v10.5 features an implementation of KeyStore that uses the Mac OS X Keychain as its permanent store. You can get an instance of this implementation by using code like this:
keyStore = KeyStore.getInstance("KeychainStore", "Apple");
For more usage information, see the reference documentation on java.security.KeyStore at http://java.sun.com/j2se/1.5.0/docs/api/java/security/KeyStore.html.
Sound
Java on Mac OS X allows you to sample sound with Apples Core Audio framework at any frame rate supported by your input device. Input can be signed or unsigned PCM encoding, mono or stereo, 8 or 16 bits per sample. By default, the Java Sound engine in Mac OS X uses the midsize sound bank from http://java.sun.com/products/java-media/sound/soundbanks.html.
Input Methods
Mac OS X supports Java input methods. The utility application Java Preferences allows you to configure a trigger for input methods. You can download sample Java-specific input methods from http://java.sun.com/products/jfc/tsc/articles/InputMethod/inputmethod.html.
Java 2D
In Mac OS X, Java windows are double buffered. The Java implementation itself attempts to flush the buffer to the screen often enough to have good drawing behavior without compromising performance. If, for some reason, you need to force window buffers to be flushed immediately, use Toolkit.sync().
44
Security
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
By default, Java on Mac OS X uses the Sun2D renderer, which exactly mimics the behavior of Java 2D on other platforms. If you are developing a graphically intensive application specifically for the Mac OS X platform and the Sun2D renderers performance is inadequate, you may find better success using Apples Quartz graphics engine for your Java rendering instead (see http://developer.apple.com/graphicsimaging/quartz/ for more information). Quartz is optimized for a different set of operations from the Sun2D renderer, and its behavior is sometimes different from that of Java on other platforms. By default, Quartz displays text anti-aliased. Therefore, if you use Quartz as your renderer, Java2D turns anti-aliasing on in order to render text in the Aqua look and feel for Swing (it does this by setting KEY_ANTIALIASING to VALUE_ANTIALIAS_ON). If you want the pixels of your images and text to more closely approximate that same content on other platforms, turn off anti-aliasing. You can do so by using the properties described in Java System Properties or by calling java.awt.Graphics.setRenderingHint() from within your Java application. In applets, anti-aliasing is turned off by default. Tip: When you are using anti-aliasing, if you need to replace text or an image, repaint the graphics context. Do not use XOR mode to repaint images.
Resolution Independence
Java is not explicitly designed for resolution independence (also known as HiDPI); therefore, Java for Mac OS X borrows some functionality from the Cocoa framework. To load a resolution-independent tiff, icns, or pdf file from the Resources folder of your application bundle into your Java application, use the getImage() method of java.awt.Toolkit. The string you pass into getImage() is of the form "NSImage://MyImage". Do not include the file extension of the image. Also be aware that the Sun 2D renderer is disabled when the user interface scale factor does not have a value of 1.0. Use the Quartz renderer so that your images scale smoothly. You can test resolution independence in your application with the Quartz Debug tool, located in /Developer/Applications/Performance Tools. Quartz Debug allows you to launch your application at up to three times the default screen resolution. For a full list of features included in Quartz Debug, consult the Quartz Debug Help. Mac OS X includes resolution-independent standard images for user interfaces that you can also access with the getImage method of java.awt.Toolkit. For instance, Toolkit.getDefaultToolkit().getImage("NSImage://NSColorPanel") will return an Image reference representing the color wheel icon seen on the Colors button in applications such as Mail. For a comprehensive list of the standard images available, see Constants in NSImage Class Reference. Note: The standard image constants defined in NSImage.h all include the substring ImageName. For instance, the constant for the NSColorPanel image has the name NSImageNameColorPanel. When passing a string to getImage, do not include ImageName in the stringit is included in the name of the Objective-C constant, but not the value of the name itself.
Resolution Independence
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
45
46
Resolution Independence
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Networking
Mac OS X v10.3 and later supports IPv6 (Internet Protocol version 6). Because Java SE 6 uses IPv6 on platforms that support it, the default networking stack in Mac OS X is the IPv6 stack. You can make Java use the IPv4 stack by setting the java.net.preferIPv4Stack system property to true.
Preferences
The Preferences API is fully supported in Mac OS X, but there are two details you should be aware of to provide the best experience to users:
The preferences files generated by the Preferences API are named com.apple.java.util.prefs. The users preferences file is stored in their home directory (~/Library/Preferences/). The system preferences are stored in /Library/Preferences/ and are only persisted to disk if the user is an administrator. To be consistent with the Mac OS X user experience, your preferences should be available from the application menu. The com.apple.eawt.Application class provides a mechanism for doing this. See J2SE 5.0 Apple Extensions Reference for more information.
JNI
It is recommended that you use the Java JNI template in Xcode as a starting point for your JNI development. This template creates a bundled Mac OS X application with a JNI library inside its Resources folder. JNI libraries are named with the library name used in the System.loadLibrary() method of your Java code, prefixed by lib and suffixed with .jnilib. For example, System.loadLibrary("hello") loads the library named libhello.jnilib. Java HotSpot also recognizes .dylib as a valid JNI library format as of Mac OS X v10.5.
Networking
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
47
To build as a dynamic shared library, use the -dynamiclib flag. Since your .h file produced by javah includes jni.h, you need to make sure you include its source directory. Putting all of that together looks something like this:
cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers sourceFile.c cc -dynamiclib -o libhello.jnilib sourceFile.o -framework JavaVM
For example, if the files hello.c and hola.c contain the implementations of the native methods to be built into a dynamic shared JNI library that will be called with System.loadLibrary("hello"), you would build the resultant library, libhello.jnilib, with this code:
cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers hola.c cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers hello.c cc -dynamiclib -o libhello.jnilib hola.o hello.o -framework JavaVM
Often JNI libraries have interdependencies. For example assume the following:
libA.jnilib contains a function foo(). libB.jnilib needs to link against libA.jnilib to make use of foo().
Such an interdependency is not a problem if you build your JNI libraries as dynamic shared libraries, but if you build them as bundles it does not work since symbols are private to a bundle. If you need to use bundles for backward compatibility, one solution is to put the common functions into a separate dynamic shared library and link that to the bundle. For example: 1. Compile the JNI library.
cc -g -I/System/Library/Frameworks/JavaVM.framework/Headers -c -o myJNILib.o myJNILib.c
2.
3.
Build the object file for your common functions as a dynamic shared library.
cc -dynamiclib -o libCommonFunctions.dylib CommonFunctions.o
4.
Build your JNI library as a bundle and link against the dynamic shared library with your common functions in it.
cc -bundle -lCommonFunctions -o libMyJNILib.jnilib myJNILib.o
48
JNI
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Note: When building JNI libraries, you need to explicitly designate the path to jni.h. This is in /System/Library/Frameworks/JavaVM.framework/Headers/, not /usr/include/ as on some other platforms.
Note: After you have built your JNI libraries, make sure to let Java know where they are. It is recommended that you do this by putting your libraries into your application bundle and passing in the path with the -Djava.library.path option. It is also possible to do this by putting your libraries in /Library/Java/Extensions/, but this is discouraged, as it breaks the encapsulation of your bundle. A complete example of JNI development can be found in the MyFirstJNIProject sample code. More details on JNI can be found in Tech Note TN2147: JNI Development on Mac OS X. To interoperate with the Objective-C runtime from JNI, link against JavaNativeFoundation.framework, which is a sub-framework of JavaVM.framework. It contains Objective-C classes and macros to automatically set up and tear down autorelease pools, catch and re-throw Java and Cocoa exceptions, hold JNI global references in Foundation container classes, and convert object graphs of strings, numbers, lists, maps, and sets.
Runtime.exec()
When calling the Runtime.exec() method, be sure to call Runtime.exec(String[] cmdarray) or one of its counterparts, instead of the single-string version (Runtime.exec(String command)). Passing a string outside of an array can have unpredictable results. Runtime.exec(String[] cmdarray) behaves as it does in a standard Unix environment.
JVM properties Sample value 1.5.0_13 Notes Mac OS X v10.4 and earlier ships with earlier versions of Java. Use this property to test for the minimal version your application requires.
java.vm.version 1.5.0_13
49
Property
file.separator line.separator
Sample value / \n
Notes Note that this is a change from Mac OS 9. This is consistent with UNIX-based Java implementations, but different from Mac OS 9 and Windows. Make sure to check for Mac OS X , not just Mac OS because Mac OS returns true for Mac OS 9 (and earlier) which did not even have a Java 2 VM. Java 1.5 runs only in Mac OS X v10.4 or later.
os.name
Mac OS X
os.version
10.5.4
Note : The mrj.version system property is still exposed by the VM in Java SE 6. Although you may still use this to determine if you are running in the Mac OS, for forward compatibility consider using the os.name property to determine if you are running in Mac OS X. The reason is that this property may go away in future attempts to further synchronize the Apple source with the source from Sun.
50
This table describes the changes to Java Development Guide for Mac OS X. Date 2010-10-20 2009-10-09 2009-08-04 Notes Added deprecation information. Added information about the location of Java API documentation in Mac OS X. Corrected resolution independence information and added applet deployment information. Updated with new features and tools available for Java in Mac OS X v10.6. Updated to focus on J2SE 5.0 and Java SE6 and reflect recent updates to Java for Mac OS X. Updated content to include information for J2SE 5.0 Release 4 for Mac OS X. Fixed typos throughout the document. Fixed various errors and inconsistencies. Updated content to include information for J2SE 5.0 Release 1 for Mac OS X. Document renamed Java Development Guide for Mac OS X. Updated with information about Java on Mac OS X v10.4. 2004-11-02 2004-08-31 2003-06-23 Minor revisions and corrections throughout the document. Revised for Java 1.4.2. Updated links to reflect documentation changes. Removed appendices. They are now available as separate documents. Minor corrections in the overview chapter. Spelling and grammatical errors fixed. Revised for Java 1.4.1. Most sections are completely new to reflect the completely new Java implementation. Only the user experience information has been retained although it has been updated as well. Structure of the document was modified dramatically to align with Suns presentation of the Java 2 platform. Format completely revised. Changed target emphasis from Mac OS 9 Java developers to Java developers coming from other platforms. Updated to include new features introduced in Java 1.3.1 including the Java.applet.plugin and information about hardware acceleration. Updated for Mac OS X version 10.2. Modified tutorials to work with new operating system and corrected some typographical errors.
2009-05-28 2008-10-15
2003-05-15
2002-09-01
2002-07-01
51
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.
Date 2001-12-01
Notes Document originally released with a focus on describing what is different in Java development from Mac OS 9 to Mac OS X.
52
2010-10-20 | 2003, 2010 Apple Inc. All Rights Reserved.