Contenu connexe
Similaire à Twitter sphere of #twitter4j #twtr_hack (20)
Plus de kimukou_26 Kimukou (10)
Twitter sphere of #twitter4j #twtr_hack
- 2. ● 今日のソース
○ https://bitbucket.org/kimukou_26/twittersphere4j/src
○ にMercurial(HG)で上げてます<練習がてら
● bitbucketには
○ githubみたいな
■ 最新レポジトリのソースのzipダウンロード機能
○ ないみたいなのでごめんなさい
● Windowsの場合は UTF-8のソースなので
○ http://www.asukaze.net/etc/vcs/hg-fixutf8.html
■ を参考にしてダウンロードしてください
● MacのGUIクライアントだと
○ MacHg という物があるようです
- 3. ソース取得後の動かす前の事前設定(1)
● OAuthアプリケーションキーの取得
○ アプリの登録を行います
○ Twitter にログイン後、下記にアクセス
■ http://twitter.com/apps
○ 「create new application」をクリックしてアプリケーションを
登録
○ 登録したアプリの詳細をみる。
○ My Access Tokenをクリック。
■ consumerKey
■ consumerSecret
■ accessToken
■ accessTokenSecret
○ を取得
- 5. ソース取得後の動かす前の事前設定(3)
● IDEA11を使って実行したい場合
○ IDEAインストール
■ startupgroovy で情報まとめられていますので下記参照
■ https://bitbucket.org/kyon_mm/startupgroovy/wiki/Home
○ Griffon関係のIDEA上の設定
■ なんらかのgriffonプロジェクトを作ったり動かす時に
■ GRIFFONのパスをModule(UseLibrary)として追加する必要があり
<Androidとかも同じ
○ 詳細は下記URLのブログを参照
■ http://d.hatena.ne.jp/waman/20111209/1323454481
- 8. どんなプログラムなの?
● NASA World Wind
○ http://worldwind.arc.nasa.gov/java/index.html
● という地球儀を表示するjavaライブラリ
● を使ってTwitterの呟きを地球儀上に置く
● 大元は
○ Twitterのxml,atomをRESTで取得していた
○ griffonが0.2の頃のプログラムだからそのままでは動かな
いよ
- 10. griffonの概略イメージ(1)
● Model・・グローバル変数とか記述
● View ・・表示テンプレート(JSPイメージに近い)
● Controller・・実際のアクション処理を書く
● Service ・・抽象化した共通処理書く
○ 使っている人が少ないようで挙動が微妙な面も
View Controller Model
Service
- 11. griffonの概略イメージ(2)
● BuildConfig.groovy
○ ローカルpluginの参照
○ mavenからdllしてくるjar記述
● lib
○ mavenから落とせないjar等を入れるところ
● script
○ griffonコマンドに割込みする処理を記述します
○ 主にant(Builder)を使ってant処理記述
○ 今回は下記の処理に記述します
■ eventCompileEnd
● コンパイルした後等
● gant
○ antのgroovy拡張です
○ http://www.ruimo.
com/publication/groovyconf/gant.pdf
○ に解説あります
- 12. groovyってなに?
● javaにおけるスクリプト拡張、いわゆる簡単に使う為の糊み
たいな物です(DSLも勿論かけます)
● GroovyConsole等を使うとjavaライブラリを簡単に試す事が
出来ます
○ groovyConsole
● 最近だと
○ NTTデータ さん関連の日経記事が載りました
■ 2012/2/15
○ http://www.ntts.co.jp/products/grails/index.html
- 14. 今回一寸だけ楽になった事
● IDEA11で有料版提供されてたGriffonの機能
<Grailsは有料版のみ提供
○ 無料版 でも提供されるようになった事!
○ ステップデバックも多少は出来るようになるよ!
○ IDEA10より使い勝手はあがりました
● でもデスクトップGUIアプリって人気無いんです
よねー(griffonの一文字も記述無し
○ InfoQ IntelliJ IDEA 11 - 新機能
■ http://www.infoq.com/jp/news/2012/02/idea11
- 18. トレンド取得
def getTrends = { に記述
Twitter API ポケットリファレンス P218
● トレンド取得コード
● 途中からxmlが廃止されてたみたい
○ 元はxml操作コード
● JSON直接操作 (trends.json)
def parser = new JsonParser()
jsonText = new URL("http://api.twitter.com/1/trends.json").openStream().text
def obj = parser.parseObject(jsonText)
trendNames = obj.trends.collect{it.name}
● Twitter4J書換(trends/:woeid.json 日本トレンド絞込に P225)
def trends = twitter.getLocationTrends(locatonID).trends
trendNames = trends.collect{it.name}
- 19. statuses/public_timeline.json
def getPublicResults() に記述
Twitter API ポケットリファレンス P93
XMLをパースする方法の場合(旧コード)
def doc = slurpAPIStream("http://twitter.com/statuses/public_timeline.xml")
doc.status.each {
results << [
icon: it.user.profile_image_url as String,
tweet: it.text as String,
user: it.user.screen_name as String
] Expanddoの
} オブジェクトが
List追加
されているイメージ
- 20. Twitter4Jに書換コード(location情報も取れればセット)
twitter.getPublicTimeline().each{ st->
println "getPublicResults:" +st.dump()
if(model.japanf){
println "st.place=" + st.place?.dump() eachクロージャの中の
f("ja".equals(st.place?.country))return return分はcontinue扱いです
if(!service.chkLangage(st.text))return
}
results << [
icon: st.user.profileImageUrl as String, //Stringに明示的に型変換
tweet: st.text,
user: st.user.screenName
]
f(st.geoLocation!=null){
results.last().pos
=Position.fromDegrees(st.geoLocation.latitude,st.geoLocation.longitude,0)
}
//一度検索済みの場合
else if(model.uMap.get(st.user.screenName)?.pos != null){
results.last().pos = model.uMap.get(st.user.screenName).pos
}
}
- 21. search.json
def getSearchResults(search) { に記述
Twitter API ポケットリファレンス P247
XMLをパースする方法の場合(旧コード)
def url = "http://search.twitter.com/search.atom?q=${URLEncoder.encode(search)}&rpp=${model.
searchLimit}"
//println "url="+url
def doc = service.slurpAPIStream(url)
//println "doc="+doc.dump()
doc.entry.each {
results << [
icon: it.link[1]["@href"] as String,
tweet: it.title as String,
user: (it.author.uri as String)[19..-1] //19文字目から末尾までという意味
]
}
- 22. Twitter4Jに書換コード(location情報も取れればセット)
def q = new Query(search);
q.setRpp(model.searchLimit); //検索リミット数
//日本語限定の検索(過去7日になる)
if(model.japanf){ setLangを指定すると
q.setLang(slocale) 直近7日間の検索
q.setLocale(slocale) になってしまうらしい
}
if(twitter==null)twitter = new TwitterFactory().getInstance()
def arr = twitter.search(q).getTweets();
arr.each{
results << [
icon: it.profileImageUrl as String,
tweet: it.text,
user: it.fromUser
]
if(it.geoLocation!=null){
results.last().pos =Position.fromDegrees(it.geoLocation.latitude,it.geoLocation.longitude,0)
}
//一度検索済みの場合
else if(model.uMap.get(it.fromUser)?.pos != null){
results.last().pos = model.uMap.get(it.fromUser).pos
}
}
- 23. users/show.json
def addLocation(def tweet) { に記述
Twitter API ポケットリファレンス P153
XMLをパースする方法の場合(旧コード)
def twitterUser = slurpAPIStream("http://twitter.com/statuses/public_timeline.xml$tweet.user")
//位置情報をRESTするサービスに問い合わせ
def gnm = service.slurpAPIStream(
"http://ws.geonames.org/search?maxRows=1&q=${URLEncoder.encode(twitterUser.location as
String)}")
if (gnm.geoname.size()) {
tweet.pos = Position.fromDegrees(
Float.parseFloat(gnm.geoname[0].lat as String),
Float.parseFloat(gnm.geoname[0].lng as String),
0);
}
- 24. Twitter4Jに書換コード
def user =twitter.showUser(tweet.user)
//位置情報の取得
tweet.pos = service.getPosition user,model.tweetListPos
//ユーザ座標の記録 showuser呼びまくると
def posObj = new Expando() APIが直ぐ無くなるので
状態は保存する
posObj.pos = tweet.pos
model.uMap.put(tweet.user,posObj)
● Map等で複数の値を持つオブジェクト等を値にしたい時
○ Expando を使うと便利です
■ プログラミングGroovy P206 のコラムに記載があります
○ 動的にプロパティ(値,関数)を生成できます
def obj = new Expando()
obj.name ='ほげほげ'
println "obj.name = ${obj.name}"
- 25. statuses/sample.json
def getStreamResults(){ に記述
Twitter API ポケットリファレンス P273
if(stream == null ){
stream = new TwitterStreamFactory().instance
stream.addListener(listener)
}
stream.sample()
statuses/filter.json
def getFilterResults = { に記述
Twitter API ポケットリファレンス P273
FilterQuery query = new FilterQuery()
query.track([search] as String[])
stream.filter(query)
- 26. StatusListener記述(1)
listener = [
onStatus: { st ->
if(model.japanf){
println "st.place=" + st.place?.dump()
if(st.place !=null && !"ja".equals(st.place?.country))return
if(!service.chkLangage(st.text))return
}
model.tweetList << [
icon: st?.user?.profileImageUrl as String,
tweet: st?.text,
user: st?.user?.screenName
]
if(st?.geoLocation!=null){
model.tweetList.last().pos =Position.fromDegrees(st.geoLocation.latitude,st.geoLocation.
longitude,0)
}
//一度User検索済みの場合
else if(model.uMap.get(st?.user?.screenName)?.pos != null){
model.tweetList.last().pos = model.uMap.get(st?.user?.screenName).pos
}
//model.tweetListPos = 0
//model.searching = false
if(model.searching==false)nextTweet()
},
- 27. StatusListener記述(2)
listener = [
〜略〜
//http://twitter4j.org/ja/code-examples.html
onDeletionNotice:{statusDeletionNotice->
println "Got a status deletion notice id:" + statusDeletionNotice.statusId
},
onTrackLimitationNotice:{numberOfLimitedStatuses->
println "Got track limitation notice:" + numberOfLimitedStatuses
},
onScrubGeo:{ userId,upToStatusId ->
println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId)
},
onException: { ex -> ex.printStackTrace() },
//] as UserStreamAdapter
] as StatusListener
● Streaming処理で使っているリスナー定義です
(コールバック処理)
- 28. def getAsyncResults = {
Twitter API ポケットリファレンス ??
if(asyncTwitter == null ){
asyncTwitter = new AsyncTwitterFactory().instance
asyncTwitter.addListener asynclistener
}
//asyncTwitter.updateStatus(args[0]);
Paging page = new Paging(1,20)
asyncTwitter.getHomeTimeline(page)
//asyncTwitter.getDirectMessages(page)
//asyncTwitter.getMentions(page)
自分で定義した
プロパティ関数
呼んでるイメージ
- 29. TwitterAdapter記述 <AsyncTwitter処理で使用
listener = [
gotHomeTimeline:{statuses ->
List results = []
statuses?.each {st->
if(model.japanf){
if(st.place !=null && !"ja".equals(st.place?.country))return
if(!service.chkLangage(st.text))return
}
results << [
icon: st?.user?.profileImageUrl as String,
tweet: st?.text,
user: st?.user?.screenName
]
if(st?.geoLocation!=null){
results.last().pos =Position.fromDegrees(st?.geoLocation?.latitude,st?.geoLocation?.
longitude,0)
}//一度検索済みの場合
else if(model.uMap.get(st.user.screenName)?.pos != null){
results.last().pos = model.uMap.get(st.user.screenName).pos
}
}
edt {
model.tweetListPos = 0
model.tweetList = results
model.searching = false
if(model.searching==false)nextTweet()
}
},
〜略〜
] as TwitterAdapter
- 30. Streaming等の停止は・・・
def onSearch = { に記述
//streaming 一度止める
//ストリーミング受信
if(stream!=null){
stream.cleanUp()
stream=null viewの表示と同期を取りたい変数に関しては
} edt{
//非同期検索 //実際の処理
if(asyncTwitter!=null){ }
asyncTwitter.shutdown()
asyncTwitter=null 依存しなくても問題無い非同期処理は
} doOutside{
//実際の処理
//GUIと連動している変数は同期を取る }
edt { クロージャの中に記述します
model.tweetListPos = 0
model.tweetList?.clear()
}
● ModelでBindable、Viewでbind と記述されている変数に関しては edt で書換す
る方が良いとされています (値が変わると画面の表示状態が連動して動く為)
● http://www.slideshare.net/kiy0taka/griffong のP46に対応表あり
- 32. griffon plugin編<twitter plugin>(1)
● def twitterと記述するとinstanceが自動DI(インジェクション)されるはずなのにイ
ンスタンスがNullでくる事がある
○ if(twitter==null)twitter = new TwitterFactory().getInstance()
■ の記述を追記
● 「griffon install-plugin twitter」 でPluginをインストール時
● twitter4j.propertiesはinstall時に作るけど、動かす時にclassの位置にコピーし
てくれない
■ =>
○ script/_Events.groovyでclassフォルダにコピー処理記述
● twitter-core 、しかも古いのしか標準ではサポートしていないよ
○ =>
○ じゃあローカル参照しますか
■ 公式にはあまり推奨されていないので多少手を入れる必要があり
- 33. griffon plugin編<twitter plugin>(2)
griffon-twitter/dependencies.groovy
package-pluginの時に参照(公式推奨の記述
正確にはプラグインの griffon-app/conf/BuildConfig.groovy
が変換されたものらしい
//runtime 'org.twitter4j:twitter4j-core:2.2.0'
runtime 'org.twitter4j:twitter4j-core:2.2.6-SNAPSHOT'
runtime 'org.twitter4j:twitter4j-stream:2.2.6-SNAPSHOT'
runtime 'org.twitter4j:twitter4j-async:2.2.6-SNAPSHOT'
griffon-twitter/script/_Events.groovy
ローカル参照でも動かせるようにする時に記述する
compileに変更しておかないとエラーになるので注意!(詳細は次ページ
//compile 'org.twitter4j:twitter4j-core:2.2.0'
compile 'org.twitter4j:twitter4j-core:2.2.6-SNAPSHOT'
compile 'org.twitter4j:twitter4j-stream:2.2.6-SNAPSHOT'
compile 'org.twitter4j:twitter4j-async:2.2.6-SNAPSHOT'
- 34. プラグインのローカル参照記述個所
相対パスでOKです
griffon-app/conf/BuildConfig.groovy 末尾追記
griffon.plugin.location.'eclipse-support'="../griffon-eclipse-support"
griffon.plugin.location.'twitter'="../griffon-twitter"
プラグイン側の修正
grails pluginと微妙に作りが違うので小手先技が必要
griffon-twitter/script/_Events.groovy
//mavenからjarをDL(ダウンロード)してくる記述
eventSetClasspath = { cl ->
manager.parseDependencies { 等記述
//addon のjarコピー記述
eventCopyLibsEnd = { jardir ->
def twitterLibDir = "${getPluginDirForName('twitter').file}/addon"
ant.copy(todir: jardir, overwrite: true ) {
fileset(dir: twitterLibDir, includes: '*.jar')
}
- 35. addon-jarの正規の挙動的には
● install-plugin 時に
○ griffon-app/conf/Builder.groovy
■ root.'TwitterGriffonAddon'.addon=true
○ の追記処理の記述が追加されています
■ griffon-twitter/scripts/_install.groovy に記載あり
● が
○ 相対参照しているときはどうもadd-onは動くような挙動する気がする
○ コントローラ等のEventに対して、DSL記述により
イベント割込を付加するイメージなので、その場合は必要かも
■ 今回はその割込イベント未使用なので記述を有効にしてません
○ 使用サンプルの tweetagile は 0.9.4では動きませんでした
■ http://sourceforge.net/projects/tweetagile/develop
- 36. Nasa World Wind 編
● pluginアップデートで処理関数の記述が変更
● デフォルトのフォントが日本語未対応
■ =>
○ 日本語呟きが化ける
■ =>
○ アプリ側でfontを設定して表示
○ IPAフォントを griffon-app/resources にいれて
○ script/_Events.groovy でclassフォルダにコピー処理記
述
● 地表から300km以下になると地表表示が出来ない
○ 350km辺りで調整
■ plugin 自体は worldwind-0.6.680.14215.jar
を使っていますが最新の1.2でも同じなので公式のその
まま使う
- 37. script/_Events.groovyの記述例
○の箇所(antの知識は必要かも
eventCompileEnd = {msg->
println "==compile end(${msg})=="
growlNotify("eventCompileEnd")
srcDir ="${basedir}/griffon-app/resources"
destDir = "${classesDir}" ant.copy(file:"${srcDir}/twitter4j.properties_t",tofile:"${destDir}/twitter4j.
properties",overwrite:true) //ant.copy(file:"${srcDir}/twitter4j.properties_n",tofile:"${destDir}/twitter4j.
properties",overwrite:true)
destDir = "${basedir}/staging"
copySetting(destDir)
//need TTF & DDL Copy (defaul griffon-app/resources only image file) //○
srcDir ="${basedir}/griffon-app/resources"
destDir = "${classesDir}"
設定は手動でコピーし
ant.copy(todir: destDir, overwrite: true ) {
ましょう。
fileset(dir: srcDir, includes: '*.ddl,*.TTF') な話は結構あります
}
}
- 38. giffon-app/controllers/twittersphere4j/TwitterSphere4JController.groovy
//コントローラ初期化時に最初に通る関数
void mvcGroupInit(Map args) {
if(model.vfont==null)
def fontname="ipag.ttf"
InputStream is=getClass().classLoader.getResourceAsStream(fontname)
model.vfont = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(12.0f)
is.close()
}
//コントローラ終了時(アプリケーション終了時)に必ず通る関数
void mvcGroupDestroy() {
//viewが初期化された後に通るイベントプロパティ関数
def onStartupEnd = {
giffon-app/views/twittersphere4j/TwitterSphere4JView.groovy
def addTweet(pos, user, tweet, tweetImage) {
bean(ga.attributes,
insets: [inset, 48 + inset * 2, inset, inset],
font:model.vfont, //☆ 追加
- 40. giffon-app/service/twittersphere4j/TwitterSphere4JService.groovy
def chkLangage = {msg ->
//http://code.google.com/p/language-detection/wiki/ProjectHomeJa
def detector = DetectorFactory.create()
detector.append(msg)
String cn = detector.detect()
println "detector.detect()=$cn"
if( !"ja".equals(cn) ) return false
return true
}
● ファイル構成は
○ lib/langdetect.jar
○ setting/profiles
● に配置
● script/_Events.groovyに下記にコピー処理記述追記
○ stanging
- 43. 一応Springの技術的には
● UTF-8 encoding and Spring message sources
○ http://www.cakesolutions.
net/teamblogs/2009/04/02/utf-8-encoding-and-
message-sources/
■ みたいな話はあって
○ org.springframework.context.support.
ResourceBundleMessageSource
● =>
○ org.springframework.context.support.
ReloadableResourceBundleMessageSource
○ に差し替えれば可能な記述はあるのですが・・orz
- 46. griffonコマンドの発行
● ベースはコマンドライン開発FWなのでコマンドでコンパイル、実行できたりします
● IDEA上からのコマンド実行は下記な感じ(「griffon clean」実行例
○ griffon の部分は いらない感じです
- 47. よく使うコマンド
● griffon clean
○ コンパイル済みのクラスファイル、
直下のstadingフォルダを削除します
(エラーが出た場合はjavaプロセスを終了して再実行)
● griffon run-app
○ IDEAの実行ボタンと同じ
● griffon install-plugin XXX
○ http://griffon.codehaus.org/Plugins
○ http://svn.codehaus.org/griffon/plugins/
○ に公開されているPluginをインストールして機能拡張が出来ます
● griffon interactive
○ 継続実行が速くできるという奴ですけど。
■ コマンドライン実行では重宝
○ IDEAでやるとOutOfmemoryがよく出るorz
- 50. script/_Events.groovyの記述例
eventCompileEnd = {msg->
println "==compile end(${msg})=="
growlNotify("eventCompileEnd")
//上がキー書いた方、下がキー書いていない方の記述例(認証いらない奴なら下でOK)
srcDir ="${basedir}/griffon-app/resources"
destDir = "${classesDir}" ant.copy(file:"${srcDir}/twitter4j.properties_t",tofile:"${destDir}
/twitter4j.properties",overwrite:true) //ant.copy(file:"${srcDir}/twitter4j.properties_n",
tofile:"${destDir}/twitter4j.properties",overwrite:true)
destDir = "${basedir}/staging"
copySetting(destDir)
//need TTF & ddl Copy (defaul griffon-app/resources only image file)
srcDir ="${basedir}/griffon-app/resources"
destDir = "${classesDir}"
ant.copy(todir: destDir, overwrite: true ) {
fileset(dir: srcDir, includes: '*.ddl,*.TTF')
}
}
- 51. 立ち上がらないんだけど?
● プロセスが正常終了しない場合
○ GUIが立ち上がっていない状態で、タスクマネージャで、
jqs、javaのプロセスが立ち上がっていたら強制終了しま
しょう
■ エラーが発生したりするとSwingプロセスが残ってしま
う
○ mac等
■ ps -aux | grep java 等で確認して kill -9 で
■ コンソール実行している場合は command +・ で
- 53. ClassNotFoundExceptionが・・
● jarのコピー失敗
○ griffon run-app 実行時
○ $HOME/.ivy からjarの存在チェック
● 無ければ maven Repo から自動DL
○ $HOME/.ivy =>stanging フォルダ にコピー
● のどの段階かでライブラリが破損している(DL失敗)恐れがあります
1. stangingフォルダのjarのサイズが小さくないか
a. 「griffon clean」コマンドを行う
2. $HOME/.ivyの位置にjarが存在するかサイズがおかしく
ないか
a. サイズがおかしい場合=>そのjarを消して再実行
b. ダウンロードが動いていないとき
i. BuildConfig.groovy に事前にDL記述を書いて落とす
- 54. griffon-app/conf/BuildConfig.groovy 記述例
language_detection内部でjsonicを使っているのその記述例
griffon.project.dependency.resolution = {
// inherit Griffon' default dependencies
inherits("global") {
}
log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
repositories {
griffonPlugins()
griffonHome()
griffonCentral()
// uncomment the below to enable remote dependency resolution
// from public Maven repositories
//mavenLocal()
//mavenCentral()
mavenRepo "http://maven.seasar.org/maven2/" //DL(ダウンロード)元のMavenレポジトリ
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.5' //jarの中の関連参照なら runtime
compile 'net.arnx.jsonic:jsonic:1.2.0' //ソースのコンパイルに必要ならcompile
}
}
- 56. groovy編(1)
● println "obj=$obj" な形でコンソール出力できます
○ うまく表示されない時は ${obj} のように記述
● オブジェクトの中身は dump() コマンドで表示可能です
○ println "obj=${obj.dump()}"
● オプジェクとのNullチェックは下記のように書けば不要です
○ println "obj=${obj?.dump()}"
○ この場合、objがnullならnullと出力されます
● オブジェクトのプロパティにはダイレクトにアクセスできます
○ obj.A = "テスト"
○ println "obj=${obj.A}"
● 厳密にはこういう話です
https://gist.github.com/1041631
class Hoge {
def xxx = 10
def getXxx() { 100 }
}
def h = new Hoge()
assert h.xxx == 100 // getXxxがあればそちら優先
assert h.@xxx == 10 // フィールド値をダイレクトで取得
assert h.getXxx() == 100 // メソッド値をダイレクトで取得
- 57. groovy編(2)
● def funcA() { } と書くと関数に見えますが、
実はプロパティ扱い(クロージャ変数)です!
○ def func(num){}
■ =
○ def func = {num -> }
○ と同じ意味になります。
○ また引数の型の方も省略する書き方も可能です(自動判
別
● void funcB(){ } みたいな書き方は普通の関数
- 58. groovy編(3)
● クロージャってなんじゃらほ?
○ { }で囲んだ部分の記述 で表現されるCloureという名前のクラスです
■ http://groovy.codehaus.org/api/groovy/lang/Closure.html
○ javascript 等のコールバック関数記述イメージが近いかも
○ 参考資料)
■ Groovyでクロージャ内部で設定してもらった値を利用する
■ http://d.hatena.ne.jp/fumokmm/20101008/1286547976
■ 下記は testというクロージャ変数の例
test {
println it // => 一つ目の引数
println this // => このクラス
println owner // => このクロージャ保有者
println delegate // => このクロージャ移譲先(Objective-Cでいう親クラス参照)
println that // thatで指定された文字列
map.count = 1 // mapも参照できる
map.clos = { that * 3 }
}
- 59. griffon編・・SwingBuilder編(1)
● Plugin拡張をしていない場合、Viewは
SwingBuilderというSwingのDSL拡張で記述
○ http://groovy.codehaus.org/Japanese+Swing+Builder
○ http://groovy.codehaus.org/Alphabetical+Widgets+List
■ の記載情報が編集する為の情報のベースになります
● 「プログラミングGroovy 」の P139
から数ページ少し解説があります
● IBMの技術資料
○ http://www.ibm.com/developerworks/jp/java/library/j-
groovy09299/index.html
● @toby55kij さん SwingBuilderでGroupLayoutを使ってみる。
○ http://www.tobikkiri.org/2009/08/swingbuildergrouplayout.html
- 60. griffon編・・SwingBuilder編(2)
● よく使う奴を列挙してみます
● レイアウト系
○ hbox { } ・・ 横レイアウト
○ vbox { } ・・縦レイアウト
○ レイアウト() みたいに記載するとその直後の奴はそのレイ
アウトで配置できます
■ borderLayout()
■ cardLayout()
■ gridBugLayout()
● http://desmontandojava.blogspot.
com/2012/02/swingbuilder-series-layouts.
html
- 61. GUIパーツの記載イメージ
● 下記みたいにmapイメージで書けます
○ 変数名:値
○ どんな値があるかは、下記みたいに
■ dump()してみるか
■ IDEAで候補出してみるか
● http://d.hatena.ne.
jp/masanobuimai/20090105#1231168963
■ みたいな方法もあります
progressBar(id:'hoge',maximum: bind { model.tweetList?.size() ?: 1 },
value: bind {model.tweetListPos}
)
println hoge.dump()
値の連動関連づけです
Modelクラスの中でBindableと記載があ
る物が対象になります
(今回は全体に付いている)
- 63. griffon編・・SwingBuilder編(4)
● viewで関連づけるClousure参照の記述例ではまることも・・
○ OK例
■ button(id:'DLGBTN1',text:'btn1',
actionPerformed:{controller.&action()})
● closure代入(既存Closureに対してappend(追記)
■ button(id:'DLGBTN2',text:'btn2',
actionPerformed:controller.action)
● closure参照
■ button(id:'DLGBTN3',text:'btn3',
actionPerformed:controller.&action)
● MethodClosure参照
○ NG例
■ button(id:'DLGBTN4',text:'btn4',
actionPerformed:{controller.&action})
● MethodClosure参照をClosure代入しようとしたから駄目
- 64. griffon編・・SwingBuilder編(5)
● 普通のjavaのパーツを
SwingBuilder上に設定する場合2パターンの方
法があります
○ 単純に埋め込み
■ widget
■ http://groovy.codehaus.org/SwingBuilder.widget
● widget(new hogehoge())
○ SwingBuilderにDSL関連づけする場合
■ registerFactory
■ registerBeanFactory
● registerFactory("migLayout", new LayoutFactory(MigLayout))
● registerBeanFactory("led", Led)
- 66. griffon編(2)
● LL言語は基本エディタで開発するのが前提なので
○ =>「最低限以外は自分で書換」 等のお話が多い
■ 解らなければ末尾の方に載っけている、自分より詳し
い方々に聞くと良いかも
● serviceクラスをコマンドで作る時
○ griffon create-service twittersphere4j.TwitterSphere4JService
○ Controller に def service という形で参照したい時
○ Application.groovyに下記の★
記述を追加
'twittersphere4j' {
model = 'twittersphere4j.TwitterSphere4JModel'
view = 'twittersphere4j.TwitterSphere4JView'
controller = 'twittersphere4j.TwitterSphere4JController'
service = 'twittersphere4j.TwitterSphere4JService' //★
}
- 67. griffon編(3)
● airbag plugin とかの説明そのままだと動かなかったり(汗
○ http://griffon.codehaus.org/Airbag+Plugin
■ 実はTwitterSphere4JView.groovyの
記述修正が必要だったりとか・・・
○ application(title: 'TwitterSphere4J',
■ =>
○ mainWindow = application(title: 'TwitterSphere4J',
- 68. IDEAを使うと多少楽になるので
● キーマップに慣れましょう
○ eclipseと大分違うので混乱はします
○ http://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf
● @masanobuimai さんブログIDEA周りの話を読みましょう
○ 初めてIntelliJに触れる人へ
■ http://d.hatena.ne.jp/masanobuimai/20091017/1255784181
■ http://d.hatena.ne.jp/masanobuimai/20091021/1256129174
○ モダンなIntelliJ環境の構築方法 http://d.hatena.ne.
jp/masanobuimai/20100726%231280151977
● IDEAに詳しい人に効いてみましょう
- 72. IDEA11で現状残念な処<use griffon(2)
● ivy経由で取得したjarがうまく認識しない
○ 従ってIDEAの強力機能 => リアルタイム補完 ×
● maven だと下記の記事参考になるようなんだけど・・
● @yusukeyさんの記事 Mars Phoenix の最後の Tweet を IntelliJ IDEA 8 と
Twitter4J を使ってデコードする
○ http://samuraism.jp/diary/2008/11/15/1226684171300.html
@masanobuimai さん記事 Scripting IDE for DSL awareness
○ http://d.hatena.ne.jp/masanobuimai/20091021#1256129173
- 75. eclipseではどう?
● griffon-eclipse-support plugin
○ griffonコマンドを実行するたびに.classpath等更新
○ 公式のだとWinXP等空白パスあるのでは動きません
■ =>
○ 修正してローカル参照で動かしています
○ 一応jarのクラスパスは通っているのでエラーは出ないけど・・
● groovy eclipse plugin 自体が
○ def 等に代入した変数に対して補完きかない
○ そもそもブレークポイントでとまらない事が多い
■ Grailsでは止まるので<STS対応されている為か
- 76. NetBeansでは?
● NetBeansインストール後手動で下記のPlugin等
を追加する必要があり
(すみません。最新版で確認する時間ありませんでした)
● Netbeans griffon plugin
○ http://plugins.netbeans.
org/PluginPortal/faces/PluginDetailPage.jsp?
pluginid=18664
● Netbeans gradle plugin
○ http://plugins.netbeans.org/plugin/41776/gradle
- 78. ネットの情報で学習(お試しレベル
● @fumokmm さんのブログ
○ Groovy基礎文法最速マスター
○ http://d.hatena.ne.jp/fumokmm/20100605/1275736594
○ Groovy全般に関して広い知見を学べます
● 日曜プログラマ劇場
○ http://www.noids.net/groovy/
● 試す実行環境(Javaは別途必要)
○ @bluepapa32 さん GroovyConsole JavaWebStart
■ http://d.hatena.ne.jp/bluepapa32/20101228/1293466511
■ gradleの記事が豊富に書かれているブログです
- 79. ● このインタビューに載っている本を買いましょう
○ 青い本とは何でしょう? 日本鼻メガネの会 の公式読本
でしょうか?
○ http://theinterviews.jp/inda_re/3039859
■ プログラミングGroovyというタイトルです
- 80. ネットの情報で学習(少し慣れてきたら
● @uehaj さんの Grな日々
○ http://d.hatena.ne.jp/uehaj/
■ 最新技術や情報について記載されていますので
中級者~上級者向けかも
● @kazuchika さんの Groovyラボ
○ http://d.hatena.ne.jp/ksky/
○ JavaOne等の情報も絡めたお話があります
● @bikisuke さんの bikisuke in Action
○ http://d.hatena.ne.jp/bikisuke/
Spockのお話とかがあります
- 81. ネットの情報で学習(少し慣れてきたら
● @nobusueさん nobusueの日記
○ http://d.hatena.ne.jp/nobusue/
● @genzouw さんゲンゾウ用ポストイット
○ http://d.hatena.ne.jp/genzouw/
● @kiy0taka さんblog4j 2.0
○ http://d.hatena.ne.jp/kiy0taka/
○ Griffon、Jenkinsの情報が豊富です
- 82. ネットの情報で学習(少し慣れてきたら
● @tyama さんleftovers...
○ http://d.hatena.ne.jp/mottsnite/
○ Grails情報はここが一番充実
● @yamadamasaki さんGrails goes on
○ http://grailsgoeson.metabolics.co.jp/
○ JGGUG主宰の方です
● @nobeans さん豆無日記
○ http://d.hatena.ne.jp/nobeans/
○ GroovyServの開発者の方です
- 83. ネットの情報で学習(少し慣れてきたら
● @literalice さんLiteral Ice
○ http://monochromeroad.blogspot.com/
○ gradleの日本語翻訳をメインでされてます
○ http://monochromeroad.com/artifacts/gradle/userguide/userguide.
html
● @irof さん日々常々
○ http://d.hatena.ne.jp/irof/
○ 全国の勉強会を行脚していらっしゃいます
○ すごく知見に富んだ方です
● 海外サイトだと下記が超有名(コミッタさん)
○ Groovy Goodnes
■ http://mrhaki.blogspot.com/search/label/Groovy%3AGoodness
- 84. 下記のクラスタをフォローしましょう
● Groovyクラスタ
○ 特にJGGUG講師の方はオススメ
○ @orange_clover さんまとめ
○ 今すぐフォローすべき
Groovy界のスーパーエンジニア
■ http://d.hatena.ne.
jp/orangeclover/20110618/1308355956
- 85. ● 日本鼻メガネ会クラスタ(#riskrisk #日本鼻メガネの
会)
■ Groovyクラスタと重なっている人が多いです
■ http://riskrisk.hatenablog.com/entry/2012/02/14/032704
● という組織
■ ただ有能な方々ばかりでお忙しい方々なので
● インタビューズを遣られている方にはそちらで質問しましょう
● inda_re 先生、kyon_mm先生、mike_neck先生あたり
@orange_clover @shinyaa31 @inda_re @riskrisk @kyon_mm @mike_neck @nobusue
- 86. Groovy系の勉強会に参加しましょう
● JGGUG
○ 日本Groovyユーザ会
■ 定期的に
■ http://kokucheese.com/main/host/JGGUG
■ http://grails.jp/
■ #JGGUG ハッシュタグ
○ Grailsドキュメント会 (名古屋)
■ Grailsのドキュメント翻訳をされている @tyama さんが
メインで開催されています
■ http://kokucheese.com/main/host/+Grails%E3%
83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%
B3%E3%83%88%E4%BC%9A
Grailsに関して
日本で一番詳し
い方の一人
- 87. Groovy系の勉強会に参加しましょう
● StartupGroovy
○ 2012 /02 / 18
■ 開催まとめ
● http://d.hatena.ne.
jp/absj31/20120218/1329636558
○ http://kokucheese.com/event/index/26942/
■ 2回目も要望があれば企画されるそうです