先週に引き続き今週も次世代Java Plug-inの実験的機能であるドラッガブルアプレットについて紹介していきます。

先週は,ドラッガブルアプレットにするための設定について解説しました。今週は,ドラッガブルアプレットのカスタマイズについて解説していきます。

ドラッグ開始のカスタマイズ

デフォルトでは,ドラッガブルアプレットに対したドラッグを開始するにはAltキーを押しながら左マウスボタンでドラッグします。

これを他のキーに変更したり,マウスボタンを変更したりするにはどうすればいいでしょうか。

そのためには,アプレットクラスにisAppletDragStartメソッドを定義します。

isAppletDragStartメソッドはアプレット上でマウス操作が行われた時に,マウスイベントを引数にしてコールされます。もし,ドラッグをするのであればtrueを返します。ドラッグをしない場合はfalseを返します。

では,実際にサンプルで確かめてみましょう。

サンプルのソース (こちらからダウンロードできます)
DraggableClock2.java
draggableclock2.jnlp
draggableclock2.html

DraggableClock2クラスは先週使用した時計のアプレットに,isAppletDragStartメソッドを追加したクラスです。以下にisAppletDragStartメソッドを示します。

    // ドラッグ開始をカスタマイズするためのメソッド
    public boolean isAppletDragStart(MouseEvent event) {
        // CTRLキーが押されていたら,ドラッグ可
        int modifiers = event.getModifiers();
        
        if ((modifiers & MouseEvent.CTRL_MASK) != 0) {
            return true;
        } else {
            return false;
        }
    }

ここでは,Altキーの代わりにCtrlキーでドラッグを開始するようにしています。

マウスをクリックした時,同時に押されているAltキーやCtrlキーなどのキーを取得するにはjava.awt.event.MouseEventクラスのgetModifiersメソッドを使用します(青字部分)。

Modifiersと複数形になっているのは複数のキーが同時に押された場合にも対応しているためです。

getModifiersメソッドの戻り値の型はintで,キーに応じたビットが立った数値が返ります。ビット演算なので,赤字で示したようにキーに応じたマスク(ここではCTRL_MASK)とアンドを取り,0と比較しています。

CTRL_MASKと同じビットが立っていればtrueを返し,立っていなければfalseを返します。

これで,AltキーからCtrlキーへの変更が完了しました。ぜひ,実際に試してみてください。

ところで,java.awt.AppletクラスのJavadocを見てみても,isAppletDragStartメソッドはどこにも記載されていません。つまり,Appletクラスで定義されたメソッドではないのです。

筆者はてっきりAppletクラスで定義されたメソッドだと勘違いして,isAppletDragStartメソッドに@Overrideアノテーションを付加していました。しかし,これはコンパイルエラーになります。

通常,Java SE 6u10のようなアップデートリリースでは,標準APIに新たなメソッドが追加されることはありません。この原則がここでも適用されているようです。また,実験的機能という理由もあるのかもしれません。

次世代Java Plug-inのリリースノートにはisAppletDragStartメソッドは記載されているにしても,Javadocに記載されていないメソッドを使用するのはちょっと変な感じです。

このサンプルではソースコード中にドラッグ開始するためのキーの指定を行っていましたが,パラメータとして指定することも可能です。

サンプルのソース (こちらからダウンロードできます)
DraggableClock3.java
draggableclock3.jnlp
draggableclock3.html

DraggableClock3クラスのinitメソッドでは,パラメータからドラッグ開始のキーとマウスボタンを設定します。

    private int modifierMask = -1;
    private int mouseButton = MouseEvent.BUTTON1;
 
    @Override
    public void init() {
        // ドラッグ開始のキーの設定
        String modifierKey = getParameter("modifier");
        if ("ctrl".equalsIgnoreCase(modifierKey)) {
            modifierMask = MouseEvent.CTRL_MASK;
        } else if ("shift".equalsIgnoreCase(modifierKey)) {
            modifierMask = MouseEvent.SHIFT_MASK;
        } else if ("alt".equalsIgnoreCase(modifierKey)) {
            modifierMask = MouseEvent.ALT_MASK;
        }
 
        // ドラッグ開始のマウスボタンの設定
        String mouseButtonTxt = getParameter("button");
        if ("2".equalsIgnoreCase(mouseButtonTxt)) {
            mouseButton = MouseEvent.BUTTON2;
        } else if ("3".equalsIgnoreCase(mouseButtonTxt)) {
            mouseButton = MouseEvent.BUTTON3;
        }
        
        <<以下,省略>>

パラメータはAppletクラスのgetParameterメソッドで取得できます(赤字部分)。ドラッグ開始キーはmodifierパラメータ,マウスボタンはbuttonパラメータで設定します。

modifierパラメータには"ctrl","shift","alt"のいずれかを指定できます。デフォルトは-1にしました。つまり,すべてのビットが立っている状態です。

同じようにマウスボタンは1から3まで使用できます。デフォルトは1です。

次に,isAppletDragStartメソッドを示します。

    public boolean isAppletDragStart(MouseEvent event) {
        if ((event.getModifiers() & modifierMask) != 0
            && event.getButton() == mouseButton) {
            return true;
        } else {
            return false;
        }
    }

赤字部分がキーの比較,青字部分がマウスボタンの比較を行っている部分です。

JNLPファイルには次のように指定します。

    <applet-desc name="DraggableClock3" 
                 main-class="DraggableClock3"
                 width="300" height="50">
      <param name="modifier" value="ctrl" />
      <param name="button" value="3" />
    </applet-desc>

赤字がmodifierパラメータの設定で,"ctrl"を値に設定しています。青字がbuttonパラメータで,値は"3"です。

このパラメータの設定はHTMLファイルに記述することもできます。しかし,ドラッガブルアプレットはショートカットから実行されることもあります。この場合HTMLファイルに記述したパラメータは読み込めないため,JNLPファイルに記述しました。

ショートカットを作成しないようにするのであれば,HTMLファイルに記述してもかまいません。