UiBinderがうまく動作した件
更新が大幅に遅れてしまいましたが、前回のUiBinderがうまく動作しない件の後、
なんとか最初のとっかかりが出来たので報告します。
最初に、UiBInderで作ったオブジェクトをUiBinder.java、それのui.xmlをUiBinder.ui.xml、gタグで表示されるウィジェットをWigetと呼ぶことにします。
1.最初のページは必ずDockLayoutPanelにする
2.HTMLページへのバインドは必ずRootLayoutPanelにする
これでDockLayoutPanelのスタイルをwidth:100%;height:100%にするとちゃんと表示されます。
ここからいろいろなWidgetなりUiBinderをDockLayoutPanelくっつけていきます。
3.イベントはUiBinder.javaに直接記述する
ButtonのClickもそうですが、TreeのSelectionも直接書けます。
これのいいところは記述量が減るところ、.netのFormのように画面のオブジェクトの動作を
それにくっついているオブジェクトで直接指定できることです。
逆に悪いところは、GWTのサンプルに有るMVPのようにイベントが分離できないことです。
(でもまぁ@fieldでオブジェクトを抽出することで分離することは出来るので不可能ではありません)
4.WidgetのsetなんちゃらメソッドはUiBInder.ui.xmlのプロパティに書ける
これは次の原則とあわせると理解が早いです。
5.Hyperlinkを使ってHistoryの処理を簡単にできる
Historyとの絡みで画面遷移はHyperlinkを使います。
このとき、UiBInder.ui.xmlへは<g:Hyperlink ui:field="main" targetHistoryToken="main">main</g:Hyperlink>
のようにすると、そのHyperlinkをクリックしたとき自動でHistoryにTokenが追加されます。
最後に
6.画面遷移はSimplePanelを挿む
例えばナビゲーターのデータをメインコンテンツのタブに渡すときは、
メインコンテンツをSimplePanelでラップし、データの受け渡しはUiBInder.javaで行うようにします。
画面上のデータを取得するのはUiBinder.ui.xmlではなくUiBinder.javaの方だからです。
また、他のコンテンツに移動したいときもここだけを書き直せばよいので
@UiFactoryを使うよりこっちの方が楽だと思います。
いろいろ書いてきましたが、UiBinderの一番の魅力はこういうことではなくて
従来のHTMLの書き方でGWTのいろんな画面が作れるという点です。(えっ…)
ただそれを可能にするHTMLPanelを使い、その下にDockLayoutPanelを配置すると
DockLaytouPanelがうまく動作しないので、あくまでDockLayoutPanelの下にHTMLPanelを使うか、
DockLayoutPanelを使わずRootに直接書くようにします。
今はBlueprintなどのCSSフレームワークとGWTを組み合わせるのと、
HTML5のタグとWidgetを組み合わせて魅力的なアプリケーションが出来ないかなと考えています。
しかし業務アプリとなると普通のHTMLページとは異なり、
いろいろな機能をそこに追加しそこで何かしらの作業をするわけで、
そうすると例えばLombardiのblueprint(GWT Blueprintでググるとこれが出てきましたが、CSSのBlueprintとは関係が無いようです…)のような
動的な生成やコンテンツ作りには骨が折れる作業になると思います。
その辺を軽減してくれるのがGWTの各種Widget、特にDockLayoutPanelとTabLayoutPanelとなんちゃらSplitPanel、
およびHyperlinkなどなので、表や文章の表示をするUiBinderには
見た目がすっきりするBlueprintのGridを使おうかなと考えています。
なんとか最初のとっかかりが出来たので報告します。
最初に、UiBInderで作ったオブジェクトをUiBinder.java、それのui.xmlをUiBinder.ui.xml、gタグで表示されるウィジェットをWigetと呼ぶことにします。
1.最初のページは必ずDockLayoutPanelにする
2.HTMLページへのバインドは必ずRootLayoutPanelにする
これでDockLayoutPanelのスタイルをwidth:100%;height:100%にするとちゃんと表示されます。
ここからいろいろなWidgetなりUiBinderをDockLayoutPanelくっつけていきます。
3.イベントはUiBinder.javaに直接記述する
ButtonのClickもそうですが、TreeのSelectionも直接書けます。
これのいいところは記述量が減るところ、.netのFormのように画面のオブジェクトの動作を
それにくっついているオブジェクトで直接指定できることです。
逆に悪いところは、GWTのサンプルに有るMVPのようにイベントが分離できないことです。
(でもまぁ@fieldでオブジェクトを抽出することで分離することは出来るので不可能ではありません)
4.WidgetのsetなんちゃらメソッドはUiBInder.ui.xmlのプロパティに書ける
これは次の原則とあわせると理解が早いです。
5.Hyperlinkを使ってHistoryの処理を簡単にできる
Historyとの絡みで画面遷移はHyperlinkを使います。
このとき、UiBInder.ui.xmlへは<g:Hyperlink ui:field="main" targetHistoryToken="main">main</g:Hyperlink>
のようにすると、そのHyperlinkをクリックしたとき自動でHistoryにTokenが追加されます。
最後に
6.画面遷移はSimplePanelを挿む
例えばナビゲーターのデータをメインコンテンツのタブに渡すときは、
メインコンテンツをSimplePanelでラップし、データの受け渡しはUiBInder.javaで行うようにします。
画面上のデータを取得するのはUiBinder.ui.xmlではなくUiBinder.javaの方だからです。
また、他のコンテンツに移動したいときもここだけを書き直せばよいので
@UiFactoryを使うよりこっちの方が楽だと思います。
いろいろ書いてきましたが、UiBinderの一番の魅力はこういうことではなくて
従来のHTMLの書き方でGWTのいろんな画面が作れるという点です。(えっ…)
ただそれを可能にするHTMLPanelを使い、その下にDockLayoutPanelを配置すると
DockLaytouPanelがうまく動作しないので、あくまでDockLayoutPanelの下にHTMLPanelを使うか、
DockLayoutPanelを使わずRootに直接書くようにします。
今はBlueprintなどのCSSフレームワークとGWTを組み合わせるのと、
HTML5のタグとWidgetを組み合わせて魅力的なアプリケーションが出来ないかなと考えています。
しかし業務アプリとなると普通のHTMLページとは異なり、
いろいろな機能をそこに追加しそこで何かしらの作業をするわけで、
そうすると例えばLombardiのblueprint(GWT Blueprintでググるとこれが出てきましたが、CSSのBlueprintとは関係が無いようです…)のような
動的な生成やコンテンツ作りには骨が折れる作業になると思います。
その辺を軽減してくれるのがGWTの各種Widget、特にDockLayoutPanelとTabLayoutPanelとなんちゃらSplitPanel、
およびHyperlinkなどなので、表や文章の表示をするUiBinderには
見た目がすっきりするBlueprintのGridを使おうかなと考えています。
UiBinderがうまく動作しない件
GWT2.0からUiBinderというものが利用できるようになりましたが、
これがうまく動作しません。
普通APIにあるExampleの通りにすると正常に動くものだと思うのですが、
Firefox/Chromeで試したところこんな感じになりました。

