Kenji Tachibana's Weblog

« 2008年Oct月月 | 月別メイン | 2008年Nov月月 »

http://blogs.sun.com/kenji/date/20081226 2008年 12月 26日 金曜日

チーム対抗戦

先日、私の通っているスクール のチーム対抗戦がありました。8チームのエントリがあったので、4チームずつに分け、リーグ戦という形になりました (時間の都合上、それぞれのリーグで優勝/準優勝を決めました)。我がチームは... 2位。4チーム中の2位ですから、微妙なところですねぇー。最終リーグ戦で、2勝同士、決勝戦を行う形になったのですが、1 セットマッチを3回やって、一度も勝てませんでした。しかも... こっちは、全部、男ダブ、向こうは全部、女ダブだったのですが。いや、お上手でした。

私は、その決勝戦の第2試合に出たんですが、相手は、かわいい奥様 (たぶん) ペアでした。失礼な話ですが、楽勝だと思ったんですけどね... ロブで抜かれれるし、前に落とされるし、強打しても拾われるしと、惨めなものでした。しかも、5 - 5 (タイブレークなしで、6 ゲーム取ったら、即終了) になった後、最後のサーバーが私に... これまで2回ともキープしてきたのですが、プレッシャーで、がたがたでした。シングルスより、ダブルスは、こういう緊張感がいやですね... 勝つ負けるというよりも、だめなプレーだと見方に申し訳ないというか。しかも、優勝のかかった一戦、スコア 5 - 5。あまり緊張するタイプではないのですが、久しぶりに「緊張」した気がしました。勿論、全然ダメで、2度のダブルフォールト。テニスはメンタルスポーツなんだと、あらためて認識しました。

修行のやり直しですね。(テニスの修行は大歓迎です)

JavaFX 日本語サイトがオープン!

JavaFX の日本語サイトが、オープンしました!

http://sdc.sun.co.jp/java/javafx/index.html

それほどコンテンツは多くないのですが、日本語版 core チュートリアル JavaFX Script プログラミング言語について と、日本語版 GUI チュートリアル JavaFX を使用した GUI アプリケーションの構築 は、初めて JavaFX を使おうと思っている方は、必見だと思います。是非、アクセスしてみてください!

http://blogs.sun.com/kenji/date/20081225 2008年 12月 25日 木曜日

JavaFX SDK 1.0.1 がリリースされました。

今更なんですが... JavaFX SDK 1.0.1 (アップデートリリース 1) がリリースされました。SDK のダウンロードページ からダウンロードできます。主なアップデートは以下の通りです。

- サイズの大きいビデオファイルの再生パフォーマンスの改善。
- HTTP リクエストによるリモートサーバーからの進行型再生機能の変更
- FLV と FXM ファイルの早送り機能の追加

詳細は、 こちら をご覧ください。

なお、現時点では、NetBeans plugin の update は、まだのようです。

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 もさまざまな「回答」があります。こちらも参照してください。



Martin Brehovsky からのコメント


Hi everyone,
-----------
こんにちは、みなさん、

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 にもこの話を投稿しておきます。

http://blogs.sun.com/kenji/date/20081222 2008年 12月 22日 月曜日

ハンバーガー大好き

突然ですが、ハンバーガー、大好きです。小さいころから結構好きでしたが、特に好きになったのは、まだ入社して間もないころ、半年間アメリカに出張していたのがきっかけです。ともかく、何を食べてもまずくて、しかも、お金も大してない私には、Burger King が、主食でした。ハンバーガーばかり食べていることを現地の日本の方に告げると、「もっとおいしいところがあるよ」といろいろ連れて行ってもらい、ハンバーガーっておいしいく、奥が深いなーと感じるようになりました。で、日本に帰ってきてからも、ちょくちょくおいしいというお店に食べにいきます。おりしもハンバーガーブームらしいですし (もう去ったかな?)



CoCoChi


神奈川県横浜市青葉区藤が丘2-3-1 桂ビル1F


