連載
» 2007年10月05日 00時00分 公開

デスクトップをJava製ウィジェットでにぎやかに小山博史のJavaを楽しむ(8)(2/3 ページ)

[小山博史,ガリレオ]

Deskletを作ってみよう

 簡単に動作させることができましたから、NetBeans IDEを利用して、SampleWidgetプロジェクトをひな型とすれば、Deskletを作成できそうです。とはいえ、資料が少ないので、もう少し、すでにあるDeskletのコードを見てみたいところです。

Deskletのコードを調べてみる

 ということで、Deskletのコードもダウンロードしてみました。Subversionでチェックアウトできるようなので、NetBeans 5.5 日本語 Subversionモジュールの開発版を使ってチェックアウトすることにしました。

編集部注:Subversionについて詳しく知りたい読者は、連載「CoolなEclipseプラグイン」第15回「バージョン管理に便利なSubversiveプラグイン」をご参照ください。

 subversion.tigris.orgのサイトからWindows版のSubversionもダウンロードして使えるように設定する必要があります。サーバ用にApache HTTP サーバも必要だと書いてありましたが、クライアントを使う分には必要ありませんでした。

 NetBeans IDEへSubversionモジュールを組み込んで、こちらからDeskletのソースをチェックアウトしたところ、std_deskletsディレクトリに「Clock」「Weather」「JRubyConsole」といったDeskletが含まれていました。なかなか面白そうです。

必要なJARファイルがない!?

 試しに、「Clock」をNetBeansプロジェクトとして開いてみたところ、「ClockDesklet」プロジェクトとして開くことができました。ただ、残念ながらこのままではJARファイルが足りません。Mavenなども用意して、必要なJARファイルをすべて作成する必要があるようです。

 Mavenなども用意して対応することもできるはずですが、よく考えてみると、「ClockDesklet」は手元の環境で動作しています。つまり、必要なJARファイルはどこかにあって、すでに入手しているはずです。

 Glossitope.jnlpをJava Web Startから開かないで保存して開いてみたところ、必要なJARファイルのダウンロードをどこからしているのか分かりました。これを見ると、こちらからダウンロードすればよいことが分かりました。

小さな画面と大きな画面が表示される

 早速ダウンロードして、「ClockDesklet」プロジェクトから参照するように設定してみたところ、無事コンパイルできるようになりました。プロジェクトを構築して、コマンドプロンプトを実行してみると、次のようになります。サイドバーに表示される小さい画面と、コンテナに表示される大きな画面の2つが出ていることがよく分かります。

図8 「ClockDesklet」プロジェクトの実行 図8 「ClockDesklet」プロジェクトの実行

本質的な部分を理解することが必要

 アニメーションをさせたり、バックグラウンドでネットワークからデータを取ってきて、それを表示するアプリケーションを作るためには、このClockDeskletの本質的な部分を理解することが必要です。そこで、無駄な要素を除いて、独自のものを作成してみました。

 具体的には、NetBeans IDEでSampleClockプロジェクトを新規作成して、ライブラリとしてdesklet-specification-1.0.jarを参照するように設定しました。

 Java Appletを作ったことがある人ならば想像がつくと思いますが、Deskletでは、 org.glossitope.desklet.Deskletを拡張extends)して、4つのメソッド(initstartstopdestroy)をオーバーライドするのが基本です。何かリソースを使っていない限りdestroy()メソッドをオーバーライドする必要はありません。

 なお、注意点としては、これらのメソッドはイベントディスパッチ・スレッドから呼び出されるわけではないので、それを意識する必要があります。

ソースコードからDeskletをひも解く

 今回は、次のようなプログラムにしてみました。Clockクラスが動作の基本を与えます。このクラスのオブジェクトを作成するために、ファクトリクラスDeskletFactoryを用意しています。終了時には「getContext().notifyStopped()」を呼び出す必要がある点には注意してください。

package sampleclock;

……(略)……

public class Desklet extends org.glossitope.desklet.Desklet {
    public Desklet() {
        super();
    }
    private Clock clock;
    public void init() throws Exception {
        clock = DeskletFactory.createClock(this);
    }
    public void start() throws Exception {
    clock.start();
    }
    public void stop() throws Exception {
        clock.quit();
        getContext().notifyStopped();
    }
    public void destroy() throws Exception {
    }
}

 Clockクラスは時間を1秒単位で刻み、登録されているObserverインターフェイスへ更新要求をします。このプログラム自体はSwingアプリケーションで普通に使うことができます。内部でスレッドを使って、start()で開始、quit()で停止するようになっています。このクラスへObserverをimplementsしたSwingコンポーネントを登録すれば、1秒ごとにアニメーションさせることができます。

package sampleclock;

……(略)……

public class Clock extends Observable implements Runnable {
    private final static long INTERVAL = 1000;
    private volatile Thread thread = null;

    public void
start() {
        thread = new Thread(this);
        thread.
start();
    }
    public void quit() {
        Thread t = thread;
        this.thread = null;
        t.interrupt();
    }
    public void run() {
        Thread current = Thread.currentThread();
        while(current == thread) {
            try {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        setChanged();
                        notifyObservers();
                    }
                });
                Thread.sleep(INTERVAL);
            } catch (InterruptedException ex) {
            }
        }
    }
}

 例えば、JPanelでは次のようなプログラムとなります。Observerインターフェイスのupdate()メソッドでJLabelオブジェクトのテキストを更新しています。

package sampleclock;

……(略)……

public class DigitalClockByJLabel
extends JPanel implements Observer {
    private JLabel lblTime;
    private final SimpleDateFormat dateFromat
         = new SimpleDateFormat("aa hh:mm:ss");

……(略)……

    public void update(Observable o, Object arg) {
        lblTime.setText(dateFromat.format(new Date()));
    }
}

 例えば、JComponentでは次のようなプログラムとなります。Observerインターフェイスのupdate()メソッドでコンポーネントの描画を更新しています。

package sampleclock;

……(略)……

public class DigitalClockByJComponent
extends JComponent implements Observer {

……(略)……

    public void paintComponent(Graphics g) {
        String s = dateFromat.format(new Date());
        g.setColor(Color.YELLOW);
        g.fillRect(10, 2, 80, 16);
        g.setColor(Color.BLUE);
        g.drawString(s, 12,14);
    }
    public void update(Observable o, Object arg) {
        repaint();
    }
}

 今回は、あらかじめ、こういったコンポーネントを含んで実行するSwingアプリケーションとしてsampleclock.DigitalClockFrameクラスを作成して動作を確認しておきました。このクラスのコードはそれほど重要ではないので示しませんが、Swingアプリケーションで使えるコンポーネントを作成したという点に注目してもらいたいので、紹介しておきます。次のように実行して、画面を表示してみました。

以下のコマンドを実行
>java -classpath SampleClock.jar sampleclock.DigitalClockFrame

図9 作ったサンプルをJavaアプリケーションとして実行 図9 作ったサンプルをJavaアプリケーションとして実行

 それでは、次ページでは作成したDeskletのサンプルをウィジェットとして実行する方法を解説します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。