XULRunnerにはJavaXPCOMが標準搭載されており、これは、JavaのコードとXPCOMの相互利用を可能にするものです。この記事で示すとおり、JavaでのXPCOMオブジェクトの操作は、C++の場合とそれほど大きな差はありません。
必要な環境
- Java 1.4.2 以降
- XULRunner 1.8.0.1 以降
組み込み
Mozilla を Java アプリケーションに埋め込むためには、<tt>xulrunner/sdk/lib</tt>フォルダーにある<tt>MozillaInterfaces.jar</tt>というライブラリをclasspathに追加する必要があります。このライブラリは Mozilla をブートストラップし、XPCOM メソッドを呼び出すために必要なインターフェースを提供します。
組み込みを開始するために、Mozilla共有クラスの提供するメソッドを使用します。はじめに、Java アプリケーションは適切な XULRunner installationを見つける必要があります。
Mozilla mozilla = Mozilla.getInstance(); GREVersionRange[] range = new GREVersionRange[1]; range[0] = new GREVersionRange("1.8.0", true, "1.9", false); // work with trunk nightly version 1.9a1 ^^ try { File grePath = Mozilla.getGREPathWithProperties(range, null); LocationProvider locProvider = new LocationProvider(grePath); mozilla.initEmbedding(grePath, grePath, locProvider); } catch (FileNotFoundException e) { // この例外は greGREPathWithProperties が GRE を見つけられなかったときに送出されます } catch (XPCOMException e) { // この例外は initEmbedding が失敗したときに送出されます }
LocationProvider
はJavaアプリケーションによって提供されるクラスです。これはインターフェースIAppFileLocProviderを実装しているもので、
and tells XPCOM where to find certain files and directories.
initEmbedding
メソッドは embedding process を開始するもので、Java アプリケーションと XPCOM や Mozilla の連携を可能にするものです。ひとたび Java アプリケーションが Mozilla を使う作業を終えたとき、それは embedding process を terminate する必要があります。
try {
mozilla.termEmbedding();
} catch (XPCOMException e) {
// この例外は termEmbedding が失敗したときに送出されます
}
XPCOMオブジェクトを利用する
Mozilla が組み込まれると、Java アプリケーションは XPCOM オブジェクトを利用することができるようになります。Mozilla
クラスはこれの手助けをするメソッドを提供しており、たとえば、getServiceManager
、getComponentManager
、newLocalFile
があります。JavaXPCOM により、 Java アプリケーションがXPCOM オブジェクトを取得し、メソッドを呼び出すのに加え、Java クラスオブジェクトを XPCOM メソッドに渡すことも可能になります。
例えば:
Mozilla mozilla = Mozilla.getInstance();
WindowCreator creator = new WindowCreator(); // nsIWindowCreator を実装
nsIServiceManager serviceManager = mozilla.getServiceManager();
nsIWindowWatcher windowWatcher = (nsIWindowWatcher) serviceManager
.getServiceManagerByContractID(NS_WINDOWWATCHER_CONTRACTID,
nsIWindowWatcher.NS_IWINDOWWATCHER_IID);
windowWatcher.setWindowCreator(creator);
この例では、nsIWindowCreator
インターフェースを実装した Java のクラスであるWindowCreator
が存在し、それを Mozilla に登録しようとしています。そのために、まず service manager を取得するのですが、それは Mozilla のwindow watcherのリファレンスにある方法によります。
別の例: (rayh.co.ukにあるもの)
// linux 上ではこのコードが実行されるより前に gtk が初期化されている必要があることに注意 Mozilla moz = Mozilla.getInstance(); // 次に XUL アプリケーションを実行するために、XPCOMのservice managerのインスタンスを取得する必要がある nsIServiceManager serviceManager = moz.getServiceManager(); // 次に @mozilla.org/toolkit/app-startup;1 サービスを取得する必要がある nsIAppStartup appStartup = (nsIAppStartup)serviceManager.getServiceByContractID("@mozilla.org/toolkit/app-startup;1", nsIAppStartup.NS_IAPPSTARTUP_IID); // 上のものへの nsIWindowWatcher インターフェースを取得する nsIWindowCreator windowCreator = (nsIWindowCreator)appStartup.queryInterface(nsIWindowCreator.NS_IWINDOWCREATOR_IID); // window watcher サービスを取得する nsIWindowWatcher windowWatcher = (nsIWindowWatcher)serviceManager.getServiceByContractID("@mozilla.org/embedcomp/window-watcher;1", nsIWindowWatcher.NS_IWINDOWWATCHER_IID); // window creator をsetする (from step 6) windowWatcher.setWindowCreator(windowCreator); // Create the root XUL window を作成: nsIDOMWindow win = windowWatcher.openWindow(null, "chrome://your-app/content/window.xul", "mywindow", "chrome,resizable,centerscreen", null); // これを active window にする windowWatcher.setActiveWindow(win); // application を xpcom/xul に手渡し、ここでブロックする: appStartup.run();
これは動作する LocationProvider の例です :
public class LocationProvider implements IAppFileLocProvider {
private final File libXULPath; int counter = 0; public LocationProvider(File grePath) { this.libXULPath = grePath; }
public File getFile(String aProp, boolean[] aPersistent) { File file = null; if (aProp.equals("GreD") || aProp.equals("GreComsD")) { file = libXULPath; if (aProp.equals("GreComsD")) { file = new File(file, "components"); } } else if (aProp.equals("MozBinD") || aProp.equals("CurProcD") || aProp.equals("ComsD") || aProp.equals("ProfD")) { file = libXULPath; if (aProp.equals("ComsD")) { file = new File(file, "components"); } } return file; }
public File[] getFiles(String aProp) { File[] files = null; if (aProp.equals("APluginsDL")) { files = new File[1]; files[0] = new File(libXULPath, "plugins"); } return files; }
XPCOM の UI を別のスレッドから呼び出す
appStartup.run() はメインのイベントループを始動し、アプリケーションが終了するまでそこに留まります。これ以降の場所で XPCOM とcommunicateするためには、nsIProxyObjectManager を使用する必要があります。
上の例に引き続き新しいウインドウを作成するためには、このようにします :
// まず、event queue service を取得します。これは、XPCOM の全てのイベントキューを処理するものです。 nsIEventQueueService eventQueueServive = (nsIEventQueueService)serviceManager.getServiceByContractID("@mozilla.org/event-queue-service;1",nsIEventQueueService.NS_IEVENTQUEUESERVICE_IID); // 次に、ウインドウを開くために、UI スレッドを取得します。 // nsIEventQueueService が所有するstatic変数がUIイベント用の特別なキューを所有しています。 nsIEventQueue eventQueue = eventQueueServive.getSpecialEventQueue(nsIEventQueueService.UI_THREAD_EVENT_QUEUE); // 次に、proxy object manager 用の proxy を作成します。 nsIProxyObjectManager proxy = (nsIProxyObjectManager)componentManager.createInstanceByContractID("@mozilla.org/xpcomproxy;1",null,nsIProxyObjectManager.NS_IPROXYOBJECTMANAGER_IID); // そして、proxy object manager を使って、さきほど作成した nsIWindowWatcher のインスタンスへの proxy を作成します。 nsIWindowWatcher windowProxy = (nsIWindowWatcher)proxy.getProxyForObject(eventQueue,windowWatcher.NS_IWINDOWWATCHER_IID,windowWatcher,nsIProxyObjectManager.INVOKE_SYNC); // そうすれば、proxy を使ってメソッドを普通に呼び出すことができます。 windowProxy.openWindow(null, chromeUri, name, "centerscreen", null);
さらに詳しい情報は、XulPlanet's documentation of nsIProxyObjectManagerを参照してください。
これは、Injecting Events onto XPCOM’s UI Threadからとられたものです。