JDK7u6に入ってくるJavaFXのネイティブパッケージ機能を早速試してみました
先日、OracleのJava開発に関するblogに "Native packaging for JavaFX" なるエントリが載っていたことを知りました (こちらに江草ロジ子さんによる日本語訳もあります) 。
なんとJavaFX2.2にはOSネイティブなパッケージを生成する機能が付いてくるということです!
JavaFX 2.2 adds new packaging option for JavaFX applications, allowing you to package your application as a "native bundle". This gives your users a way to install and run your application without any external dependencies on a system JRE or FX SDK.
具体的にはJavaFXアプリケーションをWindowsなら.exeや.msi、Macなら.appや.dmg、そしてLinuxならrpmの形でアプリケーションパッケージやインストーラーを出力できるようになるということです。
パッケージにはJREやJavaFXのランタイムも含めてしまい、配布先にJavaFXのランタイムはおろか、JREが入っていなくてもインストール、実行可能にすることができるということです。
これは今までのJavaの歴史を考えると結構衝撃的な話だと思っています。
と言うわけで早速試してみました。
この機能はJDK7u6の最新版のDeveloper Previewに入っているので、まずは以下の場所からダウンロードします。
http://jdk7.java.net/download.html
自分はMac環境で試しました。ダウンロードしたインストーラーを使ってインストールするだけです。
既にJDK7のGA版をインストールしている場合は上書きしてしまうので注意してください。
$ java -version java version "1.7.0_06-ea" Java(TM) SE Runtime Environment (build 1.7.0_06-ea-b14) Java HotSpot(TM) 64-Bit Server VM (build 23.2-b05, mixed mode) $ /usr/libexec/java_home /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home
自分の環境だと、NetBeansのJavaプラットフォーム設定の変更も必要でした。以下のスクリーンショットのように、デフォルトJavaプラットフォームの設定で、JDK7u6のパスを指定する必要があります。
では早速試してみます。NetBeansのビルドでネイティブパッケージを生成したい場合、NetBeansのJavaFXアプリケーションプロジェクトの直下にあるbuild.xmlに対して、次のように -post-jfx-deploy タスクをオーバーライドします。fx 名前空間の記述の追加が必要なことに注意してください (
<project name="MouseInfoSample" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant"> (中略) <target name="-post-jfx-deploy"> <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" nativeBundles="all" outdir="${basedir}/${dist.dir}" outfile="${application.title}"> <fx:info title="${application.title}" vendor="${application.vendor}"/> <fx:application name="${application.title}" mainClass="${javafx.main.class}"> </fx:application> <fx:resources> <fx:fileset dir="${basedir}/${dist.dir}" includes="${application.title}.jar"/> </fx:resources> </fx:deploy> </target> </project>
ポイントは
これでNetBeansの構築を実行したところ、appの生成には成功しましたが、dmgの生成には失敗しちゃいました。
Launching <fx:deploy> task from /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home/lib/ant-javafx.jar Using base JDK at: /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk Creating app bundle: /Users/aoetakashi/NetBeansProjects/MouseInfoSample/dist/bundles/MouseInfoSample.app Building DMG package for MouseInfoSample java.io.IOException: Exec of failed with code 1 command [[osascript, /var/folders/m5/vk8q5qx16yd2scc1jt0mlv100000gn/T/build3045467055592762416.fxbundler/macosx/MouseInfoSample-dmg-setup.scpt] in unspecified directory at com.sun.javafx.tools.packager.bundlers.IOUtils.exec(IOUtils.java:130) at com.sun.javafx.tools.packager.bundlers.IOUtils.exec(IOUtils.java:108) at com.sun.javafx.tools.packager.bundlers.MacDMGBundler.buildDMG(MacDMGBundler.java:262) at com.sun.javafx.tools.packager.bundlers.MacDMGBundler.bundle(MacDMGBundler.java:71) at com.sun.javafx.tools.packager.PackagerLib.generateNativeBundles(PackagerLib.java:453) at com.sun.javafx.tools.packager.PackagerLib.generateDeploymentPackages(PackagerLib.java:434) ...
でも、この例外メッセージが出る前に、何故かそのdmgが以下のスクリーンショットのように「マウント」はされていたんですよね。うーむ不思議だw
いくつかのJavaFXプロジェクトで試しましたが、同じ結果でした。まあ、今回はここについてはまだ深くは調べていません。とりあえずappが出来たので自分的にはOKですw
で、できあがったappはちゃんとダブルクリックで普通に起動します。デフォルトでも結構かっこいいアイコンです。
でも、ファイルサイズを見てみると...
166.9MBだとぉ!?
ちなみにアプリ本体のJARのサイズは20KBです。いったい何が入っているんだと思って中身を見てみると...。
はい、JDKが丸ごと入っていました。いくら何でもワイルドすぎやろこれwww
とまあ、こんな感じでした。色々と問題はありますが、まだ実験段階ですし、これから少しずつ洗練されていくでしょう。
アプリケーションの配布形態としてネイティブパッケージという選択肢が出てきたことは素直に嬉しいことだと思っています。
ランタイムごと配布するので、配布先の環境のことを考慮しなくてもいいというのは色んな場面で効いてくるでしょう。例えばなかなかソフトウェア環境を更新してくれない企業向けとか...。*1
もっとも、これはデスクトップアプリ向けというよりはiOSやWindows Metroの方をにらんで用意した機能だと見ています。
と言うわけで皆さんも是非試してみてください。
今度はWindowsでも試してみよう。
JavaFXで画像を使ったボタンを作る方法
ちょっとしたメモです。
RIAを開発するとき、デザイナさんと連携して作ることが多いと思います。
ボタンのようなコントロールについても画像として素材を作ってもらい、それを組み込んで使うというシチュエーションも結構あることでしょう。
というわけでJavaFXで画像を使ってボタンを作る方法です。
JavaFXはCSSを使って装飾することができます。HTMLのCSS2.1やCSS3をベースにしており、多くの場合同じプロパティを使うことができます。ただし、ベンダープレフィックス "-fx-" を付ける必要がありますが。
画像をボタンの背景として使いたい場合、CSS3のborder-image属性を使うことができます。次のようにCSSを作成します。
.img-button { -fx-border-image-source: url('img/btn.png'); -fx-border-image-slice: 4 5 4 5 fill; -fx-border-image-width: 4 5 4 5; -fx-border-image-repeat: stretch; -fx-border-color: null; -fx-background-color: null; -fx-text-fill: white; } .img-button:hover { -fx-border-image-source: url('img/btn_hover.png'); } .img-button:pressed { -fx-border-image-source: url('img/btn_pressed.png'); } .img-button:disabled { -fx-border-image-source: url('img/btn_disabled.png'); }
border-image-slice プロパティを使うことで、画像を枠の部分と中央部分に分割し、枠部分の拡大率を保持したまま中央部分のみを拡大縮小する、いわゆる「9スライス」も指定可能です。fill も指定して、真ん中も塗りつぶすようにします。
border-image-width プロパティでボーダーの幅を指定します。border-image-repeat で stretch を指定すると、中央は引き伸ばされるようになります。
ベンダープレフィックスを取り除けば、HTMLのCSSと同じになることが分かります。
文字の色については -fx-text-fill プロパティで指定します。これはHTMLとは異なるので注意が必要です。
後は、border-color、background-color を null にして、従来の描画を消せばOKです。
hover や pressed といった疑似クラスもHTMLの場合と同じように指定可能です。
final Button imgBtn = new Button("これは画像を使ったボタンです"); imgBtn.setPrefHeight(40); imgBtn.getStyleClass().add("img-button");
実行するとこんな感じで画像を背景にしたボタンが表示されます。わざと縦方向も伸ばしていますがちゃんと四隅を崩さずに伸ばしているのが分かりますね。
スクリーンショットじゃ分かりませんが、マウスオーバーやマウスクリックでも用意した画像に切り替わります。
とまあこんな感じで割とHTMLでのCSSと同じように書けそうです。HTMLデザインの技術を活かすことができるというのは結構なアドバンテージではないかと思っています。*1
JavaFXでxeyes作ってみました
今の自分の仕事場は環境的に結構恵まれています。広い机にエルゴヒューマンの椅子。
そしてディスクプレイが27インチのデュアルです! (iMac+Thunderbolt Display)
広いディスプレイはやっぱり快適です。あまりに快適なので家でも27インチのUltra Cinema Displayを買っちゃったくらいです。
でも広いディスプレイだと1つ困ることがあります。それはマウスカーソルを見失いやすいということです。
そこで古き良きxeyesを使うことにしました。(確かxeyeが元々作られた理由ってマウスカーソルの位置を把握するためでしたよね?)
ところがMacにはxeyesが確かに付属しているのですが、これはX Window上で動くアプリケーションで、Xのアプリケーション上にマウスカーソルがあるときしか反応してくれません...。
というわけでJavaFXを使って自分で作ってみることにしました。
が、まず一番最初でつまずきます。今のJavaFXのAPIではマウスのグローバルな座標を取る手段が見当たりません。
仕方が無いのでAWTの MouseInfo を使って取得しようと思ったのですが、JavaFXのアプリケーション上で使うと、HeadlessExceptionが飛びます。
JavaFXはAWTを全く使わず一から作り直しているので、AWT的にはヘッドレスで動いていることになるのです。(システムプロパティ java.awt.headless に true がセットされています)
(2011/12/26 修正)
櫻庭さんからご指摘があり、SwingのEDT上で実行すれば、Swingを土台とせずともHeadlessExceptionは飛ばないとのことでした。
簡単なサンプルで確認したところ、Windows環境では問題なく動作しました。ただ、Mac環境ではやはりHeadlessExceptionが送出され、どうもMac環境固有の問題だったようです。
ただ、WinとMacで微妙に実行環境が異なるところがあったので (前者はJDK7update1 + JavaFX2.0.2で後者はJDK6update29 + JavaFX2.0.1beta) 、後ほど時間があるときにもう少し詳しく再現条件について調べてみます。
あと、改めてJavaFXとして作ってみます。
櫻庭さん、ご指摘ありがとうございました!
(2012/02/21 追記)
どうもJIRAで報告されているRT-13739が近い感じです。一応修正ターゲットは2.1になってますが、これを書いた時点ではまだアサインがないようです。
結局Swingを土台にしてその上にJavaFXで作ることにしました。全ソースコードはgistに貼り付けてあります。
https://gist.github.com/1519410
ちょっとしたアプリケーションですが、結構学ぶことがありました。
まず、Swingアプリケーション上にJavaFXアプリケーションを構築する方法です。
public class SwingFXEyes extends JFrame { private JFXPanel jfxPanel; private Eye leftEye; private Eye rightEye; private Timer timer; public SwingFXEyes() throws HeadlessException { initComponents(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingFXEyes().setVisible(true); } }); } private void initComponents() { setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jfxPanel = new JFXPanel(); add(jfxPanel); Platform.runLater(new Runnable() { public void run() { initJFXComponents(); } }); pack(); } private void initJFXComponents() { Group root = new Group(); Scene scene = new Scene(root); leftEye = new Eye(); rightEye = new Eye(); rightEye.setLayoutX(leftEye.prefWidth(-1) + 5); root.getChildren().addAll(leftEye, rightEye); jfxPanel.setScene(scene); SwingUtilities.invokeLater(new Runnable() { public void run() { startTimer(); } }); }
Swing上にJavaFXのコンポーネントを載せるには JFXPanel を貼り (initComponents) 、その上にJavaFXのシーングラフを構築 (initJFXComponents) します。目玉部分は独自コンポーネント Eye クラスとして作りました。
注意点としてはSwingとJavaFXは実行スレッドが異なるので、互いのコンポーネントを触るときは SwingUtilities.invokeLater、Platform.runLater を経由して触る必要があります。これがちょっとめんどくさいです。
マウス位置の取得はSwingのタイマーを使って行いました。
/** * マウス位置取得処理を行うタイマーを起動する。 */ private void startTimer() { timer = new Timer(50, new ActionListener() { public void actionPerformed(ActionEvent ae) { updateMousePosition(); } }); timer.start(); } /** * グローバルのマウス位置を取得し、目のマウス位置を更新する。 */ private void updateMousePosition() { final Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); Platform.runLater(new Runnable() { public void run() { updateEye(mouseLocation.x, mouseLocation.y); } }); } /** * 左右のEyeにコンポーネントからの相対的なマウス位置を渡す。 */ private void updateEye(double mouseX, double mouseY) { Point panelLocaiton = jfxPanel.getLocationOnScreen(); leftEye.updateMousePosition(mouseX - panelLocaiton.x, mouseY - panelLocaiton.y); rightEye.updateMousePosition(mouseX - panelLocaiton.x - leftEye.prefWidth(-1) - 5, mouseY - panelLocaiton.y); }
AWTの MouseInfo を使って、マウス位置を取得し、目玉コンポーネントにはコンポーネントからの相対的な座標を渡すようにしています。
JFXPanel は javax.swing.JComponent を継承しているので、getLocationOnScreen メソッドを使って画面上での位置を取得可能であることを利用しました。
目玉は独立したコンポーネントとして作ってみました。JavaFXでは子を持つコンポーネントは Parent クラスを継承する必要があります。
public class Eye extends Parent { private static final double CENTER_X = 42.5; private static final double CENTER_Y = 62.5; private static final double ELLIPSE_RADIUS_X = 40d; private static final double ELLIPSE_RADIUS_Y = 60d; private Circle eye; public Eye() { super(); createChildren(); } private void createChildren() { final Ellipse ellipse = new Ellipse(CENTER_X, CENTER_Y, ELLIPSE_RADIUS_X, ELLIPSE_RADIUS_Y); ellipse.setStrokeWidth(5.0); ellipse.setStroke(Color.BLACK); ellipse.setFill(null); eye = new Circle(CENTER_X, CENTER_Y, 10d, Color.BLACK); this.getChildren().addAll(ellipse, eye); } /** * 自分の位置からの相対的なマウス位置を受け取り、自身のステータス (つまり目玉の位置) を更新する。 * @param mouseX マウスのx座標 * @param mouseY マウスのy座標 */ public void updateMousePosition(double mouseX, double mouseY) { // マウスの自コンポーネントの中心からの相対座標を算出 double localMouseX = mouseX - CENTER_X; double localMouseY = mouseY - CENTER_Y; computeEyePosition(localMouseX, localMouseY); } private void computeEyePosition(double mouseX, double mouseY) { double parameter = Math.atan2(mouseY, mouseX); double eyeX = (ELLIPSE_RADIUS_X - 7.5) * Math.cos(parameter); if (Math.abs(mouseX) < Math.abs(eyeX)) { eyeX = mouseX; } double eyeY = (ELLIPSE_RADIUS_Y - 7.5) * Math.sin(parameter); if (Math.abs(mouseY) < Math.abs(eyeY)) { eyeY = mouseY; } eye.setCenterX(eyeX + CENTER_X); eye.setCenterY(eyeY + CENTER_Y); } }
目玉の縁を Ellipse で、目玉を Circle で書いて自分の子供に追加しています。
外からマウスの相対的な位置をもらって目玉の位置を決めるようにしました。 Math.atan2 を使って極座標に変換しています。
JavaFXユーザグループ第6回勉強会に行って来ました
前回に引き続き第6回JavaFX勉強会に参加してきましたので、その時のメモを貼っておきます。色々あって公開が遅くなっちゃいました。
今回は参加者が随分増えていて驚きました。やはりJavaOneでOracleがJavaFXを全面に押し出したことや、GroovyやScalaの話題があったからでしょうか。
何が変わった JavaFX 2.0 by 櫻庭さん (@skrb)
JavaOneでの話題や、正式版となったJavaFX2.0についての説明が中心でした。
JavaOneでのお話し
JavaFX2.0で変わったこと
前回のご説明とかぶっている内容も結構あったので、差分点を中心にメモっています。
- シーングラフをJavaで書くのは辛いので、XMLでも書けるようにした。それがFXML。
- Production Suiteなくなっちゃった!
- JSONのParserがなくなっちゃった。JavaEE7にも入るので、まとめようとしているのかな?
デモ
テキストエリアに入れたコードをその場で解釈して実装するアプリを使ってデモしていました。
- WebView
- HTML文字列の解釈もOK。
- この上でHTML5で作っても大抵のアプリは提供できちゃいますね。(身も蓋もないこと言いますねw)
- 純粋な意味でのHTML5、CSS、JavaScriptは大体OK。WebSocketなど幾つか使えない仕様もある。
- アニメーション
- 移動とか回転だったら始点と終点を指定するだけで後は自動補完する。
- 移動、回転、拡大縮小、パスアニメーションとかができる。
- Effect
- 基本 Node に対して setEffect する。
- 徐々に効果を掛ける時はタイムラインを作って少しずつ変えていく。
- CSS
- Scene に対して add する。つまり複数指定がOK。
- 接頭辞 "-fx" が付く。
- Bind
まとめとか
質疑応答
Q. まだJavaSEに組み込める水準ではないとは?
A. まだ意図した動きがしない所があるとか、Prismが対応しているGPUがまだ少ない所とか。
Q. CSSの属性名に何で接頭辞が入っている?
A. 何ででしょう、困りますよねえ (爆
Q. FXMLには日本語が使えるか?
A. XMLなのでたぶん大丈夫なはず。
(これは私がコメント) 自分が試してみたところ、属性では普通に使えましたよー。
※こんな感じで試してました。
<VBox id="boxPane" prefHeight="200" prefWidth="320" spacing="10" xmlns:fx="http://javafx.com/fxml" fx:controller="samplefxmlapplication.Sample"> <children> <Button id="button" prefWidth="80" text="Click Me!" onAction="#handleButtonAction" fx:id="button" /> <Label id="label" prefHeight="16" prefWidth="200" text="クリックしたら表示が変わるよ" fx:id="label"> <alignment> <Pos fx:value="CENTER"/> </alignment> </Label> </children> <alignment> <Pos fx:value="CENTER"/> </alignment> </VBox>
Q. コンパイルはどのように行うのか?FXMLは?
A. 普通にJavaアプリケーションとしてビルドする。FXMLはJavaプログラム中でロード処理を書く。(デコンパイルしたら中でStAXを使ってた)
Q. bindを入力チェックとかに応用できるか?
A. 低レベルAPIを使えば割と好きに書けるのでいけます。
Q. CSSのリファレンスが見当たらなかったのですが。(<- 質問者私です)
A. OracleのJavaFXのページからリンクがありますよ。
すみません、めっちゃ正面玄関にありましたね!失礼しましたー。
Q. Swingとの混在はやりやすい?
A. スレッドが別になるのでやりにくい。また、Swing上でJavaFXを動かすとJava2D上で動くことになるので遅くなる。
感想
JavaOneではJavaFXが全面に押し出されていて、自分も結構驚きました。ただ、現時点ではJavaSE本体に入るレベルじゃないというのは分かります。AWT/Swingと決別して一から作り直しているので、AWT/Swingが長い時間を掛けて蓄積してきた資産がそのままでは使えないですからねえ。自分でいじっている時でもグローバルなマウス位置が取れなくて面食らったりとか*1、まだまだ不足しているところはあるという印象です。
FXMLは結構面白いと思っています。XML側とJavaコード側を結びつける仕組みがMXML等の類似技術よりも良く考えられているという印象です。
MXMLはコンパイルするとActionScriptクラスに変換されますが、FXMLはあくまでXMLドキュメントのまま読み込む形になっているのもちょっと変わっていますね。この方法が本当にいいのかは分からないですが...。
GroovyFX – Groovy な JavaFX 2.0 by 関谷さん (@kazuchika)
「プログラミングGROOVY」の共著者でもある関谷さんから、GroovyFXについて、デモアプリケーションと共に紹介して頂きました。デモアプリケーションが素晴らしかったです。
Groovyとは?
GroovyFX
デモアプリケーション
その他
JavaFX 2.0 + Scala → ScalaFX by 深井さん (@fukai_yas)
こちらはScalaFXの紹介です。深井さんはScalaは業務ではなく趣味で触っているとのことでした。
ScalaFXはまだまだ始まったばかりの状態のようですが、こちらはこちらでとても興味深いものがありました。
ScalaFXの概要
シーングラフの構築
- ぱっと見はGroovyFXと同様、JavaFXScriptに似せた書き方になっている。
- JFXAppがmainメソッド起動前提なのでAppletがNG。
- バインドは次のように書く。複雑な処理も書ける。
new Rectangle { width <== stage.widthProperty / 2 height <== stage.heightProperty / 2 fill <== when (checkbox.selected) then Color.RED otherwise Color.BLUE }
何これ、めっちゃクールなんですけど!
※同じ事をJavaで書くと次のようになります。分かりやすさが全然違いますよね!
Rectangle rect = new Rectangle(); rect.widthProperty().bind(stage.widthProperty().divide(2)); rect.heightProperty().bind(stage.heightProperty().divide(2)); rect.fillProperty().bind(new ObjectBinding<Color>() { { super.bind(checkbox.selectedProperty()); } @Override protected Color computeValue() { return checkbox.selectedProperty().getValue() ? Color.RED : Color.BLUE; } });
- GroovyFXと同様、Duarationとかを書きやすくするようにしている。
その他
- 次回は来年1月くらいに。ツールをメインテーマに!
全体を通しての感想
冒頭にも書きましたが参加者が増えて驚きました。懇親会でも様々なバックグラウンドを持つ人が集まってきているという印象でした。JavaEE系の人とかAndroidの人とか自分みたいにHadoop触っている人とかw
少しずつ盛り上がり始めているのは確かだと思っています。別のエントリでも書きましたが、Flexがあんなことになったので、実は今JavaFXは結構いい立ち位置にあるのかも知れません。
*1:これについては別途エントリを書こうと思っています。
MacでJavaFX2.0を触り始めてみる
先日のJavaOneでJavaFX2.0が正式発表され、そして待望のMac向けDeveloper Previewも登場しました。
過去にRIA開発をやったことがあるのでJavaFXにはすごく興味があります。今後果たしてJavaFXが来るのかどうか?という疑問はありますが、自分としては特に業務系システムにおけるクライアントとして今後徐々に採用されていくのではと考えています。
というのも、業務系システムではクライアントアプリケーションをSwingで開発することが意外と多い気がするからです。サーバーサイドをJavaで開発していると、やっぱりクライアントもJavaで開発した方がやりやすいですし。*1
で、OracleはSwingをJavaFXにシフトさせるつもりのようですし、Oracleの用意したJavaFXのデータシートを見ても、JavaFXを "Rich Enterprise Client Applications" とうたっており、JavaFXをエンタープライズ向けのクライアント開発基盤として押していく姿勢を見せています。なので、段々業務系のシステム開発ではJavaFXを使う場面が出てくるんじゃないかなー考えています。(数年くらいかかるかも知れませんが)
という訳で今のうちからJavaFX触るぞーと考えて早速Macに入れてみたのですが、意外と躓いたところが結構あったので環境を作って触り始めてみるところまでをメモっておきました。
JavaFX本体とサンプルのダウンロード
ダウンロードサイトは以下です。ダウンロードにはOTNのアカウントが必要です。
http://www.oracle.com/technetwork/java/javafx/downloads/javafx2-macosx-487281.html
SDKの方はZIPアーカイブになっているので、適当な場所に解凍すればいいです。
サンプルの方は次のように、SDKのインストールディレクトリの下に置く必要があります。そうでないと動きません。リリースノートではこの辺が割とさらっと書かれているので注意してください。
javafx-sdk2.0.2-beta/ ├── bin/ ├── docs/ ├── javafx-samples-2.0/ <- ここ ├── rt/ └── tools/
NetBeans7.1 betaのセッティング
次はNetBeansです。NetBeans7.1 (現在ベータ版) はJavaFX2.0をサポートしているので是非入れましょう。後述しますが、NetBeansを入れておくとサンプルを使っての勉強もやりやすくなります。
Windowsの場合だと、先にJavaFXをインストールしておけば、その後にNetBeansを入れるとNetBeans側で自動認識し、すぐに使えるようになりますが、Mac版は手動でセットアップが必要となります。(Windows版のJavaFXはインストーラが用意されており、基本的には決まったディレクトリに入りますが、Mac版は適当なディレクトリに解凍するだけなのでこの辺りは致し方ないですね)
これがちょっと面倒です。NetBeans側でも解説を用意していますが、Windows向けの内容となっており、Macユーザーには分かりにくくなっています。
まずは以下のサイトからNetBeans7.1 betaをダウンロード、インストールします。betaなのに日本語版もちゃんと用意されています。この辺りNetBeansはスバラシイ。
http://dlc.sun.com.edgesuite.net/netbeans/7.1/beta/
NetBeansでJavaFXの開発を行うためには、"JavaFX enabled" なJavaプラットフォームを用意する必要があります。
まず、メニューから [ツール]-[Java プラットフォーム] を選択して、Javaプラットフォームマネージャーを起動します。
起動したプラットフォームマネージャーで [プラットフォームを追加...] ボタンをクリックし、新しいJavaプラットフォームを追加します。
Java自身のプラットフォームフォルダの選択はデフォルトと一緒でいいです。
プラットフォーム名は何でもいいのですが、"Default_JFX_Platform" という名前にしておいた方がいいみたいです。(下のスクリーンショットでは違う名前にしているので注意!)
これはWindows版のNetBeansでJavaFX環境を自動認識した際に作られるJavaプラットフォームの名前のようで (すみません、Win版は未チェックです) 、後述するサンプルアプリケーションから作成したNetBeansプロジェクトは、Javaプラットフォームがこの名前になっていることを前提としているからです。
作成したプラットフォームの設定パネルには [JavaFx] という名前のタブが追加されているはずです。これをクリックして、SDKやランタイムのディレクトリを指定します。
[JavaFX SDK] にはSDKのインストールディレクトリを、[JavaFX Runtime] にはSDKのインストールディレクトリの下にある rt というディレクトリを指定します。設定途中で NPE が発生したという警告ダイアログが出ますが、ランタイムの設定を行ったら直ります。
これでNetBeans上でJavaFXプロジェクトを作成することができるようになります。
JavaFXプロジェクトを作成する際、[JavaFX Application]、[JavaFX Preloader]、[JavaFX FXML Application] の3種類から選べます。
普通は [JavaFX Application] を選びます。UIの構造定義にFXMLを使いたい場合は [JavaFX FXML Application] を選びますが、FXMLを使ったアプリケーションの雛形を作ってくれる以外、特に違いはありません。[JavaFX Preloader] はアプリケーション起動時のリソースロード中に表示するプリローダーを作成するためのプロジェクトです。
FXMLとはJavaFXのUI構造を宣言的に記述することができるマークアップ言語で、FlexのMXMLやWPFのXAMLと同じような立ち位置の技術です。解説はこことかここにあります。
早速NetBeansでこれをサポートしてくれたと喜んだのですが、残念ながらマークアップの補完とかは全然行なってくれませんでした。(;_;)
サンプルのJavaFX Ensembleがスバラシイ
サンプルには4種類のサンプルアプリケーションが収録されていますが (ブロック崩しとかもあります)、中でもJavaFX Ensembleが素晴らしいです。
Ensemble.jar を実行すると起動します。
いわゆるサンプルアプリケーション集で、SwingのSwingSetに相当するものです。サンプルアプリケーションとJavaDocが収録されており、サンプルとドキュメントを相互に行き来できるようになっていて、勉強するには最適なアプリケーションになっています。
GUIフレームワークの勉強には豊富なサンプルの存在がとても重要だと思っています。昨年の今頃、SmartClientというJavaScript製RIAフレームワークを使った開発を行なっていたのですが、こちらもSDKに付属していたサンプルが豊富で、比較的短い期間で習得できたことを憶えています。JavaFXは後発なだけに、こういった学習環境に力を入れていることはとてもいいことだと思いました。
さらにこのサンプル、ソースコードも閲覧できますが、[Save NetBeans Project...] というボタンがあり、ここからNetBeansプロジェクトを作ってくれます! サンプルを見て、自分の手でいじってみたいと思ったらすぐに試せるようになっているわけです。これはありがたいです。
まだかなりバグバグ...
さて、Mac版はまだプレビュー版なだけに、ちょっと触ってみただけでも結構バグが出てきました。まあ致し方ないですが。リリースノートでも色々載っていますが、それ以外にも次のようなのが目に付きました。
- TextFieldやTextAreaで日本語が入力できない
- TableViewでカラムのドラッグ&ドロップが効かない (さらに適当にいじっているとハングアップ...)
- RichTextEditorが重い&いじっているとハングアップ...
- WebViewはまだまだレンダリングが乱れまくり
そんな訳で、自分もこれからこのサンプルを中心にちょくちょく勉強していこうと思っています。現状業務が忙しいのでほんとにちょくちょくって感じになりますが...。
*1:ここでクライアントを無理にJavaScriptで頑張ろうとすると大変なことになるケースをしばしば見掛けたり...
JavaFXユーザグループ第5回勉強会に行ってきました
JavaFXユーザグループ第5回勉強会に参加してきました。そのメモと感想をまとめました。途中仕事場からトラブルの電話が掛かってきたので、一部聞けなかったところがありましたが...。
JavaFXの勉強会に参加するのはこれが初めてです。先日のエントリにも書きましたが、ここ最近JavaFXにはすごく注目しているので楽しみにしていました。
What's new JavaFX 2.0 by 櫻庭 (@skrb) さん
JavaFXのこれまでの経緯
JavaFXScriptをやめた理由
良くなった点
JavaFXのUIコントロール
感想
JavaFX2.0での路線変換 (JavaFX Scriptをやめる、デスクトップアプリに集中) は良くも悪くもきちんと現実を見据えて選択と集中を行った結果なんでしょうね。Oracleらしいと思います。でもJavaで手続き的にUIツリーを組み立てるのは面倒なので、UI構造の定義部分だけは宣言的な記述を残して欲しかったですが。
業務系のシステム開発ではSwingでGUIを作ることが結構あります。そこに新しくモダンな (Javaの) GUIツールキットを提供してくれるのは嬉しいです。懇親会でもちょっと話題にあがったのですが、iOS等のお陰で企業向けシステム開発においてもUIのベースラインが上がっちゃいましたからねえ。
Swingは中々良く出来たGUIツールキットだと思いますが、アニメーションやエフェクト周りが辛かったので、その辺りがJavaFXではお手軽に扱えるようになったのがいいです。
ハンズオン by 櫻庭 (@skrb) さん
ハンズオンではミニブラウザを作りました。短い時間の間でJavaScriptも動くブラウザが簡単にでき、さらに鏡面効果やページ遷移時のスライドアニメーション、ドロップシャドウといった演出も簡単に追加できちゃいました。
以下、ハンズオン時に出てきた説明のポイントをまとめておきます。
- サイズを指定する時、Swingは外枠の大きさを指定することが多いが、JavaFXは中のコントロールの大きさを指定することが多い
- AWTと同じ名前のコントロールが多いので注意!
- WebEngineはページ読み込みの非同期処理をハンドリングできるようにTaskオブジェクトを返すが、TaskクラスはDeprecatedになっている...
ハンズオン後の質疑応答では次のような話が出てきました。
- SwingとJavaFXの混在は?
- SwingにJFXPanelを貼ると、その下にシーングラフを構築することができる
- レイアウトの種類は?
- SwingのGroupLayout、SpringLayout以外はみんなカバーしている
- アプリケーションの配布方法は?
- アプレット、アプリケーション、Java Web Start
- 現在アプレットにはランタイムが必要
- アプリケーションとアプレットで書き方を変えなくてもいい
NetBeansのJavaFXサポートについて by 片貝さん
NetBeans国際化担当のOracle片貝さんから、今後のNetBeansにおけるJavaFXのサポートについてのお話をしてもらいました。ただ、現時点ではまだ余り情報がないようです。
- NetBeans7ではJavaFXComposerがなくなった
- 先日JavaFX2.0プラグイン登場
- NetBeans7.1
感想
一番知りたかったデザインツールですが、やはり現時点ではほとんど情報がないようですね...。NetBeansとは別になるそうですが。
個人的にはPhotoshopとかにプラグインして、そこでデザイナーがデザインしたものからCSS定義と画像パーツを吐き出してくれるようになれば、まずは十分なのかなあと思っています。ちなみに懇親会でもこの話をしましたが、「それだけだとプログラマとデザイナーの間でラウンドトリップできないので不十分では」という意見を櫻庭さんらから頂きました。このやり方は自分が以前関わったFlexでの開発で行ったやり方だったのですが、確かに実装が始まってからのデザイン変更は少し大変でしたね。
とまあこんな感じで、色んな情報が得られてとっても良かったです。何より懇親会 (結局終電になりましたw) でJavaでGUI作りたい、な人達と交流できたのが大きかったです。次回以降も都合が合えばぜひぜひ参加したいです。