2008年 12月 26日 金曜日
チーム対抗戦
先日、私の通っているスクール のチーム対抗戦がありました。8チームのエントリがあったので、4チームずつに分け、リーグ戦という形になりました (時間の都合上、それぞれのリーグで優勝/準優勝を決めました)。我がチームは... 2位。4チーム中の2位ですから、微妙なところですねぇー。最終リーグ戦で、2勝同士、決勝戦を行う形になったのですが、1 セットマッチを3回やって、一度も勝てませんでした。しかも... こっちは、全部、男ダブ、向こうは全部、女ダブだったのですが。いや、お上手でした。
私は、その決勝戦の第2試合に出たんですが、相手は、かわいい奥様 (たぶん) ペアでした。失礼な話ですが、楽勝だと思ったんですけどね... ロブで抜かれれるし、前に落とされるし、強打しても拾われるしと、惨めなものでした。しかも、5 - 5 (タイブレークなしで、6 ゲーム取ったら、即終了) になった後、最後のサーバーが私に... これまで2回ともキープしてきたのですが、プレッシャーで、がたがたでした。シングルスより、ダブルスは、こういう緊張感がいやですね... 勝つ負けるというよりも、だめなプレーだと見方に申し訳ないというか。しかも、優勝のかかった一戦、スコア 5 - 5。あまり緊張するタイプではないのですが、久しぶりに「緊張」した気がしました。勿論、全然ダメで、2度のダブルフォールト。テニスはメンタルスポーツなんだと、あらためて認識しました。
修行のやり直しですね。(テニスの修行は大歓迎です)
Posted at 04:24午後 12 26, 2008 by kenji in テニスやってる人には見えない blog |
JavaFX 日本語サイトがオープン!
JavaFX の日本語サイトが、オープンしました!
http://sdc.sun.co.jp/java/javafx/index.html
それほどコンテンツは多くないのですが、日本語版 core チュートリアル JavaFX Script プログラミング言語について と、日本語版 GUI チュートリアル JavaFX を使用した GUI アプリケーションの構築 は、初めて JavaFX を使おうと思っている方は、必見だと思います。是非、アクセスしてみてください!
Posted at 01:14午後 12 26, 2008 by kenji in JavaFX の素人 |
2008年 12月 25日 木曜日
JavaFX SDK 1.0.1 がリリースされました。
今更なんですが... JavaFX SDK 1.0.1 (アップデートリリース 1) がリリースされました。SDK のダウンロードページ からダウンロードできます。主なアップデートは以下の通りです。
- サイズの大きいビデオファイルの再生パフォーマンスの改善。
- HTTP リクエストによるリモートサーバーからの進行型再生機能の変更
- FLV と FXM ファイルの早送り機能の追加
詳細は、 こちら をご覧ください。
なお、現時点では、NetBeans plugin の update は、まだのようです。
Posted at 01:54午後 12 25, 2008 by kenji in JavaFX の素人 |
JavaFX: 今後について (Meet Jeet ブログより)
クライアントソフトウェアグループ副社長 Jeet Kaul のブログ から、JavaFX に関する FAQ が載っていたので翻訳しました。JavaFX の将来について書いてあるので、とても、興味深い内容になっていると思います。(原文は 2008年12月16日にかかれました)
また、Jeet からのコメントで、Martin Brehovsky が blog へのコメントとしていくつか修正をしてくれているそうなので、その部分も翻訳して載せておきました。
# 専門的な話も多く、もしかしたら誤訳があるかもしれません。。。
見つけたら是非教えてください。
I have been getting a lot of great feedback on JavaFX after the launch and obviously a lot of questions too. Since people don't have the ability to walk across the hallway to question Jai, our PM for JavaFX, and get questions answered; I will do that here. I loved Osvaldo's blog. It contains a great set of questions, so I will respond to them along with a few others that I have encountered.
------------------
JavaFX の発表後、たくさんのフィードバックと同時に、たくさんの質問が寄せられています。ですが、すべての人が、JavaFX のプログラムマネージャである Jai に直接質問をして、その回答を得られるわけではないので、このブログでいくつか回答したいと思います。 Osvaldo's blog には、とても興味深い質問がいくつもあったので、私自身が受けた質問をそれに加えて、回答していきたいと思います。
1. When will Sun publish a complete specification?
Sun is committed to open standards and open source, and specifications are coming soon. We'll be publishing the specifications for FXD, FXZ, FXM and the language spec for JavaFX Script shortly. We have already started working on a draft for the language reference guide for JavaFX Script.
---------------------------
1. JavaFX の完全な仕様を Sun はいつ発表するのでしょうか?
Sun は、JavaFX をオープンスタンダード、そして、オープンソースとしていくことを約束しており、FXD, FXZ, FXM および言語仕様はもうすぐ発表されると思います。JavaFX スクリプトの言語リファレンスガイドはすでに作成が始まっています。
2. Any plans for open source?
There are some dependencies on licensed code that cannot be open sourced. We are working towards decoupling the dependencies so that the non-proprietary portions can be open sourced. Currently the JavaFX compiler, Netbeans JavaFX plugin and Eclipse JavaFX plugin are already being developed in the open source. The scene graph is out in the open. We will put the core runtime out in the open over time.
--------------------------
2. オープンソース化については?
まだ、ライセンスの問題で、いくつかのオープンソースにできない部分があります。現在は、ライセンスに抵触しない部分を分離して、その部分をオープンソースにする作業を進めているところです。現時点では、JavaFX コンパイラ、NetBeans JavaFX プラグイン、そして、Exlipse JavaFX プラグインが既に、オープンソースとして開発されています。また、scene graph も同様にオープンになっています。コアランタイムもじきにオープンになるでしょう。
3. A detailed roadmap
We will be rolling out JavaFX releases fast. The mobile platform will be released by March. You will get to see JavaFX Mobile in action at the Mobile World Congress in February '09. The current Desktop release of JavaFX 1.0 already has a beta runtime for mobile. The mobile release will be for OTA deployments that will allow JavaFX applications to run on existing phones. Following the mobile release, a visual designer tool for JavaFX will be available in mid-2009. Better media support with streaming capabilities will also be added in this release. We will be releasing bug fix releases on a continual basis.
---------------------------
3. 詳細なロードマップについて
私たちはまず JavaFX のリリースを先にしました。モバイルプラットフォームは来年の3月にはリリースされるはずです。2月に実施される Mobile World Congress で詳細が明らかになると思います。現在の JavaFX 1.0 の Desktop release には、既にこのモバイル版のランタイムがバンドルされています。モバイルリリースは、JavaFX アプリケーションが、既存の携帯電話から実行できるための OTA 開発リリースになります。その後、2009 年の中ごろには、JavaFX のビジュアルデザイナーツールをリリースする予定です。このリリースには、ストリーミングをサポートする機能も追加されている予定です。bug fix リリースは、継続的に行われていきます。
4. Where is the public bugtrack?
Developers can currently file issues at http://javafx-jira.kenai.com/secure/Dashboard.jspa. We have linked this bug database from the downloads page at http://www.javafx.com.
--------------------------
4. 公開されているバグ管理ツールは?
開発者の方は、http://javafx-jira.kenai.com/secure/Dashboard.jspa からバグを登録することができます。このバグデータベースは、http://www.javafx.com のダウンロードページからもリンクされています。
5. Do you have plans to reduce the desktop FX runtime's dependency on Swing?
Yes we will be adding new UI controls and widgets that'll be based on the common profile of the JavaFX platform. This will remove dependency on Swing and allow the UI components to be used across all devices. We will, however, also provide a better integration for existing Swing applications separately.
-------------------------
5. FX ランタイムの Swing への依存性を減らす予定はありますか?
はい。JavaFX プラットフォームの共通プロファイルに基づいた、新しい UI コントローラと、ウェジットを追加する予定です。この機能は、Swing への依存性をなくし、すべてのデバイスを通して、利用することが可能になります。しかし、それと同時に、より良い Swing コンポーネントを提供していく予定でもあります。
6. Can you share more details about the FX Mobile platform?
We intend to support CLDC and CDC stacks. Ideally we would like people to build JavaFX Mobile applications on MSA subset to enable compelling solutions, but the JavaFX runtime has a hard requirement on mostly JSR135. At this point of time there are no plans to release a full stack with the OS. We might do that in the future though. Yes we intend to support a thin layer on existing JavaME stacks so existing partners can deploy JavaFX on the OS of their choice. There will be support on Windows Mobile.
----------------------
6. FX モバイルプラットフォームについて、より詳細な情報はありませんか?
CLDC と CDC スタックについてはサポートする予定です。理想的には、JavaFX モバイルアプリケーションを、より高いレベルのソリューションを提供できる、MSA サブセットで開発してほしいですが、JavaFX ランタイムには JSR135 と同等のハードウェアが必要になります。このため、現時点では、OS のフルスタックでのリリースは予定されておりません。しかし、将来的には実現したいと思います。現在のパートナーがどの OS 上でも、JavaFX を配備できるように、既存の javaME スタックの一部をサポートした形をとる予定です。Windows Mobile でもサポートされる予定です。
7. What's the reason to create a new vector graphics format, the FXD?
The FXD file format provides significant advantages such as preservation of layers when a graphic created in Photoshop or Illustrator is exported to FXZ format. And FXZ can handle vectors and rasters as well. This allows developers greater flexibility in manipulating the exported graphics and creating amazing new visual effects.
-------------------
7. なぜ新しいベクトルグラフィックフォーマット、FXD を作成したのですか?
FDX ファイルフォーマットは、グラフィックが Photoshop や Illustrator で作られていた場合に、とても有効な、たとえばレイヤーの保存などを FXZ フォーマットとしてエクスポートする形で提供してくれます。FXZ はベクター、ラスター処理も可能です。この機能は開発者に、エクスポートされたグラフィックを処理する際の自由度を提供し、新しい画期的なビジュアルエフェクトを作成することを可能にしてくれます。
8. Some people complained about ugly security dialogs
The security dialogs are critical in providing applications a secure runtime that allows deeper system access than other technologies. However we recognize the usability issues surrounding this model. Our goal is to make the Java browser plugin completely "invisible" while keeping the powerful security model of the Java browser plugin. Java SE 6u10 is a great step in this direction. Future releases of the Java runtime will further address these issues.
--------------------------------------
8. セキュリティダイアログの見栄えが良くなく不満があります。
ほかのテクノロジーに比べ、より高度なシステムアクセスを実現するセキュアランタイムをアプリケーションに提供することがセキュリティダイアログではもっとも重要です。同時に、このモデルはユーザビリティの問題を抱えていることは認識しています。最終目標は、Java ブラウザプラグインの強力なセキュリティモデルを維持しつつ、完全に、「見えない」Java ブラウザプラグインを作ることです。Java SE 6u10 はこの方向へのよい一歩となっています。将来のリリースでは、この問題についてさらに改善するつもりです。
9. When will the JRE CDS be enhanced to support non-RT libraries?
At a higher level we are working on fixing the startup time for JavaFX and Java simultaneously. One of the initiatives is around the work that Mark Reinhold is doing with OpenJDK 7. Stay posted - we are making big changes.
-----------------------------
9. いつ JRE CDS は、non-RT ライブラリをサポートするのでしょう?
概略的には、JavaFX と Java で試験的に変更を実施しているところです。ひとつの例として、Mark Reinhold が OpenJDK 7 で実施しているものがあります。今後にご期待ください - いろいろ改善中です。
10. Perspectives on performance?
We intend to continually improve performance. It is very high on the priority list. Our current focus is on JavaFX Mobile performance. The JRE provides a great foundation for this.
------------------------
10. パフォーマンス改善の見通しは?
継続的にパフォーマンスの改善は実施していきます。パフォーマンスは最重要事項の一つです。現在は、JavaFX モバイルのパフォーマンス改善に力を注いでいます。JRE がその基礎を提供しています。
11. Do you intend to support other codecs?
The On2 VP6 codec is our cross platform story for media. We also support native codecs. Over time we will expand the number of codecs supported. We are also following OMS closely.
----------------------
11. ほかのコーデックをサポートする予定は?
On2 VP6 コーデックがメディアのクロスプラットフォームサポートの中心です。ほかには、native コーデックもサポートしています。今後は、さまざまなコーデックをサポートする予定です。OMS もサポートする予定です。
12. Will there be Linux support?
Yes there will be Linux and OpenSolaris support. Check out Josh's blog for more detail.
---------------------
12. リナックスサポートは?
Linux や オープンソラリスもサポート予定です。詳細は Josh's blog をみてください。
One of the best places to get answers is the FAQ on javafx.com/faq.
-------------------------------
javafx.com/faq の FAQ もさまざまな「回答」があります。こちらも参照してください。
I'm the guy who came with the FXD/FXD idea and who's team is working on the JavaFX Production Suite. The main reason for creating FXD (and FXZ as compressed version with embedded assets) was we needed a mechanism which would map 1:1 to the FX scene graph APIs. Because of that we couldn't really use SVG directly, as not all elements we have in FX are present in SVG (e.g. advanced filter effects, ) and also not all SVG features can be easily represented in FX (e.g. defs/use mechanism).
--------------
私は、FXD/FXZ の開発をしているもので、JavaFX Production Suite のチームに属しています。FXD (と、アセットを組み込んだ圧縮バージョンである FXZ) を開発したもっとも大きな理由は、JavaFX scene graph API と一対一で対応するメカニズムが必要だったからです。JavaFX のすべての要素を、SVG で表現することができず (たとえば、advanced filter effect など)、また、すべての SVG の機能を JavaFX で簡単に表現することもできなかったので (たとえば、defs/use メカニズム)、SVG を直接利用するすることができませんでした。
Furthermore we are planning to enhance the format over the time as the FX platform evolves - new scene graph elements are coming, high level components (UI controls) are coming, maybe 3D scene graph at some point, etc .... In the case we would be using SVG, we have to follow the standard and all advanced features coming from FX would have to exist in a different namespace and all tools working directly with SVG would obviously ignore them. Not exactly the best solution and definitely not scalable.
---------------------
さらに言うと、JavaFX プラットフォームの今後のリリースで、フォーマットの拡張も検討しています - 新しい scene graph 要素の追加、上位レベルのコンポーネント (UI controls) の追加、または、3D scene graph などです。もし、SVG を使っているなら、標準に準拠し、すべての JavaFX の拡張機能は、別の名前空間に存在しなくてはなりません。また、すべての SVG を直接操作する tool は、明らかにこれらを無視しています。SVG を使うことは必ずしも最良の方法ではないし、スケーラブルではありません。
Also FXD has been designed to always map 1:1 to the FX classes. With SVG or other formats it would be nearly impossible to achieve the same (e.g. group is 'g' in SVG would you like to use class 'g' in FX - I'm not sure about that.).
---------------------
FXD は、常に JavaFX クラスと一対一の対応をします。SVG や他のフォーマットでは、これはほとんど不可能です。(たとえば、SVG では、グループは、 'g' ですが、JavaFX では、'g' クラスを使うこともできます - そういう要求があるかはわかりませんが.)
And finally - FXD/FXZ has been designed as a design-time format. For the time being it is being used as the runtime format as well, but in the future we might introduce a binary runtime format, which would be a way more efficient than the design time. For you developers nothing will be changed, as you will always work with FXD/FXZ and the SDK/tools will be responsible for translating it into a binary form, so the the runtime will be able to read the optimized binary form and the runtime should be able to read that in a way more efficient way (this is important especially for smaller devices such as mobile phones or other embedded devices).
-----------------
最後に - FXD/FXZ はデザインタイムフォーマットとして設計されています。当面は、ランタイムフォーマットとしても使用されますが、将来的には、デザインタイムよりもっと効率的な、ランタイムフォーマットを提供する予定です。開発者の側からはなにも変わりませんが、FXD/FXZ や、SDK/ツール 側が、最適化されたバイナリをランタイムを使用できるような、バイナリフォームを生成し、より効率的な実行を目指しています (これは、携帯電話や、組み込みデバイスなど、小さなデバイスに特に重要です)
Let me know if this explained the reasons why FXD and not SVG or any other existing file format. I'll try to post this also to the official javafx blog.
-----------------
SVG や他のフォーマットではなく、FXD を作り出した理由の説明になっていればと思います。javafx blog にもこの話を投稿しておきます。
Posted at 01:22午後 12 25, 2008 by kenji in JavaFX の素人 |
2008年 12月 22日 月曜日
ハンバーガー大好き
突然ですが、ハンバーガー、大好きです。小さいころから結構好きでしたが、特に好きになったのは、まだ入社して間もないころ、半年間アメリカに出張していたのがきっかけです。ともかく、何を食べてもまずくて、しかも、お金も大してない私には、Burger King が、主食でした。ハンバーガーばかり食べていることを現地の日本の方に告げると、「もっとおいしいところがあるよ」といろいろ連れて行ってもらい、ハンバーガーっておいしいく、奥が深いなーと感じるようになりました。で、日本に帰ってきてからも、ちょくちょくおいしいというお店に食べにいきます。おりしもハンバーガーブームらしいですし (もう去ったかな?)
Posted at 01:21午前 12 22, 2008 by kenji in 食道楽 |
Access DB from JavaFX with NetBeans - use Async
This is English version of DB access from JavaFX.
I've got a few comments for my previous blog for about DB access.
Those comments are completely correct and when I added animation with previous animation, it became freeze while toplink was accessing to database. So, I searched how to use AsyncCallback, and found the answer in Clarkeman's blog . So, I've revised my previous code by following Clarkeman's code (Thank you, Clarkeman!)
As Clarkeman also said in his blog, JavaFX UI is invoked in the single EDT (Event Dispatch Thread), so if I kick the heavy process from JavaFX UI, other process is stopped until that task is finished. To avoid this, need to access DB in asynchronous by using com.sun.javafx.runtime.async package.
package javaapplication1;
import com.sun.javafx.runtime.async.AbstractAsyncOperation;
import com.sun.javafx.runtime.async.AsyncOperationListener;
public class CustomerLoadImpl extends AbstractAsyncOperation {
private Customer customer;
private int Id;
public CustomerLoadImpl(Customer customer, int Id, AsyncOperationListener listener) {
super(listener);
this.customer = customer;
this.Id = Id;
}
@Override
public Object call() throws Exception {
CustomerJpaController test2 = new CustomerJpaController();
this.customer = test2.findCustomer(Id);
return(this.customer);
}
public Customer getCustomer(){
return this.customer;
}
}
Then, create JavaFX side, to create asynchronous thread and get the result from CustomerLoadImpl. Before go forward, please confirm to finish the step 6 - 7, except SwingButton part (for here, add the new way to access database).
At first, create CustomerLoad class with inherited AbstractAsyncOperation class as follow.
public class CustomerLoad extends AbstractAsyncOperation {
var peer: CustomerLoadImpl;
public-init var customer:Customer;
public var onComplete: function(customer: Customer): Void;
public override function cancel() : Void {
if (peer != null) then peer.cancel();
}
protected override function start() : Void {
peer = new CustomerLoadImpl(customer, CustomerId, listener);
peer.start();
}
protected override function onCompletion(value : Object) : Void {
this.customer = peer.getCustomer();
onComplete(customer);
}
}
The last thing is, to define the SwingButton action. When the button is clicked.
var tmpcustomer = new Customer();
var test = CustomerLoad {
customer: tmpcustomer
onComplete: function(cus: Customer) : Void {
if (cus != null) {
CustomerName = cus.getName();
}
}
}
The all implementation is finished, and I confirmed that the application is accessing the DB and get the correct value. But, not sure this is actually working or not... So, to confirm this, I add an animation, which is described in GUI tutorial , and try to access DB again with this animation. And the result is... seems to be working fine. The animation is not freeze. I also tried the same way in previous db access way, but the animation is freeze correctly
.

Whole source code for JavaFX side is here .
Posted at 12:14午前 12 22, 2008 by kenji in JavaFX の素人 |
2008年 12月 21日 日曜日
両方そろいました。
O3 グラファイトですが、結局、ストリングホールのやつをもう一本買いました。スピードポートのほうは、嫁が気に入ったので、そのまま使っています。2本あったほうが、試合の時とか便利ですし、いろいろな設定も試せると思うので。で、早速、ためし打ちをかねて、新横浜のテニスコートへいってきました。この新横浜のコートは最近よく使っているコートです。横浜市民なら、はまっ子カードを取得すれば、借りられます。料金も、ほかのコートに比べればかなり安く、できたばかりなので、きれいで、とても気に入ってます。さらによいことに、壁が狭いですがあります。ちょっと早めにコートにいって、壁で練習前にアップする、なんてことも可能です。「2時間じゃ物足りない!」って人にはお勧めです。(ただ、その分、休日とかは混んでいて、なかなか予約取れないですが...)
今日は、やたらと車が多いと思ったら、トヨタカップの日だったんですね。テレビで見るまで気がつきませんでした。トヨタカップを見た方は気づいたかもしれませんが、今日は、やったらと風が強く、あまりテニスに向いていなかったですねー。
それはさておき、やっぱりストリングホールのほうが私には合っているようでした。吸い付く感覚と、ベースライン手前で、ぐっと落ちてくれる感覚がスピードポートだとちょっと感じられなかったので。ストリングホールだと、「引っかかる」感覚で、その調節ができるところがいいですね。ただ、すでに触れましたが、嫁はスピードポートのほうが良いようです。グラファイトの唯一の欠点は、ボレーのしにくさだと思うのですが、スピードポートだと、それはまったく感じられません。ピュアドラと同じぐらいだと思います。で、さらに良いのは、振りぬきがいいからか、飛びすぎないからか、スイングボレーも決まりやすいようです。(嫁に何度か決められました... 前は、ネットに引っかかるのが関の山だったんですけどね)
ということで、小さくあまり力のない女性から、私のような中級中年テニスプレーヤーでも、まったく問題なく使えるラケットでした。フェースが 93 inch というと、とても難しい、上級者ようのモデルのような気がしましたが、使いやすく、お勧めだと思います。(まあ、サーブ & ボレーを主体にする人とかには向かないかもしれないですけど)
Posted at 10:25午後 12 21, 2008 by kenji in テニスやってる人には見えない blog |
2008年 12月 20日 土曜日
JavaFX でデータベースにアクセス - Async を使って非同期で
JavaFX は単一の EDT (イベントディスパッチスレッド) 上で、実行されているので、DB へのアクセスを JavaFX 上で実行すると、たとえば、同じアプリケーション上で、アニメーションを実行していたりすると、そのアニメーションが止まってしまうらしいです。なので、前に作った DB へのアクセス方法を、 Clarkeman's Weblog を参考にして (翻訳版もこの blog に載せてあります) com.sun.javafx.runtime.async パッケージを利用し、非同期で実行することにしました。ただ、ここまでくると、「簡単に」とは言いがたいですね... Clarkeman も言っていましたが、早く JavaFX が非同期実行を簡単に実装できる方法を用意してくれるといいですね。
package javaapplication1;
import com.sun.javafx.runtime.async.AbstractAsyncOperation;
import com.sun.javafx.runtime.async.AsyncOperationListener;
public class CustomerLoadImpl extends AbstractAsyncOperation {
private Customer customer;
private int Id;
public CustomerLoadImpl(Customer customer, int Id, AsyncOperationListener listener) {
super(listener);
this.customer = customer;
this.Id = Id;
}
@Override
public Object call() throws Exception {
CustomerJpaController test2 = new CustomerJpaController();
this.customer = test2.findCustomer(Id);
return(this.customer);
}
public Customer getCustomer(){
return this.customer;
}
}
次に JavaFX 側を作成しましょう。「JavaFX でデータベースに簡単にアクセスできるという事実 - その2」を実行した後に、CustomerLoad クラスを作成します。
public class CustomerLoad extends AbstractAsyncOperation {
var peer: CustomerLoadImpl;
public-init var customer:Customer;
public var onComplete: function(customer: Customer): Void;
public override function cancel() : Void {
if (peer != null) then peer.cancel();
}
protected override function start() : Void {
peer = new CustomerLoadImpl(customer, CustomerId, listener);
peer.start();
}
protected override function onCompletion(value : Object) : Void {
this.customer = peer.getCustomer();
onComplete(customer);
}
}
最後に CustomerLoad のオブジェクトをボタンがクリックされたときに、以下のように作成します。
var tmpcustomer = new Customer();
var test = CustomerLoad {
customer: tmpcustomer
onComplete: function(cus: Customer) : Void {
if (cus != null) {
CustomerName = cus.getName();
}
}
}
これで、実装は完成で、実際に、DB からも値がとってこれたのですが、果たしてこれで、本当に、非同期で実行されているのでしょうか?これを確認するために、 GUI チュートリアルの、雲のアニメーション を無理やり、このアプリケーションに追加しました。以前の「その1 - その3」を使って作ったアプリケーションでは、ボタンを押して、TopLink にアクセスしたときに、確かに、アニメーションが止まってしまいました。ですが、Async を利用した今回のアプリケーションは、アニメーションは止まらず、動いたままでした。どうやらうまく言っているようですね。

JavaFX のソースは ここ においておきました。
Posted at 06:34午後 12 20, 2008 by kenji in JavaFX の素人 |
2008年 12月 18日 木曜日
翻訳: JavaFX Async 操作
Clarkeman's Weblog からの翻訳です。以前に作った JavaFX から DB へのアクセス方法で、「それじゃまずいだろ!」というコメントをもらって、AsyncOperation について調べていたときに見つけました。とりあえず、これを翻訳して、私のプログラムも直してみます...
I am helping a client with a JavaFX application and the client caches data locally using Mysql, after fetching it from a web service. To start the application, an animated splash screen is shown, then the initial fetch of data is done, before showing the main application screen.
---------------
わたしは、現在 JavaFX アプリケーションのクライアントを作っていて、そのクライアントは、web サービスから、データをフェッチしたあと、ローカルの Mysql にデータをキャッシュしています。アプリケーションをスタートさせると、短いアニメーションを表示させ、データのフェッチを完了した後とで、メインアプリケーションを表示させるようになっています。
What I noticed is that if I did the fetch routines in JavaFX script, the animation on the splash screen would pause. This is because JavaFX script executes on a single thread (Event Dispatch Thread, EDT, in the Desktop environment). To get around this, I needed the database and web service access to happen off the EDT in their own Thread. JavaFX does not support creating you own threads, so I had to resort to the javafx.async package.
----------------
アプリケーションを作成実行して気づいたのですが、フェッチを JavaFX から始めると、アニメーションが手停止してしまいます。これは、JavaFX が、単一のスレッド (デスクトップ環境の EDT - イベントディスパッチスレッド) で実行されているためです。これを回避するためには、データベースや web サービスへのアクセスを、EDT ではなく、別のスレッドで実行する必要があります。JavaFX では、独自のスレッドを作成することはサポートされていないので、javafx.async パッケージを使うことにしました。
Currently, there is built in support for asynchrously retrieving a remote text document from the Web via the javafx.async.RemoteTextDocument class. However, my problem is I had to implement logic that would first check locally in the database, and if not present there, then go out over the web. Because of this, I could not use this class; off to write my own accessor class.
----------------
現在、JavaFX では、 javafx.async.RemoteTextDocument クラスを使って、リモートにあるテキストファイルを web から取得することがデフォルトできます。しかし、私のケースでは、最初に、ローカルのデータベースをチェックし、もし存在しない場合は、web から取得するというロジックを実装しなくてはなりません。なので、このクラスを使うのではなく、自前の accessor クラスを実装しなくてはなりません。
To do this, I had to write a Java class that extends com.sun.javafx.runtime.async.AbstractAsyncOperation. This class requires a constructor that takes at a minimum, a com.sun.javafx.runtime.async.AsyncOperationListener object. The AsyncOperationListener provides various call back methods allowing control over the asynchrounous call and reporting of status, such as completion or failure. The could news here is that in the JavaFX side, the javafx.async.AbstractAsyncOperation class handles this plumbing.
------------------
このため、com.sun.javafx.runtime.async.AbstractAsyncOperation クラスを継承したクラスを書く必要があります。また、このクラスは、com.sun.javafx.runtime.async.AsyncOperationListener オブジェクトをコンストラクタの引数として、取る必要があります。AsyncOperationListener は、asynchrounous コールの操作や、完了/失敗のステータスをレポートしてくれる多くのコールバックメソッドを提供してくれます。
import com.mycompany.model.Employee;
import com.sun.javafx.runtime.async.AbstractAsyncOperation;
import com.sun.javafx.runtime.async.AsyncOperationListener;
import java.util.List;
import javax.sql.DataSource;
/* EmployeeLoadImpl.java */
public class EmployeeLoadImpl extends AbstractAsyncOperation {
private Employee employee;
public EmployeeLoadImpl(Employee employee, AsyncOperationListener listener) {
super(listener);
this.employee = employee;
}
@Override
public Object call() throws Exception {
DataSource ds2 = MyDatasource.getCommonsPooledDatasource();
java.sql.Connection con = ds2.getConnection();
// getDirectReports checks local db, and then web service if needed
List directReports = EmployeeReportsDB.getDirectReports(con, employee.getId());
employee.setDirectReports(directReports);
return employee;
}
}
The reason this is done in Java, is that the Call method executes its own Thread, and is not on the Event Dispatch Thread (EDT). By not attempting this in JavaFX, you can avoid unintended clashes with the JavaFX runtime. For example, you avoid clashes with binding or triggers. To be totally safe, the Employee model object is in Java, also.
--------------------
Java で行っている理由は、call メソッドが EDT ではなく、独自のスレッドを実行するためです。JavaFX で実行していない理由は、意図しない理由で JavaFX ランタイムをクラッシュしないようにするためです。たとえば、バインドやトリガーのクラッシュを避けることができます。なので、Employee モデルオブジェクトは、Java で実装した方が安全です。
The second part of this is to write a JavaFX class that extends javafx.async.AbstractAsyncOperation. javafx.async.AbstractAsyncOperation provides the basic plumbing to interact with the asynchronous runtime. Here is an example:
--------------------
次に、javafx.async.AbstractAsyncOperation クラスを継承して、JavaFX のクラスを作成します。javafx.async.AbstractAsyncOperation は、asynchronous ランタイムとの、基本的な相互接続方法を提供してくれます。以下に例を載せます:
import javafx.async.AbstractAsyncOperation;
import com.mycompany.model.Employee;
/**
* @author jclarke
*/
public class EmployeeLoad extends AbstractAsyncOperation {
var peer: EmployeeLoadImpl;
public-init var employee:Employee;
public var onComplete: function(employee: Employee): Void;
public override function cancel() : Void {
if (peer != null) then peer.cancel();
}
protected override function start() : Void {
peer = new EmployeeLoadImpl(employee, listener);
peer.start();
}
protected override function onCompletion(value : Object) : Void {
onComplete(employee);
}
}
To use this in a program:
--------------------------
これをプログラムで使うには以下のようにします:
EmployeeLoad {
employee: employee
onComplete: function(emp: Employee) : Void {
employeeUI = EmployeeUI {
employee: emp
}
}
};
This is a little cumbersome, having to jump down into Java to execute the asynchrounous logic. The JavaFX team is currently looking at solutions to asynchronous use cases and hopefully enhanced language support or more Aysnchrounous framework classes will make this easier.
-------------
asynchrounous ロジックを使うために、java を利用しなくてはならないのは、ちょっと扱いにくい感じがします。JavaFX チームは、asynchronous のユースケースを解析しているので、もしかしたら、JavaFX の機能拡張や、Aysnchrounous フレームワーククラスをもっと簡単につくれるようになるかもしれません。
Posted at 02:54午後 12 18, 2008 by kenji in JavaFX の素人 |
2008年 12月 17日 水曜日
翻訳: コーヒーカップを JavaFX で。
JavaFX blog に出ていたコーヒーカップの作り方の翻訳です。
Scott Hommel の blog が原文になります。
かなり長いですが、とても面白い内容だと思うので、是非、読んでみてください。
So the JavaFX™ SDK 1.0 has shipped. I thought that now would be a fun time to try out some of its graphics capabilities. I know that its graphics are really slick... but how easy are they to program? Do you need to be a graphics expert to figure it all out, or can anyone just pick it up and learn?
----------
JavaFX SDK 1.0 がリリースされました。JavaFX SDK のグラフィック機能を使ってちょっと遊んでみましょう。とてもきれいに作られているグラフィックは、簡単にプログラムできるのでしょうか?グラフィックの専門家だけがつくれるものなのか、誰でも簡単に学び、作成できるものなのでしょうか?
As for my background, I'm a technical writer and general-purpose computer programmer. I am not a software engineer, graphic designer, or GUI expert. Because of that I'm probably the ideal person to test drive the usability of GUI coding with the SDK. The challenge to myself was to take a single afternoon and code up something "impressive"; it didn't matter what, I just wanted it to have a 3D feel with modern visual/lighting effects like what I see in the SDK demos.
-----------
私の経歴をちょっとご紹介すると、私は、テクニカルライターであり、多目的のコンピュータプログラマーです。が、ソフトウェアエンジニアでもなければ、グラフィックデザイナー、GUI の専門家というわけでもありません。なので、私は、JavaFX SDK を使って GUI を簡単に作ることができるか、ということを試す理想的な立場にいます。今回紹介している試みは、ある日の午後だけでできてしまうものでしたが、自分としては、とてもいい物ができました。すごい機能があるというわけではないですが、モダンな見かけで、陰影効果を用いた、SDK のデモで見たような 3D のグラフィックを作ることができました。
So the first thing I did was to read the GUI tutorial, which quickly brought me up to speed on the basics. (Those completely new to the JavaFX Script programming language will want to first read the core tutorial as well.) I then went to the web, looking for information on drawing 3D shapes in general.
------------
最初に私が行ったことは、GUI のチュートリアルを読んだことで、そのチュートリアルによって、基本的なことがすごいスピードで身に付きました。(JavaFX スクリプトを初めて使う人は、コアチュートリアルと同様、まずお読みになることをお勧めします)。次に、web サイトをのぞいて、一般的な、 3D を書く情報を探しました。
I came across this article, which builds a 3D coffee cup using a freeware vector graphics drawing program called inkscape. Having a limited GUI background, this was exactly the kind of breakdown that I needed. It explained how to make "3D" looking objects from basic 2D shapes, filled in with various color gradients. The challenge to myself was to basically "port" their tool instructions to equivalent calls in the API. By the end of the afternoon, I'd made this cool looking cup:
--------------
探したなかで、inkscape という、ベクトルグラフィックスを描画するフリーウェアを使って、3D コーヒーカップを描く文章を見つけました。GUI 作成経験の少ない私でも、3D 描画を理解できる、まさに私が求めていた文章でした。inkscape には、2D のグラフィクスを元に、どうやって 3D に見える物体を作り出すかを、様々な色のグラデーションを使うことで表現する方法について説明されていました。なので、その説明を JavaFX API を使うことで実現してみようと思いました。午後の終わりには、かっこいいコーヒーカップを作り終えることができました。

Here's how I did it...
-------------
以下、やったことです。
Making the Frame
-------------
フレームの作成
Setting up the basic application frame was super easy to do. JavaFX technology lets you "group" multiple objects together, so I made one group for the plate, and another for the cup. These two groups will contain the graphical objects to be rendered on screen:
--------------
基本的なアプリケーションフレームワークを作るのは、とても簡単です。JavaFX テクノロジーは、複数のオブジェクトをグループとして、一緒にすることができるので、片方のグループをコーヒーソーサー、もう片方をカップとして作成しました。この2つのグループは、画面に表示されるグラフィカルオブジェクトを含んでいます。
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
def plateGroup = Group {
// The group of objects forming the "plate" will go here
}
def cupGroup = Group {
// The group of objects forming the "cup" will go here
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
There's nothing to display yet, but the code is organized, and that's an important first step. I've used the def keyword to assign these groups to individual variables; this makes it easier to "unplug" a finished group (i.e. the plate) to work on the other (the cup) in isolation, if need be.
-------------
現段階では、なにも表示されません。ただ、コードは基本的な構造を実装してあり、これはとても重要なことです。各グループを、def を使って、変数に割り当てています。これは、もし片方のグループ (ソーサー) をもう片方のグループ (カップ) から、取り外したいようなことがあった場合に、簡単に行えるようにするためのものです
Making the Plate
--------------
コーヒーソーサーの作成
The first step in making the plate was to draw an Ellipse, filled with a RadialGradient that spans three colors (Color.WHITESMOKE, Color.LIGHTGRAY, and Color.DARKGREY):
---------------
コーヒーソーサー作成の最初の手順は、3色のグラデーション(RadialGradient) をもつ (Color.WHITESMOKE、 Color.LIGHTGRAY と Color.DARKGREY)、 Ellipse (楕円) を作成することです。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
Ellipse {centerX: 0 centerY: 0 radiusX: 170 radiusY: 50
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops: [Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
}
]
}
def cupGroup = Group {
// The group of objects forming the "cup" will go here
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
The translateX and translateY variables of the Group object proved useful for moving the entire group around on screen. I found that getting the exact values for the gradient was just a matter of trial and error. There are a number of different settings that all looked good; finding something that looked "right" was just a matter of plugging in different values and recompiling the program.
------------------
translateX と translateY 変数からなるグループオブジェクトは、スクリーン上で、グループ全体を移動させたいときに便利です。 私の経験では、丁度よい位置を求めるためには、何度もやり直してみるしかないと思います。見栄えのよくなる設定はいくらでもあります。なので、一番適した場所を見つけるためには、別の値を設定し、コンパイルして実行してみるしかないと思います。
Next I added a dark gray ellipse below the plate, and another thin ellipse to make the lip (giving it a 3D feel):
------------------
次は、ソーサーの下にダークグレーの楕円を影として追加しました。また、もうひとつの細い楕円を、ふちとして追加しました (これが 3D 感を出してくれます)

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX: 0 centerY: 10 radiusX: 160 radiusY: 50 fill: Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX: 0 centerY: 3 radiusX: 170 radiusY: 50 fill: Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX: 0 centerY: 0 radiusX: 170 radiusY: 50
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
}
]
}
def cupGroup = Group {
// The group of objects forming the "cup" will go here
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
Since GUI objects are rendered in the order they appear in the source code, I put the main plate ellipse last so that it would cover the tops of all the others. Again, finding the exact values was just a matter of experimentation.
---------------------------
GUI オブジェクトはソースコードに出てきた順番で描画されるので、ソーサーをかたどるメインの楕円を一番最後におき、ほかのオブジェクト (ふちや、影) を覆い隠すようにしました。繰り返しますが、最適な位置の値は、何度か試してみて求めました。
Finally, I recessed the center of the plate:
-----------------------
最後に、ソーサーを中央におきました。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
// The group of objects forming the "cup" will go here
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
Without this dark shadow, the cup bottom would be hard to see when it's finally in place. In the end this darkened area will be more subtle because the cup will be hiding most of it.
---------------------
この影なしでは、最後にカップを設定したときに、カップの下の方が見えにくくなってしまいます。ですが、この影はカップが隠してしまうので、微妙にしか表示されません。
Making the Cup
---------------------
カップの作成
To make the cup, I just started with a Circle, giving it the the same kind of gradient as used in the plate. My approach here was to treat the cup like a blob of clay. The API contains powerful built-in transforms that I can later use to "stretch" the cup into shape. How cool is that?
---------------------
カップの作成は、まず、ソーサーと同じようなグラデーションの円を作成します。私の方法では、まず、カップをまるで、粘土の丸いひとかたまりのようにしています。JavaFX API では、とても簡単に変形を行うことができるので、後で、この粘土をのばすして、カップの形にすることができます。すごいですね!

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
}
]
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
To make this ball more "cup-like", I next placed a white rectangle over the top of the circle to flatten it out:
--------------
この丸をカップらしくするために、白い四角形を円の上部におき、平たくしました。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: Color.WHITE fill: Color.WHITE
x: 25 y: 50 width: 150 height: 50}
]
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
After that, I just added a couple more ellipses to make the outer and inner rims:
------------------
そして、内側と外側のふちを作るため、いくつかの楕円を追加しました。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: Color.WHITE fill: Color.WHITE
x: 25 y: 50 width: 150 height: 50},
// Outer rim
Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},
// Inner rim
Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
}
]
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
Things are looking good! But the cup is still too small. So to make the cup "grow", I just scaled the entire cup group upwards. I actually scaled the y axis slightly more, so as to squish the cup inwards a little to shape it more like an egg:
-------------------
うまくいっているようです! ただ、カップが小さすぎるようです。なので、カップを「成長」させてみました。ただ、カップ全体の縮尺をかえる��けです。実際には、Y 座標を少し大きめに広げ、内側へつぶしたような、卵形のようになるようにしました。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
scaleX: 3.0
scaleY: 4.0
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: Color.WHITE fill: Color.WHITE
x: 25 y: 50 width: 150 height: 50},
// Outer rim
Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},// Inner rim
Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
]
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
Filling the Cup
---------------
カップを満たす
Now it's time to fill the cup! For this I made a custom shape from the intersection of the inner rim and a new coffee-colored ellipse. The built-in ShapeIntersect class makes this a trivial matter:
---------------
次に、カップに何か飲み物を注いでみましょう。内側のふちとコーヒーを表現する楕円の交わる部分を作成しました。ShapeIntersect クラスを使えば、これらのことは簡単にできます。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
fill: RadialGradient{
centerX: 0.5 centerY: 0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
scaleX: 3.0
scaleY: 4.0
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: Color.WHITE fill: Color.WHITE
x: 25 y: 50 width: 150 height: 50},
// Outer rim
Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},
// Inner rim
Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Create "coffee in cup" by intersecting coffee ellipse with inner rim ellipse
ShapeIntersect {
fill: Color.SADDLEBROWN
//Inner Rim
a: Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7} // inner rim dimensions
//Coffee
b: Ellipse{centerX:100 centerY:102 radiusX:46 radiusY:6} // coffee dimensions
}
]
}
Stage {
title: "Coffee Cup"
visible: true
scene: Scene {
width: 500
height: 500
content: [plateGroup,cupGroup]
}
}
And finally, I gave the whole thing a little extra class by setting the background to black:
-------------
最後に、背景を黒くするために、すべて (カップとソーサー)を追加のクラス上におきました。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.paint.Stop;
import javafx.scene.paint.RadialGradient;
def BGCOLOR = Color.BLACK;
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{
centerX:0 centerY:5 radiusX:90 radiusY:22
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
scaleX: 3.0
scaleY: 4.0
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: BGCOLOR fill: BGCOLOR
x:25 y:50 width:150 height:50},
// Outer rim
Ellipse{fill: Color.WHITE centerX:100 centerY:100 radiusX:50 radiusY:8},
// Inner rim
Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7 //inner rim
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:truestops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Create "coffee in cup" by intersecting coffee ellipse with inner rim ellipse
ShapeIntersect {
fill:Color.SADDLEBROWN
//Inner Rim
a: Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7} // inner rim dimensions
//Coffee
b: Ellipse{centerX:100 centerY:102 radiusX:46 radiusY:6} // coffee dimensions
}
]
}
Stage {
title: "Coffee Cup"
width: 500
height: 500
visible: true
scene: Scene {
fill: BGCOLOR
content: [plateGroup,cupGroup]
}
}
Conclusion and Future Steps
---------------------------
結論と今後
In conclusion, I found my first attempt at GUI programming with the 1.0 SDK to be quite successful, and ultimately a lot of fun. The declarative programming model is easy to use. Creating sophisticated visual effects becomes almost effortless. The most time-consuming part of the entire project was just tweaking the different gradient values to get the lighting the way I wanted. But the declarative nature of this language really made the actual programming a breeze. I'm really looking forward to what this language can do when it's placed into the hands of real graphic designers!
--------------------------
JavaFX 1.0 を使って GUI を作成しようという試みは、大成功だったと思うし、とても、楽しいかったです。宣言型のプログラミングは簡単に使えました。洗練されたビジュアルエフェクトを作ることも、全く大変ではなかったです。もっとも時間のかかった部分は、光をうまく表現するために、グラデーションの調整をしたところです。ただ、JavaFX の宣言型言語の本質は、プログラミングを簡単にしてくれるというところだと思います。JavaFX が、実際のグラフィックデザイナーが使ったときに、どんなものを作り出すのか楽しみで仕方がありません。
I'm stopping here because this is what I was able to accomplish in a single afternoon. From here the cup needs a handle and some extra decorations on its face. It would also be great to use key frame animation to add in a steam effect. If you're reading this and would like to add them in, feel free to post your solutions!
--------------------------
午後だけでこれだけできたので、今回はここまでにしておきます。次は、取っ手をつけるのと、カップ自体にデコレーションをしたいと思います。また、キーフレームアニメーションをつかって、湯気のアニメーションを追加するなんてのも楽しそうですね。もし、どなたかこれを読んで、追加してくださったら、是非、私に教えてください。
-- Scott Hommel
Posted at 09:33午後 12 17, 2008 by kenji in JavaFX の素人 |
2008年 12月 15日 月曜日
How to connect Data Base from JavaFX UI with NetBeans.
This is English version of how to connect DataBase from JavaFX UI with Netbeans.
JavaFX is very compatible with Java class (JavaFX code will be compiled to Java Byte Code), and can use Java class from JavaFX script easily. So, you may would like to connect to DataBase from JavaFX UI, when you create cool UI by using JavaFX. Followings are very easy example of how to connect DataBase from JavaFX UI by using NetBeans. NetBeans can provide the many helps to create the connection to DataBase from Java, you can implement the database handling without any code. This example, shows, create a text field and button, and if you input the key in the textfield and click button, the application returns the related value, like input the ID and return the name of the user.
- From "Services" tab in NetBeans, you can find "jdbc:derby://localhost:1527/..." entry in "DataBases". This is the bundled Derby schema.
- Right click "[app on APP]" and select "Connect".

