JavaOne報告会でJavaFXについての発表&LTを行ってきました

10/19 に実施されたJavaOne 2013 サンフランシスコ報告会 Tokyoにて、JavaFXのアップデートについての発表とLTを行ってきました。

当日のJavaFXアップデートの資料は以下の通りです。

JavaOne2013報告会 JavaFX Update from Takashi Aoe

JavaOne初参加の身でありながら、例年は櫻庭さんが担当されているポジションを引き継ぐことになったので、とても緊張しました。
自分の前に寺田さん、大山さん、櫻庭さんが発表がありました。3人の発表で場が大盛り上がりした状態で自分の発表に入ったのですが、自分の発表になると雰囲気がしーんとした感じになってしまったので、「うわ、これは失敗かなあ...」とショックを受けたのですが、後から聞いた話だと結構皆さんそれなりに楽しんで聞いて頂けたようで、ほっとしています。
そうは言ってもこのような大きな場で長丁場の発表をするのにはまだまだ修行が必要だと言うことがよーく分かりました。精進します。

本編のJavaFXアップデートに続いて、LTでもお話しをしてきました。こちらはJavaOneではちょっと珍しい感じのHadoopのセッションについてです。
JavaFXの方は真面目な感じで行ったので、こちらはちょっとくだけた感じにしました。
発表資料は次の通りです。

JavaOne2013報告会 LT資料 Hadoopの話を聞いてきた from Takashi Aoe

今のところSlideShareでのページビューはLTの方がちょっと上ですね。何だかんだ言ってHadoopは注目ネタですかね。

さて、ブログの方のJavaOne報告もまだ半分ほど残っていますね。こちらも早めにアップします。(^^;;

意外に優秀なJavaFX WebViewのHTML5フォーム対応

久々のポストです。(そういやFxGlassFishMonitorの解説も1回書いただけでさぼってるなー。こちらも早くまとめねば)

今、仕事で完全に社内向けの管理用Webアプリケーションを作っているのですが、どうせ完全に内部向けなら古いブラウザなんか気にせずHTML5で追加されたフォームをばんばん使っちゃえ♪ って感じで作っています。
で、ふと、「JavaFXのWebViewはWebKitベースなんだけど対応状況はどうなんだろう?」と思って調べてみたら意外に対応状況が優秀だったことがわかりました。さすがにChromeには負けますが、Safariよりは対応が進んでいたりします。と言うわけでその点についてまとめてみます。

以下のコードを表示してみることにします。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>HTML5フォームテスト</title>
    <style>
:invalid {
  border-color: #e88;
  -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8);
  -moz-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  -o-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  -ms-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  box-shadow:0 0 5px rgba(255, 0, 0, .8);
}
    </style>
  </head>
  <body>
    <form action="" method="GET">
      <p>
        number: <input type="number" min="0" max="100" name="number">
      </p>
      <p>
        date: <input type="date" name="date">
      </p>
      <p>
        search: <input type="search" name="search">
      </p>
      <p>
        url: <input type="url" name="url">
      </p>
      <p>
        email: <input type="email" name="email">
      </p>
      <p>
        month: <input type="month" name="month">
      </p>
      <p>
        range: <input type="range" min="0" max="100" name="range">
      </p>
      <p>
        color: <input type="color" name="color">
      <p>
      <p>
        meter: <meter value="60" min="0" max="100"></meter>
      </p>
      <p>
        progress: <progress max="100">進行中だよ</progress>
      </p>
      <input type="submit" value="submit"name="submit">
    </form>
  </body>
</html>

HTML5で追加されたフォームのうち代表的なものを記述しています。invalid 疑似クラスを指定しており、指定したフォームに対して妥当でない値が入力された場合にはボーダーの色を変更するようにしています。ブラウザが対応していれば、妥当でない値を入れると色が変わるようになります。

まず、これをChrome (バージョン 28.0.1500.71) で表示すると次のようになります。

今回指定した全てのフォームに対応しています。number や date、month、range、color に対しては入力補助のコンポーネントが表示されており、url や email に対しては、妥当でない値を入れるとCSSでの指定通りにボーダーが赤くなっていることが分かります。 にもちゃんと対応していますね。
date については次のようなカレンダーピッカーを出すことができます。

Firefox (22.0) では次のように、url、email、meter、progress には対応していますが、number、date、month、range、color には対応しておらず、入力補助コンポーネントも出ません。

