ナレッジベース

Javaアプリケーションにおけるセレクタ対策 - JLayeredPaneの事例

概要

Javaアプリケーションを自動化する際にセレクタが取得できないというお問い合わせをこれまで何度か受けました。ここでは過去の問題解決の事例を、実際のサンプルアプリケーションを使いながら紹介します。

多くの場合において、UiPath Studioを使えばJavaアプリケーションの自動化は問題なくできますが、アプリケーションの構造上の理由で自動的にセレクタが取得できないケースがあります。そのような場合、UI Explorerを利用して問題の原因を特定し、画面要素を特定するロジックを実装することで問題を解決することができます。

ここで紹介する問題解決のアプローチはJavaアプリケーションに限らず、WindowsアプリケーションやWebアプリケーションなど他のタイプのアプリケーションの問題解決のヒントにもなるかもしれません。セレクタが取得できない場合、UI Explorerを使用して目的の画面要素を調べるというのは一般的なアプローチです。

※なお、ここでご紹介する問題はUiPath Studio v2018.3.1 以降では対策がなされているため発生いたしません。

 

【事例】

セレクタで個々の画面要素が選択できず、画面全体が選択されてしまう

 

この問題を実際に再現するためのサンプルアプリケーションはこちらです。

サンプルアプリケーション

Java Webstart
※Java Webstartでアプリケーションを実行するためには、コントロールパネルの設定が必要です(注1)。launch.jnlpファイルがダウンロードされたら、ファイルをダブルクリックしてアプリケーションを起動します。

ソースコード
https://uidemo.azurewebsites.net/app/hidden_objects/Form.java.txt
https://uidemo.azurewebsites.net/app/hidden_objects/Form.form (Net Beans 8.2使用)

 

レコーディングで画面全体が選択されてしまう

下の画像をご覧ください。これは、UiPath Studioでボタンのセレクタを取得しようとレコーディングや各アクティビティの"Indicate on screen"機能でマウスカーソルを画面上のボタンに合わせた時のものです。
ボタンを選択したいのにもかかわらず、選ぶことができません。

image1

 

問題の原因はJLayeredPaneの存在

UI Explorerでこのアプリケーションを透視してみましょう。この状態でのセレクタは"<java name='jLayeredPane1' role='layered pane'"となっています。本当に取得したいのは同じ階層にあるpanel要素 "panel jPanel1"の下の"push button jButton1"です。layered paneが布団のように覆いかぶさってしまって、同じ階層にあるpanel要素を隠してしまっているのです。JLayeredPange (Javadoc: https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JLayeredPane.html)は他のJava Swingコンテナクラスと異なり画面要素間の相対的な「深さ」を扱うためのコンテナクラスですが(注2)、どうやらこれが原因です。

image2

 

Net Beans IDEの画面(jLayeredPane1とjButton1は「深さ」について相対関係はないが、JavaランタイムはjButton1ではなくjLayeredPane1をオブジェクトとして返す)

image3

 

ボタンのセレクタを取得する

 

幸いにして、UI Explorerを見るとボタン要素はきちんとUiPathから見えていることがわかります。"push button jButton1"をダブルクリックすると、ボタンのセレクタ"<java nam='jButton1' role='push button' />"が取得できました。これをアクティビティのセレクタにセットすれば動作します。

このように、マウス操作によるレコーディングでは直接取得できない画面要素もUI Explorerを活用すれば取得することができ、これはJavaアプリケーションに限ったことではなくWindowsアプリケーションやWebアプリケーションでも同様です。

image4

 

ボタンがクリックできました。

image5

 

脚注

※注1:Java Webstartを起動するには、コントロールパネルのJava (32ビット)の「セキュリティ」で例外サイトリストにhttps://uidemo.azurewebsites.net を追加する必要があります。

image6

 

また、.jnlpファイルをjavaws.exeで実行するため、「設定」→「アプリ」→「既定のアプリ」(Windows10の場合)、もしくはlaunch.jnlpファイルを右クリックし「プログラムから開く」→「別のプログラムを選択」で"C:\Program Files\Java\jre1.8.0_xxx\bin\javaws.exe (ご利用のJavaバージョンに合わせて選択します)"を関連付けます。

image7

 

※注2:少し分りづらいですが、本来JLayeredPaneはJLayeredPaneにaddする他のSwingコンポーネント間の相対的な深さを定義するため、JLayeredPaneそのものは相対的な深さがあるわけではありません。そのため、"panel JPanel1"要素より"layered pane"要素がセレクタとして優先される理由はこの深さの相対位置が直接の原因ではなく「Javaランタイム環境の振る舞いとしてそうなる」ということになります。なお、JLayeredPaneにaddされた様々なSwingコンポーネントに深さの相対な位置の定義があったとしてもUiPath Studioは個々の要素を認識することができます。