「*[JavaFX]」の検索結果を表示しています
2014-12-19 08:41

JavaFX の WebView に文字列検索機能を付けてみる

このエントリは JavaFX Advent Calendar 2014 の 19 日目のエントリです。前日は id:yumix_h さんによる、「WebView(JavaFX)のズーム機能を使ってみました」でした。

はじめに

JavaFX には Web ブラウザコンポーネントである WebView が付いているのは皆さんよくご存じかと思います。
DOM へのアクセス、JavaScript 実行、ヒストリ情報へのアクセス、JavaScript イベントのフック、など様々な機能が提供されており、他の GUI ツールキットが提供するブラウザコンポーネントと比較しても遜色がないと思っています。

ただ、残念なことに WebView 上に表示されているコンテンツに対してテキスト検索を行うための API が用意されていないんですよね。
もちろん表示されているコンテンツの DOM にアクセス可能なので、その DOM を頑張ってパースするという手もあるのですが、中々辛い。

というわけで、既存の JavaScript ライブラリを使って手っ取り早く実装する方法を考えてみました。

作ってみたもの

次の図のように、WebView を使ったブラウザアプリケーションに検索ボックスを取り付け、検索ボックスに文字列を入力するとマッチする部分をハイライトするようにしました。
f:id:aoe-tk:20141206191340p:image
マッチした部分をハイライトするだけで、ハイライトした箇所にスクロールする機能はありません。

ちなみに、このスクリーンショットは、自分が作った Social Bookmark Viewer FX という、Diigo というソーシャルブックマークサービスのビューアアプリケーションの一部です。 *1

利用した JavaScript ライブラリ

この機能を実現するために次のライブラリを利用してみました。

JavaScript text higlighting jQuery plugin
http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

jQueryプラグインとして提供されているライブラリです。
使い方としては、予め以下の CSS クラスを定義しておき、

.highlight { background-color: yellow }

あとは次のようにこのプラグインjQuery オブジェクトに生える highlight() メソッドを、ハイライトしたい文字列を引数に渡して呼べば OK です。

$('body').highlight('foo');

WebView に検索機能を追加する

それではこれを WebView で使えるようにします。まず、WebView 上のドキュメントのロードに成功したら、jQuery 及び上で紹介した検索ライブラリをドキュメントに追加します。

final WebEngine webEngine = webView.getEngine();
final Worker<Void> loadWorker = webEngine.getLoadWorker();
loadWorker.stateProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue == Worker.State.SUCCEEDED) {
        // 読み込みが成功した場合、検索用プラグインを読み込む
        Optional.ofNullable(webEngine.getDocument()).ifPresent(document -> {
            addScriptElement(document, "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"); // (1)
            addScriptElement(document, "http://johannburkard.de/resources/Johann/jquery.highlight-4.closure.js"); // (2)
            addStyleElement(document, ".highlight { background-color: yellow; }"); // (3)
        });
    }
});

WebEngine の読み込み状態を観察し、成功した場合にのみ検索用プラグインを読み込むようにしています。
(1) で jQuery を、(2) で検索ライブラリを、(3) で検索ライブラリが要求するスタイルクラスを DOM に追加しています。
JavaScript ライブラリはどちらもネットワークから直接読み込んでいます。

addScriptElement() メソッド及び addStyleElement() の実装は次のようになっています。

private void addScriptElement(Document document, String url) {
    final Element scriptElm = document.createElement("script");
    scriptElm.setAttribute("type", "text/javascript");
    scriptElm.setAttribute("src", url);
    NodeList bodys = document.getElementsByTagName("body");
    if (bodys != null && bodys.getLength() > 0) {
        bodys.item(0).appendChild(scriptElm);
    }
}

private void addStyleElement(Document document, String styleContent) {
    final Element styleElm = document.createElement("style");
    styleElm.setAttribute("type", "text/css");
    styleElm.setTextContent(styleContent);
    NodeList bodys = document.getElementsByTagName("body");
    if (bodys != null && bodys.getLength() > 0) {
        bodys.item(0).appendChild(styleElm);
    }
}