お分かりになるでしょうか?centerタグが無視されています。
本来であればbodyが出てこなければいけないのですが、どこにも見当たりません。
ここでcssをすべて切ってみました。すると

文字はちゃんと出力されているようです。
これにより、cssがおかしいことになっていることが分かります。
従来どおりJavaクラスで作るほうは正常に動いています。
サンプルが極端に少ないのとまともに動作しないのとで
UiBinderはしばらく手を出さないほうが無難と思いました。
これがうまく動作しません。
普通APIにあるExampleの通りにすると正常に動くものだと思うのですが、
Firefox/Chromeで試したところこんな感じになりました。
お分かりになるでしょうか?centerタグが無視されています。
本来であればbodyが出てこなければいけないのですが、どこにも見当たりません。
ここでcssをすべて切ってみました。すると
文字はちゃんと出力されているようです。
これにより、cssがおかしいことになっていることが分かります。
従来どおりJavaクラスで作るほうは正常に動いています。
サンプルが極端に少ないのとまともに動作しないのとで
UiBinderはしばらく手を出さないほうが無難と思いました。
cron [App Engine]
cron.xmlでurlを指定するとどうなるのかという動きについて。
urlを指定すると
・そこに何もなければ何も起きない。
・静的なファイル(htmlなど)を置いていても、何も起きない。
・ここに置くのは実ディレクトリではなく、仮想ディレクトリ。
そしてweb.xmlにてそのurlにアクセスしたら起動させるservletを置いておき、
そのservletを起点として処理を記述していく。
こんな感じ
cron.xml
web.xml
たぶん。
urlを指定すると
・そこに何もなければ何も起きない。
・静的なファイル(htmlなど)を置いていても、何も起きない。
・ここに置くのは実ディレクトリではなく、仮想ディレクトリ。
そしてweb.xmlにてそのurlにアクセスしたら起動させるservletを置いておき、
そのservletを起点として処理を記述していく。
こんな感じ
cron.xml
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/recache</url>
<description>Repopulate the cache every 2 minutes</description>
<schedule>every 2 minutes</schedule>
</cron>
</cronentries>
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>comingsoon</servlet-name>
<servlet-class>mysite.server.ComingSoonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comingsoon</servlet-name>
<url-pattern>/recache</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/recache</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
</web-app>
たぶん。
GWT+GAEでhtmlのボタンを押したらどうなるの? [App Engine]
ボタンに登録されたイベントが呼び出されます。
そのイベントの中にservletを呼び出すserviceを登録すれば、それが動作します。
servletはweb.xmlに登録し、servlet-mappingで対応するurlを登録するのですが、
htmlやWEB-INFと対応させるのではなく、
まずclientの*Service.javaのインターフェースに@RemoteServiceRelativePathという属性を追加し、
その中に入れた任意の文字列がurlになります。
servlet-mappingのほうには /(指定のパッケージ名)/(先ほどの任意の文字列 と登録します。
指定のパッケージ名とは、clientのひとつ上のパッケージ名が入ります。
サンプルのStockWatcherなら、clientの*Service.javaというのは
com.google.gwt.sample.stockwatcher.clientにあるStockService.javaで、*がStockに該当します。
指定のパッケージ名はその一つ上のパッケージは
com.google.gwt.sample.stockwatcherなので、stockwatcherに該当します。
ここで任意の文字列をstockにすると、servlet-mappingには
/stockwatcher/stockとはいり、またStockServiceには
@RemoteServiceRelativePath("stock");と入るわけです。
そして、そのstockの表示はStockServiceAsync.javaによってAjax化され
StockWatcher.javaの中でパネル・テーブルやWidgetとして作られ表示されるというわけです。
実際にはGWTがそれをコンパイルしてjavascript化して、
そのjavascriptが画面を作っています。
そのイベントの中にservletを呼び出すserviceを登録すれば、それが動作します。
servletはweb.xmlに登録し、servlet-mappingで対応するurlを登録するのですが、
htmlやWEB-INFと対応させるのではなく、
まずclientの*Service.javaのインターフェースに@RemoteServiceRelativePathという属性を追加し、
その中に入れた任意の文字列がurlになります。
servlet-mappingのほうには /(指定のパッケージ名)/(先ほどの任意の文字列 と登録します。
指定のパッケージ名とは、clientのひとつ上のパッケージ名が入ります。
サンプルのStockWatcherなら、clientの*Service.javaというのは
com.google.gwt.sample.stockwatcher.clientにあるStockService.javaで、*がStockに該当します。
指定のパッケージ名はその一つ上のパッケージは
com.google.gwt.sample.stockwatcherなので、stockwatcherに該当します。
ここで任意の文字列をstockにすると、servlet-mappingには
/stockwatcher/stockとはいり、またStockServiceには
@RemoteServiceRelativePath("stock");と入るわけです。
そして、そのstockの表示はStockServiceAsync.javaによってAjax化され
StockWatcher.javaの中でパネル・テーブルやWidgetとして作られ表示されるというわけです。
実際にはGWTがそれをコンパイルしてjavascript化して、
そのjavascriptが画面を作っています。
Googleのアカウント認証(Appsを含む)だけではちょっと・・・
ログインのセキュリティについて。
Appsのドメイン認証をGAEで行うにしても、
実際に業務アプリで使うには権限に応じた情報の表示と編集をします。
特に人事考課という究極の個人情報は、全員が見られるようなものではなく
管理職だけが編集できるようにする必要があります。
またその他法的、会計的な問題も、会社が指定した人だけが見られるように
しておく必要があると考えます。
Appsのドメイン認証だけではどうしても不十分です。
Appsのサブドメインを変えて別アプリケーションとして立ち上げ、
特定の人だけがわかるようなURLで制御することも考えましたたが、
GAEが認証時にAppsを含むGoogleのアカウント認証システムから得られる情報は
ID、Pass、ニックネーム程度と、
もしURLが見破られた場合上記のセキュリティに耐えられないし、
商品として成り立たなくなります。
いろいろ見ていく中で、GAEのJavadocを読み返してみると
javax.securityが使えることがわかったので、
これをAppsの認証を抜けた後にもう一枚画面をかませて
そこで認証させようと考えています。
ただそれもいろいろ問題がありそうなので、ちょっと時間がかかりそうです。
Appsのドメイン認証をGAEで行うにしても、
実際に業務アプリで使うには権限に応じた情報の表示と編集をします。
特に人事考課という究極の個人情報は、全員が見られるようなものではなく
管理職だけが編集できるようにする必要があります。
またその他法的、会計的な問題も、会社が指定した人だけが見られるように
しておく必要があると考えます。
Appsのドメイン認証だけではどうしても不十分です。
Appsのサブドメインを変えて別アプリケーションとして立ち上げ、
特定の人だけがわかるようなURLで制御することも考えましたたが、
GAEが認証時にAppsを含むGoogleのアカウント認証システムから得られる情報は
ID、Pass、ニックネーム程度と、
もしURLが見破られた場合上記のセキュリティに耐えられないし、
商品として成り立たなくなります。
いろいろ見ていく中で、GAEのJavadocを読み返してみると
javax.securityが使えることがわかったので、
これをAppsの認証を抜けた後にもう一枚画面をかませて
そこで認証させようと考えています。
ただそれもいろいろ問題がありそうなので、ちょっと時間がかかりそうです。
GWTの国際化
html→プロパティ・設定ファイル→javaファイルの順で作っていく。
おおよその説明は、まずhtmlで国際化するところとしないところを分ける。
その国際化する部分をプロパティファイルで、英語=国際化語という形で作る。
プロパティファイル名は規則があって、
htmlに直接表示する静的なものは「<プロジェクト名>Constants_<2文字の国際化言語コード>.properties」
つまりドイツ語なら<プロジェクト名>Constants_de.properties、
日本語なら<プロジェクト名>Constants_jp.propertiesになる。
javaコードに埋め込んで動的に生成するものは「<プロジェクト名>Messages_<2文字の国際化言語コード>.properties」。
これは言語ごとに作る。
次にgwt.xmlファイルでurlの指定を行う。extend-propertyのnameとvalueで、
http://localhost:8080/StockWatcher.htmlの次に「?locale=de」というのを入れると表示される。
nameが?で、valueが=に該当。
言語ごとに作る。
そしてhtmlで静的な部分と動的な部分に分け、
静的な部分にはhtml中のタグにidをつけjavaファイルで切り替えのプログラムを埋め込み、
動的な部分は直接javaファイルに埋め込む。
プロパティファイルとjavaコードのやり取りというか関係の設定は必要なく、
命名規則に従ってプロパティを、作成要領に基づいてjavaコードを作れば自動で認識される。
javaファイルへの埋め込みは、
インターフェースを作り、属性を追加し、
エントリクラスのonModuleメソッド内でそのインスタンスをGWT特有のメソッドで作り、
静的な部分はパネルのidを取得してからラベルで貼り付け、
動的な部分はその部分に直接貼り付け、
両方とも文書(メッセージ)を呼び出す。
これでOK。
次以降でいよいよServerとの通信を取り扱う。
その後にデータストアとの接続を行う。
おおよその説明は、まずhtmlで国際化するところとしないところを分ける。
その国際化する部分をプロパティファイルで、英語=国際化語という形で作る。
プロパティファイル名は規則があって、
htmlに直接表示する静的なものは「<プロジェクト名>Constants_<2文字の国際化言語コード>.properties」
つまりドイツ語なら<プロジェクト名>Constants_de.properties、
日本語なら<プロジェクト名>Constants_jp.propertiesになる。
javaコードに埋め込んで動的に生成するものは「<プロジェクト名>Messages_<2文字の国際化言語コード>.properties」。
これは言語ごとに作る。
次にgwt.xmlファイルでurlの指定を行う。extend-propertyのnameとvalueで、
http://localhost:8080/StockWatcher.htmlの次に「?locale=de」というのを入れると表示される。
nameが?で、valueが=に該当。
言語ごとに作る。
そしてhtmlで静的な部分と動的な部分に分け、
静的な部分にはhtml中のタグにidをつけjavaファイルで切り替えのプログラムを埋め込み、
動的な部分は直接javaファイルに埋め込む。
プロパティファイルとjavaコードのやり取りというか関係の設定は必要なく、
命名規則に従ってプロパティを、作成要領に基づいてjavaコードを作れば自動で認識される。
javaファイルへの埋め込みは、
インターフェースを作り、属性を追加し、
エントリクラスのonModuleメソッド内でそのインスタンスをGWT特有のメソッドで作り、
静的な部分はパネルのidを取得してからラベルで貼り付け、
動的な部分はその部分に直接貼り付け、
両方とも文書(メッセージ)を呼び出す。
これでOK。
次以降でいよいよServerとの通信を取り扱う。
その後にデータストアとの接続を行う。
サンプルから分かること
GWTのStarterGuideからStockWatcherを作ってみましたが、
例えば
「ハイパーリンクを左側に追加して別のページを右側に表示させたい」(Gmail風)
「そのページにある一つのコンテンツの入力フォームを作って、データを登録させたい」
「ボタンを押すと計算が始まるようにしたい」
とふと思ったときに対応できてこそ一人前だと思うのです。
後で思い出せるようにメモします。
初っ端
1.Eclipseでプロジェクトを作る
2.htmlにidをつける
3.javaファイルで作業する(スタイルはcssとgwt.xmlも)
4.コンパイルする
新しいアプリケーションを作る
初っ端の2.から
既存のアプリケーションに機能を追加・削除する
初っ端の3.から
初っ端の3.の詳細
1.ウィジェットとパネルとテーブルを作る
2.ウィジェットをパネルとテーブルに貼り付ける
3.ウィジェットのイベントを作る→動作を作る(このときにPOJOも作る)
4.動作確認
5.gwt.xmlで大まかなレイアウトを決める
6.ウィジェットやパネルなどのスタイルをjavaファイルのそれとcssで決める
7.動作確認
現状はこんなところです。
次はInternationalizing。
例えば
「ハイパーリンクを左側に追加して別のページを右側に表示させたい」(Gmail風)
「そのページにある一つのコンテンツの入力フォームを作って、データを登録させたい」
「ボタンを押すと計算が始まるようにしたい」
とふと思ったときに対応できてこそ一人前だと思うのです。
後で思い出せるようにメモします。
初っ端
1.Eclipseでプロジェクトを作る
2.htmlにidをつける
3.javaファイルで作業する(スタイルはcssとgwt.xmlも)
4.コンパイルする
新しいアプリケーションを作る
初っ端の2.から
既存のアプリケーションに機能を追加・削除する
初っ端の3.から
初っ端の3.の詳細
1.ウィジェットとパネルとテーブルを作る
2.ウィジェットをパネルとテーブルに貼り付ける
3.ウィジェットのイベントを作る→動作を作る(このときにPOJOも作る)
4.動作確認
5.gwt.xmlで大まかなレイアウトを決める
6.ウィジェットやパネルなどのスタイルをjavaファイルのそれとcssで決める
7.動作確認
現状はこんなところです。
次はInternationalizing。
はじめまして [App Engine]
急に思い立ってApp Engineで業務アプリを作ることにしました。
App Engineだけというわけではなく、Google Appsも絡めます。
後、pdfとcsvの出力と保管もやります。これはAppsのGoogle Sites Data Apiを使えば何とかなると信じています。
難しいフレームワークは使いません。
今のところ予定は
・GWTとGAE/J
だけです。
見た目のよい、使い勝手のよいUIならJQuery+BluePrintやFlash、
またAdobe Airなんていいかなと思っているのですが、
見た目がgmail風のサンプル(showcase)がGWTに用意されていたのと、
印刷はブラウザに任せてしまおうかと思うと、もう手っ取り早くこれを使おうと決めた次第です。
Appsを使うのはgmail, calendar, document, spreadsheetをイントラ内で使うためです。
当初はStandard Editionだけにしようと考えていたのですが、
業務で使うとなるとバックアップやセキュリティの事を考えなければならず、
それにはどうしてもAppsのAPIが必要になってくるので
年間6000円かかってしまいますが、Premier Editionを導入するプランも検討することにしました。
この業務アプリはローカルOSに自作ソフトをインストールしません。
すべてをクラウドで片付けます。
ローカルで行うのはブラウザで表示されたアプリの使用、
帳票の印刷、バックアップしたファイルのダウンロード程度に収めようと思います。
出来るかどうか分からないので、こっそり進めたいと思います。
開発期間は半年を見込んでいます。
このブログは自分のメモとして使っています。
しかしこういうことが低価格で出来るようになるなんて
すごい世の中になったもんだ。
App Engineだけというわけではなく、Google Appsも絡めます。
後、pdfとcsvの出力と保管もやります。これはAppsのGoogle Sites Data Apiを使えば何とかなると信じています。
難しいフレームワークは使いません。
今のところ予定は
・GWTとGAE/J
だけです。
見た目のよい、使い勝手のよいUIならJQuery+BluePrintやFlash、
またAdobe Airなんていいかなと思っているのですが、
見た目がgmail風のサンプル(showcase)がGWTに用意されていたのと、
印刷はブラウザに任せてしまおうかと思うと、もう手っ取り早くこれを使おうと決めた次第です。
Appsを使うのはgmail, calendar, document, spreadsheetをイントラ内で使うためです。
当初はStandard Editionだけにしようと考えていたのですが、
業務で使うとなるとバックアップやセキュリティの事を考えなければならず、
それにはどうしてもAppsのAPIが必要になってくるので
年間6000円かかってしまいますが、Premier Editionを導入するプランも検討することにしました。
この業務アプリはローカルOSに自作ソフトをインストールしません。
すべてをクラウドで片付けます。
ローカルで行うのはブラウザで表示されたアプリの使用、
帳票の印刷、バックアップしたファイルのダウンロード程度に収めようと思います。
出来るかどうか分からないので、こっそり進めたいと思います。
開発期間は半年を見込んでいます。
このブログは自分のメモとして使っています。
しかしこういうことが低価格で出来るようになるなんて
すごい世の中になったもんだ。







