User Defaultsを使う、NSUserDefaultsクラスの機能についてはすでに解説したが、結果的に、その機能を使って、PreferencesWindows.javaのソースは以下のように作成した。ソースを見ながら変更点を解説しよう。
/* PreferencesWindow */
import com.apple.cocoa.foundation.*; import com.apple.cocoa.application.*;
public class PreferencesWindow extends NSWindow {
NSTextField initHeightTextField; /* IBOutlet */ NSTextField initLeftTextField; /* IBOutlet */ NSTextField initTopTextField; /* IBOutlet */ NSTextField initWidthTextField; /* IBOutlet */ public void setupInitValue(Object sender) { /* IBAction */ initLeft = initLeftTextField.intValue(); initTop = initTopTextField.intValue(); initWidth = initWidthTextField.intValue(); initHeight = initHeightTextField.intValue();
NSUserDefaults ud = NSUserDefaults.standardUserDefaults(); ud.setIntegerForKey(initLeft, "Position Left"); ud.setIntegerForKey(initTop, "Position Top"); ud.setIntegerForKey(initWidth, "Width"); ud.setIntegerForKey(initHeight, "Height"); } static int initLeft ; static int initTop ; static int initWidth ; static int initHeight ;
static { NSUserDefaults ud = NSUserDefaults.standardUserDefaults(); if(ud.objectForKey("Position Left") == null) { Object obj[] = {new Integer(20), new Integer(100), new Integer(400), new Integer(200)}; Object keys[] = {"Position Left", "Position Top", "Width", "Height"}; ud.registerDefaults(new NSDictionary(obj, keys)); } initLeft = ud.integerForKey("Position Left"); initTop = ud.integerForKey("Position Top"); initWidth = ud.integerForKey("Width"); initHeight = ud.integerForKey("Height"); }
/* これがないと実行時にエラー */ public PreferencesWindow( NSRect contentRect, int styleMask, int backingType, boolean defer) { super(contentRect, styleMask, backingType, defer); setDelegate(this); }
public void windowDidBecomeKey(NSNotification aNotification) { initLeftTextField.setIntValue(initLeft); initTopTextField.setIntValue(initTop); initWidthTextField.setIntValue(initWidth); initHeightTextField.setIntValue(initHeight); } }
まず、User Defaultsに記録する値の名前を、"Position Left", "Position Top", "Width", "Height"いうことにしておく。特にネーミングの規則はないようであるが、適当に自分で規則を作っておけばよいだろう。 環境設定ウインドウのOKボタンをクリックすると、setupInitValueメソッドが呼び出される。ここでは、テキストフィールドの値をクラス変数に記録したが、ついでに、User Defaultsにもそれらを書き込んでおけば、OKボタンをクリックすることで、User Defaultsに確実に記録されることになる。 一方、アプリケーションを起動したときには、記録されているUser Defaultsを読み出したい。その方針として、アプリケーション内ではクラス変数で環境設定の値を管理しているので、staticイニシャライザで、User Defaultsからの取り出しを行い、アプリケーション起動時に確実に処理されるようにした。読み出しを行えばいいのだが、integerForKeyメソッドで数値で得たい。もちろん、文字列で得てから処理するとうい手もあるが、ここでは、1つの名前に対する値が存在するかどうかを判断して、それがない場合には、はじめてUser Defaultsを利用するものと判断し、値とキーのセットを配列で定義して、registerDefaultsメソッドを使ってNSDictionaryクラスで必要な値のセットをまとめて設定した。その後、User Defaultsから読み出しを行っている。
このままだと、アプリケーションを起動し、環境設定ウインドウを呼び出すと、環境設定のウインドウにあるテキストフィールドは空欄のままだ。つまり、環境設定のウインドウを表示したときに、現在のクラス変数の値を各テキストフィールドに記入する必要がある。そのために、ウィンドウのデリゲートを利用する。NSWindowは、キーウインドウとなったときに、デリゲートされているオブジェクトに対してwindowDidBecomeKeyメソッドの呼び出しを行う。ここでは、PreferencesWindowのコンストラクタで、setDelegate(this);によって、まず、自分自身をデリゲート先に指定した。そして、アプリケーションメニューのPreferencesを選択すると、環境設定ウインドウがキーウインドウになる(このウインドウのmakeKeyAndOrderFrontメソッドを呼び出すようになっているからだ)。したがって、PreferencesWindowクラスのwindowDidBecomeKeyメソッドが呼び出されるという仕組みである。ここで、クラス変数の値をテキストフィールドにセットすればよい。
繰り返しとなるが、以上のリストで、アプリケーションの識別子「net.msyk.mosaeditor」はまったくでてこない。アプリケーション設定をしておき、前回に説明したメソッドを使う範囲では、識別子は自動的に認識されて、それを元に設定がされるのである。
なお、User Defaultsに設定された値は、defaultsというコマンドで参照することができる。ここでは識別子はnet.msyk.mosaeditorであるので、
% defaults read net.msyk.mosaeditor
とコマンドを与えれば、設定されている値が以下のように参照できる。
{Height = 400; "Position Left" = 0; "Position Top" = 0; Width = 500; }
defaultsコマンドの詳細はmanコマンドのマニュアルで見ていただくとして、設定を書き込んだり、あるいは削除したりということもできる。いずれにしても、とりあえずアプリケーションを作成している段階では、正しく書き込まれているかどうかをチェックすることは、Terminalからコマンドをたたけばできるということだ。(なお、defaultというコマンドもあるが、これはシェルスクリプトのswitchステートメントで使うキーワードだ。)
また、自分のホームフォルダにあるLibrary/Preferencesに、アプリケーションの識別子から名前をとった「net.msyk.mosaeditor.plist」というファイルがある。ダブルクリックすると、Developer ToolsでインストールされるProperty List Editorで、ファイルの内容が参照できる。中身はXML形式であるが、このアプリケーションを使うと階層表示で内容を参照することもできる。
◇User Defaultsの結果を残すファイルを参照した
環境設定ウインドウのユーザインタフェースの組み込みと、User Defaultsを使った永続記憶の方法を5つの記事でお届けしてきたが、次回はCocoaならではの機能を紹介しよう。メニューを追加するだけで、いきなり高機能(!?)ワープロになってしまうというところだ。 (この項、続く) |