[JavaFX] Why, Where, and How JavaFX Makes Sense

Posted by Unknown Jumat, 29 Maret 2013 0 komentar
原文はこちら。
http://www.oracle.com/technetwork/articles/java/casa-1919152.html

著者について
Björn Müllerは、ヨーロッパのRich Internet Clientの領域のパイオニアの一人であり、大規模かつ長期間使われるアプリケーションシステムのためのクライアントフレームワークに特化したドイツのソフトウェア会社CaptainCasa GmbhのCEOです。

CaptainCasaとは、ビジネスアプリケーションのための共通フロントエンドインフラストラクチャであるCaptainCasa Enterprise Clientの開発およびこの製品を利用している、中規模のビジネスアプリケーションソフトウェアベンダーのオープンコミュニティです。
CaptainCasa
http://www.captaincasa.com/
ビジネスアプリケーションには以下のような傾向があります。
  • Big—たくさんの画面があります。
  • Complex—数多くのルールによってアプリケーション処理が進行します。
  • Used by employees—アプリケーションの主な利用者は日常業務で利用する社員です。もちろん、(臨時利用や匿名利用など)他の利用者もいますが、主要な利用者ではありません。
  • Long-term-oriented—アプリケーションのライフサイクルは長く、現在作成すると、将来の7年にわたって販売される可能性があります。そしてお客様先で10年以上使われる可能性があります。そのため、17年という典型的なライフサイクルを考慮に入れる必要があります。
CaptainCasa Enterprise Clientを使っている企業は、金融、リソース管理、物流、製造、人事、管理などの種々の領域に対しソフトウェアソリューションを提供しています。CaptainCasaコミュニティは2007年に創設され、その時点ではクライアントとしてSwingベースの実装を使うことに決定しました。ちょうどこのタイミングで、JavaFXベースに移行しています。それが今回の記事の内容です。

Everything in HTML5! Or Is a Window Still Open for Native Front Ends?

Should You Succumb to Fads?
2007年当時、「Adobe Flexを使わないなんて…」と言われていました。開発者向けコンファレンスではAdobeのセッションは満杯でした。時間が経ち、Steve Jobsからの一通のメールでこの流行は終わりました。
1年前、Google Web Toolkitが流行しました。現在Googleは世界に向け、Dynamic Webのための新しい言語であるDartに注力している、と発表し、次の流行はそちら方向に進んでいます。
フロントエンドの領域では流行に注意する必要があります。つまり、ころころ変わるということです。
Figure 1
図1 Web UIの流行と大規模ビジネスアプリケーションのライフサイクルの比較
もちろん、マネージャーは常に流行に乗りたいと思っています。「すべてはHTM5だ!」何回我々はこの明確でシンプルな宣告を聞いたことでしょう。こう主張する者が、HTML5とは本当は何なのか知らないことはわかっていても…。
全く流行を避ける必要はないのです!理にかなった場所、タイミングでトレンドを採用すべきです、例えば、たくさんのシナリオのためにHTML画面を必要としているけれども、他のシナリオではネイティブアプリケーションが必要です。だからこうしたテクノロジーを効率的にな方法で含めることができるよう、アーキテクチャをオープンにしておく必要があります。
とはいえ、アプリケーションアーキテクチャの主要な機能については、最新の流行に従って決定すべきではありません。ビジネスアプリケーションのライフサイクルは確実に今日の誇大広告のライフサイクルに比べて長いのです。アプリケーションの主要な画面を5年毎に適応させるための予算はとらないでしょうし、たびたびアプリケーションの主要な部分をアップデートしても感心してくれるお客様がいるとは思えません。

Once Again There Are Technical Problems
JavaScriptやHTML、CSSがHTML5ページの構成要素です。そしてすべての開発者が夜中に寝転がりながらおきまりの問題について想像を巡らす可能性があります。
  • ブラウザの非互換性
  • パフォーマンスの問題
  • ひどいスクリプト言語
状況は現在も悪化しています。
  • ブラウザの数は増加しています。例えば、デスクトップ向けには、Internet Explorer、Firefox、Chrome、およびSafari。そしてタブレットやスマートフォンにはその同等のものといった具合で、ブラウザの機能と実装は分離されています。
  • JavaScriptは、ますます複雑になっています。それはもはや一部のUIプロセスを結び付けるために使われる言語ではなく、現在では、ローカルファイルシステムへのアクセスができるような、一般的なクライアント開発目的で使われる言語を目指しています。