- Right click "Java DB (Network)" in "Services" -> "Drivers" and Select "Connect Using"
- "New Database Connection" dialog is displayed. Input following values in that dialog, and click "OK" button.
o Host: localhost
o Port: your database port (typically 1527)
o Database: sample
o User name: app
o Password: app
- For schema selection, please chose APP and click OK

Now you complete the Database setting.
- Create some Java Application Project, by selecting "File" -> "New Project", chose "Java Application". Default is fine for all settings.
- The created project contains java package. Right click it and select "New" -> "Entity class from Database"
- Select the target database (in this example, use [App on APP]) in Database Connection, and select and add "CUSTOMER" from "Available Tables".

- Click "Next"
- You may see the warning like "The project does not have a persistence unit. You need a persistence unit to persist entity classes.". So, click "Create Persistence Unit" button
- Select "TopLink" from Persistence Library in "Create Persistence Unit" dialog, and clieck "Create" button.
- Back to "Net Entity Classes from Database" dialog, and click "Complete" button.
- Right click the package in project and select "New" -> "Other".
- Select "JPA Controller class from Entity class" from "Persistence", and click "Next".
- Select all entity class from "Available Entity Classes" and add them to "Selected Entity Classes". Then, click "Next" button.

- Click "Finish" button

public static void main(String[] args) {
// TODO code application logic here
CustomerJpaController test = new CustomerJpaController();
Customer idOne = test.findCustomer(1);
System.out.println(idOne.getName());}
- "File" -> "New Project" -> JavaFX -> JavaFX Script Application
Followings are considering JavaFX application, to access database.

