Hatena::ブログ(Diary)

hd 4.0 RSSフィード

2016-12-13

javafx-maven-plugin でネイティブ用アイコンを設定する

この記事は JavaFX Advent Calendar 2016 - Qiita の 13 日目です。

昨日は @boochnich さんの JavaFXのCanvasで拡大縮小と平行移動を行う(リベンジ編) - Qiita でした。明日は @y_q1m さんです。

はじめに

JavaFX の最大の魅力の一つはなんといってもクロスプラットフォームGUI アプリを作れることです。 jar 形式でなく、各プラットフォーム向けの実行ファイル形式にビルドする方法も提供されており、 Javaインストールされていない環境でも動作するアプリを作成することができます。

Java 開発といえば Maven や Gradle がデファクトになっていますが、 javafx-maven-plugin を使うと、 JavaFX 開発で Maven を使いつつプラットフォームネイティブJavaFX アプリビルドすることができます。 NetBeansJavaFX + Maven アプリケーションを作ると javapackager を直で使うような構成の pom が出来上がりますが、 javafx-maven-plugin の方がビルドが速いしパッケージングも楽なので、自分は専らこれを使っています。

javafx-maven-plugin を導入する際は、以下のページからぽちぽちオプションを選んでいくと pom 設定の雛形が自動生成されるので便利です。

前置きが長くなりましたが、せっかくネイティブアプリができるのなら、アプリケーションアイコンデフォルトのじゃばじゃばしいやつじゃなくて、独自のものを設定したくなるものです。 Oracle の公式とかだと javapackager を ant から呼ぶみたいなサンプルしかなくて、今更 build.xml もちょっと・・・ということで、 Maven でどうやってアイコンを設定するのか調べてみました。

環境

環境は以下のとおりです。

結論

まず結論から。最低限以下のファイルを用意して mvn jfx:native すればいいです。 Linux は環境がないので調べてませんが、後述のように調べれば同様にできると思います。

アプリ名は pom の build -> finalName です。詳細は以下に述べます。

アイコンファイルをどこに置くか

とりあえず Oracle の公式は以下のような感じです。

To get more insight into what resources are being used, enable verbose mode by adding the verbose="true" attribute to <fx:deploy>, or pass the -v option to the javapackager -deploy command.

なんかよくわかりませんが、ビルド時に verbose="true" を指定すれば、どういうリソースを使うのかわかるよ!って感じでしょうか。しかしここの例では ant なので、 Maven における verbose オプションの指定方法がわかりません。 mvn コマンドの -X オプションを試してみたが、これではないようです。

ここで前述の javafx-maven-plugin の公式サイトを見てみましょう。

lag to turn on verbose logging. Set this to "true", if you are having problems and want more detailed information.

そのものずばり verbose オプションを指定するスイッチがありますね。これをオンにすると pom.xml に以下のように追加されます。

	<groupId>com.zenjava</groupId>
	<artifactId>javafx-maven-plugin</artifactId>
	<version>8.6.0</version>
	<configuration>
		<mainClass></mainClass>
		<verbose>true</verbose><!-- これ -->
	</configuration>

この状態で mvn jfx:native を叩くと以下のような出力が得られます(抜粋)。 Oracle 公式にあったような感じですね。

  Using default package resource [icon]  (add package/macosx/アプリ名.icns to the class path to customize)
(略)
  Using default package resource [dmg background]  (add package/macosx/アプリ名-background.png to the class path to customize)
  Using default package resource [volume icon]  (add package/macosx/アプリ名-volume.icns to the class path to customize)

上記は Mac で試したものですが、実行環境の OS により少しパスが異なります。

どうやら Mac の場合は package/macosx/アプリ名.icns というやつを用意してクラスパスに追加すればよさそうです。他にも アプリ名-background.pngアプリ名-volume.icns とかいうのもありますね。クラスパスということですがどこに置くのがよいのか、ここで javafx-maven-plugin の公式サイトをもう一度よく読みます。

Default: ${project.basedir}/src/main/deploy

(略)

The most common usage for this is to provide platform specific icons for native bundles. In this case you need to follow the convention of the JavaFX packaging tools to ensure your icons get picked up.

なるほど、 ${project.basedir}/src/main/deploy/package/macosx を用意すれば良いっぽいですね。

アイコンファイルの用意