すべての複雑さを隠蔽するか、少なくとも、管理しやすくなるフレームワークを使う打開策があるはずです。この複雑さを処理するために、これらのフレームワークは、独自に複雑である必要があります。
フレームワークは多々ありますが、いくつかは、現在の流行、いくつかは、以前の流行、一部は将来の誇大広告でしょう。それらの多くは消えるか、または開発やサポートが終わることでしょう。
アプリケーションのフロントエンドで何か動作しない場合にはどうしましょう。例えば、Firefoxでのみ発生するバグがありますが、Internet Explorerでは起こらない、もしくはその逆もあり得ますね。きっとフレームワークを作った面々と非常に密接にコンタクトをとる必要があるでしょう。お客様はソリューションを期待しているので、よりよいソリューションを提供したいと考えるはずです。

Is "Zero Installation" the Only Efficient Type of Installation?
フロントエンドの実装において、2つのオプションがあります。
  • 特定のフロントエンドの複雑さに従うか、複雑さを避けるか、つまりフレームワークの手助けを借りて、もしくは借りずにHTML5を使う場合。その場合、開発モデルが暗示する複雑性や課題を管理し、開発や保守リソースを割り当てる必要があります。通常全く使い物にならないのは、ソリューションで使う必要のあるブラウザを決定することです(例えば、「Firefoxでのみ動作します」)。企業はブラウザの設定を持つ傾向があるため、企業のビジネスが成功するために考慮する必要があります。
  • 対して、洗練されたアプリケーションのフロントエンドを展開する場合。(最近ではアプリと呼ばれる)簡単にインストール可能なプログラムは、クライアントOS上で動作します。
両方のアプローチは共に機能的であり、効率的であることは証明されています。
  • たくさんHTML5のコンテンツがあり、HTML5が実行可能なソリューションであることを証明できます。
  • 今日ほど数多くのネイティブアプリケーションをインストールしてきたことはありません。。スマートフォンやタブレットデバイスでは、アプリをダウンロードしてインストールすることがデフォルトです。デスクトップコンピュータ上で行われるインストール方法は全くの時代遅れです。
HTML5を利用しなければエンドユーザーに新しい機能を提供できない、と言われた場合は疑ってかかって下さい。そんなわけありません。何千ものアプリケーションや一日あたり何百万ものインストールを見れば、代替案はあるものです。
幸いなことに、Java(FX)は正しい方向へ向かっています。つまり、自己完結型バンドル(これらをJavaアプリと呼びましょう)として、Javaベースのプログラムをデプロイすることが可能なのです。これらのJavaアプリがユーザーのデスクトップ上で直接実行します。Javaランタイム環境(JRE)を個別にインストールする必要はありませんし、管理者権限を設定する必要もありません。

Conclusion from a Business Application Point of View
CaptainCasaコミュニティにおける結論は以下の通りです。
従業員のための典型的な画面は複雑で、伝えなければならない情報がたくさんあり、たくさんの操作の手段(キーボード、マウス、マウスの右ボタン、ショートカット)、デスクトップ環境との緊密な統合(ファイルシステムや、MS Officeのようなサードパーティ製アプリケーション)、そして時には周辺機器と直接統合(スキャナ、カードリーダ、プリンタ)があります。通常これらの画面では、アプリケーションの中核を形成し、アプリケーション全体と同じライフサイクルを有することが想定されています。画面は顧客の環境に対しユーザのクライアントシステムに最小限の依存性をもって、確実に動作する必要があります。これらの画面には、ネイティブ・クライアント・アプリケーションのローカルインストールが最適です。
その上で、不特定ユーザー向けの画面があります。その場合、インストールが不要であることが必須です。こうした画面の多くはかなりシンプルです(しかし当然ながらきれいですよ)。こうした画面は特定の利用シナリオにあわせて設計されることが多いため、ライフサイクルは主要な画面に比べて通常はかなり短くなります。この場合には、HTML5の利用が理に適っています。画面の複雑性が増すにつれ、ブラウザの互換性などを確保するために余計な労力が必要になることがわかっています。すべてのアプリケーション画面に対し一つのフレームワークで標準化するのではなく、正しいフレームワークを正しいユーザーインターフェースのカテゴリに対して選択することが不可欠であると信じています。すべてに対し一つのフレームワークで標準化することは理想的なソリューションですが、これまでのところ、こうしたソリューションは手に入れ難いものです。従って、リーズナブルなソリューションは、二つのフレームワークの強みを組み合わせて利用することです。

