SWTメモ

最終更新日:2004/02/26
ogwa567@oki.com

目次

  1. 準備
  2. コーディング
  3. コンパイル
  4. 実行
  5. 画面イメージ
  6. Java Web StartによるSWTアプリケーションの実行
  7. 感想
  8. 参考リンク

準備

  1. SWTのダウンロード
    http://www.eclipse.org/swt/ の「SWT Downloads」から「Eclipse 2.1.2 download page」リンクをクリックし、遷移したページの「SWT Binary and Source」からプラットフォーム毎の媒体をダウンロード。SWTはネイティブライブラリを含んでいるため、実行環境毎にバイナリが必要になります。

    尚、Eclipseがインストールされているならば、Eclipseのインストールフォルダ下のplugins/org.eclipse.swt.win32_2.0.0/os/win32/x86, plugins/org.eclipse.swt.win32_2.0.0/ws/win32 にjarファイルとネイティブライブラリがあります(Windows版Eclipse2.1.2の場合)。
  2. APIドキュメント
    Eclipseのインストールフォルダ下のplugins/org.eclipse.platform.doc.isv_2.1.0/doc.zipを展開する。

コーディング

ウィジェットの使い方、レイアウトの設定等、Swingアプリケーションとよく似ているため、Swingを知っている人はそれほど違和感なくプログラミングできるはずです。
以下ではSWTアプリケーションと作成のポイントを簡単に説明します。

  1. ウィンドウの生成
    SwingではJFrame等を生成し、それに対してコンポーネントを追加するスタイルでした。SWTでもウィンドウを表すShellクラスを生成し、それに対してコンポーネントを追加します。

    Display display = new Display();
    Shell shell = new Shell(display);
    shell.pack(); // Swingのpack()と同様
    shell.open(); // SwingのsetVisible(true)と同様
    
    // 窓が閉じるまでメインスレッドを終了しない
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    
    display.dispose();

    Shellは別スレッドで実行されますが、メインスレッドが終了すると子スレッドも終了してしまうため、メッセージループで終了させないようにする必要があります。また、最後にDisplay#dispose()でリソース解放メソッドを明示的に呼び出していることもSwingと異なっています。
  2. ウィジェットの継承
    Swingでは既存のウィジェットを継承したクラスを作成することができましたが、SWTでは基本的にはウィジェットの継承はNGです。ウィジェットクラスのAPIドキュメントを見ると、こんな記述が見つかります。

    IMPORTANT: This class is not intended to be subclassed・・・(Shellクラス)
    IMPORTANT: This class is intended to be subclassed only within the SWT 
    implementation・・・(Buttonクラス)

    これに気が付かずにうっかり継承すると、ウィジェットが表示されないといった問題が起こります。継承してもコンパイルエラーとはならないため、注意が必要です。
  3. ウィジェットの生成
    SWTのウィジェットはorg.eclipse.swt.widgetsパッケージに含まれています。以下はSWTのボタンを生成するコードです。

    Button button = new Button(shell, SWT.PUSH);

    Swingと異なる点は、ウィジェット生成時にウィジェットを配置する親を指定することです。上の例ではshellというウィンドウを表すクラスのインスタンスを第一引数に指定しています。このようにすることは他のウィジェットでも同様です。
  4. ウィジェットの修飾
    ウィジェットを修飾するには、SWTクラスの定数の和を取ります。例えば、複数行表示可能、枠付き、垂直方向スクロール有りのテキストボックスを作るには、以下のようにします。

    Text text = new Text(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);

    この定数を把握していればSWTアプリケーションはSwingよりも作りやすいと思います。ただ、把握するまではやや大変です。
    尚、クラス固有のメソッドでウィジェットを修飾するパターンもあります。例えばテーブルで罫線を表示させるには(SWTではデフォルトで表示無し)、以下のメソッドを呼び出します。

    Table#setLinesVisible(boolean);

  5. イベント処理
    イベント関連クラスはorg.eclipse.swt.eventsパッケージに収められています。使い方はSwingとほとんど同じです。Swingと同様、リスナだけでなく便利なアダプタクラスが用意されているものもあります。
  6. レイアウト
    4つのレイアウトマネージャがあり、org.eclipse.swt.layoutパッケージに収められています。FormLayoutではコンポーネントに対する相対位置指定やコンテナ全体に対する位置指定ができるため、Swingより柔軟なレイアウトができそうです。ただ、手でコーディングするのはやや大変なので、GUIから操作できるとよいでしょう(恐らくそういったツールもあると思いますが・・)

コンパイル

準備で取得したSWTの媒体の中のswt.jarをクラスパスに指定し、コンパイルする。

