SlideShare una empresa de Scribd logo
1 de 87
Descargar para leer sin conexión
TwitterSphere of
Twitter4J


       2012/02/23
      @kimukou2628
   
● 今日のソース
   ○ 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 という物があるようです
 
 
ソース取得後の動かす前の事前設定(1)

● OAuthアプリケーションキーの取得
 ○ アプリの登録を行います
 ○ Twitter にログイン後、下記にアクセス
   ■ http://twitter.com/apps
 ○ 「create new application」をクリックしてアプリケーションを
   登録
 ○ 登録したアプリの詳細をみる。
 ○ My Access Tokenをクリック。
   ■ consumerKey
   ■ consumerSecret
   ■ accessToken
   ■ accessTokenSecret
 ○ を取得
  
ソース取得後の動かす前の事前設定(2)

● TwitterSphere4J/griffon-app/resources の中の
  ○ twitter4j.properties_n をコピー
  ○ twitter4j.properties_t を作成
● 取得した情報をtwitter4j.properties_t の方に書込
  ○ その際に # のコメントは外します
 
● 実行手順)
  ○ Macの場合
     ■ sh runw.sh で実行
  ○ Winの場合
     ■ runw.bat のJAVA_HOMEを修正、実行
ソース取得後の動かす前の事前設定(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
〜基礎知識編〜
元にしているプログラム
● JavaOne 2009 のGriffon
  のデモアプリ

● @kazuchikaさんブログに
  まとめあり


● http://d.hatena.ne.
  jp/ksky/20090613/p1
どんなプログラムなの?
● NASA World Wind
    ○ http://worldwind.arc.nasa.gov/java/index.html
● という地球儀を表示するjavaライブラリ
● を使ってTwitterの呟きを地球儀上に置く
 
 
 
● 大元は
    ○ Twitterのxml,atomをRESTで取得していた
    ○ griffonが0.2の頃のプログラムだからそのままでは動かな
      いよ
 
griffonって何?
● codehausさんで作られている
● Groovy製のMVCイメージのGUIフレームワークです(デフォルトSwing拡張)
● pluginでjavafxにも対応は出来ます(groovyFX
  ○ codehaus さん
      ■ SpringSource=>VMWare って感じの系列
      ■ jetty(Androidの人なら i-jettyで知っている人多いかな?)も提供
● 詳しく知りたい人は

  ○ @kiy0taka さんのGマガジンのGriffon連載をぜひ
    ■ http://grails.jp/g_mag_jp/
    ■ Griffon不定期便〜G*ワークショップ編〜
         ●   http://www.slideshare.net/kiy0taka/griffong

         
griffonの概略イメージ(1)
●   Model・・グローバル変数とか記述
●   View ・・表示テンプレート(JSPイメージに近い)
●   Controller・・実際のアクション処理を書く
●   Service ・・抽象化した共通処理書く
    ○ 使っている人が少ないようで挙動が微妙な面も


    View       Controller   Model




                  Service
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
                ○ に解説あります
               
groovyってなに?
● javaにおけるスクリプト拡張、いわゆる簡単に使う為の糊み
    たいな物です(DSLも勿論かけます)
●   GroovyConsole等を使うとjavaライブラリを簡単に試す事が
    出来ます
    ○ groovyConsole
 
 
● 最近だと
    ○ NTTデータ さん関連の日経記事が載りました
      ■ 2012/2/15
    ○ http://www.ntts.co.jp/products/grails/index.html
Griffonに日本で一番詳
しい方の一人です

Jenkinsのコミッター
としても有名です




                 さん達とお仕事できる
                 かも~
今回一寸だけ楽になった事
● IDEA11で有料版提供されてたGriffonの機能
  <Grailsは有料版のみ提供
 ○ 無料版 でも提供されるようになった事!
 ○ ステップデバックも多少は出来るようになるよ!
 ○ IDEA10より使い勝手はあがりました
 
● でもデスクトップGUIアプリって人気無いんです
  よねー(griffonの一文字も記述無し

 ○   InfoQ IntelliJ IDEA 11 - 新機能
     ■   http://www.infoq.com/jp/news/2012/02/idea11
〜デモ〜
〜Twitter(4J)絡みの解説〜
● http://twitter4j.org/ja/api-support.html
● の対応表を後で確認しながら読み返して頂けると
● 理解は深まると思います

   ○ もしくは

● Twitter API
  ポケットリファレンス
  (POCKET REFERENCE)
  ○ 山本 裕介 (著)


● を見比べながら確認してください
トレンド取得
      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}
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追加
                                                         されているイメージ
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
       }
}
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文字目から末尾までという意味
      ]
}

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

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

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


 
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処理で使っているリスナー定義です
        (コールバック処理)
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)
 


                               自分で定義した
                               プロパティ関数
                               呼んでるイメージ
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
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に対応表あり
〜今回はまった処〜
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 、しかも古いのしか標準ではサポートしていないよ
    ○ =>
    ○   じゃあローカル参照しますか
        ■   公式にはあまり推奨されていないので多少手を入れる必要があり
 
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'
 