オーダー: アボガドバーガー


コメント:
これも近所にあるハンバーガー屋さんです。できた当初は、「これはうまい!」と感動しました。パンがほんのり甘く、お肉はしっかり、ジューシー。アボガドとの相性も抜群で、遠くまで行かなくても、こんなハンバーガーが食べられるとは幸せっと、結構よく足を運んでいました。ところが... 小麦が高いといわれてしばらくしていってみたのですが、うーん、なんかパンが変わってます。気のせいかもしれませんが、普通のパンになってました。たまたまかも知れません。でも、それ以来、足が遠のいてしまって... もう一度、いってみてもいいですね。


評価: ★★★ (以前の味なら、5つ星なんですけどね...)

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.



Implement of CustomerLoadImpl class (Java)


For preparing the database side, please use the same process as my previous blog (How to connect Data Base from JavaFX UI with NetBeans), from step 1 - step5.
After that, I need to add one more class to use Async from JavaFX, called CustomerLoadImpl inherited from AbstractAsyncOperation class.

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;
}
}

This class will be called from JavaFX side, and create Customer object by using JPA controller. This should be done in asynchronous. When this CustomerLoadImpl object is created and inherited start() method is invoked, call() method (override) is called and find the Customer object with input Id value, and put it in the attribute. Then, to be able to get this value, create getter method.
To compile this class, please add javafxrt.jar in the Library. In my env, install NetBeans 6.5 first, and add JavaFX as plugin, it is in C:\Users\tkenji\.netbeans\6.5\javafx-sdk1.0\lib\shared.

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);
}
}

This CustomerLoad object is created, call start() object of CustomerLoad (Java side) . Then, when the action is finished, call onCompletion() method. In this case, start() method in CustomerLoad create new object of CustomerLoadImpl, and execute start() method of CustomerLoadImpl. This method will invoke call() method of CustomerImpl as described before. onComplte() method is a function handed as the one of the args of CustomerLoad class constructor, and execute the defined function.

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();
}
}
}

For onCoplete function, put the Customer Name from DB to CustomerName value. This value is binded to Text UI and the name is displayed when the value is changed.

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 .

http://blogs.sun.com/kenji/date/20081221 2008年 12月 21日 日曜日

両方そろいました。

O3 グラファイトですが、結局、ストリングホールのやつをもう一本買いました。スピードポートのほうは、嫁が気に入ったので、そのまま使っています。2本あったほうが、試合の時とか便利ですし、いろいろな設定も試せると思うので。で、早速、ためし打ちをかねて、新横浜のテニスコートへいってきました。この新横浜のコートは最近よく使っているコートです。横浜市民なら、はまっ子カードを取得すれば、借りられます。料金も、ほかのコートに比べればかなり安く、できたばかりなので、きれいで、とても気に入ってます。さらによいことに、壁が狭いですがあります。ちょっと早めにコートにいって、壁で練習前にアップする、なんてことも可能です。「2時間じゃ物足りない!」って人にはお勧めです。(ただ、その分、休日とかは混んでいて、なかなか予約取れないですが...)
今日は、やたらと車が多いと思ったら、トヨタカップの日だったんですね。テレビで見るまで気がつきませんでした。トヨタカップを見た方は気づいたかもしれませんが、今日は、やったらと風が強く、あまりテニスに向いていなかったですねー。

それはさておき、やっぱりストリングホールのほうが私には合っているようでした。吸い付く感覚と、ベースライン手前で、ぐっと落ちてくれる感覚がスピードポートだとちょっと感じられなかったので。ストリングホールだと、「引っかかる」感覚で、その調節ができるところがいいですね。ただ、すでに触れましたが、嫁はスピードポートのほうが良いようです。グラファイトの唯一の欠点は、ボレーのしにくさだと思うのですが、スピードポートだと、それはまったく感じられません。ピュアドラと同じぐらいだと思います。で、さらに良いのは、振りぬきがいいからか、飛びすぎないからか、スイングボレーも決まりやすいようです。(嫁に何度か決められました... 前は、ネットに引っかかるのが関の山だったんですけどね)

