IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  XML  >

実用的なXML: Eclipseを使用してXMのユーザー・インターフェースを構築する

使用体験とユーザーからのフィードバックに基づく改善

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 中級

Benoit Marchal (bmarchal@pineapplesoft.com), Consultant, Pineapplesoft

2002年 10月 01日

XSLTに基づく低コストなオープン・ソースのコンテンツ・マネージメント・ソリューションであるXMに親しんでいる人は、その多くの長所を認めつつも、まともなユーザー・インターフェースが欠けていることを知っています。この記事で、著者のBenoit Marchalは、Eclipseプラットフォームのオープンな汎用フレームワークを使用してXM用のユーザー・インターフェースを構築しています。

前回の記事でXIに関する検討をしめくくった後で、このコラムの最初に扱った単純なXMLコンテンツ・マネージメントおよび公開用のソリューション、XMを再び取り上げることにしました。この1年、私はさまざまなプロジェクトでXMを使用し、また、読者からも意見をいただきました。その間、改善すべき部分に関する提案を集めました。今回の記事では、XM用のユーザー・インターフェースの作成方法を紹介します。適用可能なプログラミング環境を構築するために、オープン・ソース・プロジェクトであるEclipseを使用することにしました。XMLに興味がなくてもEclipse開発を行おうとする人々にとって、この記事が役に立つものと信じています。

作業対象となる領域

XMについて私が学んだこと、およびXMをどのように進化させるべきかについて言えることは、「ユーザー・インターフェースは、もっとも急を要する課題」ということです。先月の記事で述べたように、私は、何らかのグラフィカル・ユーザー・インターフェースを用意しないままXMをリリースしたのは誤りであったことに気が付きました。このような形でリリースすることは、構成ファイルが不要であることなどの、使いやすい機能とは相いれないものでした。

ディレクトリーの移動も改善する必要があります。一度に1つのファイルを扱うという単純な解決策は、リンクを管理する能力を制約し、(XMがファイル・リストを自動的にコンパイルする際の) コンテンツ生成を必要以上に複雑なものにしてしまいます。この点についても、改善のためのアイデアがあります。

そのほかにも、以下の機能を改善すると便利であると思われます。

  • JSPまたはASPページの公開 (JavaまたはVisual Basicスクリプトを含むページを生成することは簡単ですが、ファイル拡張子に関する解決策がありません)
  • 分割ファイルまたはグループ・ファイル (この制限については、最近、写真ギャラリーを公開しようとしたときに発見しました)
  • 自動的なFTPファイル転送

また、ユーザー向け文書がないことに対する不満も寄せられました。これらすべての問題に対して、1回の記事で対処することはできませんが、一度にまとめて取り上げたいと思います。今後数回の記事では、ユーザー・インターフェースの問題について考えることにします。

IDEにするか否か

私は最初、先月XI用に紹介したユーザー・インターフェース (ドラッグ・アンド・ドロップ機能を備えた単純なウィンドウ) を手直しして使用することを考えました。しかし、ファイル編集機能も提供したほうが便利であることに気が付きました。機能リストの内容が増えたため、統合開発環境 (IDE) を採用することにしました。

IDEを一から構築するのは大変ですが、幸いなことに、netBeansおよびEclipseという2つのJavaオープン・ソース・プロジェクトを利用することができます。どちらのプロジェクトも、柔軟なJava IDEの開発を目指していて、また、業界からの広範な支援を受けています。両者の最も目立つ相違点は、netBeansがSwingベースであるのに対し、EclipseがStandard Widget Toolkit (SWT) を基礎としていることです。以前のコラムを読んだ読者は、私がSwingの愛好者でないことはご存じでしょう。

