Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

Salesforce Driver by JavaFX

この記事は、JavaFX Advent Calendar 201524 日目の記事です。

昨日は id:kozake (@s_kozake) さんの 「続・AndroidでJavaFXを動かしてみたよ!」 でした。
明日は id:skrb (@skrb) さんがトリを飾られます(^^)!!


今年1年を振り返ってみると、技術的に新しいものを探したり・触ったりする余裕がない1年でした。逆に言えば真面目に仕事をしていたというか(^^;

そんなわけで、残念ながらJavaFXに関してもあまり新しいネタはありません。(すみません…

ということで、今日は実際の仕事でJavaFXをこんな風に使ってみた、というネタにしたいと思います。

現場 x JavaFX

ちょうど昨日のJavaFX Adventでこざけさんが「JavaFXは僕の好きな技術ですが、イマイチ現場で使われている感がありません。」と書かれていました(^^;

皆さんの現場ではどうでしょう(^^;?

ちなみに自分の所(部門)では、デスクトップアプリを作る際はWindows FormやWPFといった.NET技術を使っています(C#)

JavaFXは存在は知っているものの(多分…)、最終的には使い慣れた技術のほうが実案件で選ばれるのは仕方がない…という所でしょうか(^^;

元々Windows系が多いので、あえてJavaFXを選択するラインがないです。

また、会社全体でみると、同様に.NET系が多いようですが、Javaの場合だと、やっぱりSwingが主力みたいなところは普通にあるようです。

仮配属にきた新人さんへJavaFXを少し触ってもらったのですが、本配属先ではSwingでした、というのが今年はありました。

テストドライバ x JavaFX

実案件は難しいけど、脇で使ったり、直接お客さんが触るものでない所でJavaFXを…と思って1年くらい経つのですが、少し前にちょうどいい感じの仕事が出てきました。

その仕事は、Salesforceと連携して使う、とあるWebシステム構築案件です。

Salesforceをご存じの方はわかると思いますが、Salesforceは非常にカスタマイズ性が高く、Apexという言語で画面作ったり、ボタンで複雑な処理を呼び出したり、色々なことができます。

うちは導入ベンダなどではないので、Salesforce部分は専門ベンダさんが構築で、うちが作るWebと連携する形です。

f:id:kikutaro777:20151224185907p:plain

当初連携ではSalesforceのRESTを使おうとしてましたが、最終的にはSOAPを使っています(詳細は以下エントリ)

kikutaro777.hatenablog.com

実際やってみるとSOAP使った連携は楽だよなぁと。SFDCのWSDLからクラス自動生成できますし。

さて、本題です。

今回のシステムでは、Salesforce側でうちのWeb画面を呼び出す前に色々とオブジェクトを操作する流れがあります。その後、うちのシステム側に情報が来て、加工して、SOAP APIで更新する、みたいな。更新するには先にSaleforceのロジックでオブジェクトが作成されていないといけない、などですね。

連携とかの開発ではよくある話だと思いますが、両社の開発過程では、まだ色々出揃ってないのでドライバやスタブなどが必要となります。

ドライバやスタブがわからない場合は情報処理試験の本以下ページにある図などがイメージしやすいかと。

What is the difference between stubs and drivers in software testing? - Quora

実際Salesforce上のApexなどでドライバが作れれば最高なわけですが、今回は期間的にもドライバを相手方に作ってもらう時間や、うちがApexを習得して自前でドライバを作る余裕はありませんでした。

なので、Javaで普通にSOAP APIを叩いて、Salesforce上で何かの操作をした後のオブジェクト構造とかを作り出すドライバを作りました。

f:id:kikutaro777:20151224190748p:plain

せっかくなので、JavaFXで作って、ドライバで作ったデータをすぐ確認できるように、WebViewもつけてます。以下のような感じ。

f:id:kikutaro777:20151224191326j:plain

ドライバでテストデータを作って、ブラウザ使わずともWebViewでみれたり。

f:id:kikutaro777:20151224191340j:plain

現場への導入第一歩としては良い感じではないかなーと(^^;

JavaFX使うと何がどこまでできるのか、とかも徐々にナレッジが溜まりそうですし。

書いてるコード

このプロジェクトで作ってるドライバは、非常に簡単なコードの集まりです(^^;

以下に、明日トリを飾る@skrbさんが以前JJUGでハンズオンをされたときの資料がありますが、これを1回やれば普通にできるレベルです。

上記ハンズオン資料は非常に細かく手順も書かれているので、新人さんでも普通にこなせます。
実際、プログラミング経験がほとんどない新人さんにやってもらったりもしてるので。

NetBeansでunpackingが遅い

ドライバ作ってるときにちょっと出会ったネタを最後に1つだけ。

自分はNetBeansでMavenを利用してJavaFXアプリを作っています。画面はSceneBuilderで。

で、今回のドライバはSalesforceのライブラリを使ったり、その他、諸々と依存性があったのですが

ビルドが超遅い(^^;

コンソールみると

f:id:kikutaro777:20151224192542j:plain

unpackingをすごいしています。調べると、java -jarで実行可能なjarファイルを作ってくれてて、そのために依存ライブラリをいれてるっぽい。

で、以下に同じ話がありました。

stackoverflow.com

上記StackOverflowにあった解決案としてprofileを作成するというのがあって、自分はそうしました。

NetBeans(ちなみに8.0.2) & Mavenで自動作成されたpom.xmlには

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>

            <phase>package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>${java.home}/../bin/javafxpackager</executable>
                <arguments>
                    <argument>-createjar</argument>
                    <argument>-nocss2bin</argument>
                    <argument>-appclass</argument>
                    <argument>${mainClass}</argument>
                    <argument>-srcdir</argument>
                    <argument>${project.build.directory}/classes</argument>
                    <argument>-outdir</argument>
                    <argument>${project.build.directory}</argument>
                    <argument>-outfile</argument>
                    <argument>${project.build.finalName}.jar</argument>
                </arguments>
            </configuration>
        </execution>
        <execution>
            <id>default-cli</id>
            <goals>
                <goal>exec</goal>                            
            </goals>
            <configuration>
                <executable>${java.home}/bin/java</executable>
                <commandlineArgs>${runfx.args}</commandlineArgs>
            </configuration>
        </execution>
    </executions>  
</plugin>

のような定義があるので、これを

<profiles>
    <profile>
        <id>executable</id>
        <build>
            <plugins>
                <plugin>
                    <!-- <groupId>以降をここへ移動 -->
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

これで、通常ビルドではunpackingせずに、実行可能なjarを作成したいときは以下プロファイルを指定してビルドすればいいような形になりました。

f:id:kikutaro777:20151224193022j:plain

明日は@skrbさんがトリを飾られます(^^)!!!

OpenDolphinでEnterprise JavaFX

このエントリーは JavaFX Advent Calendar 2014 の 20 日目です。

昨日は @aoetk さんの「JavaFX の WebView に文字列検索機能を付けてみる - AOEの日記」でした。

少し前に、JavaFXをキーワードに色々調べていた時、OpenDolphinなるアプリケーションを知りました。
ロゴがどことなくGlassFishに似てて、なんとなく興味を抱いた…というものなのですが(^^;


OpenDolphinのロゴ
f:id:kikutaro777:20141219084246p:plain

GlassFishのロゴ
f:id:kikutaro777:20141219084311j:plain

そんなOpenDolphinについて調べたことを簡単にまとめたいと思います。

OpenDolphin

OpenDolphinのサイト
f:id:kikutaro777:20141220101845j:plain

先に書いておくと、Googleとかで単純に「OpenDolphin」と調べると、OSSの電子カルテが出てきます(^^;なので、「OpenDolphin JavaFX」と調べるのが良さそうです。

しかし、その全然関係ないOSSの電子カルテ「OpenDolphin」のほうですが、サイトみるとGitHubのリンクがあって

dolphin-dev/OpenDolphin · GitHub

なんとJava EE6で作られてて、NetBeans、Mavenという構成のようです!!なんか不思議なつながりw

おっと、いきなり脱線してしまいましたが、話を戻します。

OpenDolphinとはなんぞや?ということについては、OracleのJava Magazine(日本語翻訳版)でわかりやすく解説されていました。
http://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-JA13-RichClient-konig.pdf

すごく雑にいってしまえば、サーバサイドはJava EE、クライアントサイドはJavaFXのような構成でシステムを作る際に、クラサバを疎な結合したまま、うまいこと繋げて橋渡ししてくれるライブラリです。実際にはJavaFXに限らず、SwingでもAWTなどでも良く、柔軟にサポートされているようです。同様にサーバサイドもSpringとかでもよくて、Javaで作ってるクラサバの架け橋といった感じのようです。

解説の表題に「OpenDolphinで実現するエンタープライズJavaFX」とありますが、エンタープライズで従来多くあるサーバ中心型のモデルに対して、OpenDolphinが架け橋となってリッチなJavaFX UIを使ったりできるよ、という意味合いで「エンタープライズ」と付けているのかな…?と思います。(実際にはもっと風呂敷の大きい意味がありそうですが)

イメージ図を拝借すると次のような図で、PMというのはプレゼンテーションモデルというもので、これがデータモデルの中心となってクラサバ間をやりとりする形。
f:id:kikutaro777:20141220010331p:plain
http://open-dolphin.org/download/guide/guide/introduction.html

DolphinJumpStart

説明だけ読んでると、なんとなくわかったけど……という微妙な感じでした。
で、具体的なサンプルとして「DolphinJumpStart」なるものが。

とりあえずこれを落として、次のドキュメントを読むのが一番良さそうです。
3 How to get started with OpenDolphin - Reference Documentation

コードはMavenでもGradleでもビルドできるようになっているようですが、今回はMavenを利用しました。

Gitでcloneか、zipを落として
f:id:kikutaro777:20141220092147j:plain

NetBeansで開いてみました
f:id:kikutaro777:20141220092240j:plain

親子階層のプロジェクトになっているようです。

step

サンプルコードは、0から7のstepに分かれていて、最初はシンプルな例から始まって、モジュール分割したり、クライアント・サーバに分けたり、と理解できるようになっていました。

Step0はOpenDolphin関係なく、簡単なJavaFXアプリが起動するかどうかのコードでした。

combinedプロジェクトをダブルクリックすると個別に表示されるのでビルドします。
f:id:kikutaro777:20141220092717j:plain

自分の環境ではプロジェクトの設定でJava 5が指定されててビルドエラーになりました(^^;のでプロジェクトのプロパティでJava 7に変えてビルドしました。
(サンプルはJava 7前提のようで、Java 8にすると動かなかったです…)
f:id:kikutaro777:20141220092903j:plain

で、step_0パッケージのmainを実行すると次のような表示になります。

f:id:kikutaro777:20141220093341j:plain

それだけ(^^;

Step1はテキストとボタンがあって、ボタンを押すと入力内容が標準出力されるサンプル。これもJavaFXの基礎を確認、みたいな感じですね。

f:id:kikutaro777:20141220093534j:plain

次のStep2から、やっとOpenDolphinを使う形になります。

実行すると、一見同じ画面なのですが、文字入力するたびに標準出力されてます。
f:id:kikutaro777:20141220094731j:plain

「maki」と入力してclick meボタンを押すと、「server text field contains : maki」と出ます。

f:id:kikutaro777:20141220095400j:plain

コードではClientDolphin、ServerDolphinが定義されていて、これがそれぞれクライアントとサーバを表すオブジェクトのようです。

ClientDolphin clientDolphin = config.getClientDolphin();
ServerDolphin serverDolphin = config.getServerDolphin();

で、ここでやっと最初の図にあった「モデル」がでてきます。
まずはクライアントのclientDolphinに「input」という文字列をIDにしたPrensetationModelに「text」という属性があるよ、と定義します。

PresentationModel input = clientDolphin.presentationModel("input", new ClientAttribute("text"));

で、JavaFXのInputFieldのtextプロパティと、定義したinputというPresentationModelのtextをバインドしてね、と。

JFXBinder.bind("text").of(field).to("text").of(input);

そしてサーバのserverDolphinでは、PresentationModelのinputにあるtext属性の値を受け取って標準出力する形です。

config.getServerDolphin().action("PrintText", new NamedCommandHandler() {
    public void handleCommand(NamedCommand namedCommand, List<Command> commands) {
        Object text = serverDolphin.getAt("input").getAt("text").getValue();
        System.out.println("server text field contains: " + text);
    }
});

serverDolphinからすると、クライアント側がどんな実装でどんなオブジェクトかは気にしてない所がポイントのようです。
PresentationModelのinputにあるtext属性をみてるだけで、そこにバインドするのはクライアント側の実装次第。

なるほどー。

Step3以降はこれをベースに色々と拡張していき、Step5ではモジュールを完全に分割したりしています(clientプロジェクト、serverプロジェクトがそれにあたる)
最後はserver-appでServletベースのサーバを使った、より現実的な所まで含まれているので、興味ある方は実際に1つ1つ動かしながら確認するのがいいのかなと思います。

ここまで書いてふと思ったのですが、サーバサイドはREST APIでJSONベースにリッチクライアントとやりとりするような構成と何が違うんだろうなぁ…と(^^;簡単なレベルでしかみてないので、PresentationModelを使うことの大きなメリットとか、その辺がイマイチぴんときてなかったり…。

OpenDolphinはJavaOneなどでも発表があったり、海外では結構情報ありそうですが、日本語が全然なかったので、その辺の流行り具合とかもご存じの方がいれば是非コメント頂ければと思います(>_<;

JavaFX Advent Calendar 2014 、明日は @tomo_taka01 さんです!

JavaFX Nightに参加しました~ #javafx_ja

最近、勉強会に参加しましたエントリしか書いてない気がするのですが…(^^;

昨日11/25に行われた「JavaFX Night」に参加してきました。

JavaFX Night - 日本 JavaFX ユーザグループ | Doorkeeper

ここ最近JavaFXを触っていないのですが、いつか仕事で使ってみたいと思っているのでネタ収集はしていかないと。

発表はスライドが公開されているのと、@yusukeさんによって早くもYouTubeに動画がアップされているので、参加できなかった方はそちらでみれます!!以下スライドと動画リンクもまとめておきます。

JavaFXにダイアログがやってくる @btnrougeさん

@btnrougeさん講演動画
JavaFXにダイアログがやってくる #javafx_ja #jjug - YouTube

Twitter上で多数「なんで今までダイアログなかったんだ…」とつぶやいてるのが見えたのですが(^^;

やはりGUI作る上では欲しいですよね。

仕事で使う場合には、標準としてダイアログがないと上司が「は?ダイアログもないやつ使うな」とか言いそうで不便かなと。

それにしても蓮沼さんってJava SE, EEそしてJavaFXと、なんでこんな守備範囲広いんだ…すごいなぁ。

HeapStats loves JavaFX @YaSuenagさん

@YaSuenagさん講演動画
今さらはじめるJavaFX 北面 正英 @mshdktom #javafx_ja #jjug - YouTube

Java障害解析支援ツール「HeapStats」のアナライザをSwingからJavaFXへ移行したというお話。

プラグインで新たな機能を追加できる(画面的にはタブで)という仕組みが興味深かったです。これ絶対便利そう!

デモをみると、グラフがきれいで、やはりJavaFXいいなーと。

発表内容の後半は、実際の開発における苦労話もあって、細かい所では色々大変なんだなぁと。

とても勉強になりました。

Bind Me Softly @skrbさん

@skrbさん講演動画
Bind Me Softly 櫻庭 祐一 @skrb #javafx_ja #jjug - YouTube

日本で一番JavaFXについて詳しく書かれている「JavaFX 2で始めるGUI開発」の著者である櫻庭さんからのお話。
「JavaFX 2で始めるGUI開発」は以下ITProの「Java技術最前線」連載の中にあります(^^)って多分JavaFX書いたことある人なら一度はみてるはず。

前にJavaFXで遊んでいたときはバインドを知らなくて全然触っていなかったのですが、この話を聞いたら「めっちゃ便利そう!」となりました(>_<;

スライドの12ページとか14ページとかでスライダーを例にしたデモ(デモといっても、櫻庭さんのスライドはJavaFXで作られているので、スライドの中でそのまま動いているというww)とかみると「おおー」ってなりますね。是非動画で確認を!

プロパティとバインドの話は上記連載の中にもあるので、改めて全部じっくり読まねば(>_<;

LT

最後は2本のLTでした。

@mine_neckさんによる「サーバーサイドJavaFX」のお話。

jettyのServletからJavaFXをキックして音楽鳴らすという試みの話でした。
クラウドの音楽サービスの名前メモし忘れました(^^;;

@mshdktomさんから「今さらはじめるJavaFX」のお話。

初LTとのことでしたが、落ち着いて発表されててすごいなーと。私もJavaFX初心者な中、JavaFX勉強会で発表させて頂いたのですが、緊張しっぱなしだった記憶が(^^;
(ピンマイクつけたまま席戻ってしまった苦い思い出が)

LTの中でアプリ配信の仕組みがあれば~という話をされていて、個人的に.NETのClickOnceを思い出して以下つぶやいたのですが、Web Start使えばとコメント頂きました。なるほどー。

JavaFX Advent Calendar 2014

ということで、まだJavaFXを触ったことがない方も、触ったことがあることも、JavaFX Advent Calendarに登録してJavaFXを楽しみましょう~!

JavaFXのサードパーティ「JFXtras」を触ってみる! #javafx

この記事は「JavaFX Advent Calendar 2013」の22日目の記事となります。

昨日はもじゃ変さん(@razon)による「JavaFX 8 on Scala - SHI-Zone」でした。
明日は@tikeminさんです!宜しくお願いします。

JFXtrasとは?

JavaFXでは標準で様々な画面コンポーネントが揃っていますが、企業やコミュニティのオープンソースによるサードパーティコンポーネントも色々あるようです。情報として最新状態か不明ですが、Oracleさんのページに「JavaFX Third Party Tools and Utilities」があって、画面コントロール系としては

などが挙げられていました。今回この中から、JFXtrasを少しだけ触ってみました。
http://jfxtras.org/

なぜJSXtrasに興味を持ったかというと…

  1. ShelfViewを使ってみたかった
  2. 関わっているメンバーがすごそう

の2つでした(^^;

後者は、パッと見てわかったのはStephen ChinさんとJim Weaverさんだけなのですが、今年JJUGの勉強会やJavaOneに行っていなかったら、こうした方々の名前すら気にも止めなかったと思います…(^^;

で、いざ使ってみたら経緯がわからないのですが、ShelfViewはなくなっているようで…ちょっと残念でした。

JFXtrasについては、日本でも少し前ですがブログ書かれてる方がいらっしゃって、そちらでプロジェクトの解説等が翻訳された形になっていますので、参考にして頂くほうが良いかと思います。

JFXtras 2プロジェクトとは?

サンプルを触ってみる

jfxtras-ensembleというサンプル集のようなものがあって、GitHubからダウンロードして手元でビルド・実行してみたら、こんな感じでした。

f:id:kikutaro777:20131222053205j:plain

が、自分の設定が悪いのか触るとエラーに…(^^;

あと、Java 8を入れていれば「FXTras 8.0 Samples」を見れるよ、と書いてあったので試してみました。こちらは問題なく動かせました。

f:id:kikutaro777:20131222102950j:plain

上記はタイムスケジュールとか作るようなサンプルですね。あと放射状の(Radial)メニューとか

f:id:kikutaro777:20131222103359j:plain

ちょっと触るだけでも面白いので、JDK8を入れてる方は是非触ってみてください。
以下サイト真ん中あたりの「Try It!」からjar落として、JDK8で以下実行するだけです。
http://jfxtras.org/

java -jar jfxtras-labs-samples-8.0-r1-SNAPSHOT-shadow.jar

実際に使ってみる

で、もともとネタにしようとしていたShelfViewなるものがないので、どうしよう…と思ったのですが、とりあえず動かしてみることに。

サイトみるとUse It!のところでMavenのセントラルリポジトリにjfxtras-labsがあるとのことでしたが、バージョンが古い2.2-r5までは置いてあるのですが、2.2-r6-SNAPSHOTと8.0-r1-SNAPSHOTは候補に出てきませんでした。一応セントラルの検索ページみてみたのですが、やはりなさそうな。。

f:id:kikutaro777:20131222105002j:plain

とりあえずjarは落とせるので「jfxtras-labs-8.0-8.0-r1-20130906.112928-11.jar」を適当なフォルダに落として、Mavenを使わない流れでNetBeansプロジェクトを作りました。
で、手動でjarを参照設定します。

f:id:kikutaro777:20131222105217j:plain

f:id:kikutaro777:20131222105240j:plain

FXMLファイルを開いてコード補完みると

f:id:kikutaro777:20131222105329j:plain

と出て、一瞬「あれ、コンポーネントみえないのかな…」と思いますが、右下コメントにあるように「Ctrl+Space」を押すと、JFXtras labで定義されているコンポーネントがみえるようになりました。

AgendaとかBatteryとか(^^)見慣れないコンポーネントがぞろぞろ。

f:id:kikutaro777:20131222105617j:plain

とりあえず、何かおいてみます。わかりやすそうなClockを選択。コード補完も普通に効きます。

f:id:kikutaro777:20131222111658j:plain

実行すると

f:id:kikutaro777:20131222111725j:plain

時計ですねw

他にもTrafficLightというコンポーネントがあって、属性をみたらgreenOnとかredOnとかyellowOnとか…(^^)大体想像つきますね。

さらにgreenBlinking、redBlinking、yellowBlinkingとあるので、まさかー、と思ってgreenに両方trueを指定してみました。

属性もちゃんとみえますね。
f:id:kikutaro777:20131222111634j:plain

f:id:kikutaro777:20131222111955g:plain

実行すると以下のような画面に(^^)

カスタムコンポーネントで自分でもこういう部品が作れるの?と思うと何かちょっとワクワクしますね。

残念ながら上記FXMLをSceneBuilderで開くと

f:id:kikutaro777:20131222112228j:plain

とエラーになってしまいました。クラスパス設定でうまくできるのかも?、ですが、単純にJar指定しただけではダメだったので今回はちょっと諦めます。

堀北真希さん with JFXtras

最後はやっぱり堀北さんで何か作りたい(※この理由は最後に補足)、ということで、Windowというコンポーネントを使って遊んでみました。

FXMLでWindowをAnchorPaneのchildren内に定義します。id名を付けておいて後でプログラムから触りやすいようにしておきます。

<children>
    <jfxtras.labs.scene.control.window.Window fx:id="beautifulWindow" title="きれいな堀北真希さん" prefWidth="400" prefHeight="300" />
</children>

Controllerのプログラムで

@FXML
private Window beautifulWindow;

@Override
public void initialize(URL url, ResourceBundle rb) {
    //綺麗な堀北さんの写真を指定
    Path imagePath = Paths.get("D:\\photo\\horikita\\beautiful.jpg");
    ImageView image = new ImageView(imagePath.toUri().toString());
    
    //タイトルバーの右側に閉じるボタンつける   
    beautifulWindow.getRightIcons().add(new CloseIcon(beautifulWindow));

    //Window内はBorderPaneにしてCenterへ写真配置
    BorderPane windowPane = new BorderPane();
    beautifulWindow.getContentPane().getChildren().add(windowPane);
    windowPane.setCenter(image);
}

こんな感じでWindow内に写真を置いたりします。同じようなWindowをいくつか用意して、ついでにClockコンポーネントをつけて実行すると。
美人時計ならぬ、マイ堀北さん時計…とか(^^; Windowコンポは自由に移動できるので、配置も自由に変えられます。

f:id:kikutaro777:20131222114804j:plain

Windowコンポでは閉じるボタンを左にするか右にするか(綺麗な堀北さんは右に、舞台宣伝のは左につけてます)等、細かく設定できるので便利そうです。

また、タイトルバーのボタンでRotateIconをつけると、Windowがグルっと回転したりw

f:id:kikutaro777:20131222115147j:plain

まだまだJavaFX標準機能の理解を深めないといけない自分ですが、こんな感じでちょっと脱線して面白いライブラリをみつけたりして遊ぶのもいい感じです(^^)

補足

ということで、今年の夏から始めたJavaFX、仕事で利用しているわけではなく遊びでやっているので中々上達しませんが…楽しいです(^^)
堀北真希さんを絡めた理由は少し前にJavaFX勉強会でLTさせて頂いた以下の資料を参照下さい。

JavaFX勉強会で堀北真希さんのLTをしてしまいました… #javafx_ja

今日はGlassFish勉強会とJavaFX勉強会が同日に平行開催されました。

GlassFish勉強会に登録していたのですが、後半で抜け出してJavaFX勉強会でLTをさせて頂きました(^^;

LTきっかけ

さくらばさんからJavaFX勉強会でお話しませんか、とお声かけ頂きました(>_<)

こんな光栄な機会を断るわけにいかない!ということで、技術的な内容が全くないLTでしたが、JavaFXに興味があるけど実際に触ったことがない方をターゲットに(ってJavaFX勉強会には、そんな人いないんじゃないかと思いつつ…汗)した発表をさせて頂きました。


発表資料

発表資料はアップしました。

堀北真希さんのことばかりで本当に恐縮です…

デモ動画

上記資料にもリンクで貼ってますが、ここでも載せておきます。
アプリケーションを作成したときのブログも入れときますが、作った時点からは色々といじって非同期にしたりとかしてますが、その辺りはどこかで機会あればまとめます(^^;

MakiMakiImageViewer

上記動画の後半はStageStyleでTRANSPARENTを指定したもので、アプリ上段の枠が消えただけなのですが、なんかビューアっぽい感じになってるかと(^^)これも作った後、さくらばさんからアドバイスもらったものです。

作ったときのブログ
堀北真希さん誕生日を祝ってJavaFXで画像ビューアを作ってみる
StageStyleを指定してみる

ここから始めるJavaFX!

自分はJJUGで今年の8月に行われたJavaFXハンズオンの資料を参考にして、初めてJavaFXを触りました。

このハンズオンで、SceneBuilderやプログラム作成の基本的な流れはわかるので、あとは自分で作りたいものを作ればいいのかなと。

JavaFXハンズオンにお家でChallenge!

感想

堀北真希エバンジェリストになりたい…(*´Д`)

SendGridFX : JavaFX meets SendGrid ! #JavaFX #SendGrid

I'm new to JavaFX and want to make something interesting.

A month ago I signed up SendGrid, because my old colleague @nakansuke starts to new business with SendGrid company.
He advised me that there is a good Java wrapper library of SendGrid WebAPI, it's sendgrid4j.
http://oss.flect.co.jp/libs/en/sendgrid4j.html

Exactly, it's good and easy to use SendGrid WebAPI.

Today I was having fun with JavaFX and SendGrid.
My simple idea is sending HTML mail with HTMLEditor on JavaFX.

This is my simple application.
I only use Label, TextField, Button and HTMLEditor.

f:id:kikutaro777:20131025233829j:plain

Only input sending e-mail address and subject and contents of mail by HTML.

f:id:kikutaro777:20131025234142j:plain

HTMLEditor component on JavaFX is good to write HTML.

I sent this mail to my web-mail of Yahoo, so checked it.

I think JavaFX programmer might say "Hey guy, why don't you check your web mail by WebView?" Yeah, that's true. I did it :)

This is my JavaFX application includes WebView.
Yes! I got the mail!
f:id:kikutaro777:20131025234414j:plain

I opened it and saw HTML mail.

f:id:kikutaro777:20131025235010j:plain

Of course, it's same looking of HTMLEditor :)

I show my code of JavaFX Controller class. It's very simple.

package jp.co.hoge.sendgridfx;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.web.HTMLEditor;
import jp.co.flect.sendgrid.SendGridClient;
import jp.co.flect.sendgrid.SendGridException;
import jp.co.flect.sendgrid.model.WebMail;

public class SendGridFXController implements Initializable {
    
    //SMTP authentication info of SendGrid
    private static final String SMTP_AUTH_USER = "blah-blah-blah";
    private static final String SMTP_AUTH_PWD  = "blah-blah-blah";
    
    //Mail from info
    private static final String MAIL_FROM = "kiku@test.com";
    private static final String MAIL_FROM_NAME = "Test from Kiku";
    
    SendGridClient client;
    
    @FXML
    private HTMLEditor editor;
    
    @FXML
    private TextField textTo;
    
    @FXML
    private TextField textTitle;
    
    @FXML
    private Label message;
    
    @FXML
    private void sendButtonAction(ActionEvent event) {
        try {
            WebMail mail = new WebMail();
            
            //setting mail from
            mail.setFrom(MAIL_FROM);
            mail.setFromName(MAIL_FROM_NAME);
            
            //setting mail to
            mail.setTo(textTo.getText());
            
            //setting mail subject
            mail.setSubject(textTitle.getText());
            
            //setting HTML content
            mail.setHtml(editor.getHtmlText());
            
            //sending mail
            client.mail(mail);
            
            message.setText("Sending mail is success.");
        } catch (IOException | SendGridException ex) {
            message.setText("Sending mail is failed.");
        }
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        client = new SendGridClient(SMTP_AUTH_USER, SMTP_AUTH_PWD);
    }    
}

We can use sendgrid4j by maven.

Here is pom.xml.
Repository setting of sendgrid4j.

<repositories>
    <repository>
        <id>jp.co.flect</id>
        <name>FLECT maven repository</name>
        <url>http://flect.github.io/maven-repo/</url>
    </repository>
</repositories>

Dependency is here.

<dependencies>
    <dependency>
        <groupId>jp.co.flect</groupId>
        <artifactId>sendgrid4j</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

That's it :)

JavaFXとSendGridで簡易送信メーラーSendGridFXを作る!

少し前にSendGridへ登録したのですが、結構放置してました(^^;

登録の流れやJavaで送信する簡易プログラムは前のエントリを参照下さい↓

JavaでSendGridを利用したメール送信

sendgrid4j使うとJavaで簡単にSendGrid経由にメール送れるので何か面白いことできないかなぁ、と思ってたのですが、最近遊んでるJavaFXと合わせてみました。

名付けてSendGridFX!(なにそれ

すごい簡単なプログラムですが、JavaFXのHTMLEditorコンポーネントを使って、SendGrid経由でHTMLメールを送る、というものです(^^;それだけ

画面は以下のような感じで、ラベルとテキストとボタン、そしてHTMLEditorだけの超シンプルな構成です。

f:id:kikutaro777:20131025193729j:plain

宛先とタイトルを入れて、メール内容をHTMLEditorで書きます。

f:id:kikutaro777:20131025193805j:plain

HTMLEditorで

  • フォント色やサイズ、太字・イタリックに変えたり
  • 横罫線入れたり
  • 箇条書き(番号つきも)
  • センタリングや右寄せ

などなどしてみました。

で、送信!!

受信したメーラ(ThunderBird)でみると(本当はメーラもJavaFXで作ってるとかっこいい気も…)

ちゃんとHTMLメール!!(あたりまえっ

f:id:kikutaro777:20131025194056j:plain

せっかくなので、Yahooメール辺りに送って、JavaFXのWebViewからみてみます(^^;

こんなメールを

f:id:kikutaro777:20131025195149j:plain

送信!

JavaFXでWebViewを置いたアプリでYahooのメールをみてみます。

f:id:kikutaro777:20131025195218j:plain

おおー

f:id:kikutaro777:20131025195227j:plain

やはりJavaFX面白い!そしてSendGridも便利そう!

ちなみにSendGridは前に一緒に仕事していた後輩がSendGrid社とパートナーになって最近力を入れていますので興味ある方は是非彼に!ブログも始めたらしい(^^↓

プログラム

NetBeans7.4からJavaFXプロジェクトをMavenで作れるようになったので、sendgrid4jもpom.xml

リポジトリ

<repositories>
    <repository>
        <id>jp.co.flect</id>
        <name>FLECT maven repository</name>
        <url>http://flect.github.io/maven-repo/</url>
    </repository>
</repositories>

依存性を書けばOKですね。

<dependencies>
    <dependency>
        <groupId>jp.co.flect</groupId>
        <artifactId>sendgrid4j</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

Maven使えるとやはり楽w

コードはこんなレベルです(^^;JavaFXのコントローラだけですが

package jp.co.hoge.sendgridfx;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.web.HTMLEditor;
import jp.co.flect.sendgrid.SendGridClient;
import jp.co.flect.sendgrid.SendGridException;
import jp.co.flect.sendgrid.model.WebMail;

public class SendGridFXController implements Initializable {
    
    //SendGridのSMTPアクセス情報
    private static final String SMTP_AUTH_USER = "hogehoge";
    private static final String SMTP_AUTH_PWD  = "hogehoge";
    
    //送信元の情報
    private static final String MAIL_FROM = "kiku@test.com";
    private static final String MAIL_FROM_NAME = "キクタローテスト";
    
    SendGridClient client;
    
    @FXML
    private HTMLEditor editor;
    
    @FXML
    private TextField textTo;
    
    @FXML
    private TextField textTitle;
    
    @FXML
    private Label message;
    
    @FXML
    private void sendButtonAction(ActionEvent event) {
        try {
            WebMail mail = new WebMail();
            
            //送信元情報
            mail.setFrom(MAIL_FROM);
            mail.setFromName(MAIL_FROM_NAME);
            
            //送信先
            mail.setTo(textTo.getText());
            
            //送信タイトル
            mail.setSubject(textTitle.getText());
            
            //HTMLエディタ入力内容
            mail.setHtml(editor.getHtmlText());
            
            //メール送信
            client.mail(mail);
            
            message.setText("メールの送信に成功しました。");
        } catch (IOException | SendGridException ex) {
            message.setText("メールの送信に失敗しました。");
        }
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        client = new SendGridClient(SMTP_AUTH_USER, SMTP_AUTH_PWD);
    }    
}

簡単なメール送信するだけなら、こんなレベルで作れます(^^;

ちなみにJDK8で作っていたのですが、HTMLEditorを使うと実行時に以下のエラーで落ちました…。


Exception in Application start method
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1959)
at com.sun.javafx.scene.web.skin.HTMLEditorSkin$15$1.updateItem(HTMLEditorSkin.java:699)
at com.sun.javafx.scene.web.skin.HTMLEditorSkin$15$1.updateItem(HTMLEditorSkin.java:694)
at javafx.scene.control.ListCell.updateItem(ListCell.java:442)
at javafx.scene.control.ListCell.indexChanged(ListCell.java:320)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:115)
at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1730)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1627)
//略
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:491)
//略
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:868)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:55)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:157)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1959)
at com.sun.javafx.scene.web.skin.HTMLEditorSkin$15$1.updateItem(HTMLEditorSkin.java:699)
at com.sun.javafx.scene.web.skin.HTMLEditorSkin$15$1.updateItem(HTMLEditorSkin.java:694)
at javafx.scene.control.ListCell.updateItem(ListCell.java:442)
//略
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:101)
... 1 more
Exception running application jp.co.hoge.sendgridfx.MainApp

JDKというよりmavenまわりなのかな(^^;JDK7にしたら動いたので、とりあえず今回のサンプルはNetBeans7.4とJDK7で作りました。

JavaFXでYouTubeのダウンローダ的なサンプルを作ってみる ~動画の自動再生と履歴ページ遷移~

ブログと関係ないですが、昨日から堀北真希さん主演ドラマ「ミス・パイロット」が始まりました(^^)/システム屋らしく緊急対応で観れないっていう残念な事態になりましたが…とほほ(-_-;

まあ、録画したので、後日楽しみます。フジテレビの公式サイトはこちら↓
http://www.fujitv.co.jp/misspilot/index.html

……

宣伝はさておき、今日は先日サンプルで作ったJavaFXのYouTubeダウンローダ的なサンプルを少し改造しました。作ったときのブログはこちら↓
JavaFXでYouTubeのダウンローダ的なサンプルを作ってみる

すごいショボイですが、以下2つトライしました。

  • ダウンロードが終わったら動画を自動再生する
  • サイトの履歴を表示して、選択した履歴を表示できるようにする

ダウンロードが終わったら動画を自動再生する

本当は落としたファイルをJavaFXのMediaViewで観れるようにしてみよう!とか思ったのですが、SceneBuilderにMediaViewがない(^^;そういうものなのかな。

あと、YouTubeで落とした動画もWEBM形式というのに(最近?)なっているので、MediaViewが使えても再生できるかわからなかったので、とりあえずベタにChromeのexeを叩いて実行する、という方法でやりました。

Javaからexe叩く方法は以下サイトを参考にさせて頂きました。
ひしだまさんのサイト 外部プロセス起動

実行結果はこんな感じ。

起動するとYouTubeページを表示

f:id:kikutaro777:20131016192734j:plain

せっかくなので「ミスパイロット」で検索して

f:id:kikutaro777:20131016192822j:plain

適当な動画を選びます。
ジャケット着る姿が超りりしい (*´Д`)ハァハァ

f:id:kikutaro777:20131016192846j:plain

ダウンロードボタンを押すと、前回と同様に動画のダウンロードされます。

f:id:kikutaro777:20131016192947j:plain

で、ダウンロード完了と同時にChromeが起動して自動再生します。
二度目の (*´Д`)ハァハァ。

f:id:kikutaro777:20131016193010j:plain

こんだけ(^^;

履歴ページ遷移

画面にコンボボックスを設けてページ遷移の履歴を一覧表示するようにしました。

適当に色々たどった状態でコンボボックスを開くと

f:id:kikutaro777:20131016193204j:plain

以下のような感じで履歴が出ます。

f:id:kikutaro777:20131016193230j:plain

横が長すぎて不格好(^^;
今はWebEngineから取得できるHistoryのリストをそのままコンボボックスにぶっこむ雑な処理をしてるためです。
HistoryのEntryクラスを継承してtoStringをオーバーライドすればいいのかなと思ったら、Entryクラスがfinalでした;ここら辺はもう少し綺麗にしたいところ。

で、とりあえず選択イベントで履歴URLのページへ遷移するようになってます。

f:id:kikutaro777:20131016193843j:plain

コード

前回のをベースに以下のような感じです。

Chromeの実行はProcessBuilderでexeファイルを叩いてるだけ(^^;
履歴もWebEngineのHistoryにListChangeListenerをつけて履歴が変わるタイミングでコンボボックスの中身を入れ替えてるだけです。

package maki.makimakidownloader;

import com.github.axet.vget.VGet;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory.Entry;
import javafx.scene.web.WebView;

public class MakiMakiDownloaderController implements Initializable {

    private static final String DL_DIR = "D:\\movie\\horikita";
    
    private static final String CHROME_EXE = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
    
    @FXML
    private WebView webView;
    
    @FXML
    private ComboBox historyComboBox;
    
    private WebEngine webEngine;
    
    /**
     * ダウンロードボタン押下時のイベント.
     * 
     * 動画をダウンロードして、Chromeでビューする。
     * 
     * @param event 
     */
    @FXML
    private void handleBtnDownloadAction(ActionEvent event) {     
        try {
            //動画のダウンロード
            URL downloadUrl = new URL(webEngine.getLocation());
            VGet vget = new VGet(downloadUrl, new File(DL_DIR));
            vget.download();

            //ダウンロードしたファイル(webm形式)をChromeで実行する
            ProcessBuilder processBuilder 
                    = new ProcessBuilder(CHROME_EXE, "\"" + vget.getTarget().getAbsoluteFile() +"\"");
            Process process = processBuilder.start();
            
            //実行結果の判定
            int ret = process.waitFor();
            if(ret == 0){
                System.out.println("正常終了しました。");
            }else{
                System.out.println("異常終了しました。コードは" + ret);
            }
        } catch (IOException | InterruptedException ex) {
            System.out.println(ex.getMessage());
        }
    }
    
    /**
     * コンボボックス選択時のイベント.
     * 
     * 選択された履歴のURLに遷移する。
     * 
     * @param event 
     */
    public void selectHistoryComboBox(ActionEvent event){
        if(historyComboBox.getValue() instanceof Entry){
            Entry selectedEntry = (Entry) historyComboBox.getValue();
            webEngine.load(selectedEntry.getUrl());
        }
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        webEngine = webView.getEngine();
        
        //YouTubeのサイトを表示
        webEngine.load("http://www.youtube.com/?gl=JP&hl=ja");
        
        //サイト履歴が変わる度にコンボボックスの値を更新する
        webEngine.getHistory().getEntries().addListener(new ListChangeListener<Entry>(){

            @Override
            public void onChanged(ListChangeListener.Change<? extends Entry> change) {
                change.next();
                historyComboBox.getItems().clear();
                historyComboBox.getItems().addAll(webEngine.getHistory().getEntries());
            }
            
        });
    }
}

JavaFXおもしろいなぁ。

JavaFXでYouTubeのダウンローダ的なサンプルを作ってみる

今や便利なダウンロードツールが色々あるので、作る意味はあまりないのですが、JavaYouTube動画とか取るには…と探したらライブラリがあったので、JavaFXと合わせてみました(^^;

注意
ちなみにYouTubeの動画をダウンロードすること自体、本来は(自分の著作物を上げた場合以外は)いけないことですね;利用規約はこちら。「5. お客様によるサイト上のコンテンツの使用」の部分です。
http://www.youtube.com/static?template=terms&hl=ja&gl=JP

その他の参考
http://ihoudownload.chosakuken-kouza.com/q/q2.html

というわけで、今回のブログ、不適切だったら後で削除するかも…です。

ちなみにJavaYouTubeをダウンロードする、で調べたら海外にわんさか(^^;
自分が参考にしたのは

How to download videos from youtube on java?

でした。で、回答の1つに「vget」なるライブラリがあって簡単そうだったので使ってみました。

https://github.com/axet/vget

このライブラリの内部では他のライブラリを使っているようで、Maven使うのが楽そうです。

で、NetBeans7.3.1を使っていたのですが、MavenのメニューにJavaFXがない!とつぶやいたら@sk44_さんと@aoetkさんからNetBeans7.4から使えます、と教えて頂きました。
というわけで7.4RC1入れていたので(今はもうRC2出てますが)やってみたところ

f:id:kikutaro777:20131014234914j:plain

あった!やったー(^^)/

ということで、MavenJavaFXプロジェクト作りました。

このvgetというライブラリ、URLがわかればダウンロードできるので、JavaFXのWebView使ってURLを取るようにしただけの雑なサンプルです(^^;

起動するとYouTubeのトップを表示するようにして、検索して目的の動画へ。
自分の著作物であげたものがないので…一時的に堀北さんのCMを試してみました。

f:id:kikutaro777:20131014233457j:plain

ダウンロードボタンを押してしばらくするとwebm形式のファイルを取得。

f:id:kikutaro777:20131014234132j:plain

実行するとこんな感じ!取れてる!

f:id:kikutaro777:20131014234103j:plain

コードは超適当ですが、こんなんで動いてます。
ちなみにViewのFXMLはWebViewとVBox、Buttonだけです。

package maki.makimakidownloader;

import com.github.axet.vget.VGet;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class MakiMakiDownloaderController implements Initializable {
    
    @FXML
    private WebView webView;
    
    private WebEngine webEngine;
    
    @FXML
    private void handleBtnDownloadAction(ActionEvent event) {
        try {
            URL downloadUrl = new URL(webEngine.getLocation());
            VGet vget = new VGet(downloadUrl, new File("D:\\movie\\horikita"));
            vget.download();
        } catch (MalformedURLException ex) {
            System.out.println(ex.getMessage());
        }
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        webEngine = webView.getEngine();
        webEngine.load("http://www.youtube.com/?gl=JP&hl=ja");
    }    
}

真面目に作るなら欲しい機能として

  • ダウンロード中はプログレスバーを表示
  • 落とせない形式(があるっぽい)の場合にはメッセージダイアログを表示
  • 非同期で複数ダウンロードできるようにする

などなど(^^;他にもあるよなぁ。

先日のマキマキビューアも途中だけど、これも真面目に作ってみようかな。って個人で楽しむためのツールですが。

てか、最近JavaFXネタが増えつつある(^^;

Java EEは仕事でガッツリ開発入って今まで使ってないようなものを触らないと中々書くことがない今日この頃。もっとガッツリ開発したいなぁ。

StageStyleを指定してみる

昨日のブログ、軽い気持ちで書いたプログラムだったので、思ったより反応があってびっくりでした…(^^;

Java EEより反応いいんじゃ…

……

@skrbさんから


というコメントを頂いたので、早速試してみました(^^)

StageStyleとは?

その名の通り、Stageのスタイルに設定できる列挙型とのこと。

http://docs.oracle.com/javafx/2/api/javafx/stage/StageStyle.htmlf:id:kikutaro777:20131007191758j:plain

Applicationクラスを継承したMakiMakiImageViewerクラスはNetBeansの自動生成まかせのままで昨日のブログには載せていなかったのですが、以下のような感じで、1行追加しました。

package makimakiimageviewer;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class MakiMakiImageViewer extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MakiMakiImageView.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setScene(scene);
        
        //TRANSPARENTを指定してみる
        stage.initStyle(StageStyle.TRANSPARENT);
        
        stage.show();
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

結果

昨日の実行結果は以下でした。

f:id:kikutaro777:20131007192312j:plain

で、上記プログラムの実行結果は

f:id:kikutaro777:20131007192652j:plain

拡大してるとイマイチわかりませんね(^^;ひいてみます。

昨日のプログラム

f:id:kikutaro777:20131007193414j:plain

今日のプログラム

f:id:kikutaro777:20131007193438j:plain

画像だとわかりにくいですが、実際に動いてるものをみるとだいぶ印象が違います!!

ちなみに値を色々変えてみましたが

StageStyle.DECORATEDを指定した場合(昨日と同じ)

f:id:kikutaro777:20131007193710j:plain

StageStyle.UTILITYを指定した場合

f:id:kikutaro777:20131007193800j:plain
わかりにくいですが、右上の最小化・最大化ボタンが消えてます。

StageStyle.TRANSPARENTを指定した場合

f:id:kikutaro777:20131007193855j:plain

今回のサンプルではStageStyle.UNDECORATEDもこれと同じでした。

画像のエリア以外を透明に

縦画像の場合、こんな感じです。

f:id:kikutaro777:20131007194254j:plain

で、SceneにsetFill(null)を指定してみました。すっきり!

f:id:kikutaro777:20131007194330j:plain

Scene scene = new Scene(root);
scene.setFill(null);

たいしたプログラム書いていないのですが、結構それっぽいプログラムができて楽しい!
やばいです。JavaFX面白いw

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村