普通に DOM API を用いて、script 要素や style 要素を作ってドキュメントに追加しているのが分かりますね。

続いて検索テキストボックスに入力があったら、ハイライトする処理です。

final TextField pageSearchBox = new TextField();
pageSearchBox.textProperty().addListener(
        (observable, oldValue, newValue) -> highlightpage(Optional.ofNullable(newValue)));

TextField の text プロパティの変化時に highlightpage() メソッドを呼び出しています。
highlightpage() メソッドの実装は次のようになっています。

private void highlightpage(Optional<String> word) {
    Optional.ofNullable(webEngine.getDocument()).ifPresent(document -> {
        final String keyword = word.orElse("");
        webEngine.executeScript("$('body').removeHighlight()");
        if (!keyword.isEmpty()) {
            webEngine.executeScript("$('body').removeHighlight().highlight('" + keyword + "')");
        }
    });
}

WebEngine#executeScript() メソッドを使って、ハイライトを行う JavaScript ライブラリのメソッドをコールしています。

実装は以上です。これで上のスクリーンショットのような機能を実現できます。
JavaScript ライブラリの手助けで割と簡単にできましたね。これも JavaFX の WebView/WebEngine が DOM へのアクセスや JavaScript の実行を行える仕組みを提供してくれているからです。
ただし、この方法だと script 要素を追加して余計な JavaScript ライブラリを読み込ませたり、新たなスタイル定義を追加したりしているので、元々コンテンツがロードしている JavaScript コードやスタイル定義とバッティングする危険性があることに注意してください。 *2
重要度の高いアプリケーションでは JavaScript のスコープなどをより慎重に設計する必要があります。

明日は id:kikutaro777 さんの予定です。

*1:そのうちこれ自身の紹介エントリも書きたいと思っています。

*2:実際いくつかのサイトで不具合を起こしているのを確認しました

2014-06-09 00:28

JavaFXで丸型ボタンを作ってみる (FXML + CSS + ベクター画像縛り)

はじめに

VAIO Tap 11 を購入したこともあり、Windows8 をよく使うようになったわけですが、Windows8 の Store App を使っていると、次のようなタッチでの利用を意識した丸型で大きめのボタンをよく見かけるようになりました。
f:id:aoe-tk:20140608231311p:image

で、これと同じようなものを JavaFX でも作ってみようとしました。その際に次のような条件を課すことにしました。

以下、手順について順に示していきます。

ボタンの作成

まず、ボタンの外形については CSS を使えば簡単に円形にすることができます。
またアイコンについては、JavaFX の Button クラスには graphic プロパティというものがあり、このプロパティに任意の Node を設定することでボタンに画像を表示できるようになります。

というわけでまずは CSS の準備です。ボタンに適用するクラスを作成します。

.circle-button {
    -fx-pref-width: 4.0em;
    -fx-pref-height: 4.0em;
    -fx-background-radius: 2.0em;
    -fx-background-color: null;
    -fx-border-radius: 2.0em;
    -fx-border-color: black;
    -fx-border-width: 2.0px;
}

ポイントは次の通り。

さらにマウスオーバー、クリック、無効化の状態に対応するため、hover、pressed、disabled 疑似クラスのスタイルも設定します。

.circle-button:disabled {
    -fx-border-color: rgb(0, 0, 0, 0.7);
}
.circle-button:hover {
    -fx-background-color: #dcdcdc;
}
.circle-button:pressed {
    -fx-background-color: black;
    -fx-border-color: white;
}

無効化の場合は半透明にし、マウスオーバーの場合はうっすらと背景に色をつけるようにしています。クリックされた時には色を反転させています。

このクラスをボタンに適用することで次のような見た目のボタンになります。
f:id:aoe-tk:20140608235227p:image

アイコンの作成

続いてアイコンに使うベクター画像についてです。JavaFXjavafx.scene.shape パッケージにある各種クラスを利用することでベクター画像を作ることができます。

ですが、凝った画像を Java コードや FXML コードでごりごり書きたくないですよね。 *1
できれば IllustratorInkscape などのベクターグラフィックツールで作成した画像を使ったり、あるいは ネット上でフリーで配布されている素材とかを使いたいところです。