私は、SWTについてある程度の経験を積みましたが、Swingの方が出来がよいと考えています。実際には、SwingもSWTも、豊富で移植可能なJavaウィジェットを提供することを目指しています。Swingは、ボタン、ドロップダウン・リストおよびツリー・ビューを含め、すべてのウィジェットをJavaでドローすることによって移植性を実現します。この、一見するとすばらしいアイデアは、制約を受けない移植性を保証するものですが、実際には期待どおりにはいきません。Swingウィジェットは、それに相当するネイティブ・ウィジェットとは振る舞いが異なり、また、私の経験では、そのためにユーザーが混乱させられています。

逆に、SWTは可能なかぎりネイティブ・ウィジェットを基にしています。ボタンおよびドロップダウン・リストはプラットフォーム・ネイティブです。SWTでは、Javaでウィジェットをドローすることができるのは、それに対応するネイティブなウィジェットが存在しない場合にかぎられます。例えば、SWTはWindowsプラットフォームではネイティブのツリー・ビューを使用しますが、Unixプラットフォームにはネイティブのツリー・ビューがありません。したがって、Unixでは、SWTは独自のツリー・ビューをドローします。その結果、両方の世界の長所である良好な移植性 (SWTは、Macintosh以外の、一般に使用されているほとんどのプラットフォームにすでに移植されていて、Macへの移植も現在開発中です)、良好なパフォーマンス、およびユーザー満足を享受することができます。私は、SWTがコアJavaプラットフォームに統合されることを切に願っています。

Eclipseプラグイン

要するに、Eclipseは、プログラマー向けとして人気の高いEmacsエディターの現代版です。Emacsが人気を得ているのは、世の中にあるほとんどのプログラム言語向けにカスタマイズされているためです。とはいえ、Emacsのユーザー・インターフェースは失礼ながら過去の遺物であり、どうしてもGUIにはなじみません。EclipseはEmacs同様の柔軟性を目指しつつ、より現代的なユーザー・インターフェースを提供しようとしています。図1はEclipseのメイン・ウィンドウを示しています。


図1. Eclipseのメイン・ウィンドウ
図1

また、Eclipseは単なるエディターではありません。この高度にモジュラー化された拡張可能なIDEには、開発者にとって必要なすべてのツールが組み込まれています。プロジェクト・ウィザード、統合されたコンパイラー、デバッガーなどが備わっています。標準的な出荷形態では、Javaに合わせて調整されていますが、C/C++ やCOBOLなどのその他の言語についてはプラグインを介してサポートすることによって移植性を保証しています。(現に、Eclipse IDEは、Javaエディター、コンパイラー、プロジェクト・ウィザード、およびクラス・ブラウザーなどのプラグインを使用することにより、ユーザーが目にするほとんどのものを作成しています。XM IDEを作り上げることも、XM用に類似のプラグインを書くことにより、簡単に行えます。)




上に戻る


Eclipseについて

Eclipseは、私が使用したことのあるエディターAPIの中で最も意欲的なものです。これまでに、カスタマイズされたプログラマー向けエディターを使用したことのある読者は、Eclipse APIの適用範囲の広さに驚くことでしょう。残念ながら、こうしたすばらしいツールにふさわしい文書が、必ずしも常に使用できるわけではありません。いくつかの優れた記事でEclipse向けのプログラミング方法が述べられていますが、そのほとんどは、プラットフォームを熟知している読者を想定して書かれています。特に、潜在的な落とし穴に関する警告が欠けています。この記事 (および今後の記事) では、この問題への対処に役立つ情報を提供します。

私は、APIをプラットフォームAPIとエディターAPIに大別しました。プラットフォームAPIはプラグインを取り扱います。プラグインは、プラットフォームがユーザーからの要求に応じてロードするJavaライブラリー (例えば、ユーザーがJavaクラス・ファイルを開くと、ランタイムがJavaエディターをロードします)、または他のプラグインへのサービスを提供するためにロードするJavaライブラリーです (例えば、ウィジェット・ツールキットSWTはプラグインです)。

プラグインはエディターの大半 (つまり、画面に表示されるほとんどのもの) を実装しています。したがって、

  • プラットフォームのどの要素もプラグインを介してカスタマイズすることができます。
  • エディターAPIはプラグインのセットです。