Use HBox to land textfield and button horizontally, and create a group with this textfield and button. Then, use VBox to land the group and Text vertically. The code in Stage will be as follows:
scene: Scene {
content: [
Group {
content: VBox {
content: [
Group {
content: HBox {
content: [
SwingTextField {
columns: 10
text: "textfield"
editable: true
},
SwingButton {
text: "OK"
}
]
}
},
Text {
font: Font {
size: 18
}
x: 10,
y: 50
content: "ResultText"
}
]
}
}
]
}
Then, to include Java class, created before, you need to include following libraries:
o JRE libraries
o Toplink libraries
o Java DB drivers libraries.
For Toplink and Java DB drivers, you can add them by the same way as step 4. But, JRE is not defined as default libraries set (Because JDK platform in NetBeans contains it by default. So, NetBeans did not provide JRE as libraries set). So, you need to add jar files in JRE.
- Right click "Libraries" in your JavaFX project and select "Add JAR/Folders".
- Select all jars in JRE lib (for example, C:\Program Files\Java\jdk1.6.0_11\jre\lib), and click "Open" button.
Then, you also need to include the jar file, you created in your java project.
- Right click "Libraries" in your JavaFX project and select "Add Project".
- Select the java project created in step 2, and click "Add project Jar file".

var tmpid = "1";
:
:
SwingTextField {
columns: 10
text: bind tmpid with inverse
editable: true
},
var DB = new CustomerJpaController();
SwingButton {
text: "OK"
onMouseClicked: function( e: MouseEvent ):Void {
CustomerId = Integer.parseInt(tmpid);
CustomerName = DB.findCustomer(CustomerId).getName();
}
}
import java.lang.*;
Text {
font: Font {
size: 18
}
x: 10,
y: 50
content: bind Name
}
That's all!

