asaのブログ

プログラミングの勉強まとめ

JavaFXでペイントツールのUIを作る

 JavaFXでのUI構築にはSceneBuilderという優れたツールが存在しますが、今回はJavaFXの基本から見ていくためにSceneBuilderを使わずにUIの設計を行ってみたいと思います。

 

 JavaFXの概要

 JavaFXでUIを構築していく際のキーワードは

  1. Stage
  2. Scene
  3. Node

の3つです。この3つのキーワードの関連は下の図のように表されます(汚い図ですいません)。

f:id:asa_r:20170512005854p:plain

最上位のコンテナにStageが存在し、SceneがStageに格納されています。JavaFXではこのSceneに対してNodeを追加していくことでUIを構築していきます。Nodeはツリー構造になっていてrootノードに子ノードがぶら下がっている形で表されます。

 

 NodeにはBorderPaneなどのレイアウトを持ったクラスが存在します。これらを組み合わせてUIを作っていきます。Oracleのリファレンスで紹介されているものを一覧で挙げておきます。

  1. BorderPane・・・上下左右、中央にNodeを配置できるレイアウトを提供します。
  2. Hbox・・・横方向にノードを配置できるレイアウトを提供します。
  3. VBox・・・縦方向にノードを配置できるレイアウトを提供します。
  4. StackPane・・・ノードをスタック構造で配置できるレイアウトを提供します。
  5. GridPane・・・グリッドを基にノードを配置できるレイアウトを提供します。
  6. FlowPane・・・縦横(HBoxとVBoxを併せたような)にレイアウトを提供します。
  7. TitlePane・・・ノードにタイトルを配置するレイアウトを提供します。
  8. AnchorPane・・・アンカーを基にリサイズしても崩れないレイアウトを提供します。

 

 ペイントツールのUI

 ためしに何の機能も持っていない空のJavaFXアプリケーションを作成してみました。全体の構造は下の通りです。

f:id:asa_r:20170512225218p:plain

 rootノードにBorderPaneをおき、メニューバーをHBoxとしてトップに配置し、ツールバーとパレット等を置くドックをVBoxで作り左右に置いた後、中央にキャンバスを生のPaneでラップしてから配置しました。実際にコードを走らせて見ると下のようになります。

 

f:id:asa_r:20170512225655p:plain

 

 コード

 参考までにコードはこのようになります。

gista510b13f7d2632f52ec9d7c48d4220df

 

  参考URL

 オラクル公式サイトが一番役に立ちました。後APIリファレンスも参考になります。

docs.oracle.com

mukai-lab.info 

 

はじめてのGithub

 GitとGithubの利用を始めました。はじめて利用した感じをまとめました。

 

 Gitはバージョン管理を行うツールです。今何かソフトウェアなりアプリを作ろうとしているとき、いきなり完成させるということは無理なわけで、徐々に完成を目指していくという形をとることになります。

 

 そのようなときに、これまでの開発の状況や変更点がバージョンとして管理できると開発を続けていく上で非常に便利です。Gitはそのためのツールです。

 

 Gitにはリモートレポジトリとローカルレポジトリがあり、リモートレポジトリはネット上にソースコードを公開して共有します。一方ローカルレポジトリはその名のとおりローカル環境でソースコードを管理します。

 

 Githubはリモートレポジトリを管理するWebサービスでユーザー登録することで利用可能です。

 

 具体的な流れ

 1.Githubアカウントを登録

 2.Github Desktopをダウンロード

 3.Github Desktopでリポジトリを作成

 4.開発したものをローカルフォルダに加える

 5.コミットする(commit)

 6.プッシュする(publish)

 

 簡単なGitの使い方です。他の機能についても使用するになったらまとめいきます。下は参考にさせていただいたサイトです。

 

qiita.com

techacademy.jp

 

