View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.log4j.chainsaw.osx;
    18
    19  import java.lang.reflect.InvocationHandler;
    20  import java.lang.reflect.InvocationTargetException;
    21  import java.lang.reflect.Method;
    22  import java.lang.reflect.Proxy;
    23
    24  import org.apache.log4j.Logger;
    25  import org.apache.log4j.chainsaw.LogUI;
    26
    27
    28  /**
    29   * This class adds dynamic hooks into OSX version of Java so that various
    30   * Mac-specific UI guidelines are adhered to.
    31   *
    32   * This class uses reflection to build the necessary hooks so that there is no compile-time
    33   * dependency on a Mac SDK.
    34   *
    35   * @see "http://developer.apple.com/documentation/Java/index.html"
    36   * @author psmith
    37   *
    38   */
    39  public class OSXIntegration {
    40      public static final boolean IS_OSX = System.getProperty("os.name").startsWith("Mac OS X");
    41      private static final Logger LOG = Logger.getLogger(OSXIntegration.class);
    42      private static Object applicationInstance;
    43      public static final void init(final LogUI logui) {
    44          LOG.info("OSXIntegration.init() called");
    45          if(!IS_OSX) {
    46              LOG.info("Not OSX, ignoring...");
    47              return;
    48          }
    49          try {
    50              Class applicationClazz = Class.forName("com.apple.eawt.Application");
    51              Class listenerClass = Class.forName("com.apple.eawt.ApplicationListener");
    52              applicationInstance = applicationClazz.newInstance();
    53
    54  //            now register that we want that Preferences menu
    55              Method enablePreferenceMethod = applicationClazz.getMethod("setEnabledPreferencesMenu", new Class[] {boolean.class});
    56              enablePreferenceMethod.invoke(applicationInstance, new Object[] {Boolean.TRUE});
    57
    58
    59              // no About menu for us for now.
    60              Method enableAboutMethod = applicationClazz.getMethod("setEnabledAboutMenu", new Class[] {boolean.class});
    61              enableAboutMethod.invoke(applicationInstance, new Object[] {Boolean.TRUE});
    62
    63              // Need to create a Proxy object to represent an anonymous impl of the ApplicationListener class
    64              Object listenerProxy = Proxy.newProxyInstance(OSXIntegration.class.getClassLoader(),
    65                          new Class[] {listenerClass},
    66                          new InvocationHandler() {
    67
    68                  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    69                      if("handlePreferences".equals(method.getName())){
    70                          LOG.info("handlePreferences(...) called");
    71                          logui.showApplicationPreferences();
    72                      }else if("handleQuit".equals(method.getName())){
    73                          setHandled(args[0], logui.exit()?Boolean.TRUE:Boolean.FALSE);
    74
    75                      }else if("handleAbout".equals(method.getName())) {
    76                          logui.showAboutBox();
    77                          setHandled(args[0], Boolean.TRUE);
    78                      }
    79  //                    TODO think about File Open/Save options
    80                      return null;
    81                  }
    82
    83                  private void setHandled(Object event, Boolean val) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    84                      Method handleMethod =   event.getClass().getMethod("setHandled", new Class[] {boolean.class});
    85                      handleMethod.invoke(event, new Object[] {val});
    86                  }});
    87              // register the proxy object via the addApplicationListener method, cross fingers...
    88              Method registerListenerMethod = applicationClazz.getMethod("addApplicationListener", new Class[] {listenerClass});
    89              registerListenerMethod.invoke(applicationInstance, new Object[] {listenerProxy});
    90          } catch (Exception e) {
    91              LOG.error("Failed to setup OSXIntegration", e);
    92          }
    93      }
    94  }