もくじ へ
6. フォント名を知りたい
Cocoa のプログラミングをしていて、フォント名を指定しなければならないことがある。例えば「ヒラギノ角ゴシック」を使いたいとして、コードの中には何て書いたら良いのでしょう? 解らないなら、これを表示する簡単なソフトを作れば良いじゃないか、と言うのが作ろうとした動機です。フォントパネルを組み込めば良いのでしょうが、そんなことをいちいちしなくても、自分のために作るちょっとしたプログラムなら、自分の好みのフォントを直接コード中に指定するのが普通でしょう。
下のようなツールを一つ作ればOKです。

ところが、このちょっとしたツールが、私にとっては大変な難関だった。
フォントパネルの心得
NSFontPanel って言うクラスがあるから、これをインスタンス化して配線でつなげば良いんじゃないか、なんて漠然と想像して始めたら、ぜんぜん違っていだ。
まず、フォントパネルを表示したり、そのパネルをユーザーが変更した結果を受け取ったりするのは、NSFontManager と言うクラスの仕事である。NSFontManager は、orderFrontFontPanel: と言うメッセージを受け取ると、フォントパネルを表示する。そして、ユーザーがパネル上でフォントを変更すると、changeFont: と言うメッセージをファーストレスポンダーに送る。ファーストレスポンダーに関しては、Cocoaはヤッパリ!のONLINEの記事に出ていますので、そちらを参考にして下さい。
素人的には「メッセージをファーストレスポンダーに送る」と表現してもらえば、どうにかついて行けるのだが、あるところに「メッセージをレスポンダーチェーンに投げる」と言う表現があって、本格的にはそう言うのかも知れないが、何か別のものかと思ってしまって結構悩んでしまった。要は、ウインドウ上に張付いているボタンやテキストボックスなどの中で「選ばれた」状態になっているものにメッセージが送られると言うことである。
つまり、NSFontManager が送る changeFont: と言うメッセージは、ウインドウ上に貼り付いていないオブジェクトや、貼り付いていても選ばれていないオブジェクトには、受け取るすべがないのである。いかにも、受け取るすべがあるかのように誤解させるデリゲート設定系のメッセージがあって、これにはハメられた。
次に、いつも「つかえね〜」と軽視している NSTextField に日の目を見せてやろうと、サブクラスを作って changeFont: メソッドを実装してやったのも大はずれだった。サブクラスを作って changeFont: メソッドを実装しても、もともとのクラスに changeFont: を持たない甲斐性無しには、メッセージが来ないのである。やっぱり、見た目には枠がなくてパッとしなくても、頼りがいのある NSTextView 氏にお願いして、changeFont: メソッドをオーバーライドさせてもらうことにした。
さて、NSFontManager は「InterfaceBuilder」上で、どうやってインスタンス化するのでしょう。なぜか普通にコロッとはいかない。メニューにフォントメニューを貼り付けてから消去すると、取り残されたように NSFontManager のインスタンスが置き去りにされるのを利用するしかないようである。(メニューからフォントを消去しなくっても良いのでしょうが...)
後は細かいことになりますが、受け取った changeFont: メッセージを、別のオブジェクトに転送するのはダメのようです。同様に、[ super changeFont:sender ] で、本来自分が持っている「選択範囲のフォントを変更する」と言う機能を発動させようとしてもダメのようです。でもこれ、本気でテキストエディターを作りたいときなんかに、不便じゃないのでしょうか? また、フォントパネルのフォントサイズの初期値として、見えないところで自分のフォントサイズが送られるようです。すなわちこの例で言うと、フォント見本が自分で、フォント名はもう一つのテキストボックスの方に書き出すようにしないと、動作がすっきりしないことになります。changeFont: メッセージには、表に見えない部分に何やら深い秘密がいろいろ隠されているようですが、私にはとうてい解りそうもありません。
サンプルソフトのダウンロード
いろいろ苦労話を書きましたが、コードは超簡単ですから、あとはダウンロードしてコードを読んで理解して下さい。 たったの12KB! ソースのみですので「Project Builder」でコンパイルして下さい。
2002.5.10