単体テストについて

 本を読んだり、サイトを参考にしていると未だにわからない単語がほいほいと出てきます。それらを1個1個つぶしていこうと思います。そういうわけで、今日はまず単体テストを取り上げようと思います。

 

 単体テスト

 引数のデータの組み合わせ計算結果が正しいか、DBに正しいデータが登録されるか、例外が発生した際の振舞いが正しいかを見ます。

 

 要するにある大きな機能が存在して、それが相互に依存関係にあるときに、それらを分離して一つ一つの機能単位で正しく動くかを見ていくということだと理解しました。具体的には書いたメソッド(単体)がきちんとした結果を返すか、条件分岐を正しく通るかということを確かめればよいようです。

 

 まず、テストを行う際、機能単体を切り出すために、それを呼び出すためのコードであるドライバーと、テストコードが呼び出すコードを代替するスタブを作る必要があります。

 

 またテストのポイントとしては、テストはブラックボックスとホワイトボックスの観点から行われます。ブラックボックスは、入力値に対して出力値が正しく出力されるかを見るテストです。ホワイトボックスは、条件分岐などが正しく行われているかのメソッドの中身を確認するテストです。

 

 ブラックテストで流す値は境界値、固定値、異常値です。境界値は流す予定の値の最大値、最小値です。固定値はminとmaxの間の値です。異常値はnullやブランク、半角/全角スペース、0などです。他には最大、最小値の外の値、違う型の値などです。

 

 ホワイトボックスでは、条件分岐などのパスの一覧を上げ、それを一つ一つつぶしていくこと機能の安定性を保証します。

 

 これらのテストは行った都度、実施した内容をまとめおくことで確認漏れを防ぐことができます。

 

 またテストを自動化するツールとしてJavaにはJUnitが存在します。JUnitの基本的な使い方については最後のサイトが一番参考になりました。

 

 以下参考にさせていただいたサイト

qiita.com

www.infiniteloop.co.jp

www.techmatrix.co.jp

tong-chang.hatenablog.com

gihyo.jp

アップローダの作成(サーバーサイド編終了)

 サーバーサイド編終わりました。約1ヶ月に渡ってあの分厚い参考書をバッグに入れて持ち運んでいた時期が懐かしく思えます。それももう終わり…やっと最後のiTextまで打ち込みが終わりました。

 

 いろいろとコードを書きましたが、とりあえず使えそうなものを紹介しようと思います。今回はクライエント側にあるファイルをサーバーにアップロードするアップローダーを説明します。

 

 参考書はもちろんこれ。こいつもついに見納めです。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

 

 アップローダーの概要

 ここでは外部ライブラリのCommonsFileUploadを使用しています。Apacheほんとにありがとう。それでファイルのアップロードの流れは、アップロードのための前準備、アップロードファイルの取得、アップロードファイルの保存の3段階で進みます。

 

 アップロードの前準備

 まず、アップロードの前準備をします。アップロードを行うクラスはServletFileUploadクラスの役割です。なのでまず最初にこのクラスのインスタンスuploadを作成することを頭においておきます。

 

 ServletFileUploadクラスのコンストラクタはDiskFileItemFactoryを要求します。そこでクラスのインスタンスfactoryを作ります。DiskFileItemFactoryはその名のとおり、アップロードファイルをいろいろと加工して扱いやすくするセッタメソッドが存在します。作成したインスタンスからメソッドを呼び出して、最低限の設定をしておきます。

 

 アップロードファイルのいろいろな扱いをこうしてfactoryインスタンスに詰め込んで、これをuploadインスタンスに渡します。こうして無事にアップロードの前準備が終わります。

 

 アップロードファイルの取得

 さて、そうしてアップロードファイルがPOSTされると、それはrequestオブジェクトに入れ込まれて処理に回ってきます。この中には目的のアップロードファイルに混じっていろいろなオブジェクトが混じっています。

 

 まずはそれをまとめて、Listに入れ込みます。その役割はparseRequestメソッドです。requestオブジェクトを渡すと、FileItemオブジェクトのリストで返してくれます。

 

 目的のファイルをリストから見つけるためにIteratorをつけます。IteratorのメソッドhasNextを使ってfalseを返すまでリストの中を探索していきます。あとファイルであればtrueなりfalseを返すメソッドがあったらいいなと思いますね。それがisFormFieldメソッドです。テキストであればtrueを返すので、falseの場合にはファイルを保存する処理を行います。

 

 アップロードファイルの保存

 目的のファイルが見つかったところで、まずパス名を取得します。パス名がなかったりnullだったりしなければ保存処理に移ります。次にFileオブジェクトを作って、getNameでファイル名だけ取得します。保存したいpathはweb.xmlであらかじめ記述しているのでpath+ファイル名で指定したpathにファイルをwriteメソッドで書き込み(保存)します。

 

 コード

gist664621a8d54d0b7d5f765a8073be5aa3

 

gist0514f59aaf9a287e331f443855c1450d

 

gist1e183ff6f12d186c48bf30df17b242e5

 

