# 5
/*
File:MyApp.java
Abstract: Simple Swing app demonstrating how to use the Apple EAWT
APIs by way of reflection, allowing a single codebase to
run on platforms without those APIs installed.
Version: 1.1.1
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use,
install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Computer,
Inc. may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
as expressly stated in this notice, no other rights or licenses, express
or implied, are granted by Apple herein, including but not limited to
any patent rights that may be infringed by your derivative works or by
other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright ?2003-2006 Apple Computer, Inc., All Rights Reserved
*/
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;
public class MyApp extends JFrame implements ActionListener {
protected JDialog aboutBox, prefs;
static final JMenuBar mainMenuBar = new JMenuBar();
protected JMenu fileMenu, editMenu, helpMenu;
protected JMenuItem newMI, openMI, closeMI, saveMI, saveAsMI, quitMI;
protected JMenuItem undoMI, cutMI, copyMI, pasteMI, selectAllMI, clearMI, optionsMI;
protected JMenuItem docsMI, supportMI, aboutMI;
// Check that we are on Mac OS X. This is crucial to loading and using the OSXAdapter class.
public static boolean MAC_OS_X = (System.getProperty("os.name").toLowerCase().startsWith("mac os x"));
// Ask AWT which menu modifier we should be using.
final static int MENU_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
public MyApp() {
super("OSXAdapter");
this.getContentPane().setLayout(null);
addMenus();
aboutBox = new JDialog(this, "About OSXAdapter");
aboutBox.getContentPane().setLayout(new BorderLayout());
aboutBox.getContentPane().add(new JLabel("OSXAdapter", JLabel.CENTER));
aboutBox.getContentPane().add(new JLabel("\u00A92003 Apple Computer, Inc.", JLabel.CENTER), BorderLayout.SOUTH);
prefs = new JDialog(this, "OSXAdapter Preferences");
prefs.getContentPane().setLayout(new GridLayout(2,1));
prefs.getContentPane().add(new JCheckBox("Buy a Mac"));
prefs.getContentPane().add(new JCheckBox("Don't go Back"));
// Set up our application to respond to the Mac OS X application menu
macOSXRegistration();
setSize(320, 240);
setVisible(true);
}
// Generic registration with the Mac OS X application menu. Checks the platform, then attempts
// to register with the Apple EAWT.
// This method calls OSXAdapter.registerMacOSXApplication() and OSXAdapter.enablePrefs().
// See OSXAdapter.java for the signatures of these methods.
public void macOSXRegistration() {
if (MAC_OS_X) {
try {
Class osxAdapter = ClassLoader.getSystemClassLoader().loadClass("apple.dts.samplecode.osxadapter.OSXAdapter");
Class[] defArgs = {MyApp.class};
Method registerMethod = osxAdapter.getDeclaredMethod("registerMacOSXApplication", defArgs);
if (registerMethod != null) {
Object[] args = { this };
registerMethod.invoke(osxAdapter, args);
}
// This is slightly gross. to reflectively access methods with boolean args,
// use "boolean.class", then pass a Boolean object in as the arg, which apparently
// gets converted for you by the reflection system.
defArgs[0] = boolean.class;
Method prefsEnableMethod = osxAdapter.getDeclaredMethod("enablePrefs", defArgs);
if (prefsEnableMethod != null) {
Object args[] = {Boolean.TRUE};
prefsEnableMethod.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 the OSXAdapter:");
e.printStackTrace();
}
}
}
// General info dialog. The OSXAdapter calls this method when "About OSXAdapter"
// is selected from the application menu.
public void about() {
aboutBox.setSize(320, 240);
aboutBox.setLocation((int)this.getLocation().getX() + 22, (int)this.getLocation().getY() + 22);
aboutBox.setResizable(false);
aboutBox.setVisible(true);
}
// General preferences dialog. The OSXAdapter calls this method when "Preferences..."
// is selected from the application menu.
public void preferences() {
prefs.setSize(320, 240);
prefs.setLocation((int)this.getLocation().getX() + 22, (int)this.getLocation().getY() + 22);
prefs.setResizable(false);
prefs.setVisible(true);
}
// General info dialog. The OSXAdapter calls this method when "Quit OSXAdapter"
// is selected from the application menu, Cmd-Q is pressed, or "Quit" is selected from the Dock.
public void quit() {
int option = JOptionPane.showConfirmDialog(this, "Are you sure you want to quit?", "Quit?", JOptionPane.YES_NO_OPTION);
if (option == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
public void addMenus() {
mainMenuBar.add(fileMenu = new JMenu("File"));
fileMenu.add(newMI = new JMenuItem("New" ));
newMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, MENU_MASK));
fileMenu.add(openMI = new JMenuItem("Open..."));
openMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, MENU_MASK));
fileMenu.addSeparator();
fileMenu.add(closeMI = new JMenuItem("Close"));
closeMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, MENU_MASK));
fileMenu.add(saveMI = new JMenuItem("Save"));
saveMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK));
fileMenu.add(saveAsMI = new JMenuItem("SaveAs..."));
saveAsMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK | Event.SHIFT_MASK));
// Quit menu item is provided on Mac OS X.. only make it on other platforms.
if (!MAC_OS_X) {
fileMenu.addSeparator();
fileMenu.add(quitMI = new JMenuItem("Quit"));
quitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, MENU_MASK));
quitMI.addActionListener(this);
}
mainMenuBar.add(editMenu = new JMenu("Edit"));
editMenu.add(undoMI = new JMenuItem("Undo"));
undoMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, MENU_MASK));
editMenu.addSeparator();
editMenu.add(cutMI = new JMenuItem("Cut"));
cutMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, MENU_MASK));
editMenu.add(copyMI = new JMenuItem("Copy"));
copyMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, MENU_MASK));
editMenu.add(pasteMI = new JMenuItem("Paste"));
pasteMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, MENU_MASK));
editMenu.add(clearMI = new JMenuItem("Clear"));
clearMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_K, MENU_MASK));
editMenu.addSeparator();
editMenu.add(selectAllMI = new JMenuItem("Select All"));
selectAllMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, MENU_MASK));
// Options/Prefs menu item is provided on Mac OS X.. only make it on other platforms.
if (!MAC_OS_X) {
editMenu.addSeparator();
editMenu.add(optionsMI = new JMenuItem("Options"));
optionsMI.addActionListener(this);
}
mainMenuBar.add(helpMenu = new JMenu("Help"));
helpMenu.add(docsMI = new JMenuItem("Online Documentation"));
helpMenu.addSeparator();
helpMenu.add(supportMI = new JMenuItem("Technical Support"));
// About menu item is provided on Mac OS X.. only make it on other platforms.
if (!MAC_OS_X) {
helpMenu.addSeparator();
helpMenu.add(aboutMI = new JMenuItem("About OSXAdapter"));
aboutMI.addActionListener(this);
}
setJMenuBar (mainMenuBar);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == quitMI) {
quit();
} else if (e.getSource() == optionsMI) {
preferences();
} else if (e.getSource() == aboutMI) {
about();
}
}
public static void main(String args[]) {
new MyApp();
}
}
and.....
/*
File:OSXAdapter.java
Abstract:A single class with clear, static entry points for
hooking existing preferences, about, quit functionality
from an existing Java app into handlers for the Mac OS X
application menu. Useful for developers looking to support
multiple platforms with a single codebase, and support
Mac OS X features with minimal impact.
Version: 1.1
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use,
install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Computer,
Inc. may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
as expressly stated in this notice, no other rights or licenses, express
or implied, are granted by Apple herein, including but not limited to
any patent rights that may be infringed by your derivative works or by
other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright ?2003-2006 Apple Computer, Inc., All Rights Reserved
*/
import com.apple.eawt.*;
public class OSXAdapter extends ApplicationAdapter {
// pseudo-singleton model; no point in making multiple instances
// of the EAWT application or our adapter
private static OSXAdaptertheAdapter;
private static com.apple.eawt.ApplicationtheApplication;
// reference to the app where the existing quit, about, prefs code is
private MyAppmainApp;
private OSXAdapter (MyApp inApp) {
mainApp = inApp;
}
// implemented handler methods. These are basically hooks into existing
// functionality from the main app, as if it came over from another platform.
public void handleAbout(ApplicationEvent ae) {
if (mainApp != null) {
ae.setHandled(true);
mainApp.about();
} else {
throw new IllegalStateException("handleAbout: MyApp instance detached from listener");
}
}
public void handlePreferences(ApplicationEvent ae) {
if (mainApp != null) {
mainApp.preferences();
ae.setHandled(true);
} else {
throw new IllegalStateException("handlePreferences: MyApp instance detached from listener");
}
}
public void handleQuit(ApplicationEvent ae) {
if (mainApp != null) {
/*
/ You MUST setHandled(false) if you want to delay or cancel the quit.
/ This is important for cross-platform development -- have a universal quit
/ routine that chooses whether or not to quit, so the functionality is identical
/ on all platforms. This example simply cancels the AppleEvent-based quit and
/ defers to that universal method.
*/
ae.setHandled(false);
mainApp.quit();
} else {
throw new IllegalStateException("handleQuit: MyApp instance detached from listener");
}
}
// The main entry-point for this functionality. This is the only method
// that needs to be called at runtime, and it can easily be done using
// reflection (see MyApp.java)
public static void registerMacOSXApplication(MyApp inApp) {
if (theApplication == null) {
theApplication = new com.apple.eawt.Application();
}
if (theAdapter == null) {
theAdapter = new OSXAdapter(inApp);
}
theApplication.addApplicationListener(theAdapter);
}
// Another static entry point for EAWT functionality. Enables the
// "Preferences..." menu item in the application menu.
public static void enablePrefs(boolean enabled) {
if (theApplication == null) {
theApplication = new com.apple.eawt.Application();
}
theApplication.setEnabledPreferencesMenu(enabled);
}
}
Posted