ということで、小さくあまり力のない女性から、私のような中級中年テニスプレーヤーでも、まったく問題なく使えるラケットでした。フェースが 93 inch というと、とても難しい、上級者ようのモデルのような気がしましたが、使いやすく、お勧めだと思います。(まあ、サーブ & ボレーを主体にする人とかには向かないかもしれないですけど)

http://blogs.sun.com/kenji/date/20081220 2008年 12月 20日 土曜日

JavaFX でデータベースにアクセス - Async を使って非同期で

JavaFX は単一の EDT (イベントディスパッチスレッド) 上で、実行されているので、DB へのアクセスを JavaFX 上で実行すると、たとえば、同じアプリケーション上で、アニメーションを実行していたりすると、そのアニメーションが止まってしまうらしいです。なので、前に作った DB へのアクセス方法を、 Clarkeman's Weblog を参考にして (翻訳版もこの blog に載せてあります) com.sun.javafx.runtime.async パッケージを利用し、非同期で実行することにしました。ただ、ここまでくると、「簡単に」とは言いがたいですね... Clarkeman も言っていましたが、早く JavaFX が非同期実行を簡単に実装できる方法を用意してくれるといいですね。



CustomerLoadImpl の実装 (Java)


データベースの準備等は、「JavaFX でデータベースに簡単にアクセスできるという事実 - その1」とまったく同じです。そして、Java 側にもうひとつ、Customer クラスへの JavaFX 側から、EDT とは別のスレッドからアクセスするために AbstractAsyncOperation を継承した CustomerLoadImpl クラスを実装します。

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 側から呼び出させ、JPA コントローラを使って Customer クラスのオブジェクトを作成します。実際に呼び出しているのは、JavaFX 側に作成される、 CustomerLoad クラスです (後述)。CustomerLoadImpl クラスのオブジェクトが作成され、継承されている start() メソッドが実行されると、オーバーライドで実装されている call() メソッドが呼び出され、JPA コントローラを使って、入力された Id に対応するCustomer オブジェクトを見つけ出し、CustomerLoadImpl の属性に入れておきます。また、この値は、getCustomer() メソッドで取り出せるようにしておきます。

次に 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 クラスのオブジェクトを作成すると、CustomerLoad オブジェクトのstart() メソッドを非同期で実行してくれます。スレッドの処理が終了したら、onCompletion() メソッドを実行して、スレッドを終了します。ここでは、まず、CustomerLoad クラスのオブジェクトが作成されると、Java 側の CustomerLoadImpl クラスのオブジェクトを作成し、CustomerLoadImple オブジェクトの start() メソッドを実行します。これが、先述のように call() メソッドを呼びます。onComplete() は、CustomerLoad を作成する際に、引数として渡されるメソッドで、取得した Customer クラスを引数としてとり、定義された処理を実行します。

最後に CustomerLoad のオブジェクトをボタンがクリックされたときに、以下のように作成します。


var tmpcustomer = new Customer();
var test = CustomerLoad {
customer: tmpcustomer
onComplete: function(cus: Customer) : Void {
if (cus != null) {
CustomerName = cus.getName();
}
}
}

onComplete には、取得した Customer オブジェクトの getName() メソッドの戻り値 (Customer の名前) を CustomerName に代入するメソッドを渡します。CustomerName は、Text にバインドされていて、値が変わるたびに、その値が表示されるようになっています。

これで、実装は完成で、実際に、DB からも値がとってこれたのですが、果たしてこれで、本当に、非同期で実行されているのでしょうか?これを確認するために、 GUI チュートリアルの、雲のアニメーション を無理やり、このアプリケーションに追加しました。以前の「その1 - その3」を使って作ったアプリケーションでは、ボタンを押して、TopLink にアクセスしたときに、確かに、アニメーションが止まってしまいました。ですが、Async を利用した今回のアプリケーションは、アニメーションは止まらず、動いたままでした。どうやらうまく言っているようですね。