% javac -classpath swt.jar -d classes src/*.java

尚、swt.jarはプラットフォーム毎に異なります。筆者はWindows版SWTのswt.jarでビルドしたアプリケーションをLinux環境で動作させることができました(実行時はLinux版SWTのswt.jarを使用)。ネイティブライブラリと結びつく部分だけが異なっているのであれば、コンパイルはどのプラットフォーム向けのjarを利用しても問題ないということかもしれません。

実行

コンパイルで生成されたクラスファイル及びSWTの媒体に含まれるjarファイルををクラスパスに指定し、JVMがネイティブライブラリをロードできるように、java.library.pathシステムプロパティでネイティブライブラリの位置を指定します。
以下はWindowsプラットフォームで実行する場合のコマンド例です。

% java -cp classes;lib/windows/jar/swt.jar 
       -Djava.library.path=lib/windows/dll ターゲットクラス

Linux(gtk)版ではjarファイルが2つあるため、

% java -cp classes:lib/linux-gtk/jar/swt.jar:lib/linux-gtk/jar/swt-pi.jar 
       -Djava.library.path=lib/linux-gtk/so ターゲットクラス

のようにします。

画面イメージ

以下は表とボタンを貼り付けたシンプルなGUIアプリケーションのWindowsとLinux環境でのスナップショットです。


SWTアプリケーション(Windows)


SWTアプリケーション(Linux-gtk)

以下のスナップショットは同じような画面をSwingで作成したものです。


Swingアプリケーション

SWT版のソース
Swing版のソース

Java Web StartによるSWTアプリケーションの実行

Java Web Start

Java Web Startを利用することによって、ブラウザからのリンククリックで、SWTアプリケーションをクライアントサイドで実行させることができます。Java Web StartはWeb ブラウザに関連付けて使用するヘルパーアプリケーションで、ユーザが特別な起動ファイル (JNLP ファイル) を指すリンクをクリックすると、ブラウザが Java Web Start を起動します。Java Web Startの主な利点は以下になります(Java Web Start開発者ガイドから抜粋)。

また、ブラウザからのリンククリックによる起動以外に、「Java Web Start アプリケーションマネージャ」(JWS付属)からアプリケーションを起動することも可能です。ブラウザはこのJava Web Start アプリケーションマネージャをキックする役目でしかありません。

尚、ネイティブライブラリ(WindowsならばDLL, Linuxならばso)についてもjarコマンドでアーカイブしたものをWebサーバ上へ配置する必要があります(Java Web Startによって配布可能な媒体は、Jar, イメージ, JNLPファイルです)。複数のライブラリを一つのJarにアーカイブすることが可能です。

基本的な仕組み

JNLPファイルはアプリケーションの基本的な要素や説明を記述したXMLファイルで、ダウンロードされるJarファイルや実行クラス名等を記述します。
ブラウザからこのファイルへアクセスすると、WebサーバからMIME タイプ"application/x-java-jnlp-file"としてHTTPレスポンスが返されます。ブラウザではそのMIMEタイプを見てJava Web Startを実行します。

そのため、まずWebサーバの要件として、JNLPファイルへのアクセスに対してapplication/x-java-jnlp-file MIME タイプを設定するようWebサーバを構成する必要があります。Apache等のWebサーバではMIMEタイプの設定が必要でしょう。尚、Tomcat4.1.27では拡張子.jnlpへのアクセスでMIMEタイプがapplication/x-java-jnlp-fileに設定されました。そのため、デフォルト設定でJava Web Startを使うことができます。

クライアントサイドでは上述のようにHTTPレスポンスのMIMEを見て、ブラウザがJava Web Startを実行します。そのため、クライアント側の要件としては、
  1. Java Web Startがインストールされている
  2. WebブラウザがMIMEタイプapplication/x-java-jnlp-fileに対してJava Web Startを実行するよう設定されている

この2点が必要になります。
プラットフォームがWindowsであり、JDK1.4.2以降をインストールしていれば、1, 2の設定は不要です(既に設定されています)。JDK1.4.1以前がインストールされているならばJava Web Startを個別にインストールする必要があります。Java Web Startのインストールによって、2が設定されます。

SWTアプリケーションの実行

まずはJNLPファイルを用意する必要があります。JNLPファイルにはアプリケーションの情報や、ダウンロードすべきリソースを記述します。このファイルをJava Web Startが解析し、Java Web Startによってリソースのダウンロードが行われ、アプリケーションが起動されます。

SWTアプリケーション配布のために、以下のJNLPを作成しました。

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://hostname:8080/swt" href="index.jnlp">
  <information>
    <title>SWT Table Example</title>
    <vendor>ESC</vendor>
    <homepage href="index.html"/>
    <description>SWT Table Example</description>
    <description kind="short">SWT Table Example</description>
  </information>
  <security>
    <all-permissions/>
  </security>  
  <resources>
    <j2se version="1.4+"/>
    <jar href="lib/application.jar"/>
  </resources>
  <resources os="Windows"> 
    <jar href="lib/windows/jar/swt.jar"/>
    <nativelib href="lib/windows/dll/swt-win.jar"/>
  </resources>
  <resources os="Linux"> 
    <jar href="lib/linux-gtk/jar/swt.jar"/>
    <jar href="lib/linux-gtk/jar/swt-pi.jar"/>
    <nativelib href="lib/linux-gtk/so/swt-linux.jar"/>
  </resources>
  <application-desc main-class="swt.Main"/>
</jnlp>

JNLPファイルの仕様の詳細は割愛します。ここではポイントだけ簡単に解説します。

このJNLPファイルをWebサーバへ必要なリソースと共に配置し、ブラウザやJava Web Start アプリケーションマネージャから要求を出せば、SWTアプリケーションが起動します。

Java Web Start 開発者向けパックによるバージョン管理

Java Web Startではクライアントでアプリケーションを起動する際、更新されたファイルがないかサーバ側へ問い合わせ、もしあればダウンロードを行う仕組みが備わっています。従って、サーバ側のJarファイルを更新するだけで、次回の起動時にクライアント側へファイルが自動的に配布されます(正確には、Java Web StartからWebサーバへGET要求を出し、それに対するWebサーバのレスポンスで、更新されているかどうかを判断する)。サーバ側からクライアントへファイルを配布する必要はありません。

ただ、複数のバージョンのJarをサーバへ配置し、設定を変更するだけでダウンロードさせるバージョンを変えたい場合もあると思います。このようなバージョン管理の仕組みは「Java Web Start 開発者向けパック」によって実現できます。

Java Web Start 開発者向けパックには、上記を行うためのサーブレットが含まれており、サーブレット・コンテナ上で動作するWebアプリケーションとして提供されています。そのため、サーバ側の要件として、新たにサーブレット・コンテナが必要になります。

Java Web Start 開発者向けパックのインストール

  1. http://java.sun.com/products/javawebstart/ja/download-jnlp_ja.htmlから「JNLP開発者向けパック v1.2FCS」をダウンロードします。
  2. サーブレット・コンテナ上へWebアプリケーションを作成し、WEB-INF/libへ上記パックに含まれる jnlp-servlet.jar をコピーします。
  3. 以下のようにweb.xmlへサーブレットマッピングを追加します(app/以下へアプリケーションを配置した場合の例)
      <servlet>
        <servlet-name>
          JnlpDownloadServlet
        </servlet-name>
        <servlet-class>
          com.sun.javaws.servlet.JnlpDownloadServlet
        </servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>JnlpDownloadServlet</servlet-name>
        <url-pattern>/app/*</url-pattern>
      </servlet-mapping>

バージョン管理

以下は異なるバージョン(1.0と1.1とする)のJarを2つ用意し、サーバ側の設定によってどちらを実行するかを切り替える例です。まずJNLPファイルでJarファイルにversion属性を追加します。

  <resources>
    <j2se version="1.4+"/>
    <jar href="application.jar" version="1.0"/>
  </resources>

次に、以下の version.xml ファイルを作成し、JNLPファイルと同じディレクトリに配置します。

<?xml version="1.0" encoding="utf-8"?>

<jnlp-versions>
  <resource>
    <pattern>
      <name>application.jar</name>
      <version-id>1.0</version-id>
    </pattern>
    <file>application-1_0.jar</file>
  </resource>
  <resource>
    <pattern>
      <name>application.jar</name>
      <version-id>1.1</version-id>
    </pattern>
    <file>application-1_1.jar</file>
  </resource>
</jnlp-versions>

version.xmlでは、JNLPで指定されたバージョンに対して、実際にどのファイルをダウンロードさせるかを記述します。この例ではJNLPファイルで version=1.0 としているため、application-1_0.jar がダウンロードされます。バージョン1.1のJar(application-1_1.jar)で動作させたい場合は、JNLPファイルでバージョンを1.0→1.1に変更すれば、次回の起動でapplication-1_1.jar がダウンロードされ、実行されます。

感想

筆者自身、今回初めてSWTアプリケーションを作成しましたが、その過程で感じた感想を以下に挙げます。

参考リンク

  1. EclipseによるSWTアプリケーションの作成
    SWTの解説、Eclipseを用いたSWTアプリケーションの作成方法の詳しい解説。
  2. SWTサンプル集
    SWTの使い方の基本的な説明、ウィジェット毎のサンプルプログラムがあります。
  3. Java wiz SWT
    こちらもSWTの基本からウィジェットの使い方まで詳しく書いてあります。
  4. Future's Laboratory
    こちらも3, 4と同様です。
  5. SWT Fanclub
    SWTの日本語メーリングリスト
  6. SwtFanclub - SWTの情報ページ
    上記メーリングリストの内容を中心にまとめたページ。FAQなど。SWT関連リンクが豊富。
  7. Eclipse Workbench以外でのEclipse GUIの使用(IBM developerWorks)
    スタンドアロン・モードでJFaceおよびSWTを使用する方法の解説。
  8. Java Web Startを使用して、SWTアプリケーションを配置する
    SWTアプリケーションの配置に必要な証明書の作成やJNLPファイルの作成方法など。

資料室へ戻る


Copyright (c) 2004 OKI Software Co., Ltd.