0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

デスクトップマスコットを作ってみる。【マウスの操作編】

Posted at

初めに

前回の記事ではマスコットの表示と反転までを作成しました。

今回はマウスで動かせるように処理を追加していこうと思います。
JavaFXで行っていた時と異なり、マウスイベントについて実装を変える必要があったので
そのあたりが中心になります。

MouseListenerの関数型インターフェース化

JavaFXで作成していたころはFxmlにイベントを定義していましたが、
今回からはSwingを使用しているため、同じようにはいきません。

JFrameのマウスイベントを設定するためにはMouseListenerインターフェースを
実装する必要があります。

このインターフェースにはマウス操作の必要なメソッドがずらっと定義されています。
これは関数型インターフェースではないため、ラムダで記述できないのです。

マウスイベントごとに実装クラスを作成したり、何かしらの条件分岐を作れば
実現可能と思いますが、めんどくさい・・・

悩んだ自分はどうしたかというと、こうしました。

JDIMouseClicked.java

@FunctionalInterface
public interface JDIMouseClicked extends MouseListener {

    void jdMouseClicked(MouseEvent e);

    @Override
    default void mouseReleased(MouseEvent e) {
    }

    @Override
    default void mousePressed(MouseEvent e) {
    }

    @Override
    default void mouseExited(MouseEvent e) {
    }

    @Override
    default void mouseEntered(MouseEvent e) {
    }

    @Override
    default void mouseClicked(MouseEvent e) {
        jdMouseClicked(e);
    }
}

インターフェースはデフォルトの実装ができるため、MouseListenerを実装した
インターフェースをすべてデフォルト実装をして、抽象メソッドを一個だけにすれば
関数型インターフェースになるということですね。

このインターフェースを必要なイベントの数だけ作成すれば、
マスコット側で楽にマウスの処理が実装できそうです。

マウスイベントの設定

上記の案でインターフェースを作成した後、マウスのイベントをマスコットに追加していきます。

移動はマウスのドラッグ時に現在のドラッグイベントの位置から最初にクリックした位置
引き算すると移動後の位置が出てきます。

まずはクリックした際に、どこをクリックしたかを保存する必要があるため、
クリックイベントで位置を保存します。

JDMascot.java

/** クリック位置保持用 */
protected JDPoint clickPoint = new JDPoint(0, 0);

private void eventSetClickPoint(MouseEvent e) {
    // クリック位置:X座標を取得
    clickPoint.setX(e.getX());
    // クリック位置:Y座標を取得
    clickPoint.setY(e.getY());
}

JDPointクラスはただの値を保持しているだけのクラスです。

JDPoint.java

public final class JDPoint {
    private int x;
    private int y;

    public JDPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    /**
     * xを取得します。
     *
     * @return x
     */
    public int getX() {
        return x;
    }

    /**
     * xを設定します。
     *
     * @param x
     */
    public void setX(int x) {
        this.x = x;
    }

    /**
     * yを取得します。
     *
     * @return y
     */
    public int getY() {
        return y;
    }

    /**
     * yを設定します。
     *
     * @param y
     */
    public void setY(int y) {
        this.y = y;
    }
}

次はドラッグ時の処理を作成していきます。
ドラッグ時は先ほどの通り、現在のイベント位置から最初のクリック位置を引き算して
その位置に座標を変更するようにします。

JDMascot.java

private void eventMoveWindow(MouseEvent e) {
    var moveX = e.getXOnScreen() - clickPoint.getX();
    var moveY = e.getYOnScreen() - clickPoint.getY();

    this.setLocation(moveX, this.getY());
    this.setLocation(this.getX(), moveY);
}

ここでは何もチェックしていないですが、画面外にマスコットが出ていかないように
チェック処理などを入れるとよいかもしれません。

最後に、追加した処理をマウスイベントに設定します。
設定するメソッドはコンストラクタで呼び出すことにします。

JDMascot.java

/** クリック位置保持用 */
public JDMascot() {
    // ウィンドウの設定
    setUp();

    // ※今回追加した箇所
    // イベントの登録
    setMascotEvent();
}

private void setMascotEvent() {
    // クリックイベント
    JDIMousePressed eventSetClickPoint = e -> { eventSetClickPoint(e); };
    this.addMouseListener(eventSetClickPoint);

    // ドラッグイベント
    JDIMouseDragged eventMoveWindowDragged = e -> { eventMoveWindow(e); };
    this.addMouseMotionListener(eventMoveWindowDragged);
}

テストコードの作成

では、前回作成したテストコードを使用してマウス操作が
できるようになったかを確認します。

テストコードは新規で作成していません。

Videotogif.gif

うむ。

終わりに

今回はマウスの操作をできるように実装しました。
次回はアプリケーションの終了を実装する予定です。

リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?