Everything Is Possible! But at What Cost?
これはHTML5に関する一般的な質問です
 「フロントエンド環境としてHTML5を使う上で機能的な制限はありますか?」
この質問に対しマネージャーが期待する答えは、
「いいえ、ないですよ」
HTML5をすべての画面で利用すると非常に楽になるからです。でも、もっと正確な答えは、
「(ほぼ)すべてがHTML5で実現できます」
なのです。コストと効率の問題に過ぎません。
一般的なビジネスアプリケーションの開発グループはそれほど大規模ではありません。多くの中規模の企業の開発リソースは限られており、シンプルかつ効率的なソフトウェア開発のアプローチを渇望しています。この状況から以下の要件が出てきます。
  • 均質な開発ツールや開発言語
  • フレームワークの長期信頼性
  • 複雑さを管理できるよう、クライアントサイトのランタイムシナリオの数を制限できる機能
  • デバッグ、ログ、プロファイルの機能
  • 大事なことを言い忘れていたが、技術革新に対応する、近代的かつ柔軟なUI環境
エンドユーザーは期待を膨らませています。彼らは適切なタイミング、適切な場所で、アニメーション、トランジション、およびインタラクティブなグラフィックなグラフィックスを見たいと思っています。それに対し開発者は、特定のタスク、例えばUIコントロールの作成や既存のコントロールからくみ上げるというタスクの複雑性を隠す開発環境を探しています。
どうにかしてこのすべてをHTML5で実現するとしても、どれぐらいコストが必要でしょうか。HTML5を使用することが、大規模で複数年にわたるプロジェクトを管理するための最も効率的な戦略であるかどうか、アプリケーションのライフサイクルを網羅するとは考えにくい単一のフレームワークに依存することが理にかなっているかどうか、これらを小規模な開発グループは考え直すべきです。 "アプリ"の考え方は、作成したフロントエンドがクライアント環境で動作するより効率のよいアプローチとはなり得ないのでしょうか。

JavaFX for Employee Screens

Reasons for Choosing JavaFX
これまでの経験で、従業員向けデスクトップ画面をネイティブテクノロジーで実装することは有効なアプローチであり、JavaFXは目的に適っていることがわかっています。
  • JavaFXは、主要なデスクトップオペレーティングシステム(Windows、Linux、およびMac OS X)で提供されている
  • いくつかの痛みを伴う変化を経験してきたが、その進化からそのベンダーのコミットメントのレベルがわかる
  • Swingの後継として、多くのJava開発者が利用しており、その数は増加しています。その将来にかかわらず、強力な開発者コミュニティの恩恵を受けるはず。
  • Swingに比べて、それは、明確できれいなアーキテクチャと多くの強化機能を提供している(例えば、スタイリング、イベント管理、トランジション、シーングラフなど)。
  • アニメーション、マルチタッチなどを使う最新のユーザーインターフェイスを開発することができる
  • Javaという、明確できれいな言語に基づいている
  • デバッグ、分析、プロファイル、およびクライアントアプリケーションのログを記録するために必要なすべてのプロフェッショナルJavaツールを提供している
  • 前提条件不要で、クライアント側でアプリのような簡単なインストールが可能である
手短に言えば、今日こうした機能をすべて提供しているネイティブUI環境はJavaFXだけであると信じています。