# But, this code dose not have any exception handling, so if you input the invalid ID, it throws Exception. JavaFX can handle exceptions almost the same way as Java, like try - catch sentence.
The whole source file for JavaFX is here .
Posted at 04:49午後 12 15, 2008 by kenji in JavaFX の素人 | 投稿されたコメント[3]
待っていたインド料理
私と嫁はインド料理が大好きで、家でも、よくわからないスパイスを買ってきては、カレーを作ってみているのですが、近くに本格インド料理屋ができたのはうれしいです。
Posted at 01:38午前 12 15, 2008 by kenji in 食道楽 |
2008年 12月 14日 日曜日
JavaFX でデータベースに簡単にアクセスできるという事実 - その3
その2で、JavaFX 側の準備も整ったので、本題の DB につなげてみましょう。まず、テキストフィールドに入力された ID を変数にバインドしておきます。この変数をボタンが押されたときに、ID として使用するためです。
var tmpid = "1";
:
:
SwingTextField {
columns: 10
text: bind tmpid with inverse
editable: true
},
var DB = new CustomerJpaController();
SwingButton {
text: "OK"
onMouseClicked: function( e: MouseEvent ):Void {
Id = Integer.parseInt(tmpid);
Name = DB.findCustomer(Id).getName();
}
}
import java.lang.*;
Text {
font: Font {
size: 18
}
x: 10,
y: 50
content: bind Name
}