実は JavaFXSVG 形式のパスを取り扱うことができます。先ほど言及した javafx.scene.shape パッケージには SVGPath というクラスがあります。
また、CSS でも Region クラス (Control や Pane などのスーパークラス) には -fx-shape というプロパティがあり、SVG のパス文字列を指定することができます。

以上を踏まえて Scene Builder を使ってベクター形式のアイコン画像を準備する手順について示します。

まず、使いたい SVG 画像をテキストエディタで開き、そのパス文字列をコピーします。
f:id:aoe-tk:20140609001839p:image
Scene Builder で SVGPath オブジェクトを追加し、その Content プロパティに先ほどコピーしたパス文字列を貼り付けます。すると表示がそのアイコンに変わるはずです。
f:id:aoe-tk:20140609001857p:image

ボタンにアイコンを設定する

それではボタンに対して準備した画像を設定します。
FXML 上で Button オブジェクトの graphic プロパティに対して先ほど用意した SVGPath オブジェクトを次のように設定すれば OK です。

<Button layoutX="162.0" layoutY="51.0" mnemonicParsing="false" styleClass="circle-button">
   <graphic>
      <SVGPath content="M10,16 10,0 0,8z" styleClass="button-icon-shape" />
   </graphic>
</Button>

これを Scene Builder 上で簡単に行う方法があります。次のように、Hierarchy ビューで Button に対して Shape オブジェクト (ここでは SVGPath オブジェクト) をドラッグアンドドロップすることができ、こうすると、Buttton の graphic プロパティにその Shape オブジェクトが設定されるようになります。
f:id:aoe-tk:20140609001733p:image

ちなみに CSS では Button クラス (正確には基底クラスの Labeled クラス) に -fx-graphic というプロパティがありますが、このプロパティには URI しか指定できないため、ビットマップ画像のパスを指定するしかありません。

アイコン画像もマウスクリックに反応させて色を変えるようにする

これで大体できあがりなのですが、先ほどボタンの疑似クラス設定で、マウスクリック時に色を反転させるように設定したことを覚えているでしょうか?
アイコン画像についてもそれに追随させて色を反転させることを考えます。

ここは CSS の機能を利用して実現します。次のように子孫セレクタを使って、クリックされたボタンの子孫に当たる SVGPath に対して、色を反転させる設定が適用されるようにしています。

.circle-button:pressed SVGPath {
    -fx-fill: white;
}

できあがりの例

こんな感じで JavaFX で Windows Store App にあるような丸型ボタンを作ることができました。
以下に完成例のスクリーンショットを載せておきます (アイコンの画像は このサイト で配布されているものを使わせてもらいました) 。
f:id:aoe-tk:20140609001701p:image
この作成例のソースコードは gist にアップしてあります。
https://gist.github.com/aoetk/b5b9a03e1033057224aa

*1:Scene Builder がもうちょっとお絵かきツールとしての機能も強化してくれるといいのですが...。

2014-03-31 00:14

JavaFXのWindows環境におけるHiDPI対応について調べたことのメモ

先日のVAIO Tap 11レポートのエントリで、こんなことを書いていました。

ただ、高 DPI スケーリングに対応していないアプリケーションが多いことが分かりました。
(中略)
NetBeans はデフォルトだとコンソールの文字が豆粒のようになってしまい、とても悲しかったです (タスクバーの大きさに対するコンソールの文字の大きさに着目) 。

そのうち JavaFX で高 DPI に対応するにはどうすればいいか、調べてみるつもりです。

というでちょっと調べてみましたが、まだいい対応策が見つかっていないので、以下に現在分かっている点だけをとりあえず列挙します。

というわけで現状 Windows 環境では HiDPI に対応したアプリケーションを作るのは容易ではない感じです。
一番やりやすいワークアラウンドは、CSS のピクセル指定部分をテンプレート化しておいて、まとめて置き換える方法ですかね。もしかしたら単位に em を使えばいいのかな?

とにもかくにも JavaFX が Windows でも Device Independent Pixel (DIP) に対応してくれるのが一番なんですけどねえ。
JIRA にもこのようなチケットが上がっていますが、Windows の世界でも高解像度端末が増えてきていますし、早く対処してもらいたいところです。