終わり!

 

 

サーブレット・JavaBeans・JSPの連携

 MVCモデルを元にサーブレット・JavaBeans・JSPを連携して、BMIを計算するWebページをつくります。参考書はいつもお世話になっている下の本です。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

  MVCモデル

 最初にMVCモデルについてまとめます。動的なWebページでは、クライエントから入力を受けて、その入力を処理して、結果を再びクライエントに返すという作業の繰り返しです。

 

 この作業をModel、View、Controllerに分けて考えるのがMVCモデルです。まず分かりやすいViewから説明します。Viewはクライエントが直接目を触れる入力と出力の部分を指します。入力フォームと、返ってきた結果を出力する出力ページがViewです。次にControllerですが、Controllerでは入力値を受け、それをどう処理して、どこに返すかという機能を担っています。具体的な処理の機能についてはModelで実装されます。

 

 分かりにくくもないですが、レストランを例にとるとより分かりやすいです。お客さんが入ってきて、ウェイター・ウェイトレスが注文を聞きます。ウェイター・ウェイトレスはオーダーを料理長に伝えます。料理長は専ら厨房の指揮をとっているとして、あれをこうしてこれを作って、あそこに置いておいてという指示をコックに伝えます。コックはそれを作って、言われた場所においておきます。するとウェイター・ウェイトレスはそれを受け取って、お客さんに料理が届きます。

 

 レストランでは、Viewがウェイター・ウェイトレス、Controllerが料理長、Modelがコックです。MVCモデルと名前がついていますが、どこでもやっている別にたいしたこともない普通の話です。

 

 BMI計算機

 身長と体重を入力することでBMIを返すWebページを作ります。bmiBeans.jspを入力ページ、bmiBeans_result.jspを出力ページとします。ControllerにBmiBeansServlet.javaをおき、ModelにBmi.javaをおいて構成します。

 

 コードは下の通りです。なお、デプロイメントディスクリプタにはNetBeansにより自動でサーブレットが登録されます。

 

gist0ff38b4141cb7570e58baec3aa994c7b

 

gist4fdcecccd289095c837b4fa2c95efbf7

 

gist4f5c5b23dc030dcbc94d0189f0eeef9c

 

gisteedd7b5cf1bef4f2aca99b2b94b26b2c

 

タグライブラリまとめ2

 タグライブラリまとめの続きです。前回はJavaの基本的な制御構文を代替するCoreライブラリと、データベースを取り扱うDatabaseライブラリをやりました。今回は、日付や数値、メッセージの整形を行うi18nライブラリと、Stringクラスを取り扱うFunctionライブラリをやって、JSTLを終えます。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

  i18nタグライブラリ

 さらっとコードだけ載せておきます。

gist6893251a052a65b33ccfaba616e372f3

 

 Functionタグライブラリ

 おなじくさらりとコードだけ載せておきます。

gist3809c692312c4a1b6e1a8a5c8319c036

 

 はい。これでようやくサーブレット入ります。

 

デザインパターンまとめ2(お絵かきソフト)

 前回からの続きです。下の参考書の22章でお絵かきソフトを扱っていたので詳しくやります。自分自身絵を描いているのと、pixivSketchが素晴らしかったので、こうした情報を参考にお絵かきアプリを作っていきます。

 

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

 

  

 Commandパターン

 ある処理を行ったときに、処理の結果はオブジェクトの状態に反映されます。ただ、どういう処理をしたかという履歴は残ることがありません。Commandパターンは、処理つまり命令をクラスとして扱い、インスタンスを保存することで、仕事の履歴を管理します。仕事の履歴を管理することで、同じ命令を実行するときや、複数の命令をまとめたものを新たな命令として再利用することができます。

 

 構成

 パッケージを”命令”を扱うcommandパッケージ、描画を行う"draw"パッケージ、実行用のMainを置く無名のパッケージに分けて作ります。

 

 Commandパッケージ

 このパッケージでは”命令”を扱うインタフェースとクラスを保存します。漠然とした命令をCommandインターフェースで扱い、まとまった複数の命令をMacroCommandクラスで表現します。

 

 Commandインターフェース 

gist1320acacecfc08a99cb14beed949cca2

 Commandインターフェースでは、単に命令を実行するという命令を表現するにとどめます。具体的な処理は実装クラスに記述します。

 

 MacroCommandクラス