こうした状況も、オペレーティング・システムに似ています。オペレーティング・システムの場合、カーネルがほとんどの基本サービスを提供し、その他のほとんどのサービスはライブラリーを介して実装されます。

プラットフォームAPI

それでは、プラットフォームAPIに取りかかりましょう。Eclipseでは、プラグインは Javaライブラリーと、それを記述するマニフェスト からなります。マニフェストは、plugin.xml という名前のXMLファイルです。

プラットフォームは、始動時に、インストールされているすべてのプラグインのマニフェストをロードし、レジストリーをコンパイルします。プラグイン自体のロードは、(ユーザーがファイルを編集するときなど) 必要になるまで行いません。インストールされていても使用されていないプラグインは、パフォーマンスに対して最小限の影響しか与えません。例えば、コア・ユーザー・インターフェースのプラグインは、始動時にメイン・ウィンドウをドローするためにロードされます。プラグインは、ユーザーがJavaクラスをロードするときにのみ、Javaエディター・プラグインをロードします。

プラグイン内に、抽象クラスPlugin を拡張(extend)しているクラスがある場合、ランタイムは、プラグインがロードされるときとアンロードされるときに、そのstartup() メソッドとshutdown() メソッドを呼び出します。この時点で、プラットフォームはプラグインを初期化したり、リソースを解放したりすることができるようになります。ほとんどのプラグインでは、このクラスは必要ではありません。

2番目に重要な概念は拡張点 です。拡張点は、プラグインをロードさせるイベントであると考えることができます。プラグインは、関連する拡張点をそのマニフェストに登録します。イベントが実行されると (これも、実際のイベントではありませんが、イベントと考えると便利です)、プラットフォームはそれを処理するためにプラグインをロードします。例えば、Javaエディターのプラグインは、Java文書がロードされたときに拡張ポイントを登録します。

エディターAPI

プラットフォームを除き、Eclipseのほとんどの部分はプラグインとして配布されます。これらのプラグインはEclipseの操作に不可欠なため、システム・プラグイン と呼ぶことができます。これらのシステム・プラグインには、通常のプラグイン (ユーザーが作成したプラグインなど) から呼び出すことのできる独自のAPIが備わっています。例えば、次のセクションでは、情報を表示するためのプラグインを作成します。画面上でそれ自体をドローしたり他のウィンドウと対話したりするために、私のプラグインはシステム・プラグインを呼び出します。(これらの概念は、次のセクションで明らかになります。)

識別子

Eclipse APIの要素のうち私を大いに悩ませたものとして、識別子 があります。プラグインおよび拡張点には識別子があります。識別子は、プラグインおよび拡張点を管理するためにプラットフォームによって使用されます。識別子は固有のストリングです。ここまでは問題ありません。しかし、Eclipseはその識別子をJavaパッケージ名と同じルールに従って構成するようになっているため、混乱のもととなります。

例えば、このエディターはorg.eclipse.ui.views という拡張点を定義しています。次のセクションでは、この拡張点が使用されています。EclipseはJavaで書かれているため、拡張点はorg.eclipse.ui.IViewPart と呼ばれるインターフェースを使用して実装されています。正直に言うと、私は、一方が識別子でもう一方がインターフェースであるということにしばらく気付きませんでした。さらに混乱することに、文書の中にはorg.eclipse.ui.views で始まるパッケージがいくつも記載されてます。

こうした混乱を避けるために、識別子はマニフェスト (plugin.xml) 内で使用されるということを覚えておいてください。その名前が暗示するように、ランタイムはエレメントを識別するために識別子を使用します。しかし、Javaクラス (または識別子と類似した名前のインターフェース) は、識別する意味のあるほとんどの概念を実装しています。




上に戻る


プラグインの作成