現在分かっていることはこんなところです。もう少し調べて何か分かったらまたエントリをアップします。

2013-12-07 00:55

ListViewやTableViewのセルをカスタマイズする方法 (JavaFX Advent Calendar2013 7日目)

このエントリは JavaFX Advent Calendar 2013 の 7 日目のエントリです。前日は蓮沼 (@) さんによる、「e(fx)clipseで作るJavaFXアプリケーション」でした。

はじめに

Twitter やブログなどで JavaFX に関するエントリを見ていると、ListViewTableView のセルの表示をカスタマイズする方法がよく分からずに苦戦している人をよく見かけます。
このようなリスト系コンポーネントの表示をカスタマイズする方法は、実はどの GUI ツールキットでも大体やり方が似ているのですが、HTML を使った UI の開発ばかりをやっている人には馴染みがないかも知れません。
そこで、少し地味ではありますがこの方法について解説します。また、セルのカスタマイズをする際には性能面で注意が必要なポイントがあるので、それについても触れたいと思います。
なお、ListView も TableView も基本的には同じような方法でセルのカスタマイズが行えるので、以降の説明は ListView に絞って行います。

ListView の仕組み

リストのセルの表示をカスタマイズする方法を理解するためには、まずは ListView の仕組みを知っておいた方がいいと思うので、まずはそこから説明します。
まずは次のようなシンプルなリストを見てみましょう。

f:id:aoe-tk:20131202010914p:image

このリストは 500 件のアイテムを表示しています。大量にアイテムがあるので、大半が隠れていて、スクロールを行う必要があります。
一見すると隠れている領域にもセルのインスタンスがあるかのように思えますね。
ところが、シーングラフの状態を確認することができる、Scenic View を使って見てみると...。

f:id:aoe-tk:20131202010950p:image

なんと表示されている範囲のインスタンスしか生成されていないのです! (ListCell インスタンスの数に注目してください)
ListView はこのように表示されている範囲のセルのインスタンスだけを作り、スクロールが発生するとセルの表示をスクロール位置に対応したデータに合わせて切り替えることで、あたかも隠れた範囲から新しいセルが入ってきたかのように見せかけているのです。
こうすることで、大量のデータを表示しても性能が落ちないようにしているのです。

セルのカスタマイズ方法

それではセルのカスタマイズ方法について説明しましょう。セルの表示をカスタマイズするには次の 2 つのことを行う必要があります。

  1. カスタムの Cell クラスを作り、表示したいレイアウトを実装する
  2. ListView に対して上で作ったカスタムの Cell クラスを使うように CellFactory を設定する

具体例を示しながら説明していきます。今、自分用にソーシャルブックマークサービスの Diigo のビューアを JavaFX で作ろうと考えているのですが、それのブックマークリスト部分を先に作ってみることにします。
セルの表示を次のようにすることを考えてみます。
f:id:aoe-tk:20131205011154p:image
上から順にタイトル、コメント、タグを表示します。タグはハイパーリンクとして横に並べるようにします。

まずはリストのデータソースとなるモデルを用意します。次のような JavaFX 形式の JavaBean として作ります。

/**
 * ブックマークを表すモデル.
 */
public class BookmarkModel {
    private StringProperty title = new SimpleStringProperty();
    private StringProperty comment = new SimpleStringProperty();
    private ObservableList<String> tagList = FXCollections.observableArrayList();

    /**
     * コンストラクタ.
     * @param title タイトル
     * @param comment コメント
     * @param tagList タグのリスト
     */
    public BookmarkModel(String title, String comment, List<String> tagList) {
        this.title.set(title);
        this.comment.set(comment);
        this.tagList.addAll(tagList);
    }

    public StringProperty titleProperty() {
        return title;
    }

    public StringProperty commentProperty() {
        return comment;
    }

    public ObservableList<String> getTagList() {
        return tagList;
    }
}

このオブジェクトを ObservableList にくるんで ListView にデータとして渡すことになります。

次はカスタムの Cell クラスを作りましょう。