gist2385e6ad569a3d483479be567ed92c20

 命令の集合をコレクションフレームワークのStackで表現しています。Dequeでやる場合はpushとpollになります。

 

 MacroCommandクラスは、Commandインタフェースを実装しているので定義されたメソッド(execute)をオーバーライドします。executeメソッドでは、Iteratorインターフェースを使って繰り返し処理を行っています。nextメソッドの戻り値はObject型なのでCommandでキャストした後で、executeメソッドを呼び出して命令を実行しています。

 

 続くappend、undo、clearはStackクラスのメソッドをそのまま利用しています。clearはVectorクラスからの継承されたメソッドで、全ての要素を削除します。

 

 Drawerパッケージ

 commandパッケージでは、命令と命令の集合、あと必要なメソッドを定義して終わりました。Drawerパッケージでは描画を表現します。

 

 DrawCommandクラス

gist382a7ccf6b63928231c1871b9bc00fe4

 このクラスは、Commandインターフェースを実装しています。漠然とした命令から、描画するものを描く命令へと降りています。Commndインタフェースを実装しているので、MacroCommandクラスへオブジェクトを渡すことが出来ます。

 

 Drawableは後で記載するDrawableインタフェースのことです。実際にはDrawableインタフェースを実装したクラスのインスタンスが渡されます。Pointはxとyの2値を格納するクラスです。描画場所を表しています。

 

 コンストラクタに先の2つのインスタンスを渡して初期化します。また、Commandクラスのexecuteをオーバーライドして、Drawab leクラスを実装したクラスのインスタンスからdrawメソッドを呼び出しています。

 

 Drawableインターフェース

gist62ca63355f0899f62281f751fe032e79

 何かを描くという処理を表したインターフェースです。抽象メソッドのdrawが定義されています。これを実装したクラスに具体的処理を任せます。

 

 DrawCanvasクラス  

gistd543b97f863f2b261677640c909705f5

 Canvasをextendsして、Drawableを実装したクラスです。フィールドで色、描画する点の半径、処理の履歴を持たせています。コンストラクタには描画全体の高さと幅、処理の履歴を渡して初期化します。

 

 Canvasを拡張したのは、paintメソッドをオーバーライドするためで、このメソッドはGraphicsインスタンスを引数に、履歴に保存された命令を実行します。

 

 また、Drawableインターフェースを実装しているので、drawメソッドをオーバーライドしています。Graphicsインスタンスを作成するのに、このCanvasコンポーネントを利用しています。あえて書くとthis.getGraphics()でしょうか。

 

 後はGraphicsクラスのメソッドを利用して色と描画範囲を指定しています。fillOvalは1、2番目の引数が描画する位置を表し、残りの引数が描画する大きさを表しています。

 

 Mainクラス

gist76a43fcae23469dbef1a6ad64466f769

 実行用のクラスです。なんだか一番複雑に感じました。

 JavaGUIを実現する場合、AWTとSwing、JavaFXがあります。今はJavaFXがあるので、あえてSwingで実現させる必要はないのかもしれませんが、参考書どおり行きます。

 

 Swingでは大元になるフレームにぺたぺたと部品を貼り付けていくことでGUIを構成していきます。Frameから部品を貼り付けるためには、getContentPaneで部品を載せるコンテナを取得します。

 

 今回そのコンテナに貼り付けるのは、mainBox、ボタンを置くためのButtonBox、そして描画を行うためのcanvasです。ButtonBoxはBoxLayoutを横軸にすることで、横にボタンを置くことができます。またmainBoxは縦軸に設定して縦に部品を置くようにしています。

 

 フィールドでは、履歴と領域、消去ボタンを持たせています。コンストラクタにはtitleを渡し、スーパークラスであるJFrameのコンストラクタを呼び出しています。イベント発生時のために、それぞれのコンポーネントに対応するリスナーを登録します。レイアウトの設定は上の通りです。

 

 消去ボタンが押された際には、イベントがactionPerformedメソッドに渡され、履歴が消去され、canvasが再描画されます。またマウスがドラッグされた場合には、イベントはmouseDraggedメソッドに渡り、命令が作成、履歴登録されてすぐに実行されています。後はウィンドウが閉じられると実行終了するためにexitだけ実装されています。

 

 空のメソッドはそれぞれ、リスナーを実装したためにオーバーライドする必要があるので書かれています。

 

 後はmainで実行すると、簡単なお絵かきソフトが起動します。