私は、経験から学ぶタイプの人間なので、Eclipseプラットフォーム (および前の2つのセクションで説明した要素) をよく理解するために、プラグインを作成しました。ご覧になってお分かりのように、このプラグインは多くのことを行うわけではありませんが、Eclipse文書を解読するためには非常に役立ちました、このコードの作業バージョンをダウンロードするには、参考文献 を参照してください。

ビュー・プラグイン

私が作成したビュー・プラグイン (図2で示してあります) は、Eclipse用語を使用してビューを定義しています。ビューとは、なんらかの情報を表示するウィンドウのことです。このケースでは、プラグインが、選択されたファイルの名前をナビゲーター・ウィンドウで表示しています。これは、練習以外の目的ではまったく役に立たないとしても、私が数日間を費やして文書を検索した結果が要約されている点で、ある程度注目に値します。


図2. Eclipseのプラグイン
図2

Javaインターフェースにおけるビュー

Eclipseにおける他のほとんどすべてのものと同じように、ビューはシステム・プラグイン内で宣言されます。私のプラグインは、org.eclipse.ui.views 拡張点を介してビューを登録します。上に説明したように、org.eclipse.ui.views はJavaクラスではなく識別子です。対応するJavaインターフェースはorg.eclipse.ui.IViewPart です。

リスト1は、TestView クラスにおけるビュー実装を示しています。このクラスはViewPart を拡張します。ViewPart クラスはIViewPart インターフェースのデフォルトの実装を表しています。IViewPart の実装を作ってもよかったのですが、ViewPart を拡張するほうがコーディングを少なくすることができます。

IViewPart の中で定義されているcreatePartControl() メソッドは、このビューのためのユーザー・インターフェースを作成しています。エディターは、画面にウィンドウが表示されるときにそれを呼び出します。TestView では、ユーザー・インターフェースは単なるラベルです。

TestViewISelectionListener インターフェースも実装しています。このインターフェースもEclipseエディターによって定義されたもので、選択イベントをlistenします。(図2 の画面左側にある) ナビゲーター・ビューは、ユーザーが別の文書を選択したときにこのイベントを実行させます。このイベントをインターセプトすると、プラグインはファイル名を検索してそのラベルを変更します。


リスト1. ViewTest.java
                
package org.ananas.test.plugin;
import org.eclipse.ui.*;
import org.eclipse.swt.*;
import org.eclipse.ui.part.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.ui.texteditor.*;
import org.eclipse.core.resources.*;
/**
 * @author Benoit Marchal
 */
public class TestView
extends ViewPart
   implements ISelectionListener
{
   private Label label;
   public TestView()
   {
   	  super();
   }
   public void createPartControl(Composite parent)
   {
      label = new Label(parent,SWT.WRAP);
      label.setText("None.");
      getViewSite().getPage().addSelectionListener(this);
      selectionChanged(null,getSite().getPage().getSelection());
   }
   public void setFocus()
   {
   	  label.setFocus();   // not very useful...
   }
   public void selectionChanged(IWorkbenchPart part,
                                ISelection selection)
   {
      if(selection != null
         && selection instanceof IStructuredSelection)
      {
         IStructuredSelection structured =
            (IStructuredSelection)selection;
         Object o = structured.getFirstElement();
         if(o != null
            && o instanceof IFile)
         {
         	IFile file = (IFile)o;
            label.setText("From navigator:" + file.getName());
            return;
         }
      }
      label.setText("None.");
   }
}

このクラス関するコメントをいくつか付け加えておきます。SWTウィジェットLabel は、編集不能なテキスト・フィールドを実装します。このエディターのAPIは、ISelectionListenerIWorkbenchPartISelection、およびその他の「I」インターフェースも定義しています。これらのインターフェースと拡張点の違いに注意してください。拡張点は、プラグインをいつロードするのかを制御します。これに対し、ISelectionListener およびその他のインターフェースは、プラグインがロードされた後で 作動します。

マニフェスト