Experiences with JavaFX
2012年中頃からJavaFXで開発してきました。以下にわかったことをまとめました。
  • Stability—重大な問題でつまずいていません。JavaFXはいくつかの些細な画面よりはるかにたくさん処理することを前提としており、コントロールを組み立てる方法は非常に洗練されていると信じています。当社の全体的なメッセージは、"It's stable." (安定しています)です。現在、クライアントプラットフォームとしてWindowsに注力していて、まだMac OS XまたはLinux上でJavaFXを評価していないことに注意してください。
  • Standard control library—我々のニーズはJavaFXで提供されるもので満たされています。Swingに対する決定的な優位性は、ブラウザコンポーネント(WebView)とHTMLエディタコンポーネントです。現在唯一欠けている重要な機能は、すべての標準コントロールに対するリッチテキストのサポートですが、JavaFX 8で対応することが発表されました。
  • Extensibility—我々は自作の複雑なコントロールを実装することに慣れているので、既存コントロールの拡張性は、非常に重要です。これが全然問題にならないことが証明されている。
  • Third-party libraries—例えば、以前のSwingLabsからのPDF RendererやOpen Street Map Viewerや、Apache-BatikプロジェクトからSVG Viewerなど、いくつかのサードパーティ製のコンポーネントは、Swingで容易に利用できます。JavaFX用のこうしたコンポーネントはまだ利用できません。つまりJavaFXを使う場合は回避策を見つけなければなりません。
  • Development process—現在Eclipseを使っていますが、他のJava IDEと同様、プロフェッショナルなツールを備えており(デバッガ、メモリプロファイラ、パフォーマンスプロファイラなど)、Java FXアプリケーションを開発するために利用できます。画面を作成するためにビジュアルツールを使っていないので、そちら方面の評価は行っていません。
  • Performance—当社の全体的な印象ですが、多くのコンポーネントで作成した画面を描画する際、JavaFXはSwingと同じぐらい高レベルの性能が出ています。そして、トランジションやアニメーション(Swingの場合、この領域では提供している機能が限定されています)の領域では、JavaFXはずっといい性能を出しています。全体的に、性能は問題ありません。
  • Support—Oracle Technology NetworkのJavaFXフォーラムで質問をすると、多くの場合、わずか数時間後に、回答を受け取るでしょう。JIRAにバグを投稿すると、バグが処理されます。

The Architecture Around JavaFX

ここまでで、弊社の従業員向け画面のUIテクノロジー環境としてJavaFXを選択した理由を理解いただいたと思いますので、JavaFX UIがCaptainCasa enterprise clientフレームワークで使われているアーキテクチャの背景を再考しましょう。
本質的な質問はこれです。
「あなたのクライアントアプリケーションはどれほどFat/Thinですか?」
fat clientとthin clientという用語に対する混乱を避けるために、以下を一読下さい。

Thick Client Architecture
Thick Clientは、UI以外にいろいろやらなければならないことがあります。つまり、Thick Clientはアプリケーション·ロジックのかなりの量を保持しています。専門用語では、UIからのイベントとデータ入力をクライアント側のアプリケーション機能で直接(事前に)処理します。クライアントはサーバーへ通信することが時々あります、例えば特定のAPIを呼び出し、入力したデータを転送します。
Figure 2
図2 Thick Client ArchitectureはUIのやりとりに加え、アプリケーションロジックを処理します。
Thick Clientが必要なユースケースは以下のような場合です。
  • ユーザーにローカルデスクトップで操作させ、サーバーとの通信を最小限にしたい、さらにユーザーにネットワーク接続させたくない場合。
  • 非常に多くのユーザーが想定されるため、サーバーをステートレスにする必要があるようなユースケースを扱っている場合。全体のやりとりと処理状態をクライアント側で保持する。
JavaFXはThickデスクトップクライアント開発のための最適な環境です。すべての制御処理は、JavaFX APIを介して行われ、Java APIを介してすべてのアプリケーションの処理が行われています。同じタスクを実施するにあたり、HTML5(HTML、CSS、JavaScript)と比較してみましょう。しかし、thick clientにもいくつかの制限事項があります。
  • フロントエンドにアプリケーションがある、ということは、大規模なアプリケーションであれば、かなり大きなフロントエンドになる可能性があります。ロジック内のバグを修正するためにかなり頻繁にアップデートすることになるでしょう。
  • Webサービスなどの多くのサーバーAPIは、フロントエンドのニーズを満たすように定義する必要があります。
  • そして、再三再四マスターデータにアクセスしなくてよいように、こうしたサーバーAPIを効率的に呼び出すために、複雑度が高まる可能性があります。
  • 典型的には、いくつかのクライアント·アプリケーション·ロジックとそれに対応するサーバー·アプリケーション·ロジックが同じサーバAPIにマップされ、両タイプのロジックは整合する必要があります。そのため、クライアント側とサーバー側の両方で同じロジックが2度実装されることがあります。