プラグインのローカル参照記述個所
    相対パスで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')
         }

 
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
   

       
Nasa World Wind 編
● pluginアップデートで処理関数の記述が変更
● デフォルトのフォントが日本語未対応
       ■ =>
    ○ 日本語呟きが化ける
       ■ =>
    ○ アプリ側でfontを設定して表示
    ○ IPAフォントを griffon-app/resources にいれて
    ○ script/_Events.groovy でclassフォルダにコピー処理記
      述
●   地表から300km以下になると地表表示が出来ない
    ○ 350km辺りで調整
       ■ plugin 自体は worldwind-0.6.680.14215.jar
      を使っていますが最新の1.2でも同じなので公式のその
      まま使う
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')                                      な話は結構あります
      }
}
                                   
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, //☆ 追加
StremingAPIで国で絞り込めない
● @jontaniさんに教えて頂いた language_detection で
  呟き内容の言語判定で対応
  ○ http://d.hatena.ne.
    jp/n_shuyo/touch/20111125/language_detection
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
IDEAでpropertiesのnative2ascill変換のや
り方側が悩んだ
●   結論から言うと下記な形。デフォルトでONになってない
IDEAの操作的にはこんな感じ
一応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
 
Springとは
● GrailsやGriffon等Groovy系のFWで使われているコアライブ
    ラリ群です
    ○ SpringSourceで開発されています
      ■ 国内ではSeasar人気ですが
          ● 日本人のひがやすおさんが作られていて
          ● マニュアルが日本人ドキュメントの為
      ■ 日本人は英語ドキュメント嫌いな人が多いんですよね
         ~
      ■ だから海外の会社系FWは日本語マニュアル揃えた
         りする労力が・・・
 
〜griffonの
 基本オペレーション
 (IDEA)〜
griffonコマンドの発行
●   ベースはコマンドライン開発FWなのでコマンドでコンパイル、実行できたりします
●   IDEA上からのコマンド実行は下記な感じ(「griffon clean」実行例
     ○ griffon の部分は いらない感じです
よく使うコマンド
● 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
〜開発時によく困る事〜
認証情報等が入ったファイルの管理
● 認証情報が入った twitter4j.properties って上げちゃうの恐
  いですよね(下記みたいな呟きが出てしまう
 
 
 
 
 
● その場合は
  ○ scripts/_Events.groovy にファイル名変えてコピーの処理を記述
     ■ DVCS管理用のダミーファイルは用意しておきましょう
  ○ .hgignore(.gitignore)に除外処理を書いておきましょう
 
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')
     }
}
                              

 
立ち上がらないんだけど?

