Cocoaでいこう! Macらしく 第9回
Yoshiki(DreamField)
この記事は、MOSAが発行するデベロッパ向けのデジタルマガジンMOSADeN 第68号(2003年6月3日発行)に掲載された記事です。2〜3ヶ月遅れで、ここに掲載して行きます。

前回はJPEGのデータをイメージに展開する所まで作りました。これを表示すれば、第一段階は終了ですね。

画像の表示を実装しよう(後編)

前々回のプログラムの方針を見ますと、イメージの表示は、windowControllerDidLoadNib:の中で、imageをウィンドウ上のNSImageViewのインスタンスオブジェクトにセットすれば良いことになっています。NSImageViewのリファレンスを見ますと、次のメソッドがあります(リファレンスの場所は第7回を見て下さい。なお、NSImageViewはApplication Kitの方にあります。)。

- (void)setImage:(NSImage *)image

これでimageをセットすれば、目的を達成できそうです。でも、何に対してセットすれば良いのでしょう?今のままでは、nibファイルで定義したNSImageViewのインスタンスオブジェクトはプログラムから見えません。そこで、これを指すインスタンス変数を宣言し、nibファイルをロードする時に、その値をセットしてもらうようにしましょう。

MyDocument.hを開いて、1行書き加えて下さい(3行目が書き加えた行です。)。

@interface MyDocument : NSDocument
{
    IBOutlet id imageView;

    NSImage *image;
}
@end

IBOutletは、Interface Bulderがヘッダーを解析する時に使用するもので、コンパイル時には無視されます。idは任意のオブジェクト型へのポインタです。ここに、NSImageViewのインスタンスオブジェクトのポインタを格納してもらおうというわけです。では、一度ビルドして、コンパイルエラーが出ないかどうか確かめて下さい。ビルドを行うには、左上のボタンの中から、ビルドボタンをクリックします。エラーが見つかりましたら、もう一度内容を確かめて修正してください。

エラーが出なくなくなりましたら、MyDocument.nibをInterface Builderで開いて下さい。Project BuilderのResourcesの中のMyDocument.nibをダブルクリックすると開けます。ただし、既に開いている場合はこの操作では最前面に来ませんので、DockからInterface Builderを選ぶか、もしくはMyDocument.nibの中のEnglishをダブルクリックして下さい。開いたらnibファイルウィンドウを見て下さい。File's Ownerというアイコンがあると思います(fig.01)。

nibファイルウィンドウのFile's Owner
[fig.01] nibファイルウィンドウのFile's Owner

File's Ownerというのは、nibファイル内のオブジェクトとのやり取りをするために使われるオブジェクトで、nibファイルをロードする時に指定します。Document-based Applicationの雛形では、フレームワークが勝手に、windowNibNameで返した名前のnibファイルをロードしていますが、この時、File's OwnerはMyDocumentを指定しています(もちろん、必要であればこれは変更できますが、今回はこのままで行きます。)。

MyDocumentクラスは、先程ヘッダーを修正してしまいましたから、これをnibファイルに反映させなければなりません。では、File's Ownerのアイコンを選択して下さい。選択したら、Classesタブを選んで、クラスの一覧表示に切り替えましょう(fig.02)。

nibファイルウィンドウのクラスの一覧表示
[fig.02] nibファイルウィンドウのクラスの一覧表示

直前にFile's Ownerを選択していましたので、そのクラスであるMyDocumentクラスが最初から選択されています(Classesタブを選んでからMyDocumentクラスを探して選択しても良いのですが、これは面倒です。)。MyDocumentクラスを選択したままで、メニューバーからClassesメニューを選んで下さい。Read MyDocument.hという項目があると思います(fig.03)。

ClassesメニューのRead MyDocument.h
[fig.03] ClassesメニューのRead MyDocument.h

これを選択すると、変更したMyDocument.hを読み直すことが出来ますので、選択して下さい。読み込みが終わりましたら(今回は特に何もリアクションは無いと思います。)Instancesタブを選んで、再びインスタンスの一覧のアイコン表示に戻してみて下さい。File's Ownerの左下にオレンジ色のマークが付いていると思います(fig.04)。

コネクションが解決していないという印
[fig.04] コネクションが解決していないという印

これは解決していないコネクションがあるという意味です。MyDocument.hを読み直した結果、これが現れました。

MyDocument.hにはimageViewというインスタンス変数を追加しましたが、その時、IBOutletという宣言をしたことを覚えていますでしょうか。これを行いますと、Interface Builderで取り扱うOutletとなります。ここに何も接続していないので、解決していないコネクションとなったのです。では、接続を行いましょう。controlキーを押したままFile's Ownerをマウスで選択し、そのままドラッグしてデザインウィンドウのイメージを表示するために配置したNSImageViewのインスタンスまで持っていって離して下さい(fig.05)。

File's OwnerからNSImageViewのインスタンスに、Controlボタンを押したままマウスをドラッグする
[fig.05] File's OwnerからNSImageViewのインスタンスに、
Controlボタンを押したままマウスをドラッグする

すると、Connectionの設定画面に切り替わったInfoウィンドウが開きます。imageViewが選択されていますので、Connectボタンを押して下さい(fig.06)。

Infoウィンドウが表示されるのでConnectボタンを押す
[fig.06] Infoウィンドウが表示されるのでConnectボタンを押す

すると、imageViewはNSImageViewのインスタンスに接続され、nibファイルをロードした時に、自動的にそのポインタが格納されるようになります。それでは、nibファイルを保存して、再びProject Builderに戻りましょう。

MyDocument.mを開いて下さい。windowControllerDidLoadNib:に下記リストの4行目と5行目を書き加えて下さい(3行目は最初から雛形に入っています。)。

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];
    [ imageView setImage:image];
    [ image release];
}

4行目は、imageViewにimageを渡しています。そして、imageは渡してしまえば、もう必要ありませんから、5行目で解放しています。

では、ビルドして実行してみましょう。「ビルドと実行」ボタンを押して下さい。TinyViewが起動しましたら、適当なJPEGファイルを開いてみてください。きちっと表示されたと思います(fig.07)。

 ついに完成した画像ビューア
[fig.07] ついに完成した画像ビューア
(サンプル画像は、ゆきみだいふくさんのご好意により、使用させていただいています。)

ついに、画像ビューアが完成しました!(まだ、第一段階ではありますが。)

以上で、Document-based Applicationにおいて、ファイルを読み込む所からそれを処理する所まで、骨組みは理解できたと思います。これを拡張して行けば、色々なことが出来るでしょう。

それにしても、結局書いたコードがたったの6行。こんなプログラム入門も前代未聞じゃないかと思いますが(^^;)。Cocoaはそれだけ優れた開発環境である証だと思います。それでは、次回からはCocoaでプログラムをする上で、ちょっと重要な概念の説明をし、それが終わりましたら、さらにこのプログラムに手を入れていこうと思います。

前頁目次次頁