一般的にThick Clientのアプローチは、単純なシナリオで有効です。例えば、JavaFXアプリケーションとして電子メールクライアントを実装したい場合は、メール表示およびメール送信のための数少ないUIだけがあり、対応するロジックを非常にはっきりしています。
数百もの画面があるビジネスアプリケーションであれば、Thick Clientのアプローチは複雑すぎます。Thick Clientとして実装されているSAPビジネスアプリケーションのクライアントを想像してみて下さい。

Thin Client Architecture
対して、Thin Clientです。このタイプのアーキテクチャでは、クライアントは単にサーバーから送信されたXML記述のような抽象フォームを描画するだけです。このフォームを(JavaFXコンポーネントで)描画し、ユーザー入力をサーバーに返してサーバーで処理をします。
Figure 3
図3 Thin Client Architectureでは抽象フォームはサーバーから描画エンジンに到達し、処理のためにサーバーへ戻ります。
このシナリオでは、サーバはフォーム(XML)を作り、ユーザー入力を処理するものです。アプリケーションのインタラクション・ロジックの点では、これはフォームの業務処理をサーバー側で実施することを意味します。クライアントは描画しているフォームの背後のビジネスセマンティクスは知りません。フォームが注文書や休暇申請なのかどうか、クライアントは全く知りません。
Thin Clientアーキテクチャの場合、インフラストラクチャが必要です。
  • クライアント側には描画クライアント
  • フォームやレイアウトを送信し、クライアントからのユーザー入力を処理するサーバーインフラストラクチャ
  • 気の利いたサーバー・クライアント間のプロトコル—常にHTMLの全体レイアウトを送信するのではなく、変更点のみ送信する
しかしこのインフラストラクチャを持つ場合、利点は以下の通りです。
  • クライアントはアプリケーション処理から解放される。つまり、修正すべきアプリケーションのバグはサーバー側にしか存在しないため、クライアントの定常的な再配信はない。
  • クライアントサイズは小さくなる。アプリケーションのサイズから解放される。
  • サーバーとクライアント間は一つのインターフェース(レイアウトチャネル)だけ。クライアント側のロジックがアクセスするために無数の細かいサーバーAPIを呼び出す必要はない。
  • インタラクション処理(今回の場合はサーバー側)はサーバー側アプリケーションと非常に密接である。
  • 開発箇所はサーバー側1カ所のみで、すべてのコーディングはここで完了する。「フロントエンドチーム」と「サーバーチーム」に開発チームを分ける必要はない。
Preliminary Conclusions
正しいアーキテクチャを選択することが重要です。
Thick Clientアプローチの場合、最も高速に実現できます。単にJavaFXを使い、開発を始めるだけです。ただ、より複雑なシナリオになると限界があります。
Thin Clientアプローチの場合、一般に大きく複雑になる傾向にあるビジネスアプリケーションに適しています。このようなアプリケーションでは、開発効率の向上しつつ、実行時のオペレーションコストが削減できます。

JavaFX in Front of JavaServer Faces: CaptainCasa

Thin Clientアーキテクチャを使う場合、自分でフレームワークを作るか、既存のインフラストラクチャを使う選択肢があります。
CaptainCasaは既存のThin Clientインフラストラクチャであり、クライアント側にJavaベースのクライアントアプリを、サーバー側にJSFベースの処理を提供します。

JSF Being Used for a JavaFX Client
"JavaFX with JSF": 初見だといささか奇妙に感じるかもしれません。というのも、JSFはHTMLインフラストラクチャとして知られていますが、当初よりJSFは、具体的なHTMLブラウザクライアントから抽象化されたJava EEサーバーの標準であり、他のレンダリング·インフラストラクチャのサポートもします。そのため、完璧にフィットするのです!
JSFはサーバー側のインタラクション・フレームワークです。基本的な処理は、次のとおりです。
  • サーバー側では、レイアウトをコンポーネントのオブジェクトツリーとして保持します。通常宣言的なXMLコードによりツリーが構築されますが、実行時に操作することができます。
  • サーバーは再帰的にツリーをたどって、レイアウトをクライアントに送信します。ツリーに定義された各コンポーネントは、コンテンツを特定の形式の文字列にレンダリングします。HTMLの場合、各コンポーネントは対応するHTML表現にレンダリングします。ツリーをすべてたどり終えると、その結果一つのレイアウト記述に結合され、これをクライアント側へ送信します。CaptainCasa Enterprise Clientの場合、各コンポーネントは自身を特定のXML文にレンダリングします。レンダリング中にデルタ·プロセスは終了時にXMLのページが変更のあったコンポーネントツリーの部分だけを保持するよう指定します。 
  • JavaFXクライアントはXMLを受信し、描画します。再度、デルタ管理が変更された部分だけ更新されていることを保証します。
  • ユーザーがデータ入力します。フィールドに入力されると、クライアントは変更を登録し、サーバーにすべての変更を送信する重要なイベントを待機します。イベントはボタンをクリックしたり、メニュー項目を選択したり、特定のフィールドで実施した変更の場合があります。
  • サーバーはリクエストを受け取り、すべての変更をJSFコンポーネントツリーの対応するコンポーネントに渡され、そこからアプリケーション処理ロジックに転送されます。