● プロセスが正常終了しない場合
 ○ GUIが立ち上がっていない状態で、タスクマネージャで、
   jqs、javaのプロセスが立ち上がっていたら強制終了しま
   しょう
    ■ エラーが発生したりするとSwingプロセスが残ってしま
       う
 ○ mac等
    ■ ps -aux | grep java 等で確認して kill -9 で
    ■ コンソール実行している場合は command +・ で
変更が反映されない、コンパイルエラーが・・
● griffon clean コマンドを実行します
  ○ 実行の仕方は以下(IDEAから実行するときは 「clean」)
  ○ cleanコマンドで エラーが出るときはタスクマネージャ等(ps)でjavaプロセス
     がいないか確認しましょう
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記述を書いて落とす
  
  
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
    }
}
 


 
〜知っておくと
  一寸コードが
  読みやすくなる事〜
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 // メソッド値をダイレクトで取得
groovy編(2)

    ●   def funcA() { } と書くと関数に見えますが、
        実はプロパティ扱い(クロージャ変数)です!
         ○ def func(num){}
            ■ =
         ○ def func = {num -> }
         ○ と同じ意味になります。
         ○ また引数の型の方も省略する書き方も可能です(自動判
           別
 
    ●   void funcB(){ } みたいな書き方は普通の関数
         
 
 


         
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 }
 }
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
     
griffon編・・SwingBuilder編(2)

● よく使う奴を列挙してみます
 
● レイアウト系
  ○ hbox { } ・・ 横レイアウト
  ○ vbox { } ・・縦レイアウト
  ○ レイアウト() みたいに記載するとその直後の奴はそのレイ
    アウトで配置できます
    ■ borderLayout()
    ■ cardLayout()
    ■ gridBugLayout()
       ● http://desmontandojava.blogspot.
           com/2012/02/swingbuilder-series-layouts.
           html
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と記載があ
                                            る物が対象になります
                                            (今回は全体に付いている)
griffon編・・SwingBuilder編(3)

● controllerとの関連づけはactionPerformed等に
  記載します
  ○ 普通のjavaだとListnerが渡されていますが
  ○ groovyの場合はクロージャを渡します
    ■ 渡し方の記載例は次ページ


button(getMessage("view.label.Search"),
    actionPerformed: controller.onSearch,
    enabled:bind {!model.searching},
    margin: new Insets(5, 10, 15, 20)
)
 
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代入しようとしたから駄目
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)
griffon編(1)
● griffon自体のイメージをつかむには
 
● @waman10da さん Griffon の世界
    ○ http://www5.ocn.ne.
      jp/~coast/programming/groovy/griffon.html
     
    ○   あたりが一番詳しいです。
    ○   ただかなり高度な内容もありますので(数学知識も必要)
    ○   わからないところは読み飛ばしてよいかと思います
 
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' //★
  }
griffon編(3)