public class BookmarkCell extends ListCell<BookmarkModel> {
    private VBox cellContainer;
    private Text txtTitle;
    private Text txtComment;
    private HBox tagContainer;
    private boolean bound = false;

    public BookmarkCell() { // (1)
        initComponent();
        initStyle();
    }

    private void initStyle() {
        txtTitle.setFont(new Font("System Bold", 18.0));
    }

    private void initComponent() { // (2)
        cellContainer = new VBox(5);
        txtTitle = new Text();
        VBox.setVgrow(txtTitle, Priority.NEVER);
        txtComment = new Text();
        VBox.setVgrow(txtComment, Priority.ALWAYS);
        tagContainer = new HBox(); // (3)
        VBox.setVgrow(tagContainer, Priority.NEVER);
        cellContainer.getChildren().addAll(txtTitle, txtComment, tagContainer);
    }

    @Override
    protected void updateItem(BookmarkModel bookmarkModel, boolean empty) { // (4)
        super.updateItem(bookmarkModel, empty);
        if (!bound) { // (5)
            txtTitle.wrappingWidthProperty().bind(getListView().widthProperty().subtract(25));
            txtComment.wrappingWidthProperty().bind(getListView().widthProperty().subtract(25));
            bound = true;
        }
        if (empty) {
            setText(null);
            setGraphic(null);
        } else { // (6)
            txtTitle.setText(bookmarkModel.titleProperty().get());
            txtComment.setText(bookmarkModel.commentProperty().get());
            tagContainer.getChildren().clear();
            List<String> tags = bookmarkModel.getTagList();
            for (String tagName : tags) {
                tagContainer.getChildren().add(createTagLink(tagName));
            }
            setGraphic(cellContainer);
        }
    }

    private Hyperlink createTagLink(String tagName) {
        Hyperlink hyperlink = new Hyperlink(tagName);
        hyperlink.setTextFill(Color.BLUE);
        return hyperlink;
    }
}

カスタムの Cell は javafx.scene.control.Cell を継承して実装しますが、ListView 向けには javafx.scene.control.ListCell という基底クラスが用意されているので、通常はこれを継承して実装します。 (TableView の場合は javafx.scene.control.TableCell を継承します)
型パラーメータには ListView のデータソースとなるクラスを指定します。今回の場合、先ほど上で作った BookmakrModel を指定することになります。

カスタムの Cell では updateItem() メソッドをオーバーライドします。
このメソッドは初期表示やスクロール時など、セルの表示を更新する必要があるときにコールバックとして呼び出されます。
第1引数には、このセルが表示を担当することになったデータソース (この例では BookmarkModel のインスタンス) が渡されます。第2引数にはこのセルが表示するデータが空であるかが渡されます。(空の場合に true)
第1引数に渡されたデータを使って、セルの表示内容を更新することになります。Cell クラスは Label や Button のスーパークラスである javafx.scene.contorol.Labeled を継承しており、setText() メソッドを使ってテキストを、setGraphic() メソッドを使って任意のグラフィックを表示するために設定することができます。
よって、任意のコンテンツをセルに表示したい場合、表示する Node を作って、この updateItem() メソッド内において、setGraphic() メソッドの引数にその Node を渡せばいいわけです。

ここで1つ注意点があります。それは、updateItem() メソッド内での Node オブジェクトの生成は極力避ける、ということです。
updateItem() メソッドはスクロールを行った場合など、高頻度で呼び出される可能性があります。そのため、このメソッド内で Node オブジェクトの生成を行うと、その負荷はかなりのものとなります。
従って、可能な限り Node オブジェクトの生成は Cell クラスの初期化時に行い、updateItem() メソッドではプロパティやレイアウトの変更にとどめるようにします。

以上を踏まえて今回の実装例について解説します。
まず、Cell クラスのコンストラクタで初期化可能な Node のインスタンスを全て作っています。(1)
実際に Node の生成を行っているのは initComponent() メソッドです。(2)
セルでは上からブックマークタイトル、コメント、そしてタグのリストを並べるのですが、これは VBox を作って配置します。
ブックマークタイトル、コメントの表示には javafx.scene.text.Text を使います。
タグについては BookmarkModel が保持するタグの数に応じて動的に変化するので、これは updateItem() メソッドで生成するようにしていますが、そのタグを水平に並べるための HBox だけをここでは生成して、コンテナとなる VBox に追加しています。(3)

