不使用 Helper 的方法实现

From Apache OpenOffice Wiki
Jump to: navigation, search


XInterface

只要组件实现一个 UNO 接口,com.sun.star.uno.XInterface 就会自动包括在内。javamaker 生成的 com.sun.star.uno.XInterface 的 Java 接口定义只包含一个由 Java UNO 在内部使用的成员 TypeInfo,用来存储特定的 UNO 类型信息:

  // source file com/sun/star/uno/XInterface.java corresponding to the class generated by
 
  package com.sun.star.uno;
 
  public interface XInterface
  {
      // static Member
      public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = null;
  }


请注意,XInterface 不具有任何方法,这与其 IDL 说明相反。这意味着,如果将 implements com.sun.star.uno.XInterface 添加到类定义,将没有任何可实现的对象。


方法 queryInterface()<code> 在 UNO 对象的实现中是不必要的,因为 Java UNO 运行时环境可以获取接口引用,而不需要 UNO 对象自身的支持。在 Java 中,方法 <code>UnoRuntime.queryInterface() 用于获取接口,而非调用 queryInterface(),并且 Java UNO 语言绑定还将向它上面的其他进程分发 UNO 对象的接口。


方法 acquire()release() 用于引用计数和对象生命周期的控制,但由于 Java 垃圾收集器可以完成此操作,因此在 Java 组件中没有引用计数。


XTypeProvider

带有默认 com.sun.star.lang.XTypeProvider 实现的帮助程序类在 Java 中的应用尚待开发。同时,每个 Java UNO 对象实现都可以实现 XTypeProvider 接口,如以下代码所示。在您的实现中,请调整 getTypes()

  ...
 
  // XTypeProvider implementation
 
  // maintain a static implementation id for all instances of ImageShrink
  // initialized by the first call to getImplementationId()
  protected static byte[] _implementationId;
 
  public com.sun.star.uno.Type[] getTypes() {
 
      // instantiate Type instances for each interface you support and place them in a Type[] array
      // (this object supports XServiceInfo, XTypeProvider, and XImageShrinkFilter)
      return new com.sun.star.uno.Type[] {
          new com.sun.star.uno.Type(com.sun.star.lang.XServiceInfo.class),
          new com.sun.star.uno.Type(com.sun.star.lang.XTypeProvider.class),
          new com.sun.star.uno.Type(org.openoffice.test.XImageShrinkFilter.class) };
  }
 
  synchronized public byte[] getImplementationId() {
      if (_implementationId == null) {
          _implementationId= new byte[16];
          int hash = hashCode(); // hashCode of this object
          _implementationId[0] = (byte)(hash & 0xff);
          _implementationId[1] = (byte)((hash >>> 8) & 0xff);
          _implementationId[2] = (byte)((hash >>> 16) & 0xff);
          _implementationId[3] = (byte)((hash >>>24) & 0xff);
      }
      return _implementationId;
  }
 
  ...


推荐的 getImplementationId() 方法的实现并不是最佳的,它使用了初始化静态字段的第一个实例的 hashCode()。未来的 UNO 帮助程序类将改进这一点。


XComponent

XComponent 是一个有用的 可选接口。XComponent 的通知机制使侦听器对象可以了解组件何时停止提供服务,以便对象停止对组件的引用。引用计数降为零时,这将使组件可以自行删除根据 编写 UNO 组件 - 可实现的核心接口 介绍的内容,在 Xcomponent 调用 dispose() 时必须完成三件事:

  • 通知已注册的 XEventListener,通过调用它们的方法 disposing() 来处理对象。
  • 释放所有对象含有的引用,包括所有 XEvenListener 对象。
  • 如果因为组件被处置而不能再完成所需的任务,在进一步调用组件时,将抛出 com.sun.star.lang.DisposedException


在 Java 中,对象不能被删除,但是垃圾收集器可以完成这个操作。释放当前持有的所有引用足以打断循环引用,并调用所有 com.sun.star.lang.XEventListener 上的 disposing()


侦听器接口的注册和删除是 Java 中的标准过程。一些 IDE 甚至可以自动创建必要的方法。可以编写以下示例:

  ...
 
  //XComponent implementation
 
  // hold a list of eventListeners
  private java.util.ArrayList eventListeners = new java.util.ArrayList();
 
  public void dispose {
      java.util.ArrayList listeners;
      synchronized (this) {
          listeners = eventListeners;
          eventListeners = null;
      }
      for (java.util.Iterator i = listeners.iterator(); i.hasNext();) {
          fireDisposing((XEventListener) i.next());
      }
      releaseReferences();
  }
 
  public void addEventListener(XEventListener listener) {
      bool fire = false;
      synchronized (this) {
          if (eventListeners == null) {
              fire = true;
          } else {
              eventListeners.add(listener);
          }
      }
      if (fire) {
          fireDisposing(listener);
      }
  }
 
  public synchronized void removeEventListener(XEventListener listener) {
      if (eventListeners != null) {
          int i = eventListeners.indexOf(listener);
          if (i >= 0) {
              eventListeners.remove(i);
          }
      }
  }
 
  private void fireDisposing(XEventListener listener) {
      com.sun.star.uno.EventObject event = new com.sun.star.uno.EventObject(this);
      try {
          listener.disposing(event);
      } catch (com.sun.star.uno.DisposedException e) {
          // it is not an error if some listener is disposed simultaneously
      }
  }
 
  private void releaseReferences() {
      xComponentContext = null;
      // ...
  }
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages