高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technote 1162

Introduction to MRJ Scripting with AppleScript for Java


CONTENTS

MRJ スクリプト機構の動作

Applet Runner と Java アプリケーションのスクリプティング

Applet Runner のアプリケーションプロパティ

AppleScript オブジェクトとしての Java オブジェクト

AppleScript コマンドとしての Java メソッド

Java アプレットのスクリプティング

スクリプト可能な Java アプリケーションの作成

Java アプリケーションの 'aete' リソースの生成

まとめ

MRJ 2.1 のリリースで、Java のアプレットやアプリケーションの AppleScript サポートが実現しました。このテクニカルノートは、Java アプリケーションで AppleScript をフルに活用するために必要な技術情報を取り上げます。

アップルの Applet Runner と MRJShellLib (MRJLib の中にあります) は、Macintosh の OSA (Open Scripting Architecture) をサポートします。つまり、Applet Runner と、そこで実行されるアプレット、JBindery で作成されたアプリケーションは、AppleScript ほかあらゆる OSA 対応スクリプト言語でスクリプト制御できるのです。Java ベースのアプリケーションのスクリプト制御を可能にするために唯一必要な仕事は、スクリプトリソースの 'aete' と 'scsz' の包含です。Java アプレットや Java アプリケーション側にはこのほか特別なスクリプトサポートは必要ありません。MRJ ユーザが、Java アプレットや Java アプリケーションをインターネットからダウンロードして、Macintosh 上でスクリプト可能なコンポーネントとして利用できるようになりました。

この文書は MRJ スクリプティングの概要を述べます。AppleScript と OSA アーキテクチャの知識が前提となります。今後 MRJ スクリプティングに関する新情報を公開する場合は MRJ Developer Page にポストします。


MRJ スクリプト機構の動作

MRJ スクリプティングのしくみは、公開された (public な) Java のクラス、プロパティ、メソッド名を、OSA スクリプト対応の用語説明 (terminology) としてエクスポートすることで、スクリプト作成者から参照可能にするというものです。スクリプトを実行すると、MRJ スクリプト機構は、AppleEvent のデータ型とイベントを、Java のデータ型とメソッド呼び出しに変換します。スクリプト作成者は Java オブジェクトのプロパティフィールドにデータを設定したり参照したり、オブジェクトの Java メソッドを呼び出したりできるようになります。

OSA スクリプトの用語説明は Applet Runner または Java アプリケーションが動的に生成します。アップルの Applet Runner をターゲットにするスクリプトをコンパイルすると、スクリプト編集プログラム (あるいはほかのあらゆる OSA 開発環境) はその用語説明を取得します。用語説明には、動作中のアプレットに対応する AWT コンポーネント (Component) オブジェクトが含まれます。たとえば、サンプルアプレットの「Lightweight Gauge」の正式なアプレット名は ExampleApplet なので、Lightweight Gauge の動作中に Applet Runner の辞書を開くと、それには次のような用語集 (suites) が含まれるはずです。

ExampleApplet:
init: public void
                  
ExampleApplet.init()
                  
init reference
   Class Example Applet:
   Properties:
           <Inheritance> Applet [r/o]  
						Gauge:
						  Class Gauge:
    Properties:
                  
<Inheritance> Component [r/o]
         total Amount integer [r/o]  -- public int Gauge.getTotalAmount( )
         preferred Size point  [r/o] -- public java.awt.Dimension
Gauge.getPreferredSize()
         minimum Size point  [r/o] -- public java.awt.Dimension
Gauge.getMinimumSize()
         current Amount  integer -- public int Gauge.getCurrentAmount()
&
                                                      -- public void
Gauge.setCurrentAmount(int)
                  

ExampleApplet が動作中なので、Applet Runner は Gauge クラスを公開しています。Gauge クラスは Component クラスからプロパティを継承しています。読み出しのみ可能なプロパティの totalAmount と、書き込み可能なプロパティの currentAmount です。

Java オブジェクトのメソッドとプロパティはこのような方法でスクリプト作成者に公開されます。Java のオブジェクト、メソッド、プロパティ名が、AppleScript の予約語の名前空間と衝突したり、AppleScript では不正な名前である場合 (たとえば user.name のようにピリオドを含む項目) があります。このような場合、Java 名は AppleScript のリテラル引用符の縦棒 (|) に囲まれて公開されます。「columns」という名前の Java アプレットのパラメータがあるとすると、これは |columns| とすることで、AppleScript の用語説明の「columns」とは衝突しません。AppleScript のふつうの用語説明は大文字小文字の区別がありませんが、縦棒の中の識別子の大文字小文字は区別されます。

AWT を使うアプレットでは、AWT コンポーネント階層全体がスクリプティングにエクスポートされます。ユーザインタフェースから駆動できるアプレットの関数はすべて、スクリプトからも駆動できます。アプレットをスクリプト制御するのに内部メソッドを知る必要はありません。ボタン、メニュー、表示オブジェクトを直接スクリプトできるからです。このように、アプリケーション内の意味オブジェクトを操作することが多い通常の Macintosh アプリケーションのスクリプト作成とは異なることがおわかりだと思います。MRJ スクリプティングの長所は、アプレット側の特別な補助なしで、アプレットの動作のすべてがスクリプト可能だということです。短所は、アプレット内に保存された内部情報や意味情報には、AWT コンポーネントをスクリプト制御してユーザインタフェース経由でアクセスできる部分しか操作できないことです。このため、アプレットのデベロッパは、Java のアプレットやアプリケーションの最上位コンポーネントのプロパティに意味オブジェクトを含める必要があります。そうすれば、通常好ましいと考えられる Macintosh スタイルで Java のアプレットやアプリケーションをスクリプトできるようになります。

重要:
複雑な Java クラスは実用的な目的ではスクリプトできません。

Back to top

Applet Runner と Java アプリケーションのスクリプティング

The Applet Runner is a scriptable application that supports the Required and Standard suites of events, as well as a small number of custom events. Java applications should also have a dictionary that supports these events. The supported events are:

  • print - AWT コンポーネントを印刷します。
  • exists - Java オブジェクトが存在するかどうか調べます。
  • check... belongs to - Java オブジェクトが一定のクラスに属するかどうか調べます。
  • apply to - 名前を指定してメソッドを呼び出します。この方法は、用語説明が存在せず、通常の方法では呼び出すことができない場合に便利です。
  • save object - Java オブジェクトを.jar ファイルに直列化します。
  • load object - .jar ファイルからオブジェクトをロードします。
  • start tool - ここでツール (tool) とは内部に参照可能な JavaBeans を含む任意の jar ファイルです。これは Java クラスを含むツールであるため、通常の方法でスクリプトできます。この方法を使うと、デベロッパは、AEList をツリー状に表示するなど、便利な AppleScript ツールが構築できます。
  • type .. keystrokes - Java ウィンドウにキーストロークを送る低レベルなイベント。
  • click - AWT コンポーネントのマウスクリックをシミュレートする低レベルイベント。この方法は、メニュー項目を名前でクリックするなどの UI のスクリプト制御に使用することもできます。

これらのイベントのパラメータや結果の一覧は Applet Runner の辞書を参照してください。

Back to top

Applet Runner のアプリケーションプロパティ

ほかの大半のスクリプト可能なアプリケーションと同様、Applet Runner や Java アプリケーションも、アプリケーションの動作を制御するグローバルプロパティをサポートします。Java エンジンのシステムプロパティはすべて、Applet Runner や Java アプリケーションのアプリケーションプロパティとして公開されます。システムプロパティの多くは AppleScript の識別子としては不正なので、縦棒で囲みます。大文字小文字も区別されます。

tell
application "Apple Applet Runner"
    get its |user.name|
end tell
			
MRJ スクリプト機構を制御する 2 つのシステムプロパティが新しく追加されました。
                  
tell
application "Apple Applet Runner"
    set its |macos.scripting.debug| to true
    set its |macos.menu.contextual.disable| to true
end tell
                  

通常、メソッドは Java オブジェクトを非表示形式で返します。しかし、|macos.scripting.debug| をに設定すると、Java オブジェクトは、Java メソッドの toString() でテキスト文字列に変換され返されます。スクリプト実行の観点からいえば役に立たないかもしれませんが、デバッグ用途にはたいへん便利なはずです。

MRJ スクリプト機構には、Java の TextComponent オブジェクトに自動的にコンテキストメニューのサポートを追加します。|macos.menu.contextual.disable| をに設定するか、ヘルプメニューでオフにすることで、この機能を無効にできます。

Back to top

AppleScript オブジェクトとしての Java オブジェクト

Applet Runner でアプレットを開くと、アプレットは Applet Runner アプリケーションの暗黙的な最上位要素として公開されます (「暗黙的な最上位要素」とは、Finder におけるデスクトップファイルのようなものです)。これを試すには、Applet Runner に付属の「Lightweight Gauge」アプレットを開いて、次のスクリプトを実行してください。

tell
application "Apple Applet Runner"
     restart ExampleApplet 1
end tell
                  

このアプレットを構成する Java オブジェクトは ExampleApplet オブジェクトに含まれています。

重要:

現行バージョンの Applet Runner では、Java の AWT コンポーネントの包含関係は、Container オブジェクトの components プロパティで公開されます。このオブジェクトはそのコンテナに含まれる Java コンポーネントの一覧を返します。コンテナとその内容には正式な「要素」の関係はないものの、Applet Runner は、要素参照要求を受け付け、正しい Java オブジェクト参照に変換します。要素を扱う通常の AppleScript コマンド (count、each、whose など) では任意のコンテナオブジェクトに含まれる項目を操作することはできませんが、コンテナの components プロパティに対してはこのような操作が一部可能だということです。

(Applet Runner では、ウィンドウはアプレットつまり Applet のコンテナであって、Applet オブジェクトそのものではありません。Applet Runner の Window クラスは Applet Runner が表示するウィンドウの操作にだけ利用できます。このほか、アプレットを直接参照することも可能です。)

試行錯誤を繰り返してコンポーネントの名前を見つけるのは容易なことではありません。|macos.scripting.debug| プロパティを真にすると、MRJ スクリプト機構を使って、オブジェクト名 (object specifier) を調べることができます。バルーンヘルプをオンにして、任意のオブジェクトをポイントすると、その名前がバルーンに表示されます。オブジェクト名は Java コンソールにも表示されます。

AppleScript の規則にしたがえば、コンテナの内容は 1 から始まるインデックスで参照します。Java の仕様は異なり、インデックスは 0 から始まります。コンテナの最初の要素はあくまで 1 から始まります。0 ではありません。

Java オブジェクトのプロパティはほとんど AppleScript オブジェクトのプロパティとして利用できます。AppleScript の get および set コマンドで値の参照と変更が可能です。たとえば、Lightweight Gauge アプレットを例にとると、2 番めのバーの値は次のようにして取得できます。

get current Amount of Gauge 2 of PrettyPanel 1 of Double Buffer Panel 1 of Example Applet 1

辞書を見て、プロパティに [r/o] (読み出しのみ可能) の印が付いていなければ、AppleScript の set コマンドで同じようにして値を設定することができます。

Back to top

AppleScript コマンドとしての Java メソッド

Java オブジェクトのメソッドはほとんど AppleScript コマンドとして呼び出し可能です。スクリプト編集プログラムに表示された辞書には、1 つの Java クラスが 1 つの用語集に表示されます。それぞれ、Java クラスに対応する AppleScript クラスと、そのメソッド群に対応するコマンド一覧が表示されます。

重要:

AppleScript は、コマンドとオブジェクトの対応について厳密なチェックを行わないことを覚えておいてください。オブジェクトがサポートしないメソッドに対応するコマンドを送るスクリプトでもコンパイルはされますが、実行時にエラーになります。

コマンドの送信対象のオブジェクトは該当のメソッドをサポートするものでなければなりません。対象のオブジェクトにコマンドを送るには、次の AppleScript 例にあるどの文法を使ってもかまいません。

restart Example
Applet 1
restart of Example Applet 1
tell Example Applet 1 to restart
tell Example Applet 1
    restart
end tell

AppleScript は名前パラメータはサポートしますが、順序パラメータはサポートしません。Java のリフレクション機能では、順序パラメータはサポートしますが、ふつう名前パラメータ情報はサポートしません。このため、パラメータは通常「パラメータ名を伴ったパラメータ」として渡されます。Java メソッドの呼び出しのカッコの中に指定する順序で値を並べたものです。パラメータは Java メソッドが期待する順序で渡さなければなりません。デベロッパが使いやすいように、パラメータ一覧は辞書内のコマンド項目のコメント行に表示されます。例えば、replaceRange コマンドは次のように呼び出します。

replace Range Text Area 1 of MRJ Test 1 parameters {"testing",0,20}

(パラメータリストは何の解釈もなしに直接 Java メソッドに渡されますので、インデックス付きのパラメータは 0 からになります。1 からではありません。)

BeanInfo インタフェースを実装した Java クラスはスクリプト作成に役立つ追加情報を提供します。この場合、MRJ スクリプト機構は Java Parameter Descripter オブジェクトを探し、辞書に名前パラメータを追加します。こうした名前パラメータは AppleScript から直接扱うことができます。JavaBeans が今後多く登場すれば、これはあたりまえのことになるでしょうが、現在のところはこうした情報を提供する Java コードはほとんどありません。

スカラー型 (int、long、Boolean など整数型) のパラメータを取り、スカラー型の結果を返すメソッドが多数あります。Java オブジェクトの String、Rectangle、Point、Dimension、Color なども、ここではスカラー型と考えます。スカラー型の値は Java と AppleScript 間で自動的に形式変換が行われます。

Back to top

Java アプレットのスクリプティング

AppleScript はアプレット用に、Applet オブジェクトのプロパティとして applet タグを用意しています (Java の Applet クラスのフィールドではありません)。Applet タグの取得や設定を通して、実行時パラメータを変更できます。Applet タグに新しい内容を設定すると、アプレットを再起動できます。次に BarChart アプレットを縦向きに変更する例を示します。

set applet tag of Applet 1 to {c1:"10", c1_color:"blue", c1_label:"Q1",
c1_style:"striped", c2:"20", ツ c2_color:"green",
c2_label:"Q2", c2_style:"solid", c3:"5", c3_color:"magenta",
c3_label:"Q3", ツ c3_style:"striped", c4:"30",
c4_color:"yellow", c4_label:"Q4", c4_style:"solid",
|columns|:"4", ツ orientation:"vertical",
scale:"5", |title|:"Performance"}

Back to top

スクリプト可能な Java アプリケーションの作成

Java アプリケーションをスクリプトで制御するためには、アプリケーションファイルのリソースフォークに 'aete' と 'scsz' リソースが必要になります。MRJ 2.1 SDK の「MRJ Scripting」フォルダには 'aete' リソースのサンプルの「MRJ Scripting aete」があります。Applet Runner にも同様の 'aete' リソースがすでに含まれています。この 'aete' リソースには組み込み用語集と AWT 用語説明の暫定版が含まれています。他のクラスの用語説明は Java リフレクション機能で動的に生成されます。

自動生成された用語説明はあまり使いやすくはありません。コメントには単に Java オブジェクトの名前が載っているだけで、ほとんどすべてのプロパティやメソッドがスクリプト作成者に公開されているからです。自動生成された用語説明を出発点として、コメントを修正し、スクリプト作成には不要なプロパティやメソッドを削除するとよいでしょう。

'aete' は相当大きくなることがあります。スクリプト編集プログラム、HyperCard、あるいは使用中の OSA 開発環境のメモリパーティションを増やすとよいでしょう。Java アプリケーションや Applet Runner のメモリパーティションを増やす必要もあるかもしれません。

Back to top

Java アプリケーションの 'aete' リソースの生成

AppleScript など OSA スクリプト言語でスクリプト可能なアプリケーションは用語説明リソース (リソースフォークの 'aete' リソースの 0 に保存されます) を提供しなければなりません。用語説明リソースは、アプリケーションのソースコードで使われる 4 文字のイベントコードやクラスコードと、スクリプト作成者が用いる英語表現の用語説明とを対応付けるものです。デベロッパは通常、用語説明リソースは Rez ツールで .r ファイルからコンパイルするか、'aete' テンプレートを使ってリソースエディタ (Resorcerer や ResEdit など) で編集します。MRJ スクリプト機構では、スクリプティングで使用する 4 文字コードが自動生成され、デベロッパが変更する必要はありませんが、読みやすくするため用語説明を変更してもかまいません。

自動生成された用語説明は、静的な基本用語説明と、個々のスクリプト可能な Java アプリケーションごとに生成される動的用語説明との組み合わせになります。「MRJ Scripting aete」ファイルには基本用語説明と AWT コンポーネント用語説明が含まれています。MRJ スクリプト機構は、Java アプリケーションの開かれたウィンドウにある全コンポーネントについて、追加の用語説明を自動生成します。こうして、MRJ は MRJ アプリケーションをスクリプト可能にするために必要なすべての基本用語説明を生成するのです。Java アプリケーションに基本リソースを含めるには、JBindery または ResEdit を使用してください。

Java アプリケーションに基本 'aete' リソースを含めた後は、動的用語説明を生成してもらうため、アプリケーションを実行して、スクリプトで制御したい部分を実際に「触れて」ください。制御対象コンポーネントを含むウィンドウをすべて開いてください。すると、それらのコンポーネントに対応する AppleScript クラスが用語説明に取り込まれます。

ウィンドウを手動で全部開くことが実践的でない場合や、AWT コンポーネントではないクラスをスクリプト対象にしたい場合、スクリプトを使ってそれらのクラスの用語説明が必ず生成されるようにすることもできます。基本辞書には「Developer Suite」と呼ばれる用語集があります。これには、エンドユーザではなく、デベロッパを支援するコマンドやクラスが含まれています。この用語集にある add terminologies for class イベントを使うと、特定の Java クラスを動的用語説明に入れるよう指定できます。

公開したい全クラスに触れた後は (手動またはスクリプトで)、動的用語説明を取得してください。これには、スクリプト編集プログラムがアプリケーションから動的用語説明を取得するのと同じ 'gdte' イベントを使用します。通常このイベントはスクリプト作成者からは隠されており、用語説明はありません。Developer Suite にはイベント名、get terminologies を用意しましたので、スクリプトを書いてこれをアプリケーションに送ってください。

用語の説明には、get terminologies イベントにオプションの真偽値パラメータ、object parameters を追加しました。通常、Java オブジェクトをパラメータに持つイベントはすべて用語説明の生成から除外されます。このようなイベントも含めたければ、get terminologies イベントに「with object parameters」を追加して呼び出してください。

get terminologies イベントの結果は、静的および動的両方の用語説明を含む巨大なデータオブジェクトです。使いやすさを考えてこの動的用語説明を編集するのであれば、まずファイルに保存しなければなりません。この作業を行うためのシェアウェアのスクリプティング追加機能がたくさんあります。次の例は、GTQ Scripting Library (http://www.scriptweb.com/osaxen/gtq_scripting_library.html を参照) の add resource コマンドを使う例です。

tell
application "test.app"
    add terminology for class "com.acme.test.SpecialButton"
    add terminology for class "com.acme.test.SpecialClass"
    set aeteRes to get terminologies --set aeteRes to get
                   terminologies with object parameters
-- NOTE: There is currently an issue with using "get terminologies
-- with object parameters"
-- Use "get terminologies with <<class objt>>"
-- instead
                  
    add resource aeteRes to file "HD:TestRes" of
type "aete" id 0 ツ
	with replacing allowed
end tell
                  

重要:

上記 AppleScript 中の「<<」と「>>」はそれぞれ 1 文字の Option-\ と Option-Shift-\ と置換してください。置換しないとスクリプトは正常に動作しません。

「Add Resource」スクリプティング追加機能をインストールするには、スクリプト編集プログラムのパーティションサイズをおよそ 1500K に増やしてから、このスクリプトを入力し、実行してください。すると生成されるリソースは「HD:TestRes」というファイルにできますので、それを 'aete' エディタで編集してください。このリソースを .r ファイルに直してから編集するか、Resorcerer を使うか、'aete' テンプレートを使って ResEdit で編集してください。

スクリプト作成者のために用語説明の整理を行う際、関係のないイベントやプロパティはすべて削除してください。関係のないクラスも削除したほうがよいでしょう。しかし、動的用語説明がオンだと、削除したクラスの用語説明が再び動的に現われてしまいます。現在のところこの問題を回避するには、イベントとプロパティはすべて削除し、クラスだけを残しておきます。用語説明の動的生成では、'aete' にすでに存在するクラスの上書きは行いませんから、空のクラスがそのまま残るのです。

aete 内の 4 文字コードは決して変更しないでください。しかし、イベント、パラメータ、クラス、プロパティの名前は、表示名からではなく、プログラミング名から生成されている場合は変更したほうがいいでしょう。スクリプト作成者のために、各クラスがどんなもので、どのように使用するかコメントを付けておくべきです。

'aete' リソースの編集が最終形式まで済んだら、Developer Suite は削除したほうがよいでしょう。これはスクリプト作成者のためのものではないからです。

動的用語説明は 'scsz' リソースによって制御されます。'scsz' リソースを編集して、動的用語説明の生成を禁止することもできます。すると用語説明は 'aete' の変更後のまま固定されます。(こうすれば、不要な用語説明の自動生成にわずらわされることはありません。) しかしこれにも問題があります。Java アプリケーションが拡張可能な場合 (たとえば start tool イベントを使うなどして)、実行時に新しいクラスが導入されます。このようなクラスをスクリプト可能にする唯一の方法は 'scsz' リソースで動的用語説明を有効にすることです。

'aete' リソースを編集して、必ずサイズは小さくしてください。スクリプト作成者が辞書の項目の多さに圧倒されてしまいます。また、ユーザにスクリプト作成作業ではどこに注力すべきかを示唆すべきです。そうすれば、スクリプト作成者があなたのアプリケーションを大いに活用できるチャンスが増えます。アプリケーションとともにサンプルスクリプトを添付することもおすすめします。スクリプト作成者が用語説明の癖を理解することにもつながり、効果的なスクリプトの利用方法を示すことができます。

Back to top

まとめ

Java アプリケーションに AppleScript を統合すると自動化サポートが向上します。基本的なスクリプト機能を加えることは非常に簡単です。生成済みの 'aete' リソースと 'scsz' リソースを追加するだけで済みます。しかし、高度なスクリプト制御を実現するには、どのオブジェクトやメソッドを辞書に公開するかを慎重に指定しなければならず、こうしたリソースタイプを注意深く編集する必要があります。

 

参考文献

Back to top


サードパーティのサイトや製品についての言及は情報提供目的のためだけであり、アップルの支持や推薦を意味するものではありません。アップルはこうしたベンダーやその製品の選択や性能に関して一切の責任を負いません。

更新日: 1999 年 4 月 19 日