JavaFX のソースは ここ においておきました。

http://blogs.sun.com/kenji/date/20081218 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 フレームワーククラスをもっと簡単につくれるようになるかもしれません。

http://blogs.sun.com/kenji/date/20081217 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: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"
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

http://blogs.sun.com/kenji/date/20081215 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.



Step 1: Setup DB


In this example, use Derby (Java DB) for the databse. There are so many examples in NetBeans world to connect Derby from Java code by using NetBeans, so probably you have ever used this DB once. If you did not install Derby, please download the installer which contains derby and kick that installer again (download from netbeans.org).

- 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.



Step 2: Java setting - Generate Entity class


This step is to setup java class to access Database, which will perform like to connect to sample DB and get the corresponding value (from ID to Name). But, you don't need edit source code at all, because NetBeans generate all the code.

- 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.



Step 3: Java setting - Create JPA Controller class


In this step, create JAP Controller.

- 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



Step 4: Add Java DB Drivers Library


- Right Click "Libraries" in the project, and select "Add Library".
- Select "Java DB Driver" and click "Add Library" button



Step 5: Confirm the setting for Java.


Before creating JavaFX UI side, let's try to access the DB by using created java class. You may have Main.java class in the project, and use it to check the access to database.


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());

}


Above is to get "Name" field value from Customer DB, which ID is "1". If you can have output "JumboCom", the java setting is succeeded!



Step 6: Create outline with JavaFX UI


Now you can create JavaFX side. Please create New "JavaFX" project in NetBeans.

- "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"
}
]
}
}
]
}

It's long code, but still empty.

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".



Step 7: Create JavaFX UI detail


The last step is to create the function to access to database in JavaFX script. At first, create "tmpid" to bind textfield input.

var tmpid = "1";
:
:
SwingTextField {
columns: 10
text: bind tmpid with inverse
editable: true
},

Then, create CustomerJpaController instance to access to database. JavaFX can create a instance from Java class by using "new".

var DB = new CustomerJpaController();