続いて updateItem() メソッドの実装です。(4)
まず、ブックマークタイトルやコメントのテキストがセルの幅に合わせて折り返されるように、親となる ListView の width プロパティと、それぞれの wrappingWidth プロパティをバインドしています。(5)
コンストラクタの中で行わず、最初に updateItem() メソッドが呼び出されたときにこのバインドを実行している理由は、コンストラクタが呼び出される時点ではまだセルが配置される ListView と結びつけられていないからです。
そして、第2引数が false の場合に、引数として渡される BookMarkModel オブジェクトから値を取り出して、Text や HyperLink オブジェクトに設定しています。(6)
今回は少し手を抜いて、updateItem() メソッドの中で HyperLink を生成していますが、さらに性能を重視するのなら、コンストラクタである程度の数のインスタンスを作ってキャッシュしておいた方が良いでしょうね。

それでは、このカスタムのセルを使ってみることにします。まずは FXML から。

<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="460.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="aoetk.SampleListViewController">
  <center>
    <ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" />
  </center>
</BorderPane>

BorderPane の真ん中に ListView を貼っているだけです。続いて Controller の実装です。

public class SampleListViewController implements Initializable {
    public ListView<BookmarkModel> listView;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        listView.setCellFactory(new Callback<ListView<BookmarkModel>, ListCell<BookmarkModel>>() { // (1)
            @Override
            public ListCell<BookmarkModel> call(ListView<BookmarkModel> listView) {
                return new BookmarkCell();
            }
        });
        ObservableList<BookmarkModel> bookmarkModels = createBookmarkModels();
        listView.setItems(bookmarkModels); // (2)
    }

    private ObservableList<BookmarkModel> createBookmarkModels() { // (3)
        final String longComment = "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。"
                + "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。"
                + "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。";
        final String normalComment = "普通の長さのコメント。";
        ObservableList<BookmarkModel> bookmarkModels = FXCollections.observableArrayList();
        for (int i = 0; i < 500; i++) {
            String comment = "";
            if (i % 3 == 0) {
                comment = longComment;
            } else if (i % 3 == 1) {
                comment = normalComment;
            }
            BookmarkModel model = new BookmarkModel(
                    "ブックマークタイトル" + i, comment, Arrays.asList("tag1", "tag2", "tag3"));
            bookmarkModels.add(model);
        }
        return bookmarkModels;
    }
}

initialize() メソッドで ListView にセルの設定を行っています。ListView#setCellFactory() メソッドを使い、セルを生成する CellFactory を設定しています。(1)
CellFactory は、javafx.util.Callback インターフェースを実装したクラスとなります。call() メソッドで、使いたい Cell クラスのインスタンスを返すようにします。
後はデータの設定です。createBookmarkModels() メソッドにて、500個の BookmarkModel のインスタンスを生成して (3) 、そのリストを ListView のアイテムとして設定しています。(2)

これを実行すると次のようにカスタマイズしたセルを使った ListView が表示されます。

f:id:aoe-tk:20131207003047p:image

いかがでしたでしょうか。ちょっと回りくどいと感じる方もいるかもしれません。ですが、このような作りになっていることでモデルとビューが綺麗に分離できますし、リストの項目数が多くても描画性能へ与える影響を小さくすることができるというメリットがあります。
また上でも述べたように、JavaFX に限らず、GUI アプリケーションではリスト系コンポーネントの表示をカスタマイズしようとしたら、大体これと同じような方法を採ります。なので他の GUI プラットフォームで開発するときにも同じ考え方が通用するので、是非この機会に覚えてもらえたらと。

明日は@さんの予定です。

追記

ソースコード全体は gist にアップしています。ご参照ください。
https://gist.github.com/aoetk/7827455

2013-10-27 22:21

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報告もまだ半分ほど残っていますね。こちらも早めにアップします。(^^;;

aoe-tk
aoe-tk