GO BACK

Cocoa-Java 教室 その4

「コントロールのいろいろ」



■選択メニューのための2種類

 既にNSTextFieldやNSButtonといったコントロールは使いましたが、この他にもCocoaにはさまざまなコントロールが用意されています。それらについてざっと見ていきましょう。

 まずは、いくつかの項目から1つを選ぶ「選択メニュー」のためのものです。これには2つのものが用意されています。それは「ポップアップボタン(NSPopUpButton)」と「コンボボックス(NSComboBox)」です。前者は、ボタンをクリックするとメニューが現れるもので、後者は一覧リストと入力フィールドをあわせたようなものになります。これらはツールパレットの「Other Cocoa Views」というアイコン(左から3番目)の中にあります。

NSPopupButtonとNSComboBox


 これらは、コンボボックスはテキストを直接入力できるという特徴がありますが、それ以外は割と似た感じです。どちらもいくつかある中から1つを選ぶというものですね。ですが、構造的には実はかなり違っています。

 ポップアップボタンは、文字通り「ボタンをクリックするとメニューが出てくる」ものです。つまり、メニュー項目(NSMenuItem)として表示する一覧は用意されていて、必要に応じてそれを表示しているわけですね。従って、このNSPopUpButtonには、表示する一覧リストに関する情報などはまるでありません。デザインウィンドウに配置したNSPopUpButtonをダブルクリックすると表示するメニューが現れます。ここに、NSMenuItemというメニュー項目の部品を追加して、表示するメニューを構築していくのです。それぞれのメニュー項目は独立したコントロールであり、NSPopupButtonとは関係のない独立したものなのです。例えば「このメニューを選んだら何かをさせる」という場合には、もちろんNSPopUpButtonのアクションを利用することもできますが、そのメニュー項目に対してアクションを設定する、ということもできるのです。

 これに対し、コンボボックスは「一覧リストを表示する」というものです。表示するリストの情報などはすべてNSComboBox自身にアトリビュートとして設定できます。また項目を選んだときの処理なども、NSComboBox自身のアクションを利用して処理します。一覧リストはあくまでコンボボックスの一部なのです。

 構造的にわかりやすいのはNSComboBoxでしょう。これのアクションを使った簡単な例を挙げておくことにします。——デザインウィンドウにNSComboBoxを1つ配置し、用意したJavaクラスの「myAction()」というメソッドにアクションを接続したとして考えましょう。

public void myAction(Object sender) {
NSComboBox cb = (NSComboBox)sender;
String str = cb.stringValue();
NSAlertPanel.runAlert(str + " is selected.","",null,null,null);
}

NSComboBoxを選択する


 ここでは、項目を選んだりNSComboBoxの入力フィールドにテキストを書き込んでReturnキーで確定したりすると、選択した項目を画面に表示します。

 ここではまず、アクション用メソッドのパラメータである「sender」をNSComboBoxにキャストしてcbというものを得ています。キャストって、覚えてますか? Javaで、タイプの違う値やインスタンスを変換することでしたね。Cocoaでも、このキャストを使ってコントロールのインスタンスなどを変数に設定したりできます。

 アクションで渡されるsenderというのは、Objectのインスタンスということになっています。アクションは、どのコントロールに設定されるかわかりませんから、どのコントロールでも問題なく利用できるような形を考えないといけません。それで、「とりあえずイベントの発生したコントロールのインスタンスは全部Objectにキャストして渡すことにしよう。後はそれぞれで元に戻して使ってもらおう」という、フリーズドライのみそ汁みたいな発想でアクション発生コントロールを受け渡すようになっているのです。

 ですから、senderはアクションの発生したコントロールのクラスにキャストして使うのが基本、と考えましょう。まったく別のものに無理矢理キャストしたりしても動きませんからご注意を。また、現在の値はstringValueなどで得られます。NSComboBoxは、直接入力しても項目を選んでも、最終的には「テキストとしてフィールドに書き出されている」わけですから、NSTextFieldなどとなんら変わりない感覚で値を得ることができるのです。

 では、もう1つのNSPopUpButtonのほうはどうでしょう。この場合は、stringValueなどで現在選択されている値は得られません。選択されているのはテキストではなくNSMenuItemという独立したオブジェクトなのですから。その代りといってはなんですが、NSPopUpButtonには選択された項目に関するメソッドが追加されており、それらを使って現在の状態を得ることができます。


public void myAction(Object sender) {
NSPopUpButton pb = (NSPopUpButton)sender;
String str = pb.titleOfSelectedItem();
NSAlertPanel.runAlert(str + " is selected.","",null,null,null);
}


 例えば、先の例と同様に、NSPopUpButtonを選択したらその項目を表示させるならば、このようなメソッドをアクションに設定すればよいでしょう。ここでは「titleOfSelectedItem」というメソッドを使っています。これが、現在選択されている項目(NSMenuItem)の値をStringで返すメソッドです。同様に「何番めが選択されているか」を得るために「indexOfSelectedItem」というメソッドも用意されています。これらを利用すれば、NSPopUpButtonでも、選択されている項目を利用した処理が作れるようになります。


■数量を入力する

 この他、数字を入力するための専用コントロールというのもいくつかあります。その代表は「スライダー(NSSlider)」と「ステッパー(NSStepper)」でしょう。これらも、やはりパレットの「Other Cocoa Views」というアイコンの中に用意されています。スライダーは4つのものがありますが、これは縦型か横型か、また目盛り表示のあるタイプかないタイプかによる違いです。


NSSliderとNSStepper


 これらは、自身の中に現在の値を持っていて、ユーザーの操作によってそれを変更していくようになっています。まぁ、スライダーは、スライドした取っ手の位置によって「だいたいこのぐらいの値」というのがわかりますが、ステッパーはそれ自体では「現在の値がどのぐらいか」はまったくわかりません。そこで、通常はNSTextFieldに現在の値を出力させるようにして使います。これは別にややこしいプログラミングなどは必要なく、単に接続をするだけですみます。NSStepperからNSTextFieldまでCtrlキー+ドラッグし、「takeIntValueFrom:」という項目に接続すれば、現在の値(整数)をNSTextFieldに表示するようになります。この他「takeDoubleValueFrom:」「takeFloatValueFrom:」などに接続すれば、実数として値を表示できます。また、「Autorepeats」アトリビュートをONにしておくと、マウスクリック時だけでなく、プレスしていると自動的に値が変わるようになります。

 これらのコントロールは、数量を示すためのものですから、設定する範囲や現在値などのアトリビュートを設定して使わないといけません。以下の3つは、必ず設定して使うと考えておきましょう。
 この他、ステッパーの場合はIncrement Amountというものもあります。これはクリックした時に増減する量を示します。またスライダーは「Marker」という部分を設定することで目盛りの表示をすることができます。これは実際に使ってみれば働きはすぐにわかるでしょう。

 現在の値は、やはりintValueなどで得ることができます。また値を変更した際にはアクションが発生するので、それを利用して処理を行なわせることもできます。数量関係のコントロールは比較的単純な構造ですから、使い方に悩むことはおそらくないでしょう。


■NSImageViewによるイメージ表示

 この他に、グラフィックを表示するためのものとして「NSImageView」も紹介しておきましょう。え、前回描画について使った奴だろうって? その通りです。が、実をいえば「既に用意されているグラフィック」を表示するだけなら、実に簡単に使えるんですよ。

 NSImageViewは、グラフィック表示に関する全般を行なうコントロールです。自分で描画処理を作成する場合だけでなく、あらかじめ表示するイメージグラフィックを用意しておく使い方も多用されます。これは、以下のような手順をとれば行なえます。

  1. Project Builderで、「プロジェクト」メニューから「ファイルを追加」を選び、利用するイメージファイルを選択します。
  2. ターゲットの設定パネルが現れるので、デフォルトのままOKします。これでファイルがプロジェクトに組み込まれます。
  3. Interface Builderに切り替え、イメージを表示したいNSImageViewの「Icon」アトリビュートに、組み込んだファイル名(「image1.tiff」の場合は「image1」でよい。拡張子の.tiff部分はいらない)を設定してリターンして下さい。NSImageViewにイメージが表示されます。
