JavaFX 11に追加されたRobotクラスの紹介
このエントリは じゃばえふえっくす Advent Calendar 2018 の 3 日目のエントリとしてぶっ込みました。もうクリスマスは終わってますが、まだ空いていますし、 1 日目のエントリ で次のようなことを書いていたのをまだ放置していたので、それを拾うエントリとなります。
上記の Maven リポジトリをご覧になると分かりますが、Java FX 11 もリリースされました。リリースノートは次の通りです。
https://github.com/javafxports/openjdk-jfx/blob/jfx-11/doc-files/release-notes-11.md
まあ新機能は少ないのですが、
Spinner
コントロールに改善が加えられていたり (詳しくは Yucchi_jp さんのこのブログエントリ を) 、新たに Robot というクラスが追加されています。このRobot
クラスについては別のエントリで触れる予定です。
というわけで、JavaFX 11 になって新たに追加された Robot
クラスについて触れたいと思います。
Robot
クラスはプログラムから画面操作を行うために必要なメソッドが実装されたクラスです。あたかもロボットが画面操作を人の代わりに行うようなことを実現するというわけです。 AWT にも同様のクラス があります。一番のユースケースは GUI の自動テストを実装することで、それを実現するために次のような操作を実行するためのメソッドが実装されています。
- マウスの各種操作 (移動、クリック、スクロールホイール) を行う
- マウスの現在位置を取得するためのメソッドもあります
- キーボードをタイプする
- タイプとは別にプレスとリリースにもメソッドが用意されています
- 画面のスクリーンショットを撮る
- 指定した座標の色を取得する
モジュールは javafx.graphics
に、パッケージは javafx.scene.robot
に入っています。
画面を操作するのに必要なものは一通りそろっているので、これで定形作業を肩代わりするプログラムを作るのに使えますね。ゲームの周回操作とかにもいいかも。
実はこのクラス、昔からあったのですが internal なクラスとなっていました。このクラスを使って自動テストフレームワークを作っていたライブラリが多く、Java のモジュール化に伴い「外に出してほしい」というリクエストが非常に多かったのですが、11 になって晴れて表に出てきてくれました。
ところで以前、自分の書いた次のエントリで、JavaFX で xeyes のクローンを作った話をしました。
そこでこんなことを書いていました。
てなわけで、早速この Robot
を使って "Pure JavaFX" なアプリにしちゃいましょう。
まずは 10 以前のマウスポジションを取得するコード。
private void updateMousePosition() { SwingUtilities.invokeLater(() -> { final Point pointerLocation = MouseInfo.getPointerInfo().getLocation(); Platform.runLater(() -> updateEye(pointerLocation.x, pointerLocation.y)); }); }
Swing の EDT と JavaFX のアプリケーションスレッドを行ったり来たりして見通しが悪いですね。これを 11 の Robot
クラスを使うように変更します。使い方は簡単で、普通にインスタンスを取得すればいいです。Controller の初期化処理で取得しておきます。
private Robot robot; @Override public void initialize(URL location, ResourceBundle resources) { robot = new Robot(); // (以下略)
後はこのインスタンスを使ってマウスカーソルのグローバルポジションを取得するだけです。 updateMousePosition()
メソッドの内容が次のように変わりました。
private void updateMousePosition() { updateEye(robot.getMouseX(), robot.getMouseY()); }
はい、これで複数スレッドを行き来する必要がなくなりました。しかも java.desktop
モジュールへの依存も無くなるので、配布 JRE のイメージサイズも小さくすることができますね。 *1
少し付け加えると、 Robot
から取得するマウス座標の値は AWT と違って double
型になります。なので updateEye()
メソッドの引数の型を変える必要がありました。
というわけで JavaFX 11 の新機能である Robot
クラスの紹介でした。さすがに今年の Advent Calendar への投稿はこれで終わりかな。皆様良いお年を。