忍者ブログ
雇われるだけの人生から目指せ独立、社会人2年目なゲーム脳SEのブログ。更新頻度=週2~3回。
[5]  [6]  [7]  [8]  [9]  [10]  [11]  [12]  [13]  [14]  [15
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

うまくいかなかったのがあまりにも悔しかったので、引き続きGreasemonkeyの話題です。
昨日のスクリプトを書き直すことにします。やることは前回の地点ですでに明らかになっています(要するに、再描画が行われるタイミングで、styleの値を取得して書き換えるだけ!)。後はリファレンスサイトをを読みながら試行錯誤すればうまくいくに違いありません。昼休み時間を30分ほど使って挑戦してみました。

というわけで、突貫工事ですが、なんとかできました。↓こちらです。
googlenotebookcustomizer_0_2

ソースを見ていただければわかりますが、いかにもJavaプログラマくさい記法になっていますので、生粋のJavascript使いの方がごらんになられると冗長に感じられるかもしれません。でもまぁ、初心者でもわかりやすくソースを書くのがモットーですので、そこはご勘弁願いたいです。
今回Javascriptについて勉強になったことは以下の通り。
  • 匿名関数の中でさらに関数を宣言することが可能(このあたりがオブジェクト指向ですねー)
  • onresizeリスナ
  • Element.styleフィールド

さて、これで今度こそ綺麗にラベル欄の枠が広がるはず。
早速Greasemonkeyに装備してGoogleノートブックに行ってみました。
が!
一瞬だけ枠が広がるのですが、すぐまた元に戻ってしまいます。何故!?
どうやらonresizeのタイミングよりも後になってからラベル欄の枠のサイズの調整が行われているみたいです。これでは、イベントリスナを使ってもうまくいきそうにありません・・・どうしましょう。

仕方がないので再度勉強して出直してきます。
google notebookでwikiっぽくリンクを張る
こちらのサイトのスクリプトが参考になりそうです。紹介されているスクリプトは、なにやらタイマーのような機能を使って、2秒おきに全体を描き直す処理をやっています。これを真似すればうまくいくかもしれません!!
しばらくは昼休みが退屈しないですみそうです。
PR
Greasemonkeyをなめらかモンキーと書くとやわらか戦車みたいでいいですね。
一応ぐぐってみましたけど、まだ無いみたいです、なめらかモンキー。登録商標をとるなら今ですよ!

さて。本題に入ります。
普段から大活躍している私のGoogleノートブックの中身が汚くなっていたので、久しぶりに大掃除をしていらないメモを捨て、メモの分類をやり直したり、ラベルをつけ直したりしてみました。
ラベルをつけ直しているとラベルの量がどんどん増えてくるのですが、そこで気になったのが・・・

WS000074.JPG

この左下のコピーライトが書いてある領域。

そのとき、ふと私の頭にこんな考えが浮かびました。
「ここを消せばあと2個ラベルが余分に表示できる」

ようし、なら消してしまえ!近頃こういう新しいチャレンジがなくてめっきり頭が鈍っていたところです。こんなおもしろい話を逃すものかと、さっそくGreasemonkeyのスクリプトを書いてコピーライトを消してしまおうと思い立ちました。JavascriptでDOMを使う勉強にもなります。
JavascriptのDOMを使う上で、今回参考にしたサイトはこちら。
http://www.javascriptkit.com/domref/elementmethods.shtml
http://youmos.com/news/getelementsby
http://www.openspc2.org/JavaScript/JavaScript_DOM/

肝心のGreasemonkeyスクリプトの書き方はこちらを参考にいたしました。
http://www.google.com/notebook/public/18412722587928953882/BDSaYIgoQyaWT1b4h

まずはコピーライト部のソースをチェック。

<div class="rh" id="gn0_4">~中略~</div>

このようになっています(詳しくはご自身でソースをご確認ください・・・)。ということは、このid="gn0_4"の要素を削除してやれば、コピーライト部全体が消えて無くなるはずです。早速スクリプトを書いてみましょう。
完成品がこちら。→googlenotebookcustomizer.user.js
といっても別段妙なことはしていません。Greasemonkeyスクリプトのお約束通り、匿名関数を定義して、その中でイベントリスナーを作成し、DOMで要素を取得&削除する関数を定義しているだけです。

早速、動かしてみました。消えてくれるかな!?

b3b01262.jpeg

やった!消えた!!
・・・ってあれ?ラベル欄が広がりません。なぜ?

不審に思ってラベル欄のソースを見てみました。すると・・・

    <div class="we kd">
        <div style="height: 176px;" tabindex="0" class="na" id="gn2_0">
            <div id="gn2_1">
                <div id="gn6" class="aa x" tabindex="-1">
                    Blog (1)
                </div>
                <div id="gn7" class="aa x" tabindex="-1">
                    Eclipse (4)
                </div>
                <div id="gn8" class="aa x" tabindex="-1">
                    Java (5)
                </div>
            </div>
        </div>
    </div>


なんだかheightの数値がべた書きです。
どうもこのソース、javascriptで動的に生成されているみたいなんです。
ですからこの高さを生成するロジックに手をつけるわけにはいきません。しかも、ウィンドウのサイズが変わり次第、毎回高さが変わりますから・・・
  1. ウィンドウサイズが変わったときに呼び出されるイベントリスナーを新規作成する。
  2. そのイベントリスナーの中で、gn2_0要素を取得して、取得した要素のstyle属性の値を書き換える。
という処理を行ってやる必要がありそうです。こいつは困った・・・出直してきます。

こうして私のGreasemonkey初体験はなめらかな結果に終わったのでした・・・
前々回の最後に描いたいけてないシーケンス図・・・
↓こちらです

bc0cbbbf.jpeg

これをばっちり描き直しました。これで最終版です。ご覧ください!

ad08b8fa.jpeg

どうでしょう。会心のできです。
それでは個々のクラスについて説明いたします。

○CreateNotebookAction
コントロールクラスです。コントロールクラスは一つのシナリオに1個つくります。
こうしておくと、現在は画面上のボタンを押したときだけ実行されるノートブック作成動作を拡張して、メニューからノートブック作成ができるようにしたいときでも、このコントローラを呼ぶだけですむという便利なシステムになります。まぁ、Strutsの構造をパクっただけとも言うんですが。

○NotebookDao
ノートブックを作成するDAO(Data Access Object)です。ノートブックに対して、永続記憶装置へのCRUD機能を提供します。ものっすごくかみ砕いてわかりやすくすると、ノートブックをファイルに書き出して保存したり、ファイルから読み込んだりするクラスです。
ファイルではなくてデータベースに書き込みたい場合や、ファイル保存にしてもテキストベースからYAMLやXMLで保存するようにしたいなんて時は、このクラスだけをいじれば解決します。

異常系の処理についてですが、CreateNotebookActionクラスの中で例外をキャッチして処理を行います。本当はこのActionクラスを呼び出すローダークラス(ファサードクラスっていうんだっけ)を用意して、そこで例外処理をするようにすれば例外処理を個々のActionの中に書き込まなくてすむため非常に楽なのですが、そのファサードを作るのが非常に面倒なため今回はパスします。ヘタレでごめんなさい。



次回の内容ですが、一つシナリオも出来たことですし、そろそろ実装してみましょうかと考えています。本当ならステートチャート図やアクティビティ図みたいな重要な図があるのでそちらもやりたいところなんですが、こんな小さいシステムでは使いどころが少なすぎるというのと、単純に飽きてきたからそろそろ実装したいという私の自分勝手すぎる事情があります。ほんとすみません。

それではまた!
前回は概念クラス図&一気にすっとばしてノートブック作成の相互作用図を書いてみました。あまりにもすっ飛ばしすぎたので、一体全体何をやっているのかわからなかった方もいらっしゃると思います。というわけで、図の残りの部分を直しながら、きちんとした解説を行います。

まず「相互作用図(Interaction Diagram)とは何か」ですが、クラスやオブジェクトなどの登場人物間のメッセージ(message)のやりとりを表現する図です。クラス図は関係(relation)に重点を置いた静的な図だったのですが、こんどは動きをあらわそうというわけです。

たとえば、私と会社というクラスがあったとして、
クラス図なら、私と会社の間に線を引いて「雇用」という関連(assosiation)を定義しますが、
相互作用図なら、私から会社に「労働する」というメッセージを送り、
会社から私にその返り値として「給与」を渡すのが正しいことになります。
↓図にするとこんな感じです。

7fb446fb.jpeg クラス図と・・・

0de29b70.jpeg 相互作用図(シーケンス図)。

相互作用図にはシーケンス図:Sequence Diagramとコラボレーション図:Collaborating Diagram(UML2.0だとコミュニケーション図:Communication Diagram)の二つが含まれます。
この二つの図は見た目は違えど全く等価なものを表しているため、相互に変換することが可能です。
詳しいことは↓以下に挙げるようなWebページを参照していただければと思います。
@IT
WisdomSoft
列挙しながら思いましたが、「ココを見ておけば盤石」みたいなUML解説サイトがないですね・・・
一応、@ITの記事が量も質も高いのでおすすめです。でもやっぱり本を買うのがベストかなぁと思います。

話を元に戻しまして。先ほど挙げましたWebサイトを見て学習すれば、図の要素が何を意味しているのかは何となくでもわかると思います。しかし、最大の問題は「ではどうやってゼロからクラス図や相互作用図を描くのか」です。UMLはただの言葉ですので、意味を知っていても、どうやって既存のクラスやオブジェクトをその言葉で表現するのかがわからなければ役に立たないわけです。このあたりは、なかなか紹介されていません。

教科書(はじめて学ぶUML 第2版)には284ページから285ページのあたりに、次のように紹介されています。


一つのシナリオは一つの相互作用図に対応します、シナリオは自然言語を使い、箇条書きで作成しました。これをオブジェクト同士のメッセージのやりとりに変えていきます。この際のオブジェクト候補には概念モデルで抽出したクラス候補を利用します。
(中略)
バウンダリィクラス(ユーザやプリンタ、スキャナなど、今作っているシステムの外とシステムを結びつけるクラス)はこのようにシーケンス図で使用すると、クラスの役割が明確になり、図がより生成しやすくなります。この例でスタッフが情報を「商品リスト」「商品」などエンティティクラス(実際にこの世界に存在するものや概念を表すクラス)に入力するのは違和感を感じると思います。スタッフが販売処理画面に情報を入力するほうがシーケンス図をより自然な流れにします。


どうでしょう、わかりますか?
まったくUMLを知らない、オブジェクト指向もようやく覚えたばかりという人がこの文章を見て「自然な流れ」とか言われても、きっとさっぱり理解できないに違いありません。なんで「商品」クラスに直接データを入れてはならないのかが「自然」とか言われても・・・って感じです。きっと。

こんなときは身近なものに例えて考えてみます。
商品クラスを倉庫、データを荷物と考えます。この倉庫に、今はあなたは何か荷物を入れたいと考えています。どうしますか?考えているだけでいきなり倉庫の中に荷物が入ったりはしませんよね。
倉庫の中に荷物を入れるためには、倉庫と荷物の他に、
  • 荷物の取得元(他の倉庫?港?空港?工場?)
  • 荷物を運送するルート(どの経路を通って?どこに?誰を使って?)
  • 荷物を運送するもの(素手で?トラックで?フォークリフトで?はたまたヘリコプターで豪快に?)
これだけのものが必要になるはずです。これならばっちりイメージ沸きますよね。
ここで、倉庫と荷物を商品クラスとデータに戻してみます。すると・・・
  • データの取得元(画面?テキストファイル?データベース?他のシステムから?)
    バウンダリクラス
  • データを運送するルート(どのクラスを通って?どのメソッドを使って?)
    コントロールクラス
  • データを運送するもの(JavaのAPIを使って?XMLを使って?SQLを発行して?)
    エンティティクラス
お!なんだかそれっぽくなりましたね!!これでどうして商品クラスに直接データを入れることができないかがイメージできると思います。
あとは図を描く際に実装をイメージすることが大事かなと思います。描いたものは最終的に必ず実装することになるので、実装できないものを描くことはできないからです。というわけで、ある程度実装に詳しくないと厳しいかなーと・・・このあたりはやって慣れろですかねー・・・
いよいよVisual Editorの学習も終わりましたことですし、今回は張り切って抽象クラス図の続きと相互作用図を作成していきます。まずは思いつくまま、GUIを抽象クラス図に組み込んでみました。

76b8c6f9.jpeg

・・・何だこれは。
イケてない、最高にイケてないです!イメージが全く沸いてきません。どうしたものでしょう。
原因を考えてみました。
そうだ!
やはりこんな時は紙に書き下ろしてみるのが一番です。画面イメージは眺めていてもアイディアが出てこないですし、後まわしにして先にロジックを考えましょう。
それから日本語名のクラスだと実装イメージがわいてこないので全部英語名にしてしまいましょう。
それからそれから、集約(Aggregation)関係はJudeでソースをはき出す際に配列にされてしまいますから、明示的にjava.util.List<E>をパラメータバインドして・・・

32db19cd.jpeg

こうして新しく作成したクラスと既存のList<E>をテンプレートバインディング関係(bind relation)で結んで・・・

8c168572.jpeg

クラス名を削除すると匿名のバインドクラスができる!そこからさらに・・・

TO000023.JPG

実パラメータを設定!よしうまくいった!
Listをそのままエンティティとして使うなんてのはナンセンスだから新しくリスト用のエンティティを作って・・・

a89fe691.jpeg

よっし!これでどうだ!!
テンション上がってきたついでに相互作用図いってみるかー!
まずはノートブック作成のシーケンス図を作ってみるよ-!!

fff72ddf.jpeg

シーケンス図だから、こうやって適当にクラスとかオブジェクトを並べてライフライン(lifeline)を引く。余談だけれども、UML1.Xではオブジェクトからライフラインが伸びているイメージだけど、UML2.0では上の四角い箱やらよくわからない丸い記号も含めてライフラインと呼ぶらしい。線じゃあないのにラインだなんてなんだか変な話!
閑話休題、まずは俺(ユーザクラスのオブジェクトね)から画面(これはまだクラス構成が決まっていないから、暫定的にオブジェクトにしてみました)にボタンを押しましたメッセージを引いてみる!

09371227.jpeg

すると画面からはよくわからない仕組みでロジックが呼び出される!
呼び出されたロジックはこれまたよくわからない仕組みで先ほど抽象クラス図で定義したNotebookListを画面に返すわけだ。すると画面はこれを受け取ってノートブックを画面に表示する。うむ、簡単簡単、実にシンプルだ。
ロジックをわざわざ画面と分離して、画面から直接NotbookListを作る仕組みにアクセスしないのは、画面の部分がSwing実装からWebアプリケーションに変化してもロジックを一切変更しないでそのまま移植できる強みがあるから。こうして画面表示(View)とデータやロジック(Model, Control)を分離する作りが世間でよく言われているMVCという奴らしい。
どんどんインスピレーションがわいて来た。それじゃ次はロジックからデータを取得してくるクラスに対してメッセージを送ってみるか!

bc0cbbbf.jpeg

ちょちょいのちょいっと。
まずはNotebookInstanceManagerさんにノートブック作ってくれーっとメッセージを投げる。
その内容を元にNotebookInstanceManagerはNotebookをNewする(コンストラクタを呼び出す)、これでNotebookがつくられた。
作られたNotebookをそのままにしていちゃプログラムが終了したらデータが消えてしまう。当然何かにデータを残さなくちゃならない。今回はデータベースなんて用意していないから、ファイルシステムを使う。だから、ファイルシステムに対して保存してくれーと命令を投げる。ここは今のところ、Javaの標準APIを使う予定。
本当ならココもパーシスタ層といって、永続記録装置・・・要するにデータベースとかファイルシステムとか・・・に対して、データを保存する専門のクラスを作る方がいいんだけど、あまり深く考えず省いた。まぁ、最初だし。

で、保存もできたらあとはこのノートブックをNotebookListにつめて返却すればいいんだけど、じゃあそのNotebookListはどこから用意するの?(当然中身が空だとまずい。最後に作ったノートしか入っていないリストが返されることになるから)とか、そもそも本当にcreateNewNotebookの返値はNotebookListでいいのかとか(ノート作るのに成功しましたサインだけ返せばよくって、その後もう一回ノートリストを取得するためのメッセージをコントローラから投げればいいんじゃないかとか)、それ以前にノートの保存に失敗したらどうするのとか、突っ込みどころがどんどん出てきてもう大変。だんだんテンションも下がってきた。今日はここまで!



・・・すみません、途中から思いっきりテンションだけで書き連ねてしまいました。
本当はもっと教科書(はじめて学ぶUML 第2版)に即した形で進めたかったのですが、私の習熟度不足のせいで上手く型にはめることができませんでした。もうノリとテンションばっかりです。お恥ずかしい。

ただ、この図を描いていて感じたのは、「行き詰まったらとにかく別の図を書いてみるとうまくいく」ことでしょうか。
とにかくわかっているところから表現しやすい図にどんどん落とし込んでいくと、視点も切り替わり次々とアイディアがわいてくるものです。もし皆さんもUMLを描く機会がありましたら、クラス図に行き詰まったら相互作用図を、相互作用図に行き詰まったらまたクラス図に戻って続きを描いてみるなど、理解度の深い場所から進めることを(勝手に)おすすめいたします。

それよりなにより、Judeのバインドパラメータの使い方がわかったのが今回の最大の収穫ですね。何度テンプレートバインディング関係を張っても上手くできなくって半ばあきらめかけていたのですが、まさか新しくクラスを作って、それに対して線を引いてから名前を消すとは思いませんでした・・・難しい。

今回はこのあたりで失礼いたします。次回は最後に沸いてきた突っ込みどころを今日作った図に反映していきます!
前回は、本プロジェクトのGUI作成を担うであろうVisual Editorを学ぶため、Eclipse3.3非公式対応版のVisual Editorをインストールしてテスト起動を行うところまでやりました。このページのve_eclipse_34_v200711170100_win.zipというバージョンを使用しています。


今回は↓こちらのページを教科書にしまして、一通りVisual Editorを触ってみました。
Visual Editor メモ
それではさっそく見ていきましょう。



まずは教科書通り、フォームを作成し、表を追加してみることにしました。

TO000031.JPG

こんな感じです。うまくいきました。
ただし、先ほどのページでは

ここでDefaultTableModelを選択し、OKを押すとソースコードにgetDefaultTableModelというメソッドが追加されます。このメソッドで初期化を行います。以下、編集例です。

という風に紹介されていましたが、実際には自動的にソースコードには追加されませんでした。Visual Editorのバージョンが異なるからでしょうか?仕方がないので、手動でDefaultTableModelクラスをフィールドに追加して、設定してみました。

続いてパネルを作成し、先ほどのフォーム上に配置してみます。

TO000032.JPG

できました。まだボタンを押しても何も起こりません。ActionもActionListenerも登録されていないからです。というわけで、こんどはActionListenerをつけてみましょう。これも、右クリックメニューから一発です。

TO000033.JPG

ボタンを押すとコンソールに文字が出るようになりました。また、Exitボタンを押すときちんとアプリケーションが終了するようになりました。だいぶGUIアプリケーションらしくなりましたね。
一つ気になる点として、リスナークラスを登録する際に、どの選択肢を選んでも~Listenerか~Adapterを実装・拡張した匿名クラス(Anonymous Class)が自動的に登録されてしまいます。要するに、自分でListenerクラスを作ってみたりとか、内部クラスとしてListenerクラスを実装することができません。もちろん手でソースを修正すればよいのですが、面倒です。
といってもまぁ、Listenerクラスがやることなんて、共通化してあるロジックを呼び出したり、せいぜいコンポーネントの見た目を変えたりする程度の処理(行数にして10行以下)ですから、Listenerクラスをいちいち明示的に宣言するメリットはないということかもしれませんね。どうしてもそうしたいならば、Actionを使えばいいわけですし。

さて、今度はLayoutを使わない各種コンポーネントの配置を試してみました。

TO000035.JPG

こんな感じです。ボタンを押下するとコンソールに入力された文字列が出ています。ここではウィンドウサイズを変更できないようにして、レイアウトが崩れるのを防いでいます。ダイアログウィンドウなどに応用できそうですね。


一通りやってみて気づいたことですが、
このVisual Editorプラグインは、各種GUIコンポーネントを、GetterのみをもつBeanとして扱うような設計になっています。また、各種イベントリスナーは基本的には匿名クラスで実装され、どうしても複雑なことをやりたいときはActionインターフェースを実装して行うという方針。
下位のパネルから親パネルに対してアクセスしたいときは、getRootPaneとかgetTopLevelAncestorを使えばよさそうです。たぶんgetRootPaneで正解だと思うのですが・・・このあたりは実際に使ってみないと何ともいえないです。

つまり、まとめますと、
  • 各種ボタンはJButtonクラスのオブジェクトとする
  • 各種フレームやパネルはJPanelクラスを拡張したクラスとし、getterメソッドを持たせる
などなど、各種部品は基本的に既存のswingコンポーネントのオブジェクトとして表現すれば上手くUMLで表すことができるようです。

このあたりを踏まえまして閑話休題(今度こそ使い方あっているはず)、いよいよ次回はUMLに話題を戻しまして、抽象クラス図の設計と、相互作用図の作成に入っていきます。
ヤフオクのためだけにYahooのプレミアム会員になったのですが、解約しようと思い立ちました。
久しぶりにニコ動を覗いたら、ずいぶん前の動画ですが、こんなのを見つけました。
また番外編です。本編より番外編のほうが多くなってしまいました。
閑話休題ばっかりで前に進まないことこの上ない企画です。だがそれがいい。

前回の概要クラス設計で、大量のGUIコンポーネント(主にボタン)が登場してきました。こいつらの扱いを決定したいと考えています。
今回のプロジェクトでは、画面をVisual Editorプラグインを用いて設計したいと考えておりますので、できる限りこのVisual Editorによる開発に即した設計をしなければなりません。このように開発時に特殊なツールやフレームワークを使用する際には、それによる制約が設計にもかかってしまいます。

ですが問題が二つ。
  1. Visual EditorはEclipse3.3に正式に対応していない
  2. 私はVisual Editorを使ったことがない
・・・どうやらまた、本編に入る前に番外編でお勉強が必要なようです。

今日はとりあえずインストールまで。↓こちらのBlogで紹介されている手法を使い、Visual Editorをインストールします。
Eclipes 3.3.1.1 で VisualEditor

一見大変面倒そうに見えますが、WTPのインストールはPleiades WTPパックを使用した私には関係ありませんし、.eclipseextensionを使用するのはEclipse拡張機能としてインストールする場合だけなので、http://www.ehecht.com/eclipse_ve/ve.html←このページの最新ファイルを解凍して、そのままfeaturesフォルダとpluginsフォルダをEclipseホームにぶち込んでクリーンスタートすれば普通に使えます。

TO000030.JPG

無事、起動できました!

さて、明日からは使い方を学ぶわけですが・・・こちらのサイトが参考になりそうです。
Visual Editor メモ
これに沿ってやってみましょう。できる限りはやく本線に戻らないといけませんし・・・w
カレンダー
03 2024/04 05
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
ブログ内検索
最新コメント
[11/13 DSLR-A850]
[08/29 逆援助交際]
[08/23 クンニ]
[08/22 熟女]
[08/19 痴漢]
はてなブックマーク
プロフィール
HN:
akisute
性別:
男性
職業:
システムエンジニア
趣味:
ゲーム・東方・ニコ動。あと散歩。
バーコード
推奨環境

横幅900px以上、Firefox 3, Safari 3, Opera 9.5, Chrome 0.2以上。IE7ギリギリ対応。IE6未対応。

忍者ブログ [PR]