リスト2は、マニフェスト、つまりplugin.xml を示しています。1行ずつ検討していきましょう。plugin タグはプラグイン自体を宣言し、以下の属性を指定しています。

  • id はプラグイン識別子です。これもクラス名ではなく、Javaパッケージ名と同様に固有性を確保するために構成されています。
  • name は、人間にとって判読しやすい名前です。
  • version はプラグインのバージョンです。
  • provider はプラグインの開発者です。
  • class はプラグインのクラスです。このクラスとビューを混同しないでください。プラットフォームは、初期化とクリーンアップを実行するためにこのクラスを呼び出します。ほとんどのプラグインではプラグイン・クラスは不要であり、リスト2でもプラグイン・クラスは使用されていません。

リスト2. plugin.xml
                
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="org.ananas.eclipse.test"
        name="Test Plugin"
        version="1.0.0"
        provider-name="ananas.org"
        class="">
   <runtime>
      <library name="test-plugin.jar"/>
   </runtime>
   <requires>
      <import plugin="org.eclipse.core.boot"/>
      <import plugin="org.eclipse.core.runtime"/>
      <import plugin="org.eclipse.core.resources"/>
      <import plugin="org.eclipse.swt"/>
      <import plugin="org.eclipse.ui"/>
   </requires>
   <extension point="org.eclipse.ui.views">
      <category name="ananas.org"
                id="org.ananas.eclipse.view">
      </category>
      <view
            name="Name"
            icon="icons/default.gif"
            category="org.ananas.eclipse.view"
            class="org.ananas.test.plugin.TestView"
            id="org.ananas.eclipse.view.test">
      </view>
   </extension>
</plugin>

次はruntime タグです。これは1つまたは複数のJARファイルを指しています。runtime の後には、import ステートメントが指定されたrequires タグが続いています。これらのステートメントは、このプラグインの前にメモリーに記憶する必要のあるプラグインです。リスト2では、SWTや基本的なユーザー・インターフェースなどの、さまざまなシステム・プラグインが参照されています。

最後に、このマニフェストでは、関係する拡張点を宣言しています。リスト2は、ビューを登録して、ananas.org という新規ビュー・カテゴリーを宣言し、その後で私たちのビューを登録します。




上に戻る


テストおよび将来の作業

このプラグインをテストするために、Eclipse 2.01 (他のバージョンのEclipseではこのプラグインをテストしていません) をダウンロードし、次にテスト・プラグインをダウンロードするか、あるいはこの記事で示されているコードをコンパイルしてください。すべてのものをEclipseの下のplugins ディレクトリーに配置し、その後で以下のステップに従ってください。

  • Eclipseを起動します。
  • 「Window」メニューから「Show View」を選択します。
  • Other」を選択します。
  • ananas.org カテゴリー (マニフェストで定義したカテゴリー) を展開し、「Name」(マニフェストで定義した私たちのプラグイン) を選択します。このプラットフォームは拡張点を実行し、拡張点が私たちのプラグインをロードして新規「Name」ウィンドウを開きます。

すでにお気付きのように、これは始まりにすぎません。私は、Eclipseが、ユーザー・インターフェースを構築するための有望なフレームワークを提供するものと信じています。文書が不備なために苦労し、習得に思わぬ時間を要してしまいました。今後の記事では、より便利なXM用のプラグインを作成する予定です。

このシリーズがXML開発者だけでなく、Eclipseプラットフォームに興味を持つすべての人にとって役に立つことを願っています。



参考文献



著者について

Benoit Marchal氏は、ベルギーのナミュールを拠点にしたコンサルタントおよび著述家です。彼の著作には、 XML by Example(Que社、邦訳: インプレス社「実例で学ぶXML」。間もなく第2版が出版される予定です)、 Applied XML Solutions および XML and the Enterprise があります。また、Gamelanのコラムや、developerWorks XML zoneのコラムWorking XML の著者でもあります。最新プロジェクトの詳細については、www.marchal.com をご覧ください。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


    日本IBMについて プライバシー お問い合わせ