ただし、Exception 処理等は何もしていないので、へんな値を入れるとすぐに Exception をはいてしまいます。Exception も Java と同じで、try - catch で処理すればいいので、試してみてください。
JavaFX のソースは、ここにおいておきました。
Posted at 11:49午後 12 14, 2008 by kenji in JavaFX の素人 |
久しぶりの udpae & 和食
blog のアップデートを再開したので、このページも増やしていこうかと。食べるの大好きですから、テニスの次に。
Posted at 04:00午後 12 14, 2008 by kenji in 食道楽 |
JavaFX でデータベースに簡単にアクセスできるという事実 - その2
その1からの続きです。Java 側の作成は終わったので、次は、JavaFX で UI 側を作りましょう。まずは、概観を簡単に作ってしまいましょう。作りたいのは、テキストフィールドとボタン、そして、DB からのデータを表示する領域です。

HBox と VBox を使って、テキストフィールドと、ボタンを横に並べ、グループを作成し、このグループと、データを表示する領域 (Text) を縦にならべます。Stage の中身はこんなふうになります (まだ、外見だけですので、なにもしてくれません)
scene: Scene {
content: [
Group {
content: VBox {
content: [
Group {
content: HBox {
content: [
SwingTextField {
columns: 10
text: "textfield"
editable: true
},
SwingButton {
text: "OK"
}
]
}
},
Text {
font: Font {
size: 18
}
x: 10,
y: 50
content: "ResultText"
}
]
}
}
]
}
長いですが、スカスカなのは一目瞭然です。
次に、NetBeans の JavaFX プラットフォーム (JavaFX プロジェクトを作成したときに使われる環境です) には、JRE や JDBC など必要なライブラリが含まれていないので、これを追加します。その1の4と同じように、Java DB ドライバと、もうひとつ、Toplink Essensial を追加します。JRE の jar ファイルは、ライブラリとしては用意されていない (java プラットフォームにデフォルトで入っているので、ライブラリとしてはつくらなかったのかと思います) ので、JRE の jar ファイルを直接追加します。
- プロジェクトの「ライブラリ」を右クリックして、「JAR/フォルダを追加」を選択します。
- JRE がインストールされているフォルダの lib (たとえば、C:\Program Files\Java\jdk1.6.0_11\jre\lib) 以下の .jar ファイルをすべて選択し、「開く」をクリックします。
最後にその1で作った java クラスを使うため、プロジェクトをライブラリに追加してしまいましょう。
- プロジェクトの「ライブラリ」を右クリックして、「プロジェクトを追加」を選択します。
- その1で作ったプロジェクトを選択し、「Add project Jar file」をクリックします。
これで、ライブラリは以下のようになっているはずです。
(プロジェクト名はおそらくことなっていると思います)

これで、作成した java プログラムを JavaFX から呼び出す準備ができました。長くなったので、その3に続きまーす。
Posted at 01:44午前 12 14, 2008 by kenji in JavaFX の素人 |