おわかりのように、JSFをいつものように使用しますが、この場合、デフォルトのシナリオのように、ブラウザではなくJavaFXの描画クライアントが描画します。ネットワークの観点からは、HTMLの代わりに特定のXMLがネットワーク上を流れる以外は、CaptainCasaのJavaFXクライアントと通常のブラウザとの間には構造上の違いはありません。

XML Layout Is (and Must Be!) Abstracted from the Client Rendering Infrastructure
Swingを使用して、2007年にCaptainCasa Rich Enterpriseクライアントの開発に着手しました。現在、フォームに追加可能な約100個のコントロールを提供しています。今日、JavaFXで私たちのクライアントを再実装しようとしています。
どちらの実装でも、もともとSwingから取り出したXMLレイアウト定義を活用しています。結果として、JavaFXのクライアントは、Swingクライアントと同じレイアウト記述を使用しており、クライアントは相互に互換性があります。
アーキテクチャの重要な概念として、以下のことを考えています。
  • サーバーサイドでは、やりとりは安定したサーバーサイドコントロール群(JSFコンポーネント)を使います。これらはクライアントサイドのレンダリングテクノロジーからは独立しています。
  • したがって、CaptainCasaの既存ユーザーは現在のSwingクライアントからJavaFXクライアントへ素早く切り替えることができます。
まとめると、クライアントサイドで異なるレンダリングテクノロジーへ移行することにより、深刻な問題になったり、サーバーサイドでの再実装の手間が必要になることはありません。
図4と図5はSwingベースのクライアントとJavaFXベースのクライアントの描画の差を例示しています。
Figure 4
図4 Swingベースのクライアントで描画
Figure 5
図5 JavaFXベースのクライアントで描画
図4はあるページをこれまでのSwingベースのクライアントで描画したもの、図5はJavaFXベースのクライアントで描画したものです。色や角などが違いますが、これは異なる画面スタイルのアプリケーションゆえのことです。実際のところ両画面の挙動は同じです。

まとめ

  • JavaFXかHTML5か
    これが明確な回答です。
    「従業員向けデスクトップ画面にはJavaFXを、簡単なユースケースや匿名のユースケースではHTML5を使うべき」
  • JavaFXってどうよ?
    問題は見当たりませんでしたので、本当に満足しています。
  • JavaFXまわりのアーキテクチャは?
    簡単なユースケースではJavaFXを直接実装し始めてもいいですが、ビジネスアプリケーションのユースケースであれば、Thin Client Architectureを使う、もしくは定義すべきでしょう。
  • JavaFXとJSFは?
    非常にフィットします。JavaFXに加え、Java EE標準を利用するサーバーコンポーネントをベースにするThin Clientです。
  • CaptainCasaは?
    この「JavaFX on JSF」フレームワークをビジネスアプリケーションの従業員向け画面に利用することができます。

参考

CaptainCasa
http://www.captaincasa.com/
TERIMA KASIH ATAS KUNJUNGAN SAUDARA
Judul: [JavaFX] Why, Where, and How JavaFX Makes Sense
Ditulis oleh Unknown
Rating Blog 5 dari 5
Semoga artikel ini bermanfaat bagi saudara. Jika ingin mengutip, baik itu sebagian atau keseluruhan dari isi artikel ini harap menyertakan link dofollow ke http://apk-zipalign.blogspot.com/2013/03/javafx-why-where-and-how-javafx-makes.html. Terima kasih sudah singgah membaca artikel ini.

0 komentar:

Posting Komentar

Trik SEO Terbaru support Online Shop Baju Wanita - Original design by Bamz | Copyright of apk zipalign.