● airbag plugin とかの説明そのままだと動かなかったり(汗
  ○ http://griffon.codehaus.org/Airbag+Plugin
    ■ 実はTwitterSphere4JView.groovyの
       記述修正が必要だったりとか・・・
   
  ○ application(title: 'TwitterSphere4J',
    ■ =>
  ○ mainWindow = application(title: 'TwitterSphere4J',
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に詳しい人に効いてみましょう
〜今後に期待編〜
IDEA11で現状残念な処<use griffon(1)
● griffon-app/conf/BuildConfig.groovy
  ○ griffon.plugin.location.プラグイン名が認識しない・・。
  ○ 手動で追加も出来ない
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
IDEA11で現状残念な処<use griffon(3)
● スレッド周りの処理にブレークポイントを貼っても止まらない
    事が多い
●   普通のJavaプログラムでもそうなんですが
    ○   スレッドプログラムでエラー
        ■   =>
    ○   処理中断 でストール な現象になる事が多い
 
● src/main/java がちゃんと認識しない
  ○ その他の部品等は src/main/java,src/main/groovy とディレクトリを掘ってい
        れます
 
 
 
IDEAで今後出来たらいいなと思うこと

● Viewのプレビュー表示
    ○ IDEA11でAndroidのレイアウトプレビューが出来るよう
      になったのでこちらも期待したいなー
 
● groovyファイル(Controller)の関数表示がツリー
  に出てくると楽
    ○ 今は関数名等を検索しないと駄目
    ○ 関数Jumpが今は出来ない ><
 
eclipseではどう?

● griffon-eclipse-support plugin
   ○ griffonコマンドを実行するたびに.classpath等更新
   ○ 公式のだとWinXP等空白パスあるのでは動きません
     ■ =>
   ○ 修正してローカル参照で動かしています
   ○ 一応jarのクラスパスは通っているのでエラーは出ないけど・・
   

● groovy eclipse plugin 自体が
   ○ def 等に代入した変数に対して補完きかない
   ○ そもそもブレークポイントでとまらない事が多い
     ■ Grailsでは止まるので<STS対応されている為か
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
〜groovyを勉強するには〜
ネットの情報で学習(お試しレベル

● @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の記事が豊富に書かれているブログです
● このインタビューに載っている本を買いましょう
 ○ 青い本とは何でしょう? 日本鼻メガネの会 の公式読本
   でしょうか?
 ○ http://theinterviews.jp/inda_re/3039859
    
   ■ プログラミングGroovyというタイトルです
ネットの情報で学習(少し慣れてきたら

● @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のお話とかがあります
ネットの情報で学習(少し慣れてきたら

● @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の情報が豊富です
ネットの情報で学習(少し慣れてきたら
● @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の開発者の方です
ネットの情報で学習(少し慣れてきたら
● @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
下記のクラスタをフォローしましょう

●   Groovyクラスタ
    ○ 特にJGGUG講師の方はオススメ
       
    ○ @orange_clover さんまとめ
    ○ 今すぐフォローすべき
      Groovy界のスーパーエンジニア
      ■ http://d.hatena.ne.
         jp/orangeclover/20110618/1308355956
     
     
●   日本鼻メガネ会クラスタ(#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
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に関して
   
日本で一番詳し
い方の一人
   
Groovy系の勉強会に参加しましょう
● StartupGroovy
  ○ 2012 /02 / 18
    ■ 開催まとめ
       ● http://d.hatena.ne.
          jp/absj31/20120218/1329636558

  ○ http://kokucheese.com/event/index/26942/
    ■ 2回目も要望があれば企画されるそうです
   

Más contenido relacionado

La actualidad más candente

C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~Fujio Kojima
 
C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~Fujio Kojima
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesShintarou Okada
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Uehara Junji
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Yasutaka Kawamoto
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development lifeUehara Junji
 
UnityでC#を勉強しはじめた私の主張
UnityでC#を勉強しはじめた私の主張UnityでC#を勉強しはじめた私の主張
UnityでC#を勉強しはじめた私の主張Ryota Murohoshi
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
 
Good Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyGood Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyYuya Takeyama
 
appengine ja night #4 Transaction Puzzlers
appengine ja night #4 Transaction Puzzlersappengine ja night #4 Transaction Puzzlers
appengine ja night #4 Transaction PuzzlersSuguru ARAKAWA
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオンTakuya Ueda
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
PEP8を読んでみよう
PEP8を読んでみようPEP8を読んでみよう
PEP8を読んでみよう2bo 2bo
 

La actualidad más candente (20)

C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
 
C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development life
 
UnityでC#を勉強しはじめた私の主張
UnityでC#を勉強しはじめた私の主張UnityでC#を勉強しはじめた私の主張
UnityでC#を勉強しはじめた私の主張
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
Good Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyGood Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX Philosophy
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
 
appengine ja night #4 Transaction Puzzlers
appengine ja night #4 Transaction Puzzlersappengine ja night #4 Transaction Puzzlers
appengine ja night #4 Transaction Puzzlers
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオン
 
コルーチンの使い方
コルーチンの使い方コルーチンの使い方
コルーチンの使い方
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
PEP8を読んでみよう
PEP8を読んでみようPEP8を読んでみよう
PEP8を読んでみよう
 

Destacado

Webサイト向けAPI #twtr_hack
Webサイト向けAPI #twtr_hackWebサイト向けAPI #twtr_hack
Webサイト向けAPI #twtr_hackYusuke Yamamoto
 
ApiDemos of Twitter4J for Android #twtr_hack
ApiDemos of Twitter4J for Android #twtr_hackApiDemos of Twitter4J for Android #twtr_hack
ApiDemos of Twitter4J for Android #twtr_hackbina1204 Hozuki
 
Spring3.1概要 AOP & MVC
Spring3.1概要 AOP & MVCSpring3.1概要 AOP & MVC
Spring3.1概要 AOP & MVCYuichi Hasegawa
 
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hack
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hackVirtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hack
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hackTakeshi Iwasaki
 
Twitter bootstrap入門 #twtr_hack
Twitter bootstrap入門 #twtr_hackTwitter bootstrap入門 #twtr_hack
Twitter bootstrap入門 #twtr_hackToshiaki Maki
 
差別化で未来を生き抜く エンジニアの7つの秘訣
差別化で未来を生き抜く エンジニアの7つの秘訣差別化で未来を生き抜く エンジニアの7つの秘訣
差別化で未来を生き抜く エンジニアの7つの秘訣Yusuke Yamamoto
 

Destacado (7)

Webサイト向けAPI #twtr_hack
Webサイト向けAPI #twtr_hackWebサイト向けAPI #twtr_hack
Webサイト向けAPI #twtr_hack
 
ApiDemos of Twitter4J for Android #twtr_hack
ApiDemos of Twitter4J for Android #twtr_hackApiDemos of Twitter4J for Android #twtr_hack
ApiDemos of Twitter4J for Android #twtr_hack
 
Spring3.1概要 AOP & MVC
Spring3.1概要 AOP & MVCSpring3.1概要 AOP & MVC
Spring3.1概要 AOP & MVC
 
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hack
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hackVirtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hack
Virtua Fighter5 Final ShowdownのTwitter連動機能について #twtr_hack
 
Spring3.1概要x di
Spring3.1概要x diSpring3.1概要x di
Spring3.1概要x di
 
Twitter bootstrap入門 #twtr_hack
Twitter bootstrap入門 #twtr_hackTwitter bootstrap入門 #twtr_hack
Twitter bootstrap入門 #twtr_hack
 
差別化で未来を生き抜く エンジニアの7つの秘訣
差別化で未来を生き抜く エンジニアの7つの秘訣差別化で未来を生き抜く エンジニアの7つの秘訣
差別化で未来を生き抜く エンジニアの7つの秘訣
 

Similar a Twitter sphere of #twitter4j #twtr_hack

Androidの通信周りのコーディングについて
Androidの通信周りのコーディングについてAndroidの通信周りのコーディングについて
Androidの通信周りのコーディングについてShoichi Takagi
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)Fujio Kojima
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック庸介 高橋
 
Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Takashi EGAWA
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Kenta Oono
 
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会Jumpei Ogawa
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとかyouku
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programmingtakesako
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526 masahitojp
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんかcch-robo
 

Similar a Twitter sphere of #twitter4j #twtr_hack (20)

Teclab3
Teclab3Teclab3
Teclab3
 
Androidの通信周りのコーディングについて
Androidの通信周りのコーディングについてAndroidの通信周りのコーディングについて
Androidの通信周りのコーディングについて
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)
 
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとか
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programming
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
Tokyor23 doradora09
Tokyor23 doradora09Tokyor23 doradora09
Tokyor23 doradora09
 

Más de kimukou_26 Kimukou

JRebel for Android 1.2.14 update
JRebel for Android 1.2.14 updateJRebel for Android 1.2.14 update
JRebel for Android 1.2.14 updatekimukou_26 Kimukou
 
JRebel for Android 1.0 を試食してみた
JRebel for Android 1.0 を試食してみたJRebel for Android 1.0 を試食してみた
JRebel for Android 1.0 を試食してみたkimukou_26 Kimukou
 
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用kimukou_26 Kimukou
 
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築kimukou_26 Kimukou
 
Try_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackTry_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackkimukou_26 Kimukou
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggugkimukou_26 Kimukou
 
明日から使えるgradle
明日から使えるgradle明日から使えるgradle
明日から使えるgradlekimukou_26 Kimukou
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてkimukou_26 Kimukou
 

Más de kimukou_26 Kimukou (10)

JRebel for Android 1.2.14 update
JRebel for Android 1.2.14 updateJRebel for Android 1.2.14 update
JRebel for Android 1.2.14 update
 
JRebel for Android 1.0 を試食してみた
JRebel for Android 1.0 を試食してみたJRebel for Android 1.0 を試食してみた
JRebel for Android 1.0 を試食してみた
 
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用
レガシー環境で個人ベースでなんとか頑張るDVCS(Git)運用
 
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
 
Try_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackTry_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hack
 
Griffon10 in groovy_fx
Griffon10 in groovy_fxGriffon10 in groovy_fx
Griffon10 in groovy_fx
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggug
 
明日から使えるgradle
明日から使えるgradle明日から使えるgradle
明日から使えるgradle
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用について
 
Hudson using Groovy #jggug
Hudson using Groovy  #jggugHudson using Groovy  #jggug
Hudson using Groovy #jggug
 

Último

論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 

Último (10)

論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 

Twitter sphere of #twitter4j #twtr_hack

  • 1. TwitterSphere of Twitter4J 2012/02/23 @kimukou2628  
  • 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 ○ を取得  
  • 4. ソース取得後の動かす前の事前設定(2) ● TwitterSphere4J/griffon-app/resources の中の ○ twitter4j.properties_n をコピー ○ twitter4j.properties_t を作成 ● 取得した情報をtwitter4j.properties_t の方に書込 ○ その際に # のコメントは外します   ● 実行手順) ○ Macの場合 ■ sh runw.sh で実行 ○ Winの場合 ■ runw.bat のJAVA_HOMEを修正、実行
  • 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
  • 7. 元にしているプログラム ● JavaOne 2009 のGriffon のデモアプリ ● @kazuchikaさんブログに まとめあり ● http://d.hatena.ne. jp/ksky/20090613/p1
  • 8. どんなプログラムなの? ● NASA World Wind ○ http://worldwind.arc.nasa.gov/java/index.html ● という地球儀を表示するjavaライブラリ ● を使ってTwitterの呟きを地球儀上に置く       ● 大元は ○ Twitterのxml,atomをRESTで取得していた ○ griffonが0.2の頃のプログラムだからそのままでは動かな いよ  
  • 9. griffonって何? ● codehausさんで作られている ● Groovy製のMVCイメージのGUIフレームワークです(デフォルトSwing拡張) ● pluginでjavafxにも対応は出来ます(groovyFX ○ codehaus さん ■ SpringSource=>VMWare って感じの系列 ■ jetty(Androidの人なら i-jettyで知っている人多いかな?)も提供 ● 詳しく知りたい人は ○ @kiy0taka さんのGマガジンのGriffon連載をぜひ ■ http://grails.jp/g_mag_jp/ ■ Griffon不定期便〜G*ワークショップ編〜 ● http://www.slideshare.net/kiy0taka/griffong  
  • 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
  • 17. ● http://twitter4j.org/ja/api-support.html ● の対応表を後で確認しながら読み返して頂けると ● 理解は深まると思います ○ もしくは ● Twitter API ポケットリファレンス (POCKET REFERENCE) ○ 山本 裕介 (著) ● を見比べながら確認してください
  • 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, //☆ 追加
  • 39. StremingAPIで国で絞り込めない ● @jontaniさんに教えて頂いた language_detection で 呟き内容の言語判定で対応 ○ http://d.hatena.ne. jp/n_shuyo/touch/20111125/language_detection
  • 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
  • 41. IDEAでpropertiesのnative2ascill変換のや り方側が悩んだ ● 結論から言うと下記な形。デフォルトでONになってない
  • 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  
  • 44. Springとは ● GrailsやGriffon等Groovy系のFWで使われているコアライブ ラリ群です ○ SpringSourceで開発されています ■ 国内ではSeasar人気ですが ● 日本人のひがやすおさんが作られていて ● マニュアルが日本人ドキュメントの為 ■ 日本人は英語ドキュメント嫌いな人が多いんですよね ~ ■ だから海外の会社系FWは日本語マニュアル揃えた りする労力が・・・  
  • 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
  • 49. 認証情報等が入ったファイルの管理 ● 認証情報が入った twitter4j.properties って上げちゃうの恐 いですよね(下記みたいな呟きが出てしまう           ● その場合は ○ scripts/_Events.groovy にファイル名変えてコピーの処理を記述 ■ DVCS管理用のダミーファイルは用意しておきましょう ○ .hgignore(.gitignore)に除外処理を書いておきましょう  
  • 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 +・ で
  • 52. 変更が反映されない、コンパイルエラーが・・ ● griffon clean コマンドを実行します ○ 実行の仕方は以下(IDEAから実行するときは 「clean」) ○ cleanコマンドで エラーが出るときはタスクマネージャ等(ps)でjavaプロセス がいないか確認しましょう
  • 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と記載があ る物が対象になります (今回は全体に付いている)
  • 62. griffon編・・SwingBuilder編(3) ● controllerとの関連づけはactionPerformed等に 記載します ○ 普通のjavaだとListnerが渡されていますが ○ groovyの場合はクロージャを渡します ■ 渡し方の記載例は次ページ button(getMessage("view.label.Search"), actionPerformed: controller.onSearch, enabled:bind {!model.searching}, margin: new Insets(5, 10, 15, 20) )  
  • 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)
  • 65. griffon編(1) ● griffon自体のイメージをつかむには   ● @waman10da さん Griffon の世界 ○ http://www5.ocn.ne. jp/~coast/programming/groovy/griffon.html   ○ あたりが一番詳しいです。 ○ ただかなり高度な内容もありますので(数学知識も必要) ○ わからないところは読み飛ばしてよいかと思います  
  • 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に詳しい人に効いてみましょう
  • 70. IDEA11で現状残念な処<use griffon(1) ● griffon-app/conf/BuildConfig.groovy ○ griffon.plugin.location.プラグイン名が認識しない・・。 ○ 手動で追加も出来ない
  • 71.
  • 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
  • 73. IDEA11で現状残念な処<use griffon(3) ● スレッド周りの処理にブレークポイントを貼っても止まらない 事が多い ● 普通のJavaプログラムでもそうなんですが ○ スレッドプログラムでエラー ■ => ○ 処理中断 でストール な現象になる事が多い   ● src/main/java がちゃんと認識しない ○ その他の部品等は src/main/java,src/main/groovy とディレクトリを掘ってい れます      
  • 74. IDEAで今後出来たらいいなと思うこと ● Viewのプレビュー表示 ○ IDEA11でAndroidのレイアウトプレビューが出来るよう になったのでこちらも期待したいなー   ● groovyファイル(Controller)の関数表示がツリー に出てくると楽 ○ 今は関数名等を検索しないと駄目 ○ 関数Jumpが今は出来ない ><  
  • 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回目も要望があれば企画されるそうです