前のドキュメント | コンテンツ・テーブル | 次のドキュメント]

2 第一歩

 この章は、OpenOffice.org API を使う時、あなたに第一歩を見せる。 これらのステップに従うことは、7 テキスト・ドキュメント8 スプレッドシート・ドキュメントと、9 図画のような OpenOffice.org ドキュメントについて章を理解して、そして使うために不可欠である。 あなたが成功裏にこの第一歩を終えた後、直接にこのマニュアルの他の章に行くことができる。 

 第一歩のフォーカスは Java であるであろう、しかし他の言語が同様にカバーされる。 もしあなたがその後 OpenOffice.org Basic を使うことを望むなら、11.1 OpenOffice.org Basic とダイアログ - OpenOffice.org Basic と、3.4.3 プロフェッショナル UNO - UNO 言語バインディング - OpenOffice.org Basic を参照しなさい。  C++ の使用法は、3.4.2 プロフェッショナル UNO - UNO 言語バインディング - UNO C++ バインディング - で記述されている。 

2.1 UNO のプログラミング

 UNO(['ju:nou]と 発音する)  は、ユニバーサル・ネットワーク・オブジェクトを表して、そして OpenOffice.org の基本構成技術である。  あなたは、言語、コンポーネントの技術、コンピュータ・プラットホームとネットワークの向こう側に相互作用するコンポーネントを、利用して書くことができる。  現在、 UNO は Linux 、Solaris と Windows の上に Java 、 C++ と OpenOffice.org Basic のために利用可能である。 同様に、 UNO はコンポーネント技術のMicrosoft COM を通して、多くの他の言語で利用可能である。

 UNO は、そのアプリケーション・プログラミング・インタフェース(API)を使って、 OpenOffice.org にアクセスするために使われる。  OpenOffice.org API は、 OpenOffice.org のプログラムできる特徴を記述する包括的な仕様書である。 

2.2 UNO アプリケーション・フィールド

 あなたは、 C++ 、 Java と COM/DCOM から、 OpenOffice.org のローカルであるか、あるいはリモートのインスタンスに接続することができる。  C++ と Java デスクトップ・アプリケーション、 Java servlets 、 Java サーバー・ページ、 JScript と VBScript と Delphi 、 Visual Basic など、多くの他の言語は、 OpenOffice.org を Office ドキュメントで作動するために使うことができる。

  Office プロセスによってインスタンスを作られることができる C++ あるいは Java で UNO コンポーネントを開発することが出来て、そして OpenOffice.org に新しい能力を加えることは可能である。 例えば、あなたは、Chart Add-ins あるいは Calc Add-ins 、言語の拡張子、新しいファイル・フィルター、データベース・ドライバを書くことができる。 あなたは、グループウェア・クライアントのような、完全なア プリケーションを書くことさえできる。

 UNO コンポーネントが、 Java Beansとして、 OpenOffice.org に容易なアクセスを与えるために、 Java IDE (統合開発環境)に融け込む。  現在、このようなコンポーネントのセットが、Java フレームで OpenOffice.org ドキュメントをエディットするのを可能にするために、開発中である。

  OpenOffice.org Basic は UNO と協力し、UNO プログラムが直接 OpenOffice.org で書かれることが出来るようにする。  このメソッドで、あなたはイベント駆動型ダイアログ環境に基づいて、あなた自身の Officeソリューションとウィザードを供給する。

 OpenOffice.org データベース・エンジンとデータ感知の形式は、もう1つのデータベース・ドリブンなソリューションに対して、機会の広いエリアを開く。 

2.3 始めてみよう

 OpenOffice.org API を始める前に、多くのファイルとインストレーション・セットが必要とされる。 

2.3.1  必要なファイル

 これらのファイルはあなたが使う言語のいずれのためにでも必要とされる。 

OpenOffice.org インストレーション

OpenOffice.org のコピーをインストールしなさい。 現在のバージョンは OpenOffice.org 1.1である。 

あなたは www.openoffice.org から OpenOffice.org をダウンロードすることができる。 StarOffice は
Sun Microsystemsから、あるいはあなたのディストリビュータを通して得られることができる。 

注意:この本は現在のバージョンに焦点を合わせている。 

API リファレンス

OpenOffice.org API リファレンスはソフトウェア開発キットの一部であって、そして OpenOffice.org オブジェクトについての詳細なインフォメーションを提供する。 最近のバージョンは api.openoffice.org において、ドキュメントのセクションからダウンロードすることができる。 

2.3.2 インストールするセット

 次のインストレーション・セットは Java で OpenOffice.org API アプリケーションを開発するために必要である。 この章は OpenOffice.org API のために、どのように Java IDE を準備するべきか記述する。 

JDK 1. 3. 1

  OpenOffice.org 1.1のための Java アプリケーションは、Java 開発キット1.3.1あるいはそれ以降を必要とする。 java.sun.com から JDK をダウンロードして、インストールしなさい。 全ての特徴を手に入れるためには、 Java 1.4.1_01 が必要とされる。 

Java IDE

 統合開発環境( IDE )をダウンロードしなさい、たとえば、NetBeans を www.netbeans.org から、または、ForteをJava のためにSun Microsystemsから。 他の IDE が使われることもできる、しかし NetBeans/Forteは、最も良いインテグレーションを提供する。 OpenOffice.org とIDE、たとえばNetBeans とのインテグレーションは、進行中の努力である。 NetBeans や他の IDE についての最新の情報が無いか api.openoffice.org セクションのファイルをチェックしなさい。 

OpenOffice.org ソフトウェア開発キット( SDK )

 OpenOffice.org ソフトウェア開発キット( SDK )を、www.openoffice.org から得なさい。 それは、 OpenOffice.org API とJava UNO ランタイムと C++ API のための、このマニュアルとリファレンス・ドキュメンテーションに言及された例のために、ビルド環境を含む。 それは、同じく、もっと多くの例の元になる。 SDK を使って、あなたは我々がここで言及する例を構築して、そして走るためにGNU makeを使うことができる。 

 あなたのファイル・システムのどこかに SDK をアンパックしなさい。 ファイル index.html は SDK の概要を与える。  どのコンパイラを使うべきか、どうやって開発環境をセットアップするかの詳細なインストラクションのためには、SDK インストレーション・ガイドを参照してください。 

2.3.3 コンフィギュレーション

OpenOffice.org で Java を可能に

 OpenOffice.org は、 Java バーチャル・マシンを、 Java で書かれたコンポーネントのインスタンスを作るために使う。  あなたは容易に Office にどの JVM を使うべきか言うことができる: OpenOffice.org の下のプログラムのフォルダーから jvmsetup 実行可能プログラムを始動して、インストールされている JRE あるいは JDK を選んで、 OK をクリックしなさい。  タスクバーにあるQuickstarter を含めて OpenOffice.org を閉じ、OpenOffice.org をリスタートしなさい。 さらに、OpenOffice.org のTools - Option のダイアログを開いて、 OpenOffice.org - Securityのセクションを選択し、Java enableのオプションがチェックされていることを確認しなさい。 

Java UNO クラス・ファイルの使用

 次に、 OpenOffice.org クラスファイルを Java IDE に知らせらなくてはならない。 NetBeans のために、これらの Java UNO jar ファイルは、プロジェクトにマウントされなくてはならない。  次のステップはどのように新しいプロジェクトを作って、そしてバージョン3.4.1から NetBeans でクラス・ファイルをマウントするべきか示す。 

  1. Projectメニューから、 Project Manger を選択しなさい。 新しいプロジェクトを作るために、Project Manager ウインドウで、New ....ボタンをクリックしなさい。NetBeans は、あなたの新しいプロジェクトを、現在のプロジェクトとして用いる。 

  2. NetBeansの Explorerウインドウをアクティブにしなさい、それは Filesystems 項目を含んでいる( NetBeansのExplorerウインドウを表示するためには、View - Explorer をクリック)。 そのコンテキスト・メニューを開いて、そして、Mount - Archive Filesを選択して、<OfficePath>/program/classes フォルダーに ナビゲートして、そのディレクトリの全てのjarファイルを選択して、そしてあなたのプロジェクトに OpenOffice.org の jar をマウントするために、Finishをクリックしなさい。 選択肢として、あなたは同じく、File - Mount Filesystem を使って、ファイルをマウントすることもできる。 

  3. 最終的に、あなたはプロジェクトのソース・ファイルのために、フォルダーを必要とする。 Mount - Local Directory を、 Filesystems アイコンのコンテキスト・メニューから選んで、そしてファイル・マネージャー・ダイアログを、あなたのファイルシステムに新しいフォルダーを作るために使いなさい。 それを選択して、開かないで、そして、あなたのプロジェクトに加えるために Finish をクリックしなさい。 

 Office にリッスンさせる

 Java は Office に話をするために TCP/IP ソケットを使う。 Java クライアントのために、 OpenOffice.org は、 TCP/IP 接続が特別な接続 URL パラメータを使うことに関して、聞くように言われなくてはならない。 これを達成する2つの方法がある、あなたは Office を常に、あるいはただ1度聞かせることができる。 

 今あなたの必要条件に合ったプロシージャを選び、OpenOffice.orgを、今は、聴取用のモードで始動しなさい。  netstat -a あるいは -na  をコマンド・ラインで呼ぶことによって、それがリスンしているかどうか調べなさい。  次に類似したアウトプットは、 Office が聞いていることを示す:

TCP    <Hostname>:8100   <Fully qualified hostname>: 0 Listening

 もし、あなたが -n オプションを使うなら、 netstat が数の形式でアドレスとポート番号を見せる。 これは論理的な名前をポートに割り当てることが可能である UNIX システムの場合に、時々有用である。

 もし Office がリスンしていないなら、それは、おそらく適切な接続 URL パラメータで始められなかったからだろう。   Setup.xcu ファイルをチェックして、あるいは、タイピング・エラーが無いかコマンドラインをチェックして、再び試みなさい。 

メモグラフィックスが特別なテキストのセクションを表わす

注意: OpenOffice.org 1.1の前のバージョンでは、いくつかの相違がある。 

 Office を、いつもリスンさせるコンフィギュレーション設定は、ほかのところに位置している。 エディタでファイル  <OfficePath>/share/config/registry/instance/org/openoffice/Setup.xml を開いて、そして要素を探しなさい:

<ooSetupConnectionURL cfg:type="string"/>

次のコードでそれを拡張しなさい:

<ooSetupConnectionURL cfg:type="string">
socket,port=8100;urp;
</ooSetupConnectionURL>

 コマンド・ラインのオプション -accept は、quick starterとオンライン・ヘルプを含めて、 Office の走っているインスタンスが有る時、無視される。 もしあなたがそれを使うなら、 soffice プロセスがあなたのシステムの上に走っていないことを確認しなさい。 

IDE に API リファレンスを付加する

 我々は、 OpenOffice.org API と Java UNO ランタイムのオンライン・ヘルプを得るために、Java IDE に API と Java UNO リファレンスを加えることを勧める。 NetBeans 3.4.1では、以下のステップに従いなさい:

2.3.4 最初のコネクション

コネクトするには

 次のことが、 Office に接続して、接続を確立するのが可能であったか、なかったかを述べる、小さいプログラムを、どのように書くべきか例示する。 Java IDE あるいはソース・エディタを開始して、そして FirstConnection クラスのために、次のソース・コードを入力しなさい。 

NetBeans 3.4.1 IDE で、クラスを作って走らせるために、次のステップを使いなさい:

  1. プロジェクトにメイン・クラスを加えなさい。 NetBeans エクスプローラ・ウインドウで、Project  <project_name>タブをクリックして、Project 項目を右クリックして、New Wizard を表示するために Add New ....を選択して、 Java Classes フォルダーを開けて、テンプレート Main をハイライトさせて、そしてNext をヒットしなさい。 

  2. Name フィールドでは、メイン・クラスのクラス名として、'FirstConnection'を入力して、そしてあなたのプロジェクト・ファイルを含むフォルダーを選択しなさい。 FirstConnection は、あなたのプロジェクトのデフォルト・パッケージに加えられる。 クラスを作るためには、 Finish をクリックしなさい。 

  3. 下に示されたソース・コードを入力しなさい( FirstSteps/FirstConnection.java) 。 そして、 あなたの最初の接続をテストするために、 Build - Execute を選択しなさい。 NetBeans が Office に接続するあなたの試みの結果を示すOutput ウインドウを観察しなさい。 

import com.sun.star.bridge.XUnoUrlResolver;

import com.sun.star.uno.UnoRuntime;

import com.sun.star.uno.XComponentContext;

import com.sun.star.lang.XMultiComponentFactory;

import com.sun.star.beans.XPropertySet;

public class FirstConnection extends java.lang.Object {

    private XComponentContext xRemoteContext = null;

    private XMultiComponentFactory xRemoteServiceManager = null;

   

    public static void main(String[] args) {

        FirstConnection firstConnection1 = new FirstConnection();

        try {

            firstConnection1.useConnection();

        }

        catch (java.lang.Exception e) {

            e.printStackTrace();

        }

        finally {

            System.exit(0);

        }

    }

   

    protected void useConnection() throws java.lang.Exception {

        try {

            xRemoteServiceManager = this.getRemoteServiceManager(

                    "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");

            String available = (null != xRemoteServiceManager ? "available" : "not available");

            System.out.println("remote ServiceManager is " + available);

            //

            // do something with the service manager...

            //

        }

        catch (com.sun.star.connection.NoConnectException e) {

                System.err.println("No process listening on the resource");

                e.printStackTrace();

                throw e;

        }

         catch (com.sun.star.lang.DisposedException e) { //works from Patch 1

            xRemoteContext = null;

            throw e;

        }          

    }

   

    protected XMultiComponentFactory getRemoteServiceManager(String unoUrl) throws java.lang.Exception {

        if (xRemoteContext == null) {

            // First step: create local component context, get local servicemanager and

            // ask it to create a UnoUrlResolver object with an XUnoUrlResolver interface

            XComponentContext xLocalContext =

                com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);

            XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();

            Object urlResolver  = xLocalServiceManager.createInstanceWithContext(

                "com.sun.star.bridge.UnoUrlResolver", xLocalContext );

            // query XUnoUrlResolver interface from urlResolver object

            XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(

                XUnoUrlResolver.class, urlResolver);

            // Second step: use xUrlResolver interface to import the remote StarOffice.ServiceManager,

            // retrieve its property DefaultContext and get the remote servicemanager

            Object initialObject = xUnoUrlResolver.resolve(unoUrl);

            XPropertySet xPropertySet = (XPropertySet)UnoRuntime.queryInterface(

                XPropertySet.class, initialObject);

            Object context = xPropertySet.getPropertyValue("DefaultContext");            

            xRemoteContext = (XComponentContext)UnoRuntime.queryInterface(

                XComponentContext.class, context);

        }

        return xRemoteContext.getServiceManager();

    }

}

 C++ で Office に接続する事例のために、チャプター 3.4.2 Professional UNO - UNO 言語バインディング - UNO C++ バインディング  を見なさい。 OpenOffice.org Basic で Office にアクセスすることは11.1 OpenOffice.org Basic とダイアログ - OpenOffice.org Basic での第一歩 - に記述されている。

 次のセクションは、 Java プログラムと OpenOffice.org の間に接続の際に、何が起きるか記述する。 

サービス・マネージャー

 UNO は、サービス・マネージャー ( Service Manager ) のコンセプトを導入し、それは、サービス ( services ) を作る "factories" であるとみなされる。  今のところは、サービスを特定のタスクを行うために使われることができる UNO オブジェクトとして見ることは十分である。  後で、我々はサービスという用語の、正確な定義を与えるであろう。 

例えば、次のサービスは利用可能である:

com.sun.star.frame.Desktop

ロードされたドキュメントを保守する:ドキュメントをロードして、現在のドキュメントを受けとって、そして全てのロードされたドキュメントにアクセスするのに使われる

com.sun.star.configuration.ConfigurationProvider

OpenOffice.org コンフィグレーションに、アクセスを譲る。 例えば、 Tools - Option ダイアログで の設定

com.sun.star.sdb.DatabaseContext

OpenOffice.org に登録されたデータベースを持つ

com.sun.star.system.SystemShellExecute

現在のプラットホームの上に、システムコマンドあるいはアプリケーションのために登録されたドキュメントを実行する

com.sun.star.text.GlobalSettings

テキスト・ドキュメントのために、包括的なビューと印刷設定を処理する

サービスを提供している ServiceManager の概観グラフィック
図 1.1 :サービス・マネージャー

 サービスは、常にコンポーネントー・コンテキスト ( component context ) に存在する、そしてそれはサービスを作ったサービス・マネージャーとサービスによって使われる他のデータから成り立つ。 

 上の FirstConnection クラスは、 OpenOffice.org プロセスのクライアントであるとみなされる、 OpenOffice.org はこの点に関してはサーバーである。 クライアントとサーバーの両方ともが、それら自身のコンポーネント・コンテキストと、サービス・マネージャーを持っている。  クライアントのサービス・マネージャーは、クライアント・プロセスで UNO オブジェクトを作る、そしてサーバー・サービス・マネージャーはサーバー・プロセスで同じことをする。  ただサービス・マネージャーによって作られた UNO オブジェクトだけが、プロセス境界の向こう側と、お互いに話をすることができるから、これは必要である。 今は、サーバー・サイドの上にロケートされたデータで動作するために、クライアントは、サーバーのサービス・マネージャーを得る必要がある。 

 我々の FirstConnection クラスのメソッド getRemoteServiceManager () が、これを達成するために2つのステップを使う:

 最初に、それはクラス com.sun.star.comp.helper.Bootstrap から、ローカル UNO のコンポーネント・コンテキストを手に入れる。  このローカルなコンポーネント・コンテキストは、どのように他の構成するコンテキストに話をするために必要なサービスを作るべきか知っている、小さいサービス・マネージャーを含んでい る。 1つのそのようなサービが com.sun.star.bridge.UnoUrlResolver である、それでそれはローカルのサービス・マネージャーに、このサービスを作るように頼む。 

 次に、それは UnoUrlResolver オブジェクトを、サービス・マネージャーと一緒に、サーバー・サイドから、コンポーネント・コンテキストを得るために使う。 この段階において、 queryInterface () コールについて、心配するべきでない - それらは、後に説明されるであろう。 これで、クライアントは、リモートのサービス・マネージャーに、リファレンスを持つ。 

概観グラフィックス UnoUrlResolver と遠い ServiceManager の間に相互作用を示す
図 1.2: UnoUrlResolver がリモートの ServiceManager を得る

  ここで使われたオブジェクトの徹底的な記述のために、チャプター 3.3.1プロフェッショナル UNO - UNO コンセプト - UNO プロセス間接続 を参照しなさい。 

コネクションの失敗

リモートのコネクションは、ある特定の条件の下で、失敗することがある:

 ブリッジが利用できなくなって、アクセスが試みられる時、それは com.sun.star.lang.DisposedException を投げる。  あなたが、プログラムでリモートのリファレンスに、アクセスする時はいつでも、リモートのリファレンスをヌルにセットして、結果的にユーザに知らせるよう な方法で、例外を捕まえなさい。  もし、あなたのクライアントが、もっと長い期間の間も、走るよう設計されるなら、それらが現在はヌルであることに気付いた時、新しいリモートの リファレンスを受けとる用意をしなさい。 

  もう1つの方法は、 UnoUrlResolver の基礎となるリモート・ブリッジ ( remote bridge ) で、リスナを登録することである。 

 OpenOffice.org は、リモートのブリッジにおける"bridge disposed"イベントのために、リスンすることを許し、その結果、あなたが無効なリファレンスをリリースし、ユーザーに何が起きたかを通知するか、もし必要であるなら、適当な例外を投げる事ことが出来るように。 

 これをするためには、あなたは、手作業でブリッジを作って、ブリッジにおいてリスナを登録しなくてはならない。  あなたが接続失敗のために、もう働かないリファレンスを使おうとするときはいつでも、 UnoUrlResolver によって作られた接続は、単純に java.lang.RuntimeException を投げる。 チャプター 3.3.1 Professional UNO - UNO コンセプト - UNO プロセス間接続  は、コネクション・アウェアなクライアントを書く方法を示す。 

2.4 OpenOffice.org でオブジェクトを手に入れる方法

 我々のコンテキストでのオブジェクト ( Object ) は、あなたが呼び出すことができるメソッドを持っている、実装されたクラスのインスタンスである。 オブジェクトは、 OpenOffice.org と一緒に何かをするように要求される。  けれども、あなたは、どこでそれらを得るか?

新しいオブジェクト

 一般に、新しいオブジェクト、あるいは、最初のアクセスに必要なオブジェクトは、 OpenOffice.org でサービス・マネージャー ( service manager ) によって作られる。 FirstConnection の例では、ローカルのサービス・マネージャーは、 UnoUrlResolver オブジェクトを作る:

Object urlResolver  = xLocalServiceManager.createInstanceWithContext(
                "com.sun.star.bridge.UnoUrlResolver", xLocalContext );

 リモートのサービス・マネージャーは、ローカルのサービス・マネージャーと全く同じように、正確に働く。  リモートのサービス・マネージャーは、アプリケーション・ウインドウを取り扱って、そして OpenOffice.org でドキュメントをロードした、リモートのデスクトップ ( Desktop ) オブジェクト を作る:

Object desktop = xRemoteServiceManager.createInstanceWithContext(
               "com.sun.star.frame.Desktop", xRemoteContext);

ドキュメント・オブジェクト

  ドキュメン・トオブジェクトは、 OpenOffice.org と一緒に開かれるファイルを表す。 それらはデスクトップ ( Desktop ) オブジェクトによって作られ、そして、この目的のための loadComponentFromURL() メソッドを持っている。 

他のオブジェクトによって供給されるオブジェクト

オブジェクトが他のオブジェクトを配ることができる。 2つのケースがある:

オブジェクトのセット

 オブジェクトは、類似のオブジェクトのセットで要素であり得る。  セットで、オブジェクトにアクセスするために、あなたはどのようにセットから特定の要素を得るべきか知る必要がある。 OpenOffice.org API は、4つの方法がセットで要素を提供することを可能にする。 

  最初の3つの方法は、要素アクセス・メソッドを持ったオブジェクトで、それは、ネーム、インデックス、または一覧で、アクセスを許す。  4番目の方法は、アクセス方法は持っていないが、アレイとして直接に用いられる、要素のシーケンスである。  要素のセットがどのように使われるかは、後に論じられるであろう。 オブジェクトのデザイナーは、オブジェクトの特別な条件に基づいて、提供する機会のど ちらかを決める、たとえば、リモートではどのように振る舞うか、また、どのアクセス方法が実装で最も良くうまくいくかのような。 

2.5 オブジェクトを利用する

OpenOffice.org API オブジェクトを利用することは、次のことを必要とする:

2.5.1 サービス

 OpenOffice.org API で、オブジェクトはサービス ( services ) と呼ばれる。 しかしながら、オブジェクトとサービスは同じものではない。 サービスはオブジェクトのアブストラクト仕様である。 全ての UNO オブジェクトは、サービス仕様の後に続かなければならなくて、そして、少なくとも1つのサービスをサポートしなければならない。 UNO オブジェクトがサービスと呼ばれる、なぜなら、サービス仕様を満たしているから。

 アブストラクト・オブジェクト仕様の中に、インタフェース ( interface ) とプロパティ ( property ) を結合することによって、サービスがオブジェクトを記述する。 サービスという語が、他のコンテキストで持っている意味によって、混乱させられてはいけない。 UNO で、サービスが正確にこれである:インタフェースとプロパティの複合。 

  インタフェース( interface ) は、一緒にサービスの1つの局面を定義するメソッドのセットである。 例えば、 com.sun.star.view.XPrintable インタフェースは、メソッド print () 、 getPrinter () と setPrinter () を規定する。 

 プロパティ ( property ) は、統合的でも構造的でないとみなされるサービスの特徴である、そして、それゆえ、getPrinter () のような、特別なgetメソッドの代わりに、一般的な getPropertyValue () / setPropertyValue () メソッドを通して取り扱われる。  プロパティを含んでいるオブジェクトが、あらゆる種類のプロパティを処理する用意を整えているために、 com.sun.star.beans.XPropertySet インタフェースをサポートしなければならない。 典型的な例は、文字あるいはパラグラのフフォーマット化のためのプロパティである。 プロパティを使って、あなたは setPropertyValues () への一つのコールを通して、オブジェクトの多数の特徴を設定することができる、そしてそれは大いにリモートのパフォーマンスを改善する。  例えば、パラグラフが、それらの com.sun.star.beans.XMultiPropertySet インタフェースを通して、 setPropertyValues () メソッドをサポートする。

サービスのコンセプトは、次の理由のために紹介された:

サービスが仕様をインプリメンテーションから分離する

 サービスの仕様は アブストラクト( abstruct ) である、すなわち、それは、ある機能性をサポートしているオブジェクトが、どのように内部でこれを実行するかを定義しない。 OpenOffice.org API のアブストラクト仕様を通して、 API の下からインプリメンテーションを引き抜いて、そして、もし必要なら、異なったインプリメンテーションをインストールすることは可能である。

サービス名が、クラス名によってではなく、仕様名によってインスタンスを作ることを可能にする

  Java あるいは C++ で、new オペレーターを、クラスのインスタンスを作るために使う。 このアプローチは限定されている:あなたが得るクラスは、決め打ちされている。 コードをエ ディットしないで、もう1つのクラスによって、後でそれを交換することができない。 サービスのコンセプトはこれを解決する。  OpenOffice.org でのセントラル・オブジェクト・ファクトリー、つまり、グローバル・サービス・マネージャーは、その内部のインプリメンテーションを定義しないで、ある目 的のために使われ ることがで きるオブジェクトを作るように依頼される。 これは可能である、なぜなら、サービスがそのサービス名によってファクトリーから注文されることができ、そし て、ファクトリーは、それが、どのサービス・インプリ メンテーションを返すか決めるから。 あなたが、どのインプリメンテーションを得るかは、何の相違も生じない、あなたはただ明瞭なインタフェースとサービスのプロパティを使うだけである。

サービスがきめが細かいインタフェースを管理しやすくする

 アブストラクト・インタフェースは、さらに再利用可能であり、もしそれらが、もし、それらがき めが細かくて、すなわち、それらが、小さくて、オブジェクトの、複数でなく、1つのアスペクトを表記していれば。 サービスは、一方では、きめが細かいイ ンタフェースを持つのを許し、そして、サービスの中に構築することによって、容易にそれらを管理するのを許す。  Office 環境でのオブジェクトが多くの局面を共有するであろうことは、非常に移植性に富んでいるでいるので、この素晴らしい細かさは、インタフェースが再利用され て、そし て、首尾一貫して振る舞うオブジェクトを得ることを可能にする。 例えば、テキストを取り扱う、統一されたメソッドを実現することは可能であった、もし、 あなたが、ボディ・テキスト、テキスト・フレーム、ヘッダーあるいはフッター・ テキスト、脚注、テーブル・セルあるいは図形内のテキストを扱っているなら、問題は無い。 これら全ての目的のために、別個のインタフェースを定義するこ とは、必要ではなかった。

サービスが多数の構造的でないプロパティを処理する

 もしあなたがオブジェクトを指定するために、ただインタフェースだけを持っているなら、あなた は、Office ドキュメントの全ての特質を処 理するために、多くの get と set メソッドをコールする必要がある。 さらに、あなたがそれらを定義する途端に、それらはオブジェクトの構造の難しい部分になる、そして、それは他 のところに仕様を再利用する ことを難しくする。 プロパティを使って、オブジェクトの構造的な部分でない、多くのクオリティが指定されることができる、そして、多くの get と set メソッドをコールする代わりに、UNO サービスのプロパティが、1つのメソッドのコールによって、すぐに操作されることができる。

  サービス com.sun.star.text.TextDocument を、UML 表記法で考慮しよう。 図で示された UML チャートは、 TextDocument サービスの、義務的なインタフェースを描写する。 これらのインタフェースは、 OpenOffice.org でテキスト・ドキュメントの基本的な外観を表現する。 それはテキストを含んでいる、それは探索可能で、そして リフレッシュ可能 ( refreshable ) である。 これは URL とコントローラーのモデルである、そしてそれは、モディファイ可能で、プリント可能で、保存可能である。 UML チャートは、これがどのように API で指定されるかを示す。

UML 図 com.sun.star.text.TextDocument サービスを示す
図 1.3:テキスト・ドキュメント

 図の 左側に、サービス com.sun.star.text.TextDocumentcom.sun.star.document.OfficeDocument は示されている。 全ての TextDocument が、定義によってこれらのサービスを含まなくてはならない。

  図の右側に、あなたがインタフェースを見い出し、それは、サービスがエクスポートしなくてはならない。 それらのメソッドの区画が、種々のインタフェース に含まれた区画をリストする。 OpenOffice.org API では、全てのインタフェース名は、他のオブジェクト名と見分けが着くように、 X で始めなければならない。

  全ての TextDocument が、3つのインタフェースをサポートしなくてはならない: XTextDocument 、 XSearchable と XRefreshable 。 さらに、 TextDocument が常に OfficeDocument であるから、それは同じくインタフェース XPrintable 、 XStorable 、 XModifiable と XModel をイクスポートしなくてはならない。 これらのインタフェースに含まれるメソッドは、これらの局面をカバーする:プリントする、ストアする、モディファイする、そして、モデルをハンドリングする。

  図 2.2で示されるインタフェースが、ただ TextDocument の義務的なインタフェースに過ぎないことに注意を払いなさい。

 TextDocument が、オプションのプロパティとインタフェースを持ち、その中に、プロパティ CharacterCount 、 ParagraphCount と WordCount と XPropertySet インタフェース、もしプロパティが全てに存在しているなら、サポートされなくてはならないプロパティを持っている。 OpenOffice.org の TextDocument サービスの、現在のインプリメンテーションは、これらのインタフェースをサポートするのみならず、同じく、全てのオプションのインタフェースをサポートする。 TextDocument の使用法は、 7 テキスト・ドキュメント で充分に記述されている。

インタフェースを使う

  全ての UNO オブジェクトが、そのインタフェースとプロパティを通してアクセスされなくてはならないという事実は、 Java と C++ のような言語で効果を持つ、そして、メソッドを呼び出すことができる前に、コンパイラはオブジェクト・リファレンスの正しいタイプを必要 とする。
 Java または C++ では、インプリメントするインタフェースにアクセスする前に、通常は、オブジェクトを投げるだけである。
 UNO オブジェクトが作用する場合は、これは異なっている:あなたは UNO 環境に、あなたのために適切なリファレンスを得るように依頼しなくてはならない。 オブジェクトがサポートしているがコンパイラがまだ知らないインタ フェースのメソッドにアクセスするのを望む時はいつでも。 そうした場合には、あなたは安全にそれをキャストすることができる。

  Java UNO 環境は、この目的のために、メソッド queryInterface () を持つ。 それは一見すると複雑に見える、しかし、queryInterface () がプロセス境界を越えて UNO タイプの安全なキャストであることを一度理解すれば、すぐに、それに慣れるであろう。 我々がどのように UnoUrlResolver を作って、そしてその後に、 FirstConnection クラスで queryInterface() をコールしなければならなかったか、覚えておきなさい:

Object urlResolver  =  xLocalServiceManager .createInstanceWithContext (
                "com.sun.star.bridge.UnoUrlResolver", xLocalContext );
// query XUnoUrlResolver interface from urlResolver object
XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
                XUnoUrlResolver.class, urlResolver );

 我々は、ローカルのサービス・マネージャーに、そのファクトリー・メソッド createInstanceWithContext () を使って、 com.sun.star.bridge.UnoUrlResolver を 生成するように頼んだ。 このメソッドは、 Java Object タイプを返すことが可能で、それは、あなたを驚かせるべきでない-結局、全てのファクトリーは、とのようなタイプでもリターンが可能でなければならない:

java.lang.Object createInstanceWithContext(String serviceName, XComponentContext context)

  我々が受け取るオブジェクトは、 com.sun.star.bridge.UnoUrlResolver サービスである。 下に、あなたは UML 表記法でその仕様を見いだす。 サービス UnoUrlResolver はプロパティを持たず、そして、1つのメソッドで1つのインタフェース com.sun.star.bridge.XUnoUrlResolver をサポートする、すなわち、resolve () :

UML 図 com.sun.star.bridge.UnoUrlResolver serviceument を示す
図1.4: UnoUrlResolver

[ここから]

 ポ イントは、我々がファ クトリーで注文したオブジェクトが UnoUrlResolver であって、そしてインタフェース XUnoUrlResolver をイクスポートすることを知っているのに対して、コンパイラは知らない。 そのために、我々は、 UNO ランタイム環境を使って、インタフェース XUnoUrlResolver に尋ねたり質問しなければならない、なぜなら、このインタフェースの上に resolve () メソッドを使うことを望むから。 メソッド queryInterface () は、我々が、求められているインターフェース・タイプに投げられるリファレンスを得る事を確定させす、ターゲットのオブジェクトが、ロー カルであっても、リモートのオブジェクトであっても。 Java UNO 言語バインディングには、2つの queryInterface 定義がある:

java.lang.Object UnoRuntime.queryInterface(java.lang.Class targetInterface, Object sourceObject)
java.lang.Object UnoRuntime.queryInterface(com.sun.star.uno.Type targetInterface, Object sourceObject)

  UnoRuntime.queryInterface () が、ファクトリー・メソッド createInstanceWithContext () とまったく同じような java.lang.Object を返すために指定されるので、我々はまだ明示的に必要とされるタイプに、我々のインタフェース・リファレンスを投げなくてはならない。 相違は、 queryInterface () の後には、安全に我々のインタフェース・タイプに投げることができ、そして、最も重要な事は、リファレンスが、他のプロセスのオブジェクトであっても機能することである。 ここに、 queryInterface () コールの、一歩一歩の説明がある:

XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
           XUnoUrlResolver.class, urlResolver );

  XUnoUrlResolver は、我々が使うことを望むインタフェースである、そのため、我々はqueryInterface から期待するインタフェースをストアするために xUnoUrlResolver (小文字の x )という名前の XUnoUrlResolver 変数を定義する。

  それから、 XUnoUrlResolver インタフェースに対してい、我々の urlResolver オブジェクトをクエリーする、ターゲット・インターフェースとして XUnoUrlResolver.class を、ソース・オブジェクトとしてurlResolverを渡しながら。 最終的に、 XUnoUrlResolver に結果を投じて、そして結果として生じている参照を、変数 xUnoUrlResolver に割り当てる。

  もしソース・オブジェクトが、質問しているインタフェースをサポートしないなら、 queryInterface () はヌルを戻すであろう。

  Java では、 queryInterface () へのこのコールは、あなたがあなたが必要とするインタフェースをサポートすることを知られているオブジェクトに、リファレンスを持っている時と、しかし、 あなたが、まだ適切なリファレンス・タイプを持っていない時は、いつでも必要である。 幸いに、あなたは、 java.lang.Object ソース・タイプから、 queryInterface () をクエリーするのを許されるだけではなく、もう1つのインタフェース・リファレンスから、このように同じくインタフェースに問い合わせてもよい:

// loading a blank spreadsheet document gives us its XComponent interface:
XComponent xComponent = xComponentLoader.loadComponentFromURL(
                "private:factory/scalc", "_blank", 0, loadProps);
// now we query the interface XSpreadsheetDocument from xComponent
XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument)UnoRuntime.queryInterface(
                XSpreadsheetDocument.class, xComponent);

  さらに、もしメソッドが、それがすでにインタフェース・タイプを返すようなメソッドで定義されるなら、あなたはインタフェースに問い合わせる必要がない、しかし、あなた は、すぐに、そのメソッドを使うことができる。 上に書かれた断片で、メソッド loadComponentFromURL は、 com.sun.star.lang.XComponent インタフェースを返すと指定される、それで、 xComponent 変数において、 XComponent メソッド addEventListener を () と removeEventListener () とを、直接に呼んでもよい、もし、ドキュメントが閉じられているということを通知されることを望むなら。

助言グラフィックスがテキストでヒンティング処理のセクションを表わす

 Java UNO 言語バインディングの未来のバージョンが、もうインタフェースのために、もう、明白な問合せを必要としなくて済むようになるであろう。

 C++ での対応するステップは、ソースのインスタンスをパラメータとする、 Reference<> テンプレートによって実行される:

// instantiate a sample service with the servicemanager.
Reference< XInterface > rInstance =
        rServiceManager->createInstanceWithContext(
                OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),
                rComponentContext );
// Query for the XUnoUrlResolver interface
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );

< XUnoUrlResolver > rResolver ( rInstance 、 UNO_QUERY );

 OpenOffice.org Basic では、インタフェースのための質問は必要ではなく、基本的なランタイム・エンジンが内部でそれを取り扱う。

プロパティを使う

 サービスは、プロパティで処理をすることを許すインタフェースを通して、そのプロパティを提供しなくてはならない。 これらのインタフェースの最も 基本的なフォームは、インタフェース com.sun.star.beans.XPropertySet である。 プロパティのために他のインタフェースがあり、たとえば com.sun.star.beans.XMultiPropertySet のように、それは、一つのメソッド呼び出しで、多くのプロパティ を get し set する。 プロパティがサービスに存在している時、 XPropertySet は常にサポートされる。

 XPropertySet では、以下のように Java で定義される2つのメソッドが、プロパティ・アクセスを遂行する:

void setPropertyValue(String propertyName, Object propertyValue)
Object getPropertyValue(String propertyName)

 FirstConnection の例では、 XPropertySet インタフェースは、最初のオブジェクトからリモートのコンポーネント・コンテキストを得るために使われた。 最初のオブジェクトは、 StarOffice.ServiceManager であって、そして、従って、リモート・コンポーネント・コンテキストを含んでいたプロパティ DefaultContext を持っていた。 次のコードは、このプロパティが、どのように検索されたかを説明して、そして、その com.sun.star.uno.XComponentContext インタフェースに問い合わされたかを説明する:

// query the XPropertySet interface from the initial object, which is a StarOffice.ServiceManager
XPropertySet xPropertySet = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, initialObject);
// get the property DefaultContext
Object context = xPropertySet.getPropertyValue("DefaultContext");            
// query XComponentContext from the context object, we want to call XComponentContext.getServiceManager
xRemoteContext = (XComponentContext)UnoRuntime.queryInterface(
                XComponentContext.class, context);

 これで、あなたは、 OpenOffice.org ドキュメントで仕事を始める準備が出来た。

2.5.2 例:スプレッドシート・ドキュメントでの動作

 この例で、我々は、リモート・サービス・マネージャーに、我々にリモートの Desktop オブジェクトを与えて、 そして、我々は、新しいスプレッドシート・ドキュメントを作るために、その loadComponentFromUrl () メソッドを使うであろう。 ドキュメントから、我々は、名前を使って新しいシートを差し込んでアクセスする、シートのコンテナを得る。

 新しい シートで、我々は値を A1 と A2 に入力して、そして A3 に、それら要約する。 要約しているセルのセル・スタイルは、セルスタイル Result を得る、その結果、それはイタリックで、ボールドで、下線が引かれているように現 われる。 最終的に、我々は新しいシートをアクティブなシートにする、ユーザーがそれを見ることができるように。

 上記の FirstConnection の例に、これらのインポート行を加えなさい:( FirstSteps/FirstLoadComponent.java)

import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XComponent;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetView;
import com.sun.star.table.XCell;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XController;
import com.sun.star.frame.XComponentLoader;

 次のように useConnection メソッドをエディットしなさい:

protected void useConnection() throws java.lang.Exception {
    try {
        xRemoteServiceManager = this.getRemoteServiceManager(
                "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
        // get the Desktop, we need its XComponentLoader interface to load a new document
        Object desktop = xRemoteServiceManager.createInstanceWithContext(
            "com.sun.star.frame.Desktop", xRemoteContext);
       
        // query the XComponentLoader interface from the desktop
        XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(
            XComponentLoader.class, desktop);
        // create empty array of PropertyValue structs, needed for loadComponentFromURL
        PropertyValue[] loadProps = new PropertyValue[0];
        
        // load new calc file
        XComponent xSpreadsheetComponent = xComponentLoader.loadComponentFromURL(
            "private:factory/scalc", "_blank", 0, loadProps);
        // query its XSpreadsheetDocument interface, we want to use getSheets()
        XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument)UnoRuntime.queryInterface(
            XSpreadsheetDocument.class, xSpreadsheetComponent);
        // use getSheets to get spreadsheets container
        XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();
        //insert new sheet at position 0 and get it by name, then query its XSpreadsheet interface
        xSpreadsheets.insertNewByName("MySheet", (short)0);
        Object sheet = xSpreadsheets.getByName("MySheet");
        XSpreadsheet xSpreadsheet = (XSpreadsheet)UnoRuntime.queryInterface(
            XSpreadsheet.class, sheet);
        // use XSpreadsheet interface to get the cell A1 at position 0,0 and enter 21 as value
        XCell xCell = xSpreadsheet.getCellByPosition(0, 0);
        xCell.setValue(21);
        // enter another value into the cell A2 at position 0,1
        xCell = xSpreadsheet.getCellByPosition(0, 1);
        xCell.setValue(21);
        // sum up the two cells
        xCell = xSpreadsheet.getCellByPosition(0, 2);
        xCell.setFormula("=sum(A1:A2)");
        // we want to access the cell property CellStyle, so query the cell's XPropertySet interface
        XPropertySet xCellProps = (XPropertySet)UnoRuntime.queryInterface(
            XPropertySet.class, xCell);
        // assign the cell style "Result" to our formula, which is available out of the box
        xCellProps.setPropertyValue("CellStyle", "Result");
        // we want to make our new sheet the current sheet, so we need to ask the model
        // for the controller: first query the XModel interface from our spreadsheet component
        XModel xSpreadsheetModel = (XModel)UnoRuntime.queryInterface(
           XModel.class, xSpreadsheetComponent);
       
        // then get the current controller from the model
        XController xSpreadsheetController = xSpreadsheetModel.getCurrentController();
        // get the XSpreadsheetView interface from the controller, we want to call its method
        // setActiveSheet
        XSpreadsheetView xSpreadsheetView = (XSpreadsheetView)UnoRuntime.queryInterface(
           XSpreadsheetView.class, xSpreadsheetController);
        // make our newly inserted sheet the active sheet using setActiveSheet
        xSpreadsheetView.setActiveSheet(xSpreadsheet);    
    }
    catch( com.sun.star.lang.DisposedException e ) { //works from Patch 1
        xRemoteContext = null;
        throw e;
    }         
}

  代わりに、サンプル・ディレクトリから、あなたの現在のプロジェクトまで、 FirstLoadComponent.java を加えることができ、それは上に示される変更を含んでいる。

2.5.3 コモン・タイプ

  ここまで、 OpenOffice.org API が Java のために作られるかのように、リテラルと共通の Java タイプが、メソッドパラメータとリターン値のために使われた。 しかしながら、 OpenOffice.org API は、言語に依存しないように設計されている事と、あなたの言語環境に適切なタイプにマップされる自身の内部タイプを持っている事とを、理解するのは重要で ある。 タイプのマッピングは、このセクションで手短に記述されている。 タイプのマッピングについての詳細な情報のためには、3 プロフェッショナル UNO を参照しなさい。

シンプル・タイプ

 シンプル・タイプが structs 、メソッドのリターン値、あるいはパラメータで起こる。 次のテーブルは、 UNO でシンプル・タイプを示す、そして、もし利用可能であるなら、 Java への正確なマッピング、 C++ 、 OpenOffice.org と Basic のタイプで。

UNO

タイプ記述

Java

C++

Basic

char

16 bit unicodeの文字型

char

sal_Unicode

boolean

ブーリアン型;真と偽

boolean

sal_Bool

Boolean

byte

8 bit の通常の型

byte

sal_Int8

Integer

short

符号付き16 bitの通常の型

short

sal_Int16

Integer

unsigned short

符号無し16 bitの通常の型

sal_uInt16

long

符号付き32 bitの通常の型

int

sal_Int32

Long

unsigned long

符号無し32 bitの通常の型

sal_uInt32

hyper

符号付き64 bitの通常の型

long

sal_Int64

unsigned hyper

符号無し64 bitの通常の型

sal_uInt64

float

プロセッサ依存の浮動小数点

float

float( IEEE float)

Single

double

プロセッサ依存の倍精度

double

double(IEEE double)

double

 このテーブルに正確なマッピングを持っていないタイプのために、特別な条件がある。

 これらのタイプの詳細については、タイプ・マッピングについて対応するセクションの、3.4 プロフェッショナル UNO - UNO 言語バインディング を調べなさい。 

ストリング

 UNO は、ストリングが単純なタイプであると考える、しかし、それらが、若干の環境で特別な取り扱いを必要とするので、我々は別にここで、それらを論じる。

UNO

記述

Java

C++

Basic

string

16 bit unicodの文字列

java.lang.String

 ::rtl::OUString

String

  Java では、UNO ストリングは、それらがネイティブの java.lang.String オブジェクトであるかのように使いなさい。

  C++ では、文字列は、通常は、::rtl::OUString クラスにある関数 createFromAscii ()の、SAL変換機能で、UNO unicodeストリングに変換されなければならない。

//C++
static OUString createFromAscii( const sal_Char * value ) throw();

 Basic では、基本的なストリングが透過的に UNO ストリングにマップされる。

Enum タイプと定数グループ

 OpenOffice.org API は( enums と呼ばれる)多くの列挙タイプと(定数グループと呼ばれる)定数のグループを使う。 Enums は、あるコンテキストで、全てのもっともらしい値をリストするために使われる。 定数グループ( constant group ) は、プロパティ、パラメータ、リターン値と struct メンバーのために、可能な値を定義する。

 例えば、テーブル・セル内容の縦の調整のために可能な値を記述する enum com.sun.star.table.CellVertJustify がある。 テー ブル・セルの縦の調整は、それらのプロパティ com.sun.star.table.CellProperties:VertJustify によって決定される。 このプロパティのための可能な値は、 CellVertJustify によれば、STANDARD、TOP、CENTER と BOTTOM である。

// adjust a cell content to the upper cell border
// The service com.sun.star.table.Cell includes the service com.sun.star.table.CellProperties
// and therefore has a property VertJustify that controls the vertical cell adjustment
// we have to use the XPropertySet interface of our Cell to set it
xCellProps.setPropertyValue("VertJustify", com.sun.star.table.CellVertJustify.TOP);

 OpenOffice.org Basicは、列挙タイプと定数グループとを理解する。 それらの使用法は単刀直入である:

'OpenOffice.org Basic
oCellProps.VertJustify = com.sun.star.table.CellVertJustify.TOP

C++では、 enums と定数グループが、範囲オペレーター :: と一緒に使われる。

//C++
rCellProps->setPropertyValue(OUString::createFromAscii( "VertJustify" ),
        ::com::sun::star::table::CellVertJustify.TOP);

2.5.4 Struct

 OpenOffice.org API の Structs は、全ての他の UNO タイプの複合物を作るために使われる。 それらは、公共のメンバー変数のみから成り立って、C structs または Java クラスに対応する。

 structs はデータをカプセル化しないが、それらは全体として輸送することがより容易であって、整列する代わりに、get () と set () 呼び出しを前後に整列する。 特に、これは、リモートのコミュニケーションのためにアドバンテージを持っている。

 あなたは、以下のように、 .(ドット)オペレーターを通して、 struct メンバーへのアクセスを得る。

aProperty.Name = "ReadOnly";

 Java 、 C++ と OpenOffice.org Basic では、キーワード new は、 structs のインスタンスを作る。 OLE オートメーションでは、 com.sun.star.reflection.CoreReflection を UNO struct を得るために使いなさい。 サービス・マネージャーを structs を作るために使ってはいけない。

//In Java:
com.sun.star.beans.PropertyValue aProperty = new com.sun.star.beans.PropertyValue();
'In StarBasic
Dim aProperty as new com.sun.star.beans.PropertyValue

2.5.5 Any

  OpenOffice.org API は、しばしば any タイプを使う、それは、他の環境から知られている、Variantタイプと対をなしている。  any タイプは、任意の UNO タイプを保持する。 any タイプは、一般的な UNO インタフェースで特に使われる。

  any の発生の例は、以下のような、メソッド・パラメータとリターン値であって、頻繁に使われるメソッドである:

インタフェース

anyタイプを返す

anyタイプを取る

XPropertySet

any getPropertyValue(string propertyName)

void setPropertyValue(any value)

XNameContainer

any getByName(string name)

void replaceByName(string name, any element)

void replaceByName(string name, any element)

XIndexContainer

any getByIndex(long index)

void replaceByIndex(long index, any element)

void insertByIndex(long index, any element)

XEnumeration

any getByIndex(long index)

   さらに、any タイプでは、 com.sun.star.beans.PropertyValue struct で起こる。

UML 図 com.sunstar.beans.PropertyValue struct を示す
図 1.5: PropertyValue

 この struct は、2つのメンバー変数、name と value  を持っていて、そして PropertyValue structs のセットで遍在する、そして、そこで全ての PropertyValue は、ネームとバリューによってプロパティを記述する、名前と値とのペアである。

 もしあなたが、PropertyValue struct のような、バリューをセットしなくてはならないなら、any タイプをアサインしなければならない、もしあなたが PropertyValue から読んでいるなら。 これがどのように実行されるかは、あなたの言語に依存する。

  Java では、 any タイプは、 java.lang.Object でラップされる。 従うべき2つの単純な規則がある:

  あなたが any タイプを中に渡すことになっている時は、常に java.lang.Object か Java UNO オブジェクトを渡す。 

 例えば、もしあなたが、ターゲット・オブジェクトで、基本タイプを持っているプロパティをセットするために、 setPropertyValue () を使うなら、新しい値のために java.lang.Object を渡さなくてはならない。 もし、新しい値が Java で基本タイプであるなら、基本タイプのために対応する Object タイプを作りなさい:

xCellProps.setPropertyValue("CharWeight", new Double(200.0));

  もう1つの例は、 loadComponentFromURL のために使うことを望む PropertyValue struct でああろう:

com.sun.star.beans.PropertyValue aProperty = new com.sun.star.beans.PropertyValue();
aProperty.Name = "ReadOnly";
aProperty.Value = new Boolean(true);

  あなたが any タイプを受ける 時、それを評価する3つの異なった方法がある、あなたが予想する UNO タイプによって。 もし入ってくるオブジェクトが、インタフェースを持っているなら、それに対して queryInterface () を使用しなさい。 もし入ってくるオブジェクトが struct なら、 Java UNO struct に入ってくるオブジェクトをキャストしなさい。 もし入ってくるオブジェクトが、単純なタイプなら、 com.sun.star.uno.AnyConverter を使いなさい。

 次のことはキャストの例である:

// the com.sun.star.table.TableBorder property that can be found in tables is a struct
// simply cast the property to the correct UNO struct type
com.sun.star.table.TableBorder bord = (TableBorder)xTableProps.getPropertyValue("TableBorder");
// now you can access the struct member fields
com.sun.star.table.BorderLine theLine = bord.TopLine;
int col = theLine.Color;
System.out.println(col);

  AnyConverter は、より詳しく見た方が良い。 例えば、もしあなたが基本タイプを含んでいるプロパティを得るのを望むなら、  getPropertyValue () が、 any タイプにラップされた基本タイプを含んでいる java.lang.Object を返すことを知っていなくてはならない。 com.sun.star.uno.AnyConverter は、このようなオブジェクトのためのコンバータである。 実際に、それはただ変換よりも、いっそう多くの動作をすることが出来て、Java UNO リファレンスで、その仕様を見いだせる。 次のリストは、 AnyConverter での変換関数を総括する:

static java.lang.Object toArray(java.lang.Object object)
static boolean toBoolean(java.lang.Object object)
static byte toByte(java.lang.Object object)
static char toChar(java.lang.Object object)
static double toDouble(java.lang.Object object)
static float toFloat(java.lang.Object object)
static int toInt(java.lang.Object object)
static long toLong(java.lang.Object object)
static java.lang.Object toObject(Class clazz, java.lang.Object object)
static java.lang.Object toObject(Type type, java.lang.Object object)
static short toShort(java.lang.Object object)
static java.lang.String toString(java.lang.Object object)
static Type toType(java.lang.Object object)
static int toUnsignedInt(java.lang.Object object)
static long toUnsignedLong(java.lang.Object object)
static short toUnsignedShort(java.lang.Object object)

 その使用法は簡単である:

import com.sun.star.uno.AnyConverter;
long cellColor = AnyConverter.toLong(xCellProps.getPropertyValue("CharColor"));

  OpenOffice.org Basic では、 any タイプは Variant になる:

'OpenOffice.org Basic
Dim cellColor as Variant
cellColor = oCellProps.CharColor

  C++ では、any タイプのために、特別なオペレーターがある:

//C++ has >>= and <<= for Any (the pointed brackets are always left)
sal_Int32 cellColor;
Any any;
any = rCellProps->getPropertyValue(OUString::createFromAscii( "CharColor" ));
// extract the value from any
any >>= cellColor;

2.5.6 シーケンス

  シーケンスは、要素アクセスメソッドなしで直接アクセスされることができる、要素の変数を持っている UNO タイプのセットである。 シーケンスは、たいていの現在の言語バインディングでは、アレイにマップする。 しかし、UNOでのこれらのセットは、しばし ば、要素アクセスメソッドを持っているオブジェクトとして実現されるけれども、リモートのパフォーマンスが重要である、シーケンス・タイプもある。 シー ケンスは、常に API リファレンスで尖ったカッコで書かれる:

// a sequence of strings is notated as follows in the API reference
sequence < string > aStringSequence;

 Java では、シーケンスをアレイとして取り扱う。 空のアレイが new を使って作られ、そして、長さはヌルを割り当てる。 さらに、 Java オブジェクトのアレーを作る時、あなたが、ただ、リファレンスのアレーを作るだけであり、実際のオブジェクトがアロケートされないことに、留意しなさ い。 そのために、あなたは、アレーそのものを作るために new を使い、そして、再度、全てのシングル・オブジェクトに対して、アレイに新しいオブジェクトを割り当てるために、 new を使用しなければならない。

  PropertyValue structs の空シーケンスが、しばしば loadcomponentFromURL のために必要である:

// create an empty array of PropertyValue structs for loadComponentFromURL
PropertyValue[] emptyProps = new PropertyValue[0];

  PropertyValue structs のシーケンスは、 loadComponentFromURL () で、パラメータをロードするのに使うために必要とされる。 loadComponentFromURL () と、 com.sun.star.frame.XStorable インタフェースのための可能なパラメータ値は、 サービス com.sun.star.document.MediaDescriptor で見付けることができる。

//C++
Sequence< ::com::sun::star::beans::PropertyValue > loadProps( 1 );
// the structs are default constructed
loadProps[0].Name = OUString::createFromAscii( "AsTemplate" );
loadProps[0].Handle <<= true;
Reference < XComponent > rComponent = rComponentLoader->loadComponentFromURL(
        OUString::createFromAscii("private:factory/swriter"),
        OUString::createFromAscii("_blank"),
        0,
        loadProps);

  OpenOffice.org Basic では、単純な Dim が、空のアレイを作る。

'OpenOffice.org Basic
Dim loadProps()  'empty array

 structs のシーケンスは、new と Dim とを一緒に使って作成される

/'OpenOffice.org Basic
Dim loadProps(0) as new com.sun.star.beans.PropertyValue 'one PropertyValue

 C++ では、シーケンスのためにテンプレートがある。 必要とされる要素の数を省略することで、空のシーケンスが作られることができる。

//C++
Sequence < ::com::sun::star::beans::PropertyValue > loadProperties; // empty sequence

 もしあなたが、多くの要素を渡すなら、あなたは、要求されたタイプのアレーを手に入れる。

///C++
Sequence< ::com::sun::star::beans::PropertyValue > loadProps( 1 );
// the structs are default constructed
loadProps[0].Name = OUString::createFromAscii( "AsTemplate" );
loadProps[0].Handle <<= true;
Reference < XComponent > rComponent = rComponentLoader->loadComponentFromURL(
        OUString::createFromAscii("private:factory/swriter"),
        OUString::createFromAscii("_blank"),
        0,
        loadProps);

2.5.7 エレメントのアクセス

  我々は、すでに、セクション 2.4 第一歩 - OpenOffice.org でオブジェクトを手に入れる方法 で、オブジェクトのセットは、要素アクセス・メソッドを通して提供されることができるのを見た。 要素アクセス・インタフェースの、3つの最も重要な種類は、 com.sun.star.container.XNameContainer 、[ com.sun.star.container.XIndexContainer ] と com.sun.star.container.XEnumeration である。

 3つの要素アクセス・インタフェースは、OpenOffice.org API のきめが細かいインタフェースが、どのように一貫したオブジェクト・デザインを許すかについての例である。

  全ての3つのインタフェースは、 XElementAccess から相続する、すなわち、それらはメソッドを含み:

type getElementType()
boolean hasElements()

  要素のセットについての基本的なインフォメーションを見つけだすために。 メソッド hasElements () は、セットが、とにかく、要素を含むかどうか、そしてセットが、どのタイプを含んでいるかという質問に答える。 Java と C++ では、 Java UNO と C++ UNO 参照と比較して、com.sun.star.uno.Type を通して、UNO タイプについてのインフォメーションを手に入れることができる。

  com.sun.star.container.XIndexContainercom.sun.star.container.XNameContainer インタフェースは、平行したデザインを持っている。 UML 表記法で、両方ともがインタフェースすると思いなさい。

UML 図 com.sun.star.container.XIndexContainer と com.sun.star.container.XNameContainer を示す
図 1.6:インデックス付けられたコンテナと名前付けされたコンテナ

  ここから

XIndexAccess/XNameAccess インタフェースは、エレメントを得ることについてである。 XIndexReplace / XNameReplace インタフェースは、セットでエレメントの数を変えないで、既存のエレメントを置き換えることを許す、一方、 XIndexContainer/XNameContainer インタフェースは、エレメントを挿入したり削除することによって、エレメントの数を増やしたり減らしたりすることを許す。

   名前を付けられた、あるいは、インデックス付けられたオブジェクトの多くのセットは、 XIndexContainer や XNameContainer の、全ての継承ハイアラーキーをサポートしない、なぜなら、全てのサブクラスによって加えられた能力がエレメントのどんなセットのためにも常に論理的であるとい うわけではないから。

 XEumerationAccess インタフェースは、 XElementAccess インタフェースの下にある、名前付けされインデックス付けされたコンテナとは、違って働く。 XEnumerationAccess は、 XNameAccess と XIndexAccess のように、シングル・エレメントを提供しない、しかし、それは、もっと多くのエレメントが有る限り、次のエレメントに行くメソッドを持っているオブジェクトの一覧を作る。

UML 図 com.sun.star.container.XEnumeration インタフェースを示す
図 1.7:列挙されたコンテナ

 オブジェクトのセットは、しばしば、全てのエレメント・アクセス・メソッドをサポートする、若 干数は、同じく、ただ、ネーム、インデックス、あるいは列挙アクセスだけをサポートする。 どのアクセス・メソッドが利用可能であるかを見るために、常に 種々のタイプを API リファレンスで調べなさい。

  例えば、インタフェース com.sun.star.sheet.XSpreadsheetDocument のメソッド getSheets () は、XNameContainer から継承された、com.sun.star.sheet.XSpreadsheets インタフェースを、リターンするよう指定されている。 さらに、 API リファレンスは、あなたに提供されたオブジェクトが com.sun.star.sheet.Spreadsheets サービスをサポートすると言う、そして、それは、 XSpreadsheets のほかに、追加のエレメント・アクセス・インタフェースを定義する。

どのように XNameAccess 、 XIndexAccess と XEnumerationAccess とが、共に働くべきかを示す例が、下に提供される。

ネーム・アクセス

  ネームでエレメントを配る基本的なインタフェースは、 com.sun.star.container.XNameAccess インタフェースである。 それは3つのメソッドを持っている:

any getByName( [in] string name)
sequence < string > getElementNames()
boolean hasByName( [in] string name)

  上記の FirstLoadComponent の例で、メソッド getSheets () は、 com.sun.star.sheet.XSpreadsheets インタフェースを返した、そして、それは XNameAccess から継承する。 そのために、あなたは、 XSpreadsheets コンテナから、ネームによってシート "MySheet"を得るために getByName () を使うことができた:

XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();
Object sheet = xSpreadsheets.getByName("MySheet");
XSpreadsheet xSpreadsheet = (XSpreadsheet)UnoRuntime.queryInterface(
            XSpreadsheet.class, sheet);
// use XSpreadsheet interface to get the cell A1 at position 0,0 and enter 42 as value
XCell xCell = xSpreadsheet.getCellByPosition(0, 0);

  getByName () は、 any を返す事から、あなたが、スプレッドシート・オブジェクトにおいては、メソッドを呼び出す前に、 queryInterface () を使わなければならない。

インデックス・アクセス

  インデックスによってエレメントを配るインタフェースは com.sun.star.container.XIndexAccess インタフェースである。 それは2つのメソッドを持っている:

any getByIndex( [in] long index)
long getCount()

  FirstLoadComponent の例は、 XIndexAccess を証明するために許す。 API リファレンスは、我々に getSheets () によって返されたサービスが com.sun.star.sheet.Spreadsheet サービスであって、そして同様に、インタフェース com.sun.star.sheet.XSpreadsheets だけではなく、 XIndexAccess もサポートすると言う。 そのために、我々の xSpreadsheets 変数から XIndexAccess インタフェースのために検索要求を行うことによって、シートはネームでだけではなく、インデックスによってアクセスされることができたはずである:

XIndexAccess xSheetIndexAccess = (XIndexAccess)UnoRuntime.queryInterface(
           XIndexAccess.class, xSpreadsheets);
Object sheet = XSheetIndexAccess.getByIndex(0);

列挙アクセス

  インタフェース com.sun.star.container.XEnumerationAccess は、オブジェクトのセットを横切って渡ることを可能にする一覧を作る。 それは1つのメソッドを持っている:

com.sun.star.container.XEnumeration createEnumeration ()

  オブジェクトが createEnumeration () から得た列挙は、インタフェース com.sun.star.container.XEnumeration をサポートする。 このインタフェースで、それがもっと多くのエレメントを持つ限りは、我々は列挙からエレメントを引っ張り続けることができる。 XEnumeration はメソッドを供給する:

boolean hasMoreElements()
any nextElement()

それはループを作るつもりであり、以下のように:

 while (xCells.hasMoreElements()) {
    Object cell = xCells.nextElement();
    // do something with cell
}

  例えば、スプレッドシートで、あなたはどのセルが式を含むか、見つけだす機会を持つ。 セルの結果として生じているセットは、 XEnumerationAccess として供給される。

  式を含むセルについて検索要求するインタフェースは、 com.sun.star.sheet.XCellRangesQuery であり、それは(とりわけ)メソッドを定義する

XSheetCellRanges queryContentCells(short cellFlags)

  それは、定数グループ com.sun.star.sheet.CellFlags の中で定義されたように、コンテンツを持ってセルに対して、検索要求をする。 これらのセル・フラグの1つが FORMULA である。 queryContentCells () から、我々はこれらのメソッドを持っている com.sun.star.sheet.XSheetCellRanges インタフェースでオブジェクトを受け取る:

XEnumerationAccess  getCells()
String getRangeAddressesAsString()
sequence< com.sun.star.table.CellRangeAddress > getRangeAddresses()

 メソッド getCells () は、我々の FirstLoadComponent の例から、XEnumerationAccess を利用して、全ての数式セルと、 スプレッドシート・ドキュメントに含まれた式を、リストするために使われうる。( FirstSteps/FirstLoadComponent.java )

XCellRangesQuery xCellQuery = (XCellRangesQuery)UnoRuntime.queryInterface(
    XCellRangesQuery.class, sheet);
XSheetCellRanges xFormulaCells = xCellQuery.queryContentCells(
    (short)com.sun.star.sheet.CellFlags.FORMULA);
XEnumerationAccess xFormulas = xFormulaCells.getCells();
XEnumeration xFormulaEnum = xFormulas.createEnumeration();
while (xFormulaEnum.hasMoreElements()) {
    Object formulaCell = xFormulaEnum.nextElement();
    // do something with formulaCell
    xCell = (XCell)UnoRuntime.queryInterface(XCell.class, formulaCell);
    XCellAddressable xCellAddress = (XCellAddressable)UnoRuntime.queryInterface(
        XCellAddressable.class, xCell);
    System.out.print("Formula cell in column " + xCellAddress.getCellAddress().Column
        + ", row " + xCellAddress.getCellAddress().Row
        + " contains " + xCell.getFormula());
}

2.6 どうやって持っているタイプを知るか?

 普通にある問題は、メソッドからそれを受け取った後に、オブジェクトがどのような能力を本当に持っているかを決定することである。

  Java IDE で、コード完成を観察することによって、あなたはオブジェクトのベース・インタフェースがメソッドから戻ったことを発見することができる。 あなたは loadComponentFromURL () が com.sun.star.lang.XComponent を返すことに、気付くであろう。

 NetBeans IDE で Alt + F1 を押すことによって、あなたは、使っているインタフェースとサービスについて仕様を読むことができる。

  しかしながら、メソッドは、1つのインタフェース・タイプを返すように、指定されることができるだけである。 あなたが、非常にしばしば、メソッドから得るイン タフェースは、メソッドによって返されるものよりも多くのインタフェースをサポートする。 さらに、インタフェースは、オブジェクトが含んでいるプ ロパティについて、何も示さない。

 そのために、このマニュアルを、事柄がどのように働いていくかのアイデアを、このマニュアルから得るために使うべきである。 それなら、コード完成と API リファレンスを使って、コードを書き始めなさい。

 加えるに、あなたは InstanceInspector 、 OpenOffice.org SDK 例の一部である Java ツールを試みることができる。 それは、 Office に登録されることができる Java コンポーネントであって、そして、あなたが現在働いているオブジェクトのインタフェースとプロパティを示す。

 OpenOffice.org Basic では、次の基本的なプロパティを使って、オブジェクトを点検することができる。

sub main
  oDocument = thiscomponent
  msgBox(oDocument.dbg_methods)
  msgBox(oDocument.dbg_properties)
  msgBox(oDocument.dbg_supportedInterfaces)
end sub

2.7 例: Hello テキスト、 Hello テーブル、 Hello 形状

 このセクションのゴールは、 OpenOffice.org API でそれらのメカニズムの短い概要を与えることである、そして、それは、全てのドキュメント・タイプに共通である。 OpenOffice.org の3つのメインアプリケーション・エリアは、テキスト、テーブルと描画形である。 ポイントは:テキスト、 テーブルと描画形は、全ての3つのドキュメント・タイプで起こることができる、あなたが、Writer、Calc あるいは Draw/Impress ファイルを扱っているなら、しかし、それらは、どこでも同じ方法で扱われる。 あなたが共通の機構をマスターすれば、全てのドキュ メント・タイプで、テキスト、テーブルと描画形を挿入して、そして使うことが可能であるであろ う。

2.7.1 テキスト、テーブルと描画形のための共通メカニズム

  我々は共通基盤を強調することを望む、そのために、我々は、既存のテキスト、テーブルと図画を操ることを許す、共通のインタフェースとプロパティで始め る。 その後、我々は、異なったテクニックが、それぞれのドキュメント・タイプで、テキスト、テーブルと描画形を作ることを明らかにするであろう。

 既存のテキスト、テーブルと描画形で働くためのキー・インタフェースとプロパティは、次のことである:

 テキストのためにインタフェース com.sun.star.text.XText は、実際のテキストと、他のテキスト・コンテンツを変えるメソッドを含んでいる。
(従来のテキスト・パラグラフのほかに、テキスト・コンテンツのための例は、テキスト・テーブル、テキスト・フィールド、グ ラフィック・オブジェクトと類似のものである、しかし、このようなコンテンツが、全てのコンテキストで、利用可能ではない) 我々が、ここでテキストについて話をする時、どんなテキストでも - テキスト・ドキュメント、テキスト・フレーム、ページ・ヘッダーとフッター、テーブル・セルでの、あるいは描画形の中のテキスト - を意味する。 XText は、 OpenOffice.org のどこででも、テキストのためのキーである。

UML 図 com.sun.star.XTextRange インタフェースを示す
図 1.8: XTextRange

  インタフェース com.sun.star.text.XText は、一つのストリングとして、テキストをセットするか、あるいはゲットする能力と、そして、始まりとテキストの終わりをロケートする能力を持っている。 さらに、 XText は、テキストにおける任意のポジションにおいて、ストリングを挿入して、そして、テキストを選択してフォーマットするために、テキスト・カーソルを作ること ができる。 最終的に、XText はメソッド insertTextContent と removeTextContent とを通してテキスト・コンテンツを取り扱う、ただし、全てのテキストが従来のテキスト以外のテキスト・コンテンツを受け入れるわけではないけれども 。 実際に、 XText は、 com.sun.star.text.XTextRange から継承される com.sun.star.text.XSimpleText から継承することによって、この全てをカバーする。

  テキスト・フォーマット化が、サービス com.sun.star.style.ParagraphPropertiescom.sun.star.style.CharacterProperties とで記述されるプロパティを通して起きる。

  次の例のメソッド manipulateText () は、テキストを追加して、そして、 CharacterProperties を使って、いくらかの単語を選択してフォーマットするために、テキスト・カーソルを使い、その後、より多くのテキストを挿入する。 メソッド manipulateText () は、ただ XText の最も基本的なメソッドを含んでいるだけである、それが全てのテキスト・オブジェクトで作動できるように。 特に、それは insertTextContent () を避ける、なぜなら、全てのテキストオブジェクトに挿入できる従来のテキスト以外には、テキスト・コンテンツが無いので。(FirstSteps/HelloTextTableShape.java)

protected void manipulateText(XText xText) throws com.sun.star.uno.Exception {
        // simply set whole text as one string
        xText.setString("He lay flat on the brown, pine-needled floor of the forest, "
            + "his chin on his folded arms, and high overhead the wind blew in the tops "
            + "of the pine trees.");
           
        // create text cursor for selecting and formatting
        XTextCursor xTextCursor = xText.createTextCursor();
        XPropertySet xCursorProps = (XPropertySet)UnoRuntime.queryInterface(
            XPropertySet.class, xTextCursor);
        // use cursor to select "He lay" and apply bold italic
        xTextCursor.gotoStart(false);
        xTextCursor.goRight((short)6, true);        
        // from CharacterProperties
        xCursorProps.setPropertyValue("CharPosture",    
            com.sun.star.awt.FontSlant.ITALIC);
        xCursorProps.setPropertyValue("CharWeight",
            new Float(com.sun.star.awt.FontWeight.BOLD));
       
        // add more text at the end of the text using insertString
        xTextCursor.gotoEnd(false);
        xText.insertString(xTextCursor, " The mountainside sloped gently where he lay; "
            + "but below it was steep and he could see the dark of the oiled road "
            + "winding through the pass. There was a stream alongside the road "
            + "and far down the pass he saw a mill beside the stream and the falling water "
            + "of the dam, white in the summer sunlight.", false);
        // after insertString the cursor is behind the inserted text, insert more text
        xText.insertString(xTextCursor, "\n  \"Is that the mill?\" he asked.", false);  
}

  tables と table cells で、インタフェース com.sun.star.table.XCellRange は,
あなたに、一つのセルとセルの部分的な範囲を検索することを許す。 あなたがセルを持った途端に、インタフェース com.sun.star.table.XCell を通して、その公式あるいは数値で、仕事をすることができる。

UML 図 com.sun.star.table.XCellRange と com.sun.star.table.XCell インタフェースを shwoing する
図 1.9:セルとセルの範囲

  テーブル・フォーマット化、は部分的はにテキスト・テーブルとスプレッドシート・テーブとて異なっている。 テキスト・テーブルは、 com.sun.star.text.TextTable で指定されたプロパティを使うのに対して、スプレッドシート・テーブルは、 com.sun.star.table.CellProperties を使う。 さらに、セル範囲と含まれたテキストを選択してフォーマットするのを許す、テー ブル・カーソルがある。 けれども com.sun.star.text.TextTableCursor は、 com.sun.star.sheet.SheetCellCursor とは非常に違って作動するので、我々は、テキストとスプレッドシート・ドキュメントについての章でそれらを論じるであろう。(FirstSteps/HelloTextTableShape.java)

protected void manipulateTable(XCellRange xCellRange) throws com.sun.star.uno.Exception {
       
        String backColorPropertyName = "";
        XPropertySet xTableProps = null;
       
        // enter column titles and a cell value
        // Enter "Quotation" in A1, "Year" in B1. We use setString because we want to change the whole
        // cell text at once
        XCell xCell = xCellRange.getCellByPosition(0,0);
        XText xCellText = (XText)UnoRuntime.queryInterface(XText.class, xCell);
        xCellText.setString("Quotation");
        xCell = xCellRange.getCellByPosition(1,0);
        xCellText = (XText)UnoRuntime.queryInterface(XText.class, xCell);
        xCellText.setString("Year");
       
        // cell value
        xCell = xCellRange.getCellByPosition(1,1);
        xCell.setValue(1940);
       
        // select the table headers and get the cell properties
        XCellRange xSelectedCells = xCellRange.getCellRangeByName("A1:B1");
        XPropertySet xCellProps = (XPropertySet)UnoRuntime.queryInterface(
            XPropertySet.class, xSelectedCells);
       
        // format the color of the table headers and table borders
        // we need to distinguish text and spreadsheet tables:
        // - the property name for cell colors is different in text and sheet cells
        // - the common property for table borders is com.sun.star.table.TableBorder, but
        //   we must apply the property TableBorder to the whole text table,
        //   whereas we only want borders for spreadsheet cells with content.
        // XServiceInfo allows to distinguish text tables from spreadsheets
        XServiceInfo xServiceInfo = (XServiceInfo)UnoRuntime.queryInterface(
            XServiceInfo.class, xCellRange);
       
        // determine the correct property name for background color and the XPropertySet interface
        // for the cells that should get colored border lines
        if (xServiceInfo.supportsService("com.sun.star.sheet.Spreadsheet")) {
            backColorPropertyName = "CellBackColor";

            // select cells
           xSelectedCells = xCellRange.getCellRangeByName("A1:B2");
           // table properties only for selected cells
            xTableProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, xSelectedCells);
        }
        else if (xServiceInfo.supportsService("com.sun.star.text.TextTable")) {
            backColorPropertyName = "BackColor";
          // table properties for whole table
            xTableProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, xCellRange);
        }      
        // set cell background color
        xCellProps.setPropertyValue(backColorPropertyName, new Integer(0x99CCFF));
       
        // set table borders
        // create description for blue line, width 10
        // colors are given in ARGB, comprised of four bytes for alpha-red-green-blue as in 0xAARRGGBB
 
        BorderLine theLine = new BorderLine();
        theLine.Color = 0x000099;
        theLine.OuterLineWidth = 10;
        // apply line description to all border lines and make them valid
        TableBorder bord = new TableBorder();
        bord.VerticalLine = bord.HorizontalLine =
            bord.LeftLine = bord.RightLine =
            bord.TopLine = bord.BottomLine =
                theLine;
        bord.IsVerticalLineValid = bord.IsHorizontalLineValid =
            bord.IsLeftLineValid = bord.IsRightLineValid =
            bord.IsTopLineValid = bord.IsBottomLineValid =
                true;
       
        xTableProps.setPropertyValue("TableBorder", bord);
}

  図形を描くや否や、インタフェース com.sun.star.drawing.XShape は、形の位置と大きさを決定するために使われる。

UML 図 com.sun.star.drawing.XShape インタフェースを示す
図 1.10: XShape

 他の全てが、プロパティ・ベースのフォーマット化の問題である、そして、使うべき多くのプロパティが 有る。 OpenOffice.org は、 GUI の(グラフィカル・ユーザ・インタフェース)で描画ツールの基礎である11の異なった形を持って来る。 形の6つが、それらの特徴を反映する個別のプ ロパティを持っている。 6つの形は:

 5つの形が、個別のプロパティを持っていない、どちらかと言えば、それらはサービス com.sun.star.drawing.PolyPolygonBezierDescriptor で定義されたプロパティを共有する:


 これら全ての11の形状は、次のサービスからプロパティを使う:

 次の例は、これらのプロパティがどのように機能するかを示していると思いなさい:( FirstSteps/HelloTextTableShape.java)

protected void manipulateShape(XShape xShape) throws com.sun.star.uno.Exception {
        // for usage of setSize and setPosition in interface XShape see method useDraw() below
        XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape);
        // colors are given in ARGB, comprised of four bytes for alpha-red-green-blue as in 0xAARRGGBB
        xShapeProps.setPropertyValue("FillColor", new Integer(0x99CCFF));
        xShapeProps.setPropertyValue("LineColor", new Integer(0x000099));
        // angles are given in hundredth degrees, rotate by 30 degrees
        xShapeProps.setPropertyValue("RotateAngle", new Integer(3000));
}

2.7.2 テキスト、テーブルとドローイングを作成する

  上記の3つの manipulateXXX メソッドは、パラメータとして、テキスト、テーブルと形オブジェクトをとって、そして、それらを変えた。 次のメソッドは、種々のドキュメント・タイプで、 どのようにこのようなオブジェクトを作るべきか示す。 全てのドキュメントは、ドキュメントに挿入されるオブジェクトを作るために、それら自身のサー ビス・ファクトリーを持っていることに注意を払いなさい。 それは別として、あなたがどのように進むかは、ドキュメントタイプに大きく依存する。 このセクショ ンは、ただ異なったプロシージャを証明するだけである、説明はテキスト、スプレッドシートと描画ドキュメントについての章で見いだされることがで きる。

 最初に、小さい便利な道具メソッドが、新しいドキュメントを作るために使われる。(FirstSteps/HelloTextTableShape.java)

protected XComponent newDocComponent(String docType) throws java.lang.Exception {
        String loadUrl = "private:factory/" + docType;
        xRemoteServiceManager = this.getRemoteServiceManager(unoUrl);
        Object desktop = xRemoteServiceManager.createInstanceWithContext(
            "com.sun.star.frame.Desktop", xRemoteContext);
        XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(
            XComponentLoader.class, desktop);
        PropertyValue[] loadProps = new PropertyValue[0];
        return xComponentLoader.loadComponentFromURL(loadUrl, "_blank", 0, loadProps);   
}

Write でのテキスト、テーブルとドローイング

  メソッド useWriter は、Writer ドキュメントを生成して、そのテキストを操作する、それから、、テキスト・テーブルと形状のインスタンスを作るために、ドキュメントの内部サービス・マネー ジャーを使って、それらを挿入しテーブルと形状を操作する。 ( FirstSteps/HelloTextTableShape.java)  さらに詳細な情報のためには、7 テキスト・ドキュメント を参照しなさい。

protected void useWriter() throws java.lang.Exception {
        try {
            // create new writer document and get text, then manipulate text
            XComponent xWriterComponent = newDocComponent("swriter");
            XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(
                XTextDocument.class, xWriterComponent);
            XText xText = xTextDocument.getText();
           
            manipulateText(xText);
           
            // get internal service factory of the document
            XMultiServiceFactory xWriterFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
                XMultiServiceFactory.class, xWriterComponent);
           
            // insert TextTable and get cell text, then manipulate text in cell
            Object table = xWriterFactory.createInstance("com.sun.star.text.TextTable");
            XTextContent xTextContentTable = (XTextContent)UnoRuntime.queryInterface(
                XTextContent.class, table);
           
            xText.insertTextContent(xText.getEnd(), xTextContentTable, false);
            XCellRange xCellRange = (XCellRange)UnoRuntime.queryInterface(
                XCellRange.class, table);
            XCell xCell = xCellRange.getCellByPosition(0, 1);
            XText xCellText = (XText)UnoRuntime.queryInterface(XText.class, xCell);
           
            manipulateText(xCellText);
            manipulateTable(xCellRange);
           
            // insert RectangleShape and get shape text, then manipulate text

            Object writerShape = xWriterFactory.createInstance(
                "com.sun.star.drawing.RectangleShape");
            XShape xWriterShape = (XShape)UnoRuntime.queryInterface(
                XShape.class, writerShape);
            xWriterShape.setSize(new Size(10000, 10000));
            XTextContent xTextContentShape = (XTextContent)UnoRuntime.queryInterface(
                XTextContent.class, writerShape);
           
            xText.insertTextContent(xText.getEnd(), xTextContentShape, false);
           
            XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, writerShape);
            // wrap text inside shape
            xShapeProps.setPropertyValue("TextContourFrame", new Boolean(true));
           
           
            XText xShapeText = (XText)UnoRuntime.queryInterface(XText.class, writerShape);
           
            manipulateText(xShapeText);
            manipulateShape(xWriterShape);
        }
        catch( com.sun.star.lang.DisposedException e ) { //works from Patch 1
            xRemoteContext = null;
            throw e;
        }


}

Calc でのテキスト、 テーブルとドローイング

 メソッド useCalc は Calc ドキュメントを作って、形状を作るために、そのドキュメント・ファクトリーを使って、そしてセル・テキスト、テーブルと形状を操る。 チャプター 8 スプレッドシート・ドキュメント は、スプレッドシートの全ての局面を扱う。 ( FirstSteps/HelloTextTableShape.java)

protected void useCalc() throws java.lang.Exception {
        try {
            // create new calc document and manipulate cell text
            XComponent xCalcComponent = newDocComponent("scalc");
            XSpreadsheetDocument  xSpreadsheetDocument  =
                (XSpreadsheetDocument)UnoRuntime.queryInterface(
                    XSpreadsheetDocument .class, xCalcComponent);
            Object sheets = xSpreadsheetDocument.getSheets();
            XIndexAccess xIndexedSheets = (XIndexAccess)UnoRuntime.queryInterface(
                XIndexAccess.class, sheets);
            Object sheet =  xIndexedSheets.getByIndex(0);
           
            //get cell A2 in first sheet
            XCellRange xSpreadsheetCells = (XCellRange)UnoRuntime.queryInterface(
                XCellRange.class, sheet);
            XCell xCell = xSpreadsheetCells.getCellByPosition(0,1);
            XPropertySet xCellProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, xCell);
            xCellProps.setPropertyValue("IsTextWrapped", new Boolean(true));
           
            XText xCellText = (XText)UnoRuntime.queryInterface(XText.class, xCell);
           
            manipulateText(xCellText);
            manipulateTable(xSpreadsheetCells);
            // get internal service factory of the document
            XMultiServiceFactory xCalcFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
                XMultiServiceFactory.class, xCalcComponent);
            // get Drawpage
            XDrawPageSupplier xDrawPageSupplier =
               (XDrawPageSupplier)UnoRuntime.queryInterface(XDrawPageSupplier.class, sheet);
            XDrawPage xDrawPage = xDrawPageSupplier.getDrawPage();
           
            // create and insert RectangleShape and get shape text, then manipulate text
            Object calcShape = xCalcFactory.createInstance(
                "com.sun.star.drawing.RectangleShape");
            XShape xCalcShape = (XShape)UnoRuntime.queryInterface(
                XShape.class, calcShape);
            xCalcShape.setSize(new Size(10000, 10000));
            xCalcShape.setPosition(new Point(7000, 3000));
          
            xDrawPage.add(xCalcShape);
           
            XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, calcShape);
            // wrap text inside shape
            xShapeProps.setPropertyValue("TextContourFrame", new Boolean(true));
           
           
            XText xShapeText = (XText)UnoRuntime.queryInterface(XText.class, calcShape);
           
            manipulateText(xShapeText);
            manipulateShape(xCalcShape);
           
        }
        catch( com.sun.star.lang.DisposedException e ) { //works from Patch 1
            xRemoteContext = null;
            throw e;
        }
       
}

Draw でのドローイングとテキスト

  メソッド useDraw は、Draw ドキュメントを作って、そして形状のインスタンスを作って加えるために、そのドキュメント・ファクトリーを使う、それから、それは形状を操る。 チャプター 9 描画 は、描画とプレゼンテーションに、もっと多くの光を投げかける。 ( FirstSteps/HelloTextTableShape.java)

protected void useDraw() throws java.lang.Exception {
        try {
            //create new draw document and insert ractangle shape
            XComponent xDrawComponent = newDocComponent("sdraw");
            XDrawPagesSupplier xDrawPagesSupplier =
                (XDrawPagesSupplier)UnoRuntime.queryInterface(
                    XDrawPagesSupplier.class, xDrawComponent);
                       
            Object drawPages = xDrawPagesSupplier.getDrawPages();
            XIndexAccess xIndexedDrawPages = (XIndexAccess)UnoRuntime.queryInterface(
                XIndexAccess.class, drawPages);
            Object drawPage = xIndexedDrawPages.getByIndex(0);
            XDrawPage xDrawPage = (XDrawPage)UnoRuntime.queryInterface(XDrawPage.class, drawPage);
           
            // get internal service factory of the document
            XMultiServiceFactory xDrawFactory =
                (XMultiServiceFactory)UnoRuntime.queryInterface(
                    XMultiServiceFactory.class, xDrawComponent);
           
            Object drawShape = xDrawFactory.createInstance(
                "com.sun.star.drawing.RectangleShape");
            XShape xDrawShape = (XShape)UnoRuntime.queryInterface(XShape.class, drawShape);
            xDrawShape.setSize(new Size(10000, 20000));
            xDrawShape.setPosition(new Point(5000, 5000));
            xDrawPage.add(xDrawShape);
           
            XText xShapeText = (XText)UnoRuntime.queryInterface(XText.class, drawShape);
            XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, drawShape);
           
            // wrap text inside shape
            xShapeProps.setPropertyValue("TextContourFrame", new Boolean(true));            
           
            manipulateText(xShapeText);
            manipulateShape(xDrawShape);
        }
        catch( com.sun.star.lang.DisposedException e ) { //works from Patch 1
            xRemoteContext = null;
            throw e;
        }
       
           
}

前のドキュメント | コンテンツ・テーブル | 次のドキュメント]