というわけでアイコンファイルを用意しましょう。 icns という見慣れない拡張子当社比)が出てきましたが、これはなんでしょうか。

Mac 用のアイコンファイルのようですね。ターミナルから作れるようなので作ってみましょう。元ネタの png はなんとかして用意する*1として、各サイズは Macプレビューアプリからリサイズすることで作れます。

icons_256x256.png とかいろんなサイズの画像を作り、 アプリ名.iconset というフォルダに突っ込みます。しかるのちにターミナルで以下のコマンドを叩くと、 アプリ名.icns が出来上がります。

$ iconutil -c icns アプリ名.iconset

今回はめんどくさいので 256x256 だけ用意しましたが特に問題なく作成できました。ファイル名で表されたサイズと実際のファイルサイズが異なっているとうまく icns ファイルが作成されないので気をつけましょう。

出来上がったアイコンファイルを ${project.basedir}/src/main/deploy/package/macosx に配置し、改めて mvn jfx:native を叩きます。

  Using custom package resource [icon]  (loaded from package/macosx/アプリ名.icns)
(略)
  Using default package resource [dmg background]  (add package/macosx/アプリ名-background.png to the class path to customize)
  Using default package resource [volume icon]  (add package/macosx/アプリ名-volume.icns to the class path to customize)

作成したアイコンファイルが読まれているのがわかります。これでめでたくアイコンが設定できました。

f:id:hagi44:20161208001020p:image

インストールすると、ちゃんと Finder や Dock に指定したアイコンが表示されます。

アプリ名-volume.icns はインストーラーがマウントされたときにデスクトップに出現するボリュームアイコン用のようです。このファイルを指定するとデスクトップに以下のアイコンが現れます。今回は同じアイコンファイルを使っています。

f:id:hagi44:20161208001022p:image

指定しない場合、デフォルトのジャバジャバしいやつです。

f:id:hagi44:20161208001021p:image

アプリ名-background.pngインストーラーの背景画像のようです。このファイルを指定すると以下のようになります。

f:id:hagi44:20161211120105p:image

なんかうっかりひどい色になってしまいました。すいません。とりあえず画像サイズは 512x256 にしてみたのですが、微妙に合ってないですね。

ウィンドウアイコンの設定

アプリのタイトルバーに表示するアイコンは以下のようにして設定できます。これ自体はネイティブアプリとは関係ないです。

  1. アイコンファイルを src/main/resources/images/icon.png あたりに配置する
    • Java コードから参照できる場所であればどこでも良いです
  2. JavaFXインクラスの start メソッドアイコンパスを指定する

アイコンパスの指定は以下のようなコードになります。

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/Scene.fxml"));

        Scene scene = new Scene(root);
        scene.getStylesheets().add("/styles/Styles.css");

        // ↓この 1 行
        stage.getIcons().add(new Image(getClass().getResourceAsStream("/images/icon.png")));

        stage.setTitle("JavaFX Icon Sample");
        stage.setScene(scene);
        stage.show();
    }

これでこんな感じになります。もうちょいはっきりしたアイコンにしないと小さくてわかりづらいですね。

f:id:hagi44:20161211114635p:image

Mac の場合は未設定だとアイコン自体が表示されないのでなくても特に気になりませんが、 Windows だとデフォルトのウィンドウアイコンになってしまい、残念な感じになるのでこちらも設定しておいた方が良いでしょう。

Windows の場合

同様に Windowsmvn jfx:native を実行すると以下のような出力が得られます(抜粋)。

  Using default package resource [application icon]  (add package/windows/アプリ名.ico to the class path to customize)

Windows だと設定可能なアイコンが 1 種類しかないようですね。インストーラーを作成できるようにしてあるとまた違うのかもしれませんが、そのへんは未調査です。メッセージに従い、 src/main/deploy/package/windows/アプリ名.ico を用意して再度ビルドしてみると、 target/jfx/native/アプリ 以下に実行ファイル類が一式作成され、アイコンもちゃんと設定されていることがわかります。

f:id:hagi44:20161212184355j:image

以上です。

*1:とりあえずなんでもいいのであれば Placehold.jp|ダミー画像生成 モック用画像作成 でダミー画像を作るのもありかと思います。 advanced オプションCSS も使えるので、角丸やらグラデーションやら使えばそれなりにそれっぽくもなります。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/hagi44/20161213/1481557645
Connection: close