イメージの表示


 プロジェクトをビルドすると、組み込んだイメージファイルはパッケージ内の「Resources」フォルダ内に組み込まれます。従って、元のファイルが見つからなくても表示がされなくなったりする心配はありません。

 では、プログラムの中で、ファイルからイメージを読み込み表示させるにはどうすればいいでしょう。これには、ファイル選択のためのパネル「NSOpenPanel」と、イメージを示す「NSImage」という2つのクラスを知っておく必要があります。

 NSOpenPanelというのは、文字通りオープンパネルのクラスです。これは「openPanel」というメソッドでそのインスタンスを得ることができます。そして「runModal」というメソッドを呼び出せば、オープンパネルが表示されます。そしてファイルを選択してパネルを閉じると、その操作に対応する値(int値)が返されます。従って、オープンパネルを利用したければ、

NSOpenPanel ×× = NSOpenPanel.openPanel();
int ○○ = ××.runModal();

 このようにしてインスタンスをrunModalすればいいわけです。得られた値は、NSOpenPanel内のフィールドを使って値チェックできます。OKボタンの場合は「OKButton」というフィールドが用意されていますので、「if (○○ == NSOpenPanel.OKButton) 〜」というようにチェックすれば、OKしたときの処理が行なえます。

 選択したファイルは、インスタンスの「filename」というメソッドで得られます。これはファイルのパスを示すStringです。

 もう1つのNSImageは、イメージを示すクラスです。JavaのAWTにも「Image」というクラスがありましたね。あれのCocoa版と考えればいいでしょう。このNSImageは、ファイルのパスイルから読み込んだイメージのNSImageを作成することができます。

NSImage ×× = new NSImage ( ファイルのパス , boolean値);

 第1パラメータはパスのStringですが、第2パラメータは何でしょう? これは、「ファイルの参照」に関するもので、trueにすれば、ファイルを開くことなくイメージを読み込めます。「開くことなく」? そう、コンピュータでは、あるプログラムからファイルを開くと、そのファイルは使用中として他から開けなくなったり削除できなくなったりしますね? これをtrueにしておくと、ファイルは開かれませんから、自由に他からアクセスできる状態のままイメージを読み込めるのですね。

 では、これらをまとめた簡単な例を挙げておきましょう。

public NSImageView imgview;

public void myAction(Object sender) {
NSOpenPanel op = NSOpenPanel.openPanel();
if (op.runModal() == NSPanel.OKButton)
imgview.setImage(new NSImage(op.filename(),true));
}


 例えば、これは「imgview」というアウトレットに設定されたNSImageViewにイメージを読み込むサンプルです。クリックするとオープンパネルが現れ、そこで選んだファイルからイメージを読み込んでNSImageViewに表示します。

 NSImageViewの表示イメージは、「setImage」というメソッドで他のNSImageに変更できます。これを使い、ファイルパスからNSImageのインスタンスを作成して表示させているわけですね。

 ざっと主立ったコントロールのもっとも基本的な使い方だけまとめてみました。Cocoaにはこの他にも多くのコントロールがありますし、ここで紹介したものもさまざまな機能がまだまだ秘められています。が、とりあえず「使えるコントロールの種類を増やす」ことが、今の段階ではプログラムの幅を広げることにつながるでしょう。基本的な使い方だけでも確実に利用できるようになれば、十分役立つはずですよ。


GO NEXT


GO HOME