Safari (6.0.5) についてもMac版は意外と対応が遅れており、date、month、color が対応していません。iOS版はもう少し対応が進んでおり、date や month ではあのドラム型の入力コンポーネントが出てきます。

Opera (12.15 *1 ) は一番対応が早かったブラウザで、今回指定した全てのフォームに対応しています。

では、JavaFXではどうでしょうか。バージョン2.2のWebViewを使って表示した結果は次の通りです。

何と、search と color 以外は全て対応しているのです!number や date、month は一見対応していないように見えますが、実はフォーカスしてカーソルキーを上下すると数値や日付の値を入力できるようになっています。(画像では分からないですが)

で、この件についてTwitterでさくらばさんにさらに次のような情報をもらいました。

と言うわけでJDK8 Early Access (1.8.0-ea-b99) をダウンロードして、JavaFX8のWebViewでも見てみることにしました。
結果は次の通りです。

何とdate、month、colorでピッカーが用意されるようになりました!でも、このバージョン (8 Build b99) ではバグがあるのかクリックしても何も反応しませんでした。(´;ω;`)ブワッ
まあ、正式版が出るまでには対応されるでしょうw

ちなみにJavaFX8では DatePicker コンポーネントが追加されています。こんな感じです。

バグが直るときっとWebViewでもこんなピッカーが表示されるようになるのでしょう。

というわけでJavaFX WebViewのHTML5フォーム対応状況についてでした。

おまけ

今回、JDK8でJavaFXアプリを作るためにNetBeans7.4betaをダウンロードして使ってみたのですが、NetBeans7.4ではMavenベースのJavaFXプロジェクトを作れるようになっていました。これはうれしい!

(追記)
さすがにIEの結果がないのはちょっとあれだと思ったので、VMを立ち上げてWin8上のIE10での結果も撮って追加しました。

IE10は number、url、email、range、progress に対応していました。ただし number は妥当性検証のみで入力補助はありません。range の表示がWin8らしいですね。

*1:Blinkになる前のバージョンです

JavaFX2.2でダイアログを作る方法

はじめに

TwitterJavaFX関連の話になったときにしばしば見かけるのが、「ダイアログ表示できないの?」というコメントです。
JavaFXにはOSレベルでのウィンドウを作成するための Stage クラスがあり (Swingの JFrame 相当のクラスです) 、これを使えばダイアログの作成は可能です。
でも、Swingの JOptionPane に相当するユーティリティクラスは残念ながらありません。
次のバージョンに当たるJavaFX8ではSandboxプロジェクトで開発されていたのですが、いつの間にやら ControlsFX というオープンソースプロジェクトに独立していました。これもJavaFX8にならないと使えません。

と言うわけでJavaFX2ではダイアログを表示するためには自分で実装する必要があるのですが、一度やり方を覚えてしまえばまあそんなに面倒でもないです。
また、現在ベータ版の Scene Builder1.1 ではダイアログを作成するためのひな形が用意されていたりします。
ここではScene Builderのひな形を使ってダイアログを作成する方法についてまとめてみます。

今回作ってみるダイアログ

今回は懐かしのSwingSet2にあったダイアログを作ってみましょう。以下に示すものです。

Yesと答えると「コンピュータの前にいないで外へ出ろ」と説教されるやつですw
YesとNoについてはそれぞれ新たなメッセージダイアログが次に開き、Cancelが選ばれたら何も表示せずにそのまま閉じます。
Yesがデフォルトボタンに設定されていて、キーボードでEnterを押すとYesが選択されます。また、Escを押すとキャンセル扱いになり、そのまま閉じます。

Scene Builderでダイアログのデザインを作る

ではJavaFXでこれを作ってみましょう。
先にも述べたように、Scene Builder1.1 にはダイアログのひな形が用意されています*1。メニューから [ファイル] - [テンプレートから新規作成] - [アラートダイアログ] を選択します。

すると次のようにダイアログのひな形になるFXMLが生成されます。

ちなみにメニューのスクリーンショットを見てお気づきになったかと思いますが、CSSやリソースバンドルを一緒に生成してくれるメニューもあります。
これをベースに自分の好みに合わせてちょいちょいといじっていけばいいわけです。今回は次のように仕上げました。

具体的に行った変更点は次の通りです。

  • ImageView部分に60×60の画像を設定。
    • 今回はCacooを使って自作しました。
  • 文章だけを表示したいので、太字のタイトルラベルを削除。
  • Yesボタンをデフォルトボタンに設定。
    • プロパティの [Default Button] にチェックを入れます。こうすると、Enterキーを押されたときに選択されるボタンに設定されます。
  • Cancelボタンをキャンセルボタンに設定。
    • プロパティの [Cancel Button] にチェックを入れます。こうすると、Escキーを押されたときに選択されるボタンに設定されます。

FXMLは次のようになりました。

<GridPane hgap="14.0" maxHeight="+Infinity" maxWidth="+Infinity" minHeight="-Infinity" minWidth="-Infinity" vgap="20.0" xmlns:fx="http://javafx.com/fxml" fx:controller="aoetk.dialogsample.ConfirmDialogController">
  <children>
    <ImageView fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0" GridPane.valignment="TOP">
      <image>
        <Image url="@confirm.png" />
        <!-- place holder -->
      </image>
    </ImageView>
    <VBox alignment="CENTER_LEFT" maxHeight="+Infinity" maxWidth="+Infinity" minHeight="-Infinity" prefWidth="400.0" spacing="7.0" GridPane.columnIndex="1" GridPane.rowIndex="0" GridPane.valignment="CENTER">
      <children>
        <Label fx:id="detailsLabel" text="message" textAlignment="LEFT" wrapText="true">
          <font>
            <Font name="HGPGothicE" size="13.0" />
          </font>
        </Label>
      </children>
    </VBox>
    <HBox maxHeight="-Infinity" maxWidth="+Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="300.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
      <children>
        <HBox id="HBox" alignment="CENTER">
          <children>
            <Button id="btnCancel" cancelButton="true" mnemonicParsing="false" onAction="#handleBtnCancelAction" text="Cancel" HBox.hgrow="NEVER">
              <HBox.margin>
                <Insets right="14.0" />
              </HBox.margin>
            </Button>
          </children>
          <HBox.margin>
            <Insets />
          </HBox.margin>
        </HBox>
        <Pane maxWidth="+Infinity" HBox.hgrow="ALWAYS" />
        <Button id="btnNo" cancelButton="false" minWidth="80.0" mnemonicParsing="false" onAction="#handleBtnNoAction" text="No" HBox.hgrow="NEVER">
          <HBox.margin>
            <Insets />
          </HBox.margin>
        </Button>
        <HBox id="HBox" alignment="CENTER">
          <children>
            <Button id="btnYes" defaultButton="true" minWidth="80.0" mnemonicParsing="false" onAction="#handleBtnYesAction" text="Yes" HBox.hgrow="NEVER">
              <HBox.margin>
                <Insets left="14.0" />
              </HBox.margin>
            </Button>
          </children>
        </HBox>
      </children>
    </HBox>
  </children>
  <columnConstraints>
    <ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity" />
    <ColumnConstraints halignment="CENTER" hgrow="ALWAYS" maxWidth="+Infinity" minWidth="-Infinity" />
  </columnConstraints>
  <padding>
    <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
  </padding>
  <rowConstraints>
    <RowConstraints maxHeight="+Infinity" minHeight="-Infinity" valignment="CENTER" vgrow="ALWAYS" />
    <RowConstraints maxHeight="-Infinity" minHeight="-Infinity" vgrow="NEVER" />
  </rowConstraints>
</GridPane>

同じようにして、メッセージダイアログのデザインも作成します。

Javaコード側の実装

さて、お次はJavaコード側の実装です。まずは先ほど作ったダイアログのFXMLに対してコントローラーを作ります。

public class ConfirmDialogController implements Initializable {
    @FXML
    private Label detailsLabel;
    private DialogOption selectedOption = DialogOption.CANCEL;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }

    public DialogOption getSelectedOption() {
        return selectedOption;
    }

    public void setMessage(String msg) {
        detailsLabel.setText(msg);
    }

    @FXML
    void handleBtnYesAction(ActionEvent event) {
        handleCloseAction(DialogOption.YES);
    }

    @FXML
    void handleBtnNoAction(ActionEvent event) {
        handleCloseAction(DialogOption.NO);
    }

    @FXML
    void handleBtnCancelAction(ActionEvent event) {
        handleCloseAction(DialogOption.CANCEL);
    }

    private void handleCloseAction(DialogOption selectedOption) {
        this.selectedOption = selectedOption;
        getWindow().hide();
    }

    private Window getWindow() {
        return detailsLabel.getScene().getWindow();
    }
}

注目するのは各ボタンに割り当てられたハンドラメソッド (handleBtnYesAction、handleBtnNoAction、handleCancelYesAction) です。
選択結果を自身のプロパティに保存した後に、ダイアログ上のコンポーネントから Scene 、Window をたどって、自身のウィンドウを隠しています (handleCloseAction メソッド) 。
また、ダイアログに表示するメッセージはコントローラーが受け取るようにしています。
メッセージダイアログのコントローラーについても大体これと同じような実装になっています。

続いてダイアログを開く側のコードです。

    @FXML
    private void handleButtonAction(ActionEvent event) {
        try {
            // 確認ダイアログの表示
            FXMLLoader loader = new FXMLLoader(getClass().getResource("ConfirmDialog.fxml"));
            loader.load();
            Parent root = loader.getRoot();
            ConfirmDialogController controller = loader.getController();
            controller.setMessage("今日の外の天気は晴れですか?");
            Scene scene = new Scene(root);
            Stage confirmDialog = new Stage(StageStyle.UTILITY);
            confirmDialog.setScene(scene);
            confirmDialog.initOwner(button.getScene().getWindow());
            confirmDialog.initModality(Modality.WINDOW_MODAL);
            confirmDialog.setResizable(false);
            confirmDialog.setTitle("Select an Option");
            confirmDialog.showAndWait(); // ダイアログが閉じるまでブロックされる

            // 確認ダイアログの選択結果に応じたメッセージダイアログの表示
            switch (controller.getSelectedOption()) {
            case YES:
                showMessageDialog("コンピュータで遊んでないで外に出よう。\nビーチに行って太陽の日を浴びたらどうでしょう。");
                break;
            case NO:
                showMessageDialog("屋内にいて様々なものから保護されているのはいいことです。");
                break;
            }

        } catch (IOException ex) {
            Logger.getLogger(DialogSampleViewController.class.getName()).
                    log(Level.SEVERE, "読み込み失敗", ex);
        }
    }

FXMLLoader を使って、確認ダイアログのFXMLを読み込んでいます。
このコード例で示しているように、FXMLLoader からコントローラーのインスタンスを取得することが可能で、表示したいメッセージを渡していますね。
注目してもらいたいのは Stage のインスタンスを生成している部分です。

            Stage confirmDialog = new Stage(StageStyle.UTILITY);
            confirmDialog.setScene(scene);
            confirmDialog.initOwner(button.getScene().getWindow());
            confirmDialog.initModality(Modality.WINDOW_MODAL);
            confirmDialog.setResizable(false);
            confirmDialog.setTitle("Select an Option");
            confirmDialog.showAndWait(); // ダイアログが閉じるまでブロックされる

StageStyle.UTILITY を渡してインスタンスを生成していますが、これはウィンドウの装飾を最小限にするというオプションです。つまり、ウィンドウを閉じるボタンしか表示されません。*2
また、initOwner メソッドを使って、親ウィンドウのインスタンスを渡しておき、さらに initModality メソッドModality.WINDOW_MODAL を渡す事で、親ウィンドウに対してモーダルになるように設定しています。
そして、Stage#showAndWait メソッドを使ってダイアログウィンドウを表示しますが、このメソッドはウィンドウが閉じられるまでスレッドをブロックします。

従って、showAndWait 呼び出しの後はダイアログが閉じられた状態になっているので、次のように確認ダイアログコントローラーが保持している選択肢を取得して、次のメッセージダイアログに表示するメッセージを決めて、ダイアログを表示しています。

            switch (controller.getSelectedOption()) {
            case YES:
                showMessageDialog("コンピュータで遊んでないで外に出よう。\nビーチに行って太陽の日を浴びたらどうでしょう。");
                break;
            case NO:
                showMessageDialog("屋内にいて様々なものから保護されているのはいいことです。");
                break;
            }

showMessageDialog メソッドについてはもう説明するまでもないでしょう。(最後に全コードをアップしたgistのURLを示します)

このコードを実行すると次のように動きます。

とまあこんなところです。一度やり方を覚えてしまえばまあそんなに手間でもないでしょう。たぶん...きっと...。
JavaFX8、Java8に先駆けて先行リリースされないかなあ。

全コードはgistにアップしています。ご参照ください。(画像は自分で用意してくださいね)
https://gist.github.com/aoetk/5652577

*1:Scene Builderで表示されるダイアログもこのひな形を使って作っているようです。

*2:ちなみに StageStyle.UNDECORATED にすると、ウィンドウのボタンが一切表示されなくなります。ダイアログにはこっちの方がいいかも知れません。(Macのダイアログはそのようになっていますね)

FX GlassFish Monitorの解説 (見映え編)

Java The Nightのデモでお見せしたFX GlassFish Monitorの作りについての解説です。まずは反響が大きかった見映えのところから説明したいと思います。

一番目に付いたのはウィンドウ枠だと思います。OSのウィンドウ枠は全く見えず、周囲が何か光っていますね。
JavaFXではコンポーネントにドロップシャドウエフェクトを追加することができ、今回もそれを利用しているのですが、OSのウィンドウ枠に相当する Stage クラスには適用することはできません。

そこで次のような方法で実現しました。

  • Stage 及び Scene は透明にする。
  • その上に、ドロップシャドウエフェクトを効かせた Rectangle を貼り付ける。
    • この Rectangle の大きさは Scene よりシャドウの幅の分だけ小さくする。
  • その上にレイアウトコンテナ (BorderPaneAnchorPane) を貼り付ける。

図示するとこんな感じです。

メインウィンドウ (監視項目のツリーが並ぶウィンドウ) について、Stage の上に Scene を組み立てている部分のJavaコードと、FXML のコードを示しておきます。

    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("view/MainView.fxml"));
        loader.load();
        Parent root = loader.getRoot();
        MainViewController controller = loader.getController();
        controller.setParentStage(stage);
        Scene scene = new Scene(root, 924, 700, Color.TRANSPARENT);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setScene(scene);
        stage.show();
    }
<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="924.0" xmlns:fx="http://javafx.com/fxml" fx:controller="aoetk.fxglassfishmonitor.view.MainViewController">
  <children>
    <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#1e90ff00" height="690.0" stroke="$x1" strokeType="INSIDE" width="914.0">
      <effect>
        <DropShadow blurType="GAUSSIAN" spread="0.7">
          <color>
            <Color blue="0.878" green="1.000" red="0.000" fx:id="x1" />
          </color>
        </DropShadow>
      </effect>
    </Rectangle>
    <BorderPane fx:id="containerPane" onMouseDragged="#handleMouseDragged" onMousePressed="#handleMousePressed" prefHeight="200.0" prefWidth="200.0" styleClass="container">
      <center>
        <ScrollPane prefHeight="200.0" prefWidth="200.0">
          <content>
            <Pane fx:id="drawRegion" prefHeight="200.0" prefWidth="200.0" />
          </content>
        </ScrollPane>
      </center>
      <top>
        <HBox fx:id="boxTitle" prefHeight="50.0" prefWidth="200.0">
          <children>
            <Text fill="$x1" fontSmoothingType="LCD" stroke="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="FX GlassFish Monitor" HBox.hgrow="NEVER">
              <font>
                <Font name="System Bold Italic" size="28.0" />
              </font>
            </Text>
            <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
            <Button fx:id="btnExit" mnemonicParsing="false" onAction="#handleBtnExitAction" styleClass="close-button" text="Exit" HBox.hgrow="NEVER" />
          </children>
          <padding>
            <Insets bottom="20.0" left="10.0" right="10.0" top="10.0" />
          </padding>
        </HBox>
      </top>
      <StackPane.margin>
        <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
      </StackPane.margin>
    </BorderPane>
  </children>
  <stylesheets>
    <URL value="@../asset/style.css" />
  </stylesheets>
</StackPane>

Rectangle とレイアウトコンテナ (BorderPane) の貼り合わせには StackPaneを使っています。
StackPane にマージンを指定していて、その上に置いたコンテンツがドロップシャドウの幅の分だけ隙間を空けるようにしています。

BorderPane の onMousePressed と onMouseDragged にイベントハンドラを設定しています。これは Stage を透明にしたために、そのままではウィンドウ枠が消えてウィンドウの移動ができなくなるため、自分でドラッグ移動のイベントを実装しているのです。

スタイルシートはこんな感じです。

.root {
    -fx-base: #212020;
}

.container {
    -fx-background-color: rgba(0, 0, 0, 0.7);
}

.close-button {
    -fx-border-color: white;
    -fx-border-width: 2px;
    -fx-border-radius: 5px;
    -fx-background-color: transparent;
    -fx-text-fill: white;
    -fx-font-size: 16px;
    -fx-cursor: hand;
}

container クラスがレイアウトコンテナに適用するもので、色を黒で透明度を 70% に設定しているだけです。
close-button クラスはExitボタンに適用したスタイルで、背景を透明にしてあのような見た目にしているのが分かりますね。

と言うわけで見映えについての解説でした。大して手数を掛けずに実現可能だと言うことが分かりますね。

コード全体についてはもう少し整理してからGithubのURLを公開する予定です。もうしばらくお待ちを。

おまけ

解説に使った図はScene Bulderを使って描きました。が、やっぱりお絵かきにはまだまだ機能不足ですね。Rectangle を平行四辺形に変形する部分は直接FXMLを手打ちしました...。

Java Day Tokyoに参加&発表してきました

5/14 (火) に開催されたJava Day Tokyoに参加し、さらにその中のセッションの1つである、Java The Nightに登壇しました。
まさかこんな大きなイベントで自分が発表する側に立つことになるとは思わず、とても緊張しましたが良い経験になりました。
このエントリではイベントの感想についてまとめたいと思います。

Java The Nightでの発表について

Java The Nightで自分は「監視ツールでみるJavaFXJava EEの魅力」と題して発表しました。セッション資料はSlideShareにアップしています。

Java Day Tokyo 2013 Java the Night 監視ツールでみるJavaFXとJava EEの魅力 from Takashi Aoe

登壇することになった経緯ですが、Oracle寺田さんからTwitterのダイレクトメッセージで突如お願いされましたw
寺田さんからの要望は、「デモの際におもしろ、おかしく、やっていただくことはできますでしょうか。」でした。
随分ハードル高いなあと思いつつも、折角の機会なので登壇させて頂くことになりました。

発表の内容としては、JavaFXで作ったGlassFishの監視アプリケーションのデモを通して、自分がJavaFXJava EEの魅力と思っている点について伝えるというものでした。
インパクト重視という要望だったので、JavaFXで作るアプリは派手めな、中二病っぽい感じの路線で行くことにしました。

JavaFXについてここで伝えたかったことは、プログラムを使って何かやりたいタスクがあったときに、JavaならばJavaFXが加わったことで、このように綺麗なGUIで成果をアウトプットできるようになるということです。
CUIもいいけど、GUIでやると楽しいですよ。
このアプリケーションのルックスについては予想以上に反響があったようですが、実はそんなに手数を掛けなくてもこのような見た目にすることが可能です。この点については後ほど別エントリで解説します。

Java EEについては、運用フェーズにおける監視という側面からの利点を伝えようとしました。Java EE APサーバーはいずれもサーバー上で稼働するサービス、アプリケーションに対して豊富な監視オプションを提供しています。
Webアプリケーションフレームワークはともすると開発の側面ばかりに目が行きがちですが、ソフトウェアのライフサイクル全体で考えると運用も重要です。その点も考慮して選択を考えてもらったらと思います。

各セッションについての感想

それでは自分が参加した各セッションについて軽く感想を書いていきます。

基調講演

基調講演ではJava SE、Java FX/Embedded、Java EE、コミュニティについて、それぞれのOracleのキーパーソンから現状と今後の展望について説明するというものでした。
特に自分の印象に残ったのが、OracleがM2Mを重視しているように見えたことです。今後は様々なデバイスがネットワークでつながるようになるため、確かに次にソフトウェア開発の分野でホットになるのはここかも知れません。そして恐らくこの分野でもライバルになるのはAndroidでしょうね...。

Raspberry Pi NightHacking

Pro JavaFX 2の著者の一人であるStephen Chinさんによる、Raspberry Pi上でのJavaFXアプリケーションの実行についてのセッションでした。
目の前でJavaFXアプリケーションを構築して、それをRaspberry Piに移植動かすところまでを見せてもらいました。
驚いたのは、本当にそのままのJavaFXアプリケーションが動いているということです。エフェクトとかも普通に動いていました。質問したところ、動かないのはWebViewとMediaViewだけとのことです。
Raspberry Pi向けのJava SEのプロファイルは結構小さいのですが、それでもJavaFXアプリケーションがここまで動くというのには色んな可能性を感じさせてもらいました。

Java IDE の最新トレンド

EclipseNetBeansIntelliJ IDEAというJava界三大IDEについて、Eclipse派代表として竹添さん、NetBeans派代表としてきしださん、IntelliJ派代表として今井さんが語り合うというとても楽しいセッションです。
モデレータの山本裕介さんがIntelliJユーザーと言うこともあり、ややIntelliJにバイアスが掛かっていたような気がしましたが。(^^;;
スライドが三者三様でこちらもそれぞれの個性が出ていて面白かったです。竹添さんはきっちりPowerPointで、今井さんはrstテキストで、そしてきしださんは安定の手書き資料w
なお、自分は基本的にNetBeans派ですが、IntelliJもちょこちょこ触りますし *1 、もちろん仕事の必要上Eclipseも結構触ります。
ディスカッションで自分の印象に残ったのは以下の点です。

  • Eclispeは確かにセッティングが面倒だけど、Eclipseが出たての頃はみんなその作業をとても楽しんでいた。
    • 確かに自分もEclipseが登場したての頃は、とてもわくわくしながら拡張を楽しんでいたのを覚えています。
  • InteillJはJava、Groovy、Scalaを1つのプロジェクトに混在させて開発できる。
  • NetBeansはJenkins連携ができる。ただしメニュー名は "Hudson" だけどw
  • (テキストエディタ派の人に向けて) IDEの利点は「IDEが良い書き方を教えてくれる」ところにありますよ。
Groovy, Clojure, Scala, VisageでのJavaFX活用

こちらもStephen Chinさんによるセッションです。Groovy、ClojureScalaVisage *2JRubyでのJavaFXのサポート状況について順に説明してもらいました。
ちなみにChinさんはScalaFXVisageのコミッタをされています。
JavaFXのサンプルアプリケーションとしてよく使われる、Vanishing Circleを例に、他の言語で実装した例を見せてもらいました。

特に自分がいいなと思ったのがGroovyFXです。@FXBindableアノテーションを付けることで、JavaFX形式のプロパティを生成してくれるのはとても嬉しい!
自分の以前のエントリでも解説しましたが、JavaFX形式のプロパティの記述はちょっと面倒なのです。
ScalaFXもとてもScalaらしいアプローチでDSLを設計していて、こちらも好感が持てました。
VisageJavaFX Script時代から言語仕様が強化されているのですね。

なお、Chinさんは日本の漫画やアニメが相当好きなようで、各言語についてアニメに例えてらっしゃいました。以下の通りですが自分のよく知らないモノもあるw

タブレット用の JavaFX アプリケーション開発

JavaFXエヴァンジェリストであり、Pro JavaFX2の著者の一人である、Jim Weaverさん *3 による、JavaFXのマルチタッチ関連APIの解説と、タブレット向けアプリケーションを作る上での注意点について説明するというものでした。
タブレットのターゲットはWindows8でした。実際にSurface Proを操作しながら解説していました。

マルチタッチ関連APIの解説の内容は自分が先日JavaFX勉強会で行ったものとほぼ同内容でしたw
タブレット向けアプリケーションを開発する上での注意点は、やはりコントロールの大きさでした。そのためにデザインにはなるべくCSSを活用し、まずはrootクラスのフォントを32px程度にするのが良いとのことでした。

結構説明が早く終わってしまったので、質問がいっぱい出ていました。自分は高解像度端末におけるスケーリングの対応について聞いたのですが、現時点では端末に合わせて自分でサイズを調整するしかないようです。でも、後で気付いたのですが、確かJavaFX8で導入されるModenaテーマはスケーリングの変化に対応していたような?

Java The Night

最後は自分も登壇したJava The Nightです。みなさん実に色んな持ちネタを披露してもらって、とても楽しめました。
驚いたのはほとんどの人がJavaFXを使っていたことです!自分が考えている以上にJavaFXJava開発者の間で認知度を上げているのかも知れません。

最後に寺田さんから発表されたJava7のAPIドキュメント日本語化のニュースは驚きました。Oracle本体を説得して日本語化にこぎつけた日本Oracleの皆様方には感謝です!


このように、聴講、発表共にとても楽しい一日を過ごすことができました。このような素晴らしい場を提供して頂いた日本Oracleの皆様には厚く御礼申し上げます。ありがとうございました。

*1:特にJavaFXサポートが入ってからは、JavaFXサポート機能がなかなか強力なので結構触るようになりました。

*2:OracleディスコンにしてしまったJavaFX Scriptオープンソース化したものです

*3:ちなみに先日のJJUG CCCでは櫻庭さんのお誘いで、Jimさんとお昼ご飯を食べに行きました。