CusotmerJpaController is a class defined in your java class, so you may need to resolve the import. Please right click editor, and select "Fix import" to resolve the reference issue (This is the one of the most powerful function in NetBeans. It's worth to learn how to use it). Then, create the function when the button is clicked. It will access to database by using input ID in the textfield, and get the value of Name field from the database. CustomerId is "int" value, which is converted from Sting "tmpid" by using Integer.parseInt method in java. Then, use JPA controller (DB) to get the "Name" field value.

SwingButton {
text: "OK"
onMouseClicked: function( e: MouseEvent ):Void {
CustomerId = Integer.parseInt(tmpid);
CustomerName = DB.findCustomer(CustomerId).getName();
}
}

Please use the same way to fix reference issue. But, only Integer class is the same name as JavaFX primitive type. So, please use following way to include Integer class in Java.

import java.lang.*;

The last thing is, create function to display the result in Text. This is simple to bind to "Name" string, which is get after clicking OK button.

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 .

待っていたインド料理

私と嫁はインド料理が大好きで、家でも、よくわからないスパイスを買ってきては、カレーを作ってみているのですが、近くに本格インド料理屋ができたのはうれしいです。



やるき ZOU


横浜市青葉区藤が丘1-16-10 アーバンプラザ1F


オーダー: やるき ZOU C セット


コメント:
藤が丘周辺では一番いった回数が多いと思います。カレー好きなのもありますが、ほかのお店に比べたら安いので。セットで大体 2000 円弱ぐらいでしょうか。ボリュームもたっぷりでおなかいっぱいになります。ただ、ブログにも何度か書きましたが、インド料理はどうしても、インド本国のものと比較してしまうのです。やっぱり、インド料理はインドで食べるのが一番おいしいですね。値段も、1/5 ぐらいですし。なので、それを差っぴけば、かなり味は Good だと思います。マトンカレーが私のお勧めです。後は、大きく丸く膨らんだパン (名前は忘れてしまいました... ドサをもっと大きく膨らましたような感触です。)


評価: ★★★★☆

http://blogs.sun.com/kenji/date/20081214 2008年 12月 14日 日曜日

JavaFX でデータベースに簡単にアクセスできるという事実 - その3

その2で、JavaFX 側の準備も整ったので、本題の DB につなげてみましょう。まず、テキストフィールドに入力された ID を変数にバインドしておきます。この変数をボタンが押されたときに、ID として使用するためです。


var tmpid = "1";
:
:
SwingTextField {
columns: 10
text: bind tmpid with inverse
editable: true
},

次に、DB につなぐために CustomerJpaController インスタンスを作らないといけません。JavaFX でも、Java と同じように、new を使って、Java クラスから、インスタンスをつくることが可能です。

var DB = new CustomerJpaController();

var を使って JavaFX では変数を定義します。型推論を実装しているので、型を定義する必要はありません。このクラスは、その1で作成されたプロジェクトからインポートされるものなので、エディターを右クリック -> 「import を修正」を使って参照の問題を解決します。(これはもっともよく使う機能の1つなので、もし、使ったことがない方がいたら是非覚えておいたほうがいいと思います)。次にこのインスタンスをボタンが押されたときに作成し、テキストに入力された ID をもとに、Name を引っ張ってくる機能をボタンの onMouseClicked (クリックされたときに実行されるイベントとして書いてみます。この fucntion では、テキストフィールドからバインドされている tmpid を parseInt して、int 型の Id を求めます。これを、DB の findCutomer メソッドにいれ、Customer クラスのインスタンスを取得し、getName メソッドでその名前を Name に入れています。

SwingButton {
text: "OK"
onMouseClicked: function( e: MouseEvent ):Void {
Id = Integer.parseInt(tmpid);
Name = DB.findCustomer(Id).getName();
}
}

先ほどと同じく、インポートの修正を行うと、参照の問題が解決されます。ただし、Integer クラスのみ、JavaFx のプリミティブ型と衝突するので、

import java.lang.*;

のようにインポートします。最後に、この Name というを、表示させる Text にバインドしておけば、完了です。

Text {
font: Font {
size: 18
}
x: 10,
y: 50
content: bind Name
}

これで実装は完了です。簡単ですね。

ただし、Exception 処理等は何もしていないので、へんな値を入れるとすぐに Exception をはいてしまいます。Exception も Java と同じで、try - catch で処理すればいいので、試してみてください。
JavaFX のソースは、ここにおいておきました。

久しぶりの udpae & 和食

blog のアップデートを再開したので、このページも増やしていこうかと。食べるの大好きですから、テニスの次に。



和らぎ


横浜市青葉区藤が丘2-13-1山口第2コーポ1F


オーダー: 華 (コース)


コメント:
近所にある和食屋さんです。ずっと気になっていたのですが、なかなかいく機会がなくて。で、この前、私の誕生日にいってみました。小さなお店ですが、きれいで感じもなかなかよかったです。華 (4000円) のコースをたのんだのですが、どれもおいしい! 和食だと、おなかいっぱいにならないのが、どうも嫌で、あまりいかないのですが、コースということもあって、十分に満足いくものでした。特に、最後に出てくる「浜の炊き込みご飯」は絶品でした。うに、ホタテ、かになど、海の幸を贅沢につかってあって、その味がご飯にしみこんでいます。また、ベースとなっている出汁がいい味でした。何かはさっぱりわかりませんが。藤が丘駅周辺だと、フレンチの鉄人「キャトルフィユ」、イタリアンの鉄人「チンチン」、和食の鉄人「和らぎ」、中華の鉄人「味香亭 (鵬来も捨てがたい)」、ってところでしょうか。もちろん、ミシュランの何とか星のほうがおいしいのかもしれませんが、値段も手ごろだし、歩いて帰れることを考えたら、藤が丘で十分ですね。


評価: ★★★★★

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に続きまーす。


Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.