不使用 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() 在 UNO 对象的实现中是不必要的,因为 Java UNO 运行时环境可以获取接口引用,而不需要 UNO 对象自身的支持。在 Java 中,方法 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