<!DOCTYPE HTML> <html lang = "ja"> <head> <title>課題A3 (JHotDraw)</title> <meta charset = "UTF-8"> <link rel = "stylesheet" type = "text/css" href = "../../../prettify.css"> </head> <body> <h1>課題A3</h1> <p> 課題A3では, JHotDrawの図形の移動機能について見ていきます.<br> JHotDrawはオープンソースの図形描画ツールで, Javaで書かれております.<br> ワークスペース内のjhotdraw7が、JHotDrawを構成するプロジェクトです。 </p> <hr> <h2>実行手順</h2> <p> <ol> <!-- <li class = "explanation"> デスクトップのEclipseを起動し, 指定されたワークスペースを開いてください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_01.png" class = "threeQuartersSize"></div> </li> --> <li class = "explanation"> ワークスペース中にあるjhotdraw7プロジェクトを選択し, メニューバーの Search → Java で DefaultDragTracker という型の宣言を検索してください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_02.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_03.png" class = "quarterSize"></div> </li> <li class = "explanation"> DefaultDragTrackerクラスのソースファイルを開いて159行目 (DefaultDragTracker#mouseDragged(MouseEvent)) にブレークポイントを入れてください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_04.png" class = "threeQuartersSize"></div> </li> <li class = "explanation"> メニューバーの Window → Perspective → Open Perspective → Other... → トレースデバッガ(逆方向) でトレースデバッガのパースペクティブを開いてください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_05.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_06.png" class = "quarterSize"></div> </li> <li class = "explanation"> 開いたトレースデバッガのパースペクティブ右上のブレークポイントビュー上にあるフォルダアイコン(左から1番目)を<br> クリックしてトレースファイル(jHotDrawBenchMarkWithMoreStandardClasses.trace)を開いてください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_07.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_08.png" class = "halfSize"></div> </li> <li class = "explanation"> トレースファイルの読み込みが終わるまで待ってから, ブレークポイントビュー上にある「ブレークポイントをEclipseから取り入れる」アイコン(左から2番目)を<br> クリックしてトレースデバッガ用のブレークポイントを作成してください. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_09.png" class = "threeQuartersSize"></div> </li> <li class = "explanation"> ブレークポイントビュー上にあるデバッグアイコン(左から3番目)をクリックしてください.<br> トレースデバッガによるデバッグ実行が起動し, ブレークポイントを入れた位置の行が選択された状態で一時停止します. <div class = "image"><img src = "./images/images_problem1_pre/JHotDraw_1_pre_10.png" class = "threeQuartersSize"></div> </li> </ol> </p> <hr> <h2>課題A3</h2> <p> <!-- Fig クラスはグラフィックエディタ上の図形を表すGEFの内部のクラスです.<br> また, FigClass クラスはクラス図上に配置された「クラス」を表す JHotDraw のクラスで, Fig クラスの子孫クラスにあたります.<br> --> ブレークポイントを置いた行は、図形を移動するたびに実行されます. </p> <p> <p class = "explanation"> 先ほどの実行手順にしたがって進めていくと, 下図のように DefaultDragTracker クラスの<br> mouseDragged(MouseEvent) メソッド内の159行目で一時停止している状態になっているはずです.<br> この状態になっていれば, ここから時間計測を開始してください.<br> <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_01.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> DefaultDragTracker クラスの mouseDragged(MouseEvent) メソッドの159行では,<br> ローカル変数 f で参照されている RectangleFigure クラスのインスタンスに対してメソッドが呼び出されていることが確認できます.<br> まずは, この f の値がどこから来たのかを見るために, ステップバックオーバーを2回押して157行目の拡張for文まで戻ってください. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_02.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 先ほどのステップバックオーバーの実行によって157行目まで戻ってきました.<br> ここでは, まずステップネクストを1回押してください.<br> そのあと, 変数ビュー上にある「呼び出し後」を開くと, <br> 戻り値として RectangleFigure クラスのインスタンス (id = 1952912699) が返されていることがわかります. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_03.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> ソースコードを見ると, RectangleFigure クラスのインスタンス (id = 1952912699) は DefaultDragTracker クラスのインスタンス (id = 758826749) が<br> フィールド transFormedFigures の要素として保持していることがわかります.<br> 次は, この transFormedFigures に RectangleFigure クラスのインスタンスがどの実行時点で追加されたのかを見ていきます.<br> 変数ビュー上で開いている「呼び出し後」の中にある戻り値を右クリックして「オブジェクトの追加時点に飛ぶ」を選択してください.<br> 実行すると, オブジェクトの追加時点である DefaultDragTracker クラスの mousePressed(MouseEvent) メソッドの118行目にまで現在の実行時点が遡ります. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_04.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 先ほどの操作によって, DefaultDragTracker クラスの mousePressed(MouseEvent) メソッドの118行目に現在の実行時点が移りました.<br> この118行目では, ローカル変数 f の値が フィールド transFormedFigures に追加されていることが確認できます.<br> ここで, 「トレースデバッガ」パースペクティブの右下にある「実行時点の登録」ビューの追加ボタンをクリックしてください.<br> そうすると, 現在の実行時点がこのビュー上に登録されます. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_05.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> この f の値がどこから来たのかを見るために, ステップバックオーバーを1回押して116行目の拡張for文に戻ってください.<br> ここで, ソースコードを見ると, この116行目の拡張for文では, ローカル変数 view が参照しているインスタンスに対して getSelectedFigures() メソッドが呼び出され,<br> 戻り値として返された Collections$UnmodifiableSet クラスのインスタンスから先ほどのローカル変数 f の値を取得していることが確認できます.<br> これを確認したら, この戻り値がどうなっているのかを見るために, ステップバックインを4回押して getSelectedFigures() メソッドの中に後ろから入ってください.<br> <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_06.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> DefaultDrawingView クラスの getSelectedFigures() メソッドに入りました.<br> ここで, ソースコードを見ると, Collections クラスの static メソッドである unmodifiableSet(Set) が呼び出されており,<br> その引数として フィールド getSelectedFigures が渡されていることが確認できます.<br> また, 変数ビュー上の「呼び出し後」および this を開くと, このフィールド getSelectedFigures は<br> DefaultDrawingView クラスのインスタンス (id = 150367587) が保持していることがわかります.<br> これを確認したら, ステップバックリターンを1回押して呼び出し元に戻ってください. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_07.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 先ほどの結果から, RectangleFigure クラスのインスタンス (id = 1952912699) は <br> DefaultDrawingView クラスのインスタンス (id = 150367587) が セットの要素として保持していることがわかりました.<br> 次は, この DefaultDrawingView クラスのインスタンスがどこから来たのかを見ていきます.<br> ここでは, ステップバックオーバーを5回押して98行目に戻ってください.<br> ソースコードを見ると, getView() メソッドの戻り値を ローカル変数 view に代入していることが確認できます.<br> ここで, この戻り値がどうなっているのかを確認するために, ステップインを1回押してこのメソッドの中に前から入ってください.<br> <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_08.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> AbstractTool クラスの getView() メソッドに入りました.<br> ここで, 変数ビュー上の this を開くと, DefaultDragTracker クラスのインスタンス (id = 758826749) が<br> DefaultDraingEditor クラスのインスタンス (id = 1859859960) を保持していることがわかります.<br> これを確認したら, ステップインを3回押して DefaultDrawingEditor クラスの getAcitiveView() メソッドの中に前から入ってください.<br> <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_09.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> DefaultDrawingEditor クラスの getAcitiveView() メソッドに入りました.<br> ここで, 変数ビュー上の this を開くと, DefaultDrawingEditor クラスのインスタンス (id = 1859859960) が<br> DefaultDrawingView クラスのインスタンス (id = 150367587) を保持していることがわかります. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_10.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 先ほどの結果から, DefaultDrawingView クラスのインスタンス (id = 150367587) は<br> DefaultDrawingEditor クラスのインスタンス (id = 1859859960) が保持していることがわかりました.<br> 呼び出しスタック上で2つ呼び出し元である DefaultDragTrackerクラスの mousePressed(MouseEvent) メソッドをクリックしてください.<br> ここで, 課題A3は終了です. 時間計測を終了してください. <div class = "image"><img src = "./images/images_problem1/JHotDraw_1_11.png" class = "threeQuartersSize"></div> </p> </p> </body> </html>