|
Unofficial "CLDC 1.1 + MIDP 2.0" API Reference. (日本語版) |
|||||||||
前のパッケージ 次のパッケージ | フレームあり フレームなし |
参照先:
説明
インタフェースの概要 | |
---|---|
Choice | Choice は、選択のあらかじめ決められた番号から選択を行うユーザーインタフェース・コンポーネント(以下、UI コンポーネント)のための API を定義します。 |
CommandListener | このインタフェースは実装から高レベル・イベントを受け取る必要のあるアプリケーションが使用します。 |
ItemCommandListener | Item オブジェクトから通知された Command を受け取るためのリスナー型です。 |
ItemStateListener | このインタフェースは Form スクリーン内の対話型アイテムの内部状態が変化したことを示すイベントを受け取る必要があるアプリケーションが実装すべき定義を提供しています。 |
クラスの概要 | |
---|---|
Alert | Alert は次に続く Displayable の前にデータをユーザに提示して、一定時間待つスクリーンです。 |
AlertType | AlertType は Alert のインジケータの種類を提供します。 |
Canvas | Canvas クラスは低レベル・イベントの取り扱いおよびディスプレイへグラフィックスの描画を行う必要のあるアプリケーションを記述するための基底クラスです。 |
ChoiceGroup | ChoiceGroup は Form 内に置くことができる、選択可能な要素のグループを表すユーザーインタフェース・コンポーネントです。 |
Command | このクラスはアクション・イベントに関する情報をカプセル化して運搬するために使用します。 |
CustomItem | CustomItem のサブクラスを作成することで、Form に新しい視覚的で対話的な要素を追加するカスタマイズを可能にします。 |
DateField | DateField は日付と時刻情報を表示しユーザーが編集可能な、Form に登録することができるユーザーインタフェース・コンポーネントです。 |
Display | このクラスはシステムのディスプレイや入力装置のマネージャー機能を提供します。 |
Displayable | ディスプレイに表示することができる能力をもつクラスです。 |
Font | Font クラスはフォントおよびフォント・メトリクスを表します。 |
Form | Form は任意の Item を混合して含むことができる Screen です:
イメージ、書き込み禁止テキスト・フィールド、編集可能なテキスト・フィールド、編集可能な日付フィールド、ゲージ、選択グループ、およびカスタム・アイテム。 |
Gauge | 整数値に関する棒グラフなどのグラフィカルな表示を提供します。 |
Graphics | シンプルな2次元の幾何学的な描画機能を提供します。 |
Image | Image クラスはグラフィカルなイメージ・データを保持するために使用します。 |
ImageItem | イメージを格納することができる Item です。 |
Item | Form に加えることができるコンポーネントのスーパークラスです。 |
List | 選択リストを提供する Screen です。 |
Screen | 全ての高レベル・ユーザーインタフェースを提供するクラスのスーパークラスです。 |
Spacer | 最小サイズの占有を行う空白で、そして非対話なアイテムです。 |
StringItem | 文字列を含むことができるアイテムです。 |
TextBox | このクラスはユーザーがテキストを入力および編集することを可能にする Screen です。 |
TextField | このクラスは Form に置くことができる編集可能なテキスト・コンポーネントです。 |
Ticker | ディスプレイに絶え間なく文字をスクロールさせて表示する「ティッカー・テープ(テロップ)」を表現するクラスです。 |
UI API はユーザーインタフェース実装のために1セットのフィーチャを MIDP アプリケーションに提供します。
携帯情報機器(例えば携帯電話、ポケットベル)を念頭に MIDP の主な評価基準は作成されています。 これらのデバイスにおいてユーザーがどのように操作するか、デスクトップ・システムと比較して多くの点が異なります。 ユーザーインタフェース API を設計する際に、以下の UI 関連要件が重要です。
MIDP を実装するデバイスの能力と上記要件を考慮して、MIDPEG(MIDP エキスパート・グループ)は既存の Java UI(ここで言う UI は Abstract Windowing Toolkit(AWT) です)からのシンプルなサブセットにはしませんでした。 この決定の理由を以下に示します。
MIDP UI は2つの API で論理的に構成されます。それは高レベルと低レベルです。
高レベル API はクライアントの一部として携帯情報機器で動作するビジネス・アプリケーションのために設計されています。 これらのアプリケーションにおいて、デバイス間の移植性は重要です。 高レベル API はこの移植性を達成するために、高いレベルの抽象化を行い、非常に限られたルック&フィールの制御しか提供しません。 これらの抽象化はさらに以下の方法で実現されます。
言い換えれば高レベルな API を使用する場合、基本的に実装がデバイスのハードウェアとネイティブ UI スタイルへの必要な適合を行うと言えます。
高レベル API を提供するクラスは Screen
クラスのサブクラスです。
一方、低レベル API はほとんど抽象化を提供しません。 この API はグラフィック要素の正確な位置決めとコントロールを必要とするアプリケーションのために設計されており、低レベル入力イベントへのアクセスについても同様です。 また、いくつかのアプリケーションはデバイス特有のフィーチャへ特別にアクセスする必要があります。 そのようなアプリケーションの典型的な例はゲームでしょう。
低レベル API を使用してアプリケーションは以下のことをすることができます。
低レベル API を提供するクラスは、Canvas
と Graphics
です。
低レベル API は特定のデバイスの細部にアクセスする手段を提供するため、アプリケーションが低レベル API を使用するようにプログラムすると移植性は保証されません。アプリケーションがこれらの特徴を使用しなければ、移植性を確保することができます。可能であれば、いつもアプリケーションが低レベル API のプラットフォームから独立している部分のみを使用することを推奨します。これは、アプリケーションが Canvas
クラスにて定義された以外の全ての直接的なキーの存在も仮定せず、また特定の画面サイズに依存すべきではないということを意味します。むしろ、アプリケーションはゲーム・キーのイベント・マッピング・メカニズムを特定のキーの代わりに使用すべきです。またアプリケーションはディスプレイ・サイズについても問い合わせを行い、そのサイズに適応すべきです。
MIDP における UI の主要な抽象化は Displayable
オブジェクトで行われます。このオブジェクトはユーザー入力、デバイス特有のグラフィック・レンダリングをカプセル化します。一つの Displayable
だけが一度に表示されます。そしてその Displayable
だけがコンテンツでユーザーと対話することができます。
Screen
クラスは、高レベルなユーザーインタフェース・コンポーネントと全てのユーザー対話の仲立ちをする Displayable
のサブクラスです。
より高いイベントのみがアプリケーションに通知されている状態で、Screen
サブクラスはレンダリング、ユーザー対話、フォーカス・トラバースおよびスクロールを扱います。
このデザインのベースは MIDP デバイスによって異なるディスプレイと入力ソリューションが見られるという点に基づいています。 これらの違いはコンポーネント・レイアウト、スクロールおよびフォーカス・トラバースが異なるデバイスで異なった実装がなされることを含みます。 アプリケーションがこれらの問題を意識する必要があるのであれば、それは移植性に妥協があります。 また、シンプルな画面は扱いやすい量にユーザーインタフェースを編成し、使用しやすく、学びやすいユーザーインタフェースをもたらします。
Displayable
オブジェクトには3つのカテゴリがあります。
List
や TextBox
クラス)をカプセル化するスクリーン。
これらのスクリーンの構造は事前に定義されており、アプリケーションはこれらのスクリーンに他のコンポーネントを加えることはできません。
Item
オブジェクトを載せることができる汎用スクリーン(Form
クラスのインスタンス)。
アプリケーションは任意の数のテキスト、イメージおよびその他のコンポーネントを Form
オブジェクトに載せることができます。
しかし、Form
オブジェクトがシンプルに保たれ、それらは必要最小限の、密接に関連するユーザーインタフェース・コンポーネントのみを使用することを推奨します。
Canvas
クラスのサブクラス)。
各 Displayable
はタイトル、Ticker
および Command
のセットを設定することができます。
Display
クラスはそれぞれのアクティブな MIDlet のためにインスタンスが提供され、デバイスの表示能力に関する情報を取得するメソッドを提供する、ディスプレイ・マネージャとして動作します。
Display
の setCurrent()
メソッドを呼び出すことにより、Displayable
を目に見えるようにします。
Displayable
をカレントに設定すると、以前の Displayable
と置き換えます。
ほとんどのアプリケーションは List
、TextBox
および Alert
のような事前に定義された構造をもつスクリーンを使用すると思われます。
これらのクラスは以下の方法で使用します。
List
は事前に定義した選択セットの中からユーザーが選択を行う際に使用します。
TextBox
はユーザーから自由文の入力を受ける際に使用します。
AlertType
はテキストとイメージを含む、一時的なメッセージを表示する際に使用します。
特殊なクラスである Form
は事前に定義された構造を持つスクリーンが十分ではない場合のために定義されています。
例えばアプリケーションには二つの TextField
あるいは TextField
とシンプルな ChoiceGroup
があるかもしれません。
このクラス(Form
)は任意のコンポーネントの組み合わせを許容しますが、開発者は限られたディスプレイ・サイズであることを忘れずに、シンプルな Form
だけを作成すべきです。
Form
は少数の密接に関連付けられた UI 要素を載せるように設計されています。
これらの要素は Item
のサブクラスです: ImageItem
、StringItem
、TextField
、ChoiceGroup
、Gauge
および CustomItem
。
ImageItem
と StringItem
は、Form
と Alert
において特定の操作を簡単に実現するためのユーティリティ・クラスです。
CustomItem
のサブクラスを作成することで、アプリケーション開発者は新しい視覚表現と対話的な要素がある Item
を導入することができます。
コンポーネントを全てスクリーンに表示することができない場合には、実装はフォームのスクロールを可能にするか、いくつかのコンポーネントをポップアップする新しいスクリーンとして実装するか、ユーザーが要素を編集する時に拡大表示することがあります。
ユーザーインタフェースは、他のいくつかの API のリソースのように、MIDP アプリケーション管理の原則によって制御されます。 ユーザーインタフェースはアプリケーション管理ソフトウェア(AMS)から以下の条件を期待します。
getDisplay()
は MIDlet のコンストラクタから destroyApp()
の呼び出しが完了するまでの間、呼び出すことができます。
destroyApp()
が呼び出されるまで同一の Display
オブジェクトです。
setCurrent()
によって設定した Displayable
オブジェクトがアプリケーション・マネージャにより変更されることはありません。
アプリケーション・マネージャはアプリケーションが以下の通りに MIDlet イベントに関して振舞うと仮定します。
startApp
- アプリケーションは最初のスクリーンのために setCurrent()
を呼び出すことができます。
アプリケーション・マネージャは startApp()
から処理が戻ると Displayable
を実際に見えるようにします。
MIDlet の実行中に pauseApp()
が呼び出される場合、startApp()
は何度か呼び出されることに注意が必要です。
このとき、初期化は行われるべきではなく、アプリケーションが setCurrent()
によって予期しないスクリーンの切り替えを行わないようにすべきです。
pauseApp
- アプリケーションはできる限り多くのスレッドをリリースすべきです。
また、アプリケーションが再度アクティブに戻る時、別のスクリーンから開始するならば、setCurrent()
によって新しいスクリーンを設定すべきです。
destroyApp
- アプリケーションは作成したオブジェクトを削除することができます。
ユーザーによる操作はイベントを引き起こします。アプリケーションはそれぞれに対応するコールバックを作成することにより実装から通知されるイベントを受け取ることができます。 UI コールバックは4種類あります。
Canvas
クラスの paint()
メソッドを呼び出し
Display
クラスの callSerially()
の呼び出しで設定された Runnable
オブジェクトの run()
メソッドを呼び出し
全ての UI コールバックは連続的(シリアル)に呼び出されるため、それらが平行して(パラレルに)呼び出されることはありません。つまり、いかなる他のコールバックも先に呼び出したコールバックから処理が戻る前に決して呼び出されることはありません。この特性により、アプリケーションが前のユーザー・イベント処理を完了することが保証され、その後に次のイベントが提供されるということを意味します。複数の UI コールバックが未処理であれば、前の UI コールバックから処理が戻った後に次の呼び出しをできる限り早く行います。また、実装は未処理の再描画要求を満たした後に callSerially()
の呼び出しで設定された run()
を呼び出すことを保証します。
コールバックの連続的(シリアル)な呼び出し規則に一つの例外があります。それは Canvas.serviceReapints
の呼び出しによって発生します。
それは、このメソッドによって引き起こされる、Canvas.paint
の呼び出しとその終了待ちです。serviceRepaints
の呼び出しそれ自身がアクティブなコールバックの中にいたとしてもこれは起こります。
この問題の更なる議論が以下にあります。
以下のコールバックは全てお互いに関連して連続的(シリアル)に呼び出されます。
Canvas.hideNotify
Canvas.keyPressed
Canvas.keyRepeated
Canvas.keyReleased
Canvas.paint
Canvas.pointerDragged
Canvas.pointerPressed
Canvas.pointerReleased
Canvas.showNotify
Canvas.sizeChanged
CommandListener.commandAction
CustomItem.getMinContentHeight
CustomItem.getMinContentWidth
CustomItem.getPrefContentHeight
CustomItem.getPrefContentWidth
CustomItem.hideNotify
CustomItem.keyPressed
CustomItem.keyRepeated
CustomItem.keyReleased
CustomItem.paint
CustomItem.pointerDragged
CustomItem.pointerPressed
CustomItem.pointerReleased
CustomItem.showNotify
CustomItem.sizeChanged
CustomItem.traverse
CustomItem.traverseOut
Displayable.sizeChanged
ItemCommandListener.commandAction
ItemStateListener.itemStateChanged
Display.callSerially
によって発生する Runnable.run
Timer
イベントは UI イベントの一部ではないことに注意が必要です。
同じ Timer
によってスケジュールされた TimerTask
コールバックはお互いに関連して連続的(シリアル)に呼び出されますが、UI イベント・コールバックと Timer
コールバックは同時に呼び出される可能性があります。
Timer
を使用するアプリケーションは同時に発生するアクセスに対して、タイマー・スレッドと UI イベント・コールバックからそれらのデータ構造を保護しなければなりません。
代わりに、アプリケーションのタイマー・コールバックは、UI イベント・コールバックでタイム・イベントによって発生した処理を連続的(シリアル)に処理することができるように、Display.callSerially
を使用することもできます。
MIDP UI は非常に抽象的であり、それはソフト・ボタンやメニューの様に少しも具体的なユーザーによる操作の要件も指示しません。
また、トラバースやスクロールなどの低レベル・ユーザー操作もアプリケーションからは見えません。
MIDP アプリケーションは Command
を定義し、そして、実装はソフト・ボタン、メニューまたは何らかのそのデバイスのメカニズムでこれらを表現します。
Command
は表示対象(Canvas
または Screen
)に Displayable
の addCommand
メソッドでインストールします。
デバイスの自然なスタイルとして、あるタイプのコマンドに対して標準で割り当てられる位置を想定することがあります。
例えば、"戻る"は常に右のソフト・ボタンに割り当てられるかもしれません。
Command
クラスは、アプリケーションにこれらの標準のマッピングを用いることができるように、そのような意味と目的を実装に伝えます。
実際には、実装が Command
の意味に対する実装を提供することはありません。
Command
の属性は、それをユーザーインタフェースにマッピングするためだけに使用します。
Command
の実際の意味に対する処理は、常にアプリケーションにおいて CommandListener
を実装することで行います。
Command
オブジェクトには以下に示す属性があります。
Command
は短いラベルと長いラベルの二つのバージョンを持つことができます。
実装は与えられた情況に合わせて、短いバージョンか長いバージョンかいずれか適切な方を使用します。
例えば、実装はソフト・ボタンの近くに Command
オブジェクトの短いラベルを使用し、メニューによる表示を行う場合は Command
オブジェクトの長いバージョンを使用することを選択することができます。
Command
クラスはコマンドの意図をデバイスの実装に通知する能力を MIDlet に供給する固定セットのコマンド・タイプを提供します。
アプリケーションは"戻るナビゲーション"を実行するコマンドに BACK
タイプのコマンドを使用することができます。
前述の様にデバイスはこのタイプ情報を元に、コマンドを適切なソフト・キーに割り当てるために使用することができます。
Command
間の相対的な重要度を定義します。
優先度の値が小さいコマンドは、優先度の値が大きい他の同じタイプのコマンドより重要であることを意味します。
できるならば、より重要なコマンドを手前に提示するか、それほど重要ではないものよりも容易にアクセスできるように配置するでしょう。
また、多くの高レベル UI クラスには、ユーザーインタフェースで使用可能ないくつかの追加操作があります。
追加操作はエンドユーザーにのみ見え、アプリケーションからは見えません。
利用可能な操作のセットは特定のデバイスのユーザーインタフェース設計に完全に依存します。
例えば、ユーザーがテキストを入力するためにアルファベットと数字の間のモードを切り替える操作が ITU-T キーパッドしか装備していないデバイスでは必要です。
より複雑な入力体系(日本語入力など)は追加操作を必要とするでしょう。
利用可能な操作のいくつかはユーザーインタフェースにアプリケーションで定義したコマンドが存在するのと同じように提示されます。
エンドユーザーは、アプリケーションとシステムのいずれかがどの操作を提供したかを理解する必要はありません。
全ての操作があらゆる実装で使用可能であるというわけではありません。
例えば、一般的な「(POBox などの)単語ルックアップベース」の入力スキームを装備しているシステムは TextBox
クラスの中で追加操作を提供するでしょう。
また、そのような入力体系をもたないシステムは対応する操作を提供しないでしょう。
いくつかの操作は全てのデバイスで使用可能ですが、操作が実装される方法はデバイスによって大きな開きがあるかもしれません。
この種の操作に関する例は以下の通りです:
テキスト・エディタの中で挿入位置を動かしたり List
要素を選択したりして、List
要素と Form
のアイテムの間を操作している機構があったとします。
デバイスによっては、Item
の値のダイレクト編集を許可しませんが、代わりにユーザーがオフスクリーン・エディタに切り替える必要があります。
そのようなデバイスには、オフスクリーン・エディタを呼び出すために使用することができる専用の選択操作が用意されています。
List
要素の選択は、例えば専用の"実行"または"選択"、または同種のキーを実装しているかもしれません。
あるデバイスが全く専用の選択キーを持たない場合は、他の手段を使用することで要素を選択する手段を提供しなければなりません。
選択操作が専用の選択キーを使用することで実行されるデバイスでは、このキーは多くの場合ラベルを表示するということはないでしょう。
実装は意味が明白である状況において、このキーを使用することが適切です。
例えば、1セットの互いに排他的なオプションをユーザーに与えると、選択キーは明らかにそれらのオプションの1つを選択するでしょう。
しかし、専用の選択キーを持っていないデバイスでは、選択操作がラベルを必要とするソフト・キーを使用することで実行されるということがよくあります。
アプリケーションがこの操作にラベルを設定することができ、この操作が起こると通知を受け取ることができるように、タイプ IMPLICIT
の List
に選択コマンドを設定する機能と Item
にデフォルト・コマンドを設定する機能が提供されます。
高レベル API におけるイベントの取り扱いはリスナー・モデルに基づきます。
Screen
と Canvas
はコマンドのためのリスナーを持つことができます。
リスナーを持ちたいオブジェクトは、一つのメソッドを持つ CommandListener
インタフェースを実装します。
void commandAction(Command c, Displayable d);
Screen
あるいは Canvas
に Command
を設定してリスナーを登録していれば、アプリケーションはこれらのイベントを受け取ることができます。
リスナー・モデルのユニキャスト(一対一の関係)バージョンが採用されているため、Screen
または Canvas
は一度に一つのリスナーを持つことができます。
また、Form
内の Item
の状況変化を受け取るためのリスナー・インタフェースがあります。メソッドは以下の通りです。
void itemStateChanged(Item item);
ユーザーと対話が可能な Gauge
、ChoiceGroup
または TextField
の値が変化すると、ItemStateListener
インタフェースで定義された上記メソッドが呼ばれます。
リスナーが全ての変化の後に呼ばれることを想定することはできません。
しかし、Item
の値が変わったなら、別の Item
の変化によってこのリスナーが呼ばれるか、コマンドを Form
の CommandListener
に渡す前に、リスナーを呼びます。
少なくとも、フォーカス(または同等のもの)がフィールドから失われた後に、リスナーが呼ばれることを推奨します。
フィールドの値が実際に変化した場合に限り、リスナーは呼ばれるべきです。
低レベル・グラフィックとイベントには低レベル・キー・イベントを扱う以下のメソッドがあります。
public void keyPressed(int keyCode); public void keyReleased(int keyCode); public void keyRepeated(int keyCode);
最後に取り上げた keyRepeated
は必ずしも全てのデバイスで使用可能であるというわけではありません。
アプリケーションは Canvas
の以下のメソッドを呼び出すことによって、リピート動作の有効性を確認することができます。
public static boolean hasRepeatEvents();
API は ITU-T キーパッド(0 〜 9, *, #)のための標準キーコードを要求しますが、API はキーパッドのレイアウトについては何も要求しません。 実装は追加のキーを提供するかもしれませんが、これらのキーをあてにするアプリケーションは移植性を損ないます。
加えて、Canvas
クラスには抽象的なゲーム・イベントを扱うためのメソッドがあります。実装はこれら全てのデバイスのキーを適切なキー・イベントにマップします。
例えば、デバイスに四方向の移動キーと中央の選択キーがある場合にはそれらのキーを使用するかもしれませんが、よりシンプルなデバイスは数値キーパッドにあるキー(例えば 2, 4, 5, 6, 8)を使用するかもしれません。これらのゲーム・イベントは低レベル・イベントを使用する移植性のあるアプリケーションの開発をサポートします。
API は1セットの抽象的なキー・イベントを定義します: UP
、DOWN
、LEFT
、RIGHT
、FIRE
、GAME_A
、GAME_B
、GAME_C
および GAME_D
。
アプリケーションは以下のメソッドを呼び出すことによって、キーコードに対応する抽象的なキー・イベントを取得することができます。
public static int getGameAction(int keyCode);
アプリケーションのロジックがこのメソッドから返された値に基づいていれば、アプリケーションは移植性があり、キーパッドのデザインに関らず実行することができます。
また、この抽象的なイベントを対応するキーに置き換えることもできます。
public static int getKeyCode(int gameAction);
gameAction
には UP
、DOWN
、LEFT
、RIGHT
、FIRE
などが入ります。
デバイスによっては、1つ以上のキーが同じゲーム・イベントにマッピングされます。この場合、getKeyCode
は常に一つのキーを返します。
適切に記述されたアプリケーションは、キーコードを抽象的なイベントに変換し、この結果を元に決定を下すべきです。
キーと抽象的なイベントのマッピングはゲームの実行中に変化することはありません。
以下はアプリケーションがキーストロークを解釈するために、どのようにゲーム・アクションを使用することができるかを示す例です。
class MovingBlocksCanvas extends Canvas { public void keyPressed(int keyCode) { int action = getGameAction(keyCode); switch (action) { case LEFT: moveBlockLeft(); break; case RIGHT: ... } } }
低レベル API にはポインタ・イベントのサポートがありますが、対応する入力メカニズムが全てのデバイスには存在していないかもしれないため、以下のコールバック・メソッドはデバイスによっては決して呼び出されることはないでしょう。
public void pointerPressed(int x, int y); public void pointerReleased(int x, int y); public void pointerDragged(int x, int y);
アプリケーションは Canvas
クラスの以下のメソッドを呼び出すことによって、ポインタが使用可能であるかどうかを確認することができます。
public static boolean hasPointerEvents(); public static boolean hasPointerMotionEvents();
Canvas
クラスは低レベル・イベントと描画に使用する Displayable
のサブクラスであり、アプリケーションは Command
を設定することができます。これはゲームの途中にオプション設定画面へ遷移することに役立ちます。別の例では、地図ベースのナビゲーションを行うアプリケーションにおいて、キーを地図の移動に使用し、コマンドはさらに高いレベルのアクションのために使用するかもしれません。
デバイスによっては、Canvas
と低レベル・イベント・メカニズムが使用中の場合にはコマンドを呼び出す手段がないかもしれません。その場合、実装はコマンド・モードと元の画面への切り替え手段を提供するかもしれません。このコマンド・モードは Canvas
コンテンツの上にポップアップするメニューであるかもしれません。この場合、Canvas
の可視・不可視の状態に合わせて Canvas
の hideNotify()
と showNotify()
メソッドが呼び出され、それぞれの状態が明確にされます。
Canvas
にはタイトルと Ticker
が Screen
オブジェクトの様に存在するかもしれません。
しかし、Canvas
にはタイトルと Ticker
が表示されないフルスクリーン・モードも存在します。
このモードを設定することで、アプリケーションが Canvas
を使用してできる限り多くの物理的なディスプレイ領域を占有する必要があることを示します。
このモードでは、タイトルはポップアップ・メニューのためのタイトルとして実装が再利用することがあるかもしれません。
アプリケーションが低レベル Canvas
と Screen
オブジェクトを切り替えた際に視覚的な違和感が発生しないように、通常(フルスクリーンではない)モードでの Canvas
の外観は Screen
クラスのものと同様であるべきです。
全ての Screen
では自動的に再描画を行いますが、Canvas
ではそうではありません。
このため、低レベル API を使用する開発者は再描画の枠組みを理解しなければなりません。
低レベル API では、非同期に Canvas
への再描画を行うため、複数の再描画要求を最適化して一つの描画処理の呼び出しとするように実装されるかもしれません。
アプリケーションは Canvas
クラスの repaint()
を呼び出すことによって再描画要求を行うことができます。
実際の描画は(Canvas
のサブクラスによって提供される)paint()
メソッドの中で完結し、必ずしも repaint()
と同期するわけではありません。
この paint()
メソッドの呼び出しは後で発生することがあり、また複数の再描画要求が一つの描画要求にまとめられることがあります。
アプリケーションが再描画の要求を確定させる場合には serviceRepaints()
を呼び出します。
例として、アプリケーションが幅 wid
および高さ ht
の箱を、座標 (x1, y1)
から座標 (x2, y2)
へ移動させる例を示します(ただし、x2 > x1
および y2 > y1
であることを条件とします)。
// 箱の座標を移動 box.x = x2; box.y = y2; // 古い領域の再描画を確保します(バックグラウンドにて) canvas.repaint(x1,y1, wid, ht); // 新しい領域の再描画を作成します canvas.repaint(x2,y2, wid, ht); // 全ての再描画要求を確実に実施します canvas.serviceRepaints();
最後の呼び出しは再描画を行うスレッドをスケジュールするようにします。 再描画スレッドがイベント・キューに要求(この例では二つ)を発見すると、再描画の対象となる共有エリアを設定し再描画を行います:
graphics.clipRect(x1,y1, (x2-x1+wid), (y2-y1+ht)); canvas.paint(graphics);
この仮想の実装部分による canvas.paint()
の呼び出しは、対象となるアプリケーションで定義された paint()
メソッドを呼び出すことを意味します。
第一の描画操作はピクセル置換であり、線や長方形などの幾何学描画に使用します。 オフスクリーン・イメージには完全な透明のサポートが必要です。不完全な透明(アルファブレンディング)のサポートは任意です。
8ビットの赤、緑および青の色成分による、24ビットのカラーモデルを提供します。
全てのデバイスが24ビット・カラーをサポートするわけではないので、必要に応じてアプリケーションが要求した色をデバイスで利用可能な色へ割り当てることがあります。
カラー表示が利用可能か、何段階のグレースケール表現が利用可能かといったデバイスの特性を得るための機能を Display
クラスが提供します。
これにより、アプリケーションがデバイス独自の機能性に影響されずに、それらのデバイスの振る舞いに適合することが可能になります。
グラフィックスは直接ディスプレイへ、またはオフスクリーン・イメージ・バッファへの描画を行います。
グラフィックスの描画先は、その Graphics
オブジェクトを生成した対象となります。
ディスプレイへの描画を行う Graphics
オブジェクトは Canvas
オブジェクトの paint()
メソッドに渡されます。
これはディスプレイを描画先とする Graphics
オブジェクトの唯一の入手方法です。
なお、アプリケーションは paint()
メソッドの実行中に限り、この Graphics
オブジェクトを使用するように作成しなければなりません。
希望するイメージの getGraphics()
メソッドを呼び出すことでオフスクリーン・イメージ・バッファへ描画するための Graphics
オブジェクトを入手することができます。
これらの Graphics
オブジェクトはアプリケーションで無期限に所持することができ、必要に応じて描画要求をいつでも出すことができます。
Graphics
クラスには setColor()
メソッドで設定する現在の色があります。
ライン、長方形および円弧を含む全ての幾何学描画が現在の色を使用します。
これらの操作で対象となるピクセルを現在の色に置き換えます。
背景色は存在しません。
アプリケーションが setColor()
を呼び出して、明示的に背景の描画を行います。
完全な透明のサポートが必須です。不完全な透明(アルファブレンディング)のサポートは任意です。 透明(完全なものおよび不完全なもの)は PNG ファイルまたは ARGB データ配列からロードされたオフスクリーン・イメージにのみ存在します。 アプリケーションによるイメージに含まれるピクセル・データに対するどのような変更も排除されるため、そのように生成されたイメージは不変タイプです。 描画はどのような描画操作の対象ピクセルも常に完全に不透明なピクセルから構成されるように定義されています。
利用可能な描画領域とイメージの原点座標 (0, 0)
がディスプレイの左上隅にあります。
X座標の数値は左から右に単調増加し、Y座標の数値は上から下に単調増加します(単調増加=全ての範囲で等幅に1単位ずつ増加するということです)。
アプリケーションは、座標系の水平と垂直の距離が実際のディスプレイ・デバイス上にて等しい距離であるという仮定をすることができます。
デバイスのピクセルの形状が正方形とはかけ離れている場合、UI の実装は必要な座標変換を行います。
座標系の原点を変換する機能が提供されます。
全ての座標は整数として指定します。
座標系はピクセルそのものではなく、ピクセルの間の位置を表します。
したがって、ディスプレイの左上隅における最初のピクセルは、座標 (0,0), (1,0), (0,1), (1,1)
による正方形の範囲にあります。
アプリケーションは Canvas
の以下のメソッドを呼び出すことにより、利用可能な描画領域について問い合わせをすることができます:
public static final int getWidth(); public static final int getHeight();
アプリケーションは以下で指定する、文字装飾の一つを要求することができます。 しかし、基本的な実装では指定された内容に対してのサブセットを使用することがあります。 したがって、実装は最も要求されたフォントに類似しているフォントを返します。
システムの各フォントは個別に実装されます。
プログラマは Font
オブジェクトを new
の代わりに静的メソッド getFont()
を呼び出すことができます。
この実例は、通常のフォントの使用に関連して発生する無駄なオブジェクトの生成を排除します。
Font
クラスはフォント・メトリクス(測定基準)にアクセスするためのメソッドを提供します。
以下の属性はフォント(Font
クラスが提供)を要求するために使用することができます:
SIZE_SMALL
、SIZE_MEDIUM
、SIZE_LARGE
FACE_PROPORTIONAL
、FACE_MONOSPACE
、FACE_SYSTEM
PLAIN
、STYLE_BOLD
、STYLE_ITALIC
、STYLE_UNDERLINED
UI API はスレッドセーフであるように設計されています。
メソッドはアプリケーションが作成したコールバック、TimerTask
、または他のスレッドから呼び出すことができます。
また、一般に実装はアプリケーションが目に見えるオブジェクトにいかなるロックも設定していません。
これはアプリケーションのスレッドが、アプリケーションによって定義された同期方針にしたがって、必要なオブジェクトをロックすることによって、自身とイベント・コールバックで同期することができることを意味します。
この規則への一つの例外が Canvas.serviceRepaints()
メソッドで発生します。
このメソッドは paint()
メソッドを呼び出し、その完了まで待ちます。
厳密に言うと、serviceRepaints()
は直接 paint()
を呼び出さないかもしれませんが、代わりに paint()
を呼び出す別スレッドを起動することがあります。
いずれの場合でも、paint()
の終了まで serviceRepaints()
はブロックします。
これは以下のケースでは特異点となります。
serviceRepaints()
の呼び出し元が、paint()
メソッドで必要とするロックを所持していると仮定します。
paint()
が別のスレッドから呼び出される可能性があるため、そのスレッドはロックを入手する試みをブロックするでしょう。
しかし、このロックは serviceRepaints()
の呼び出し元によって所持されているため、paint()
の呼び出しが終わるまでブロックします。
この結果はデッドロックです。
デッドロックを避けるために、serviceRepaints()
の呼び出し元は paint()
の呼び出しに必要とされる全てのロックを所有してはなりません。
また、UI API はイベント・ストリームでのアクションを連続化するために、他の UI ツール・キットと同様のメカニズムを含みます。
Display.callSerially
メソッドで要求された Runnable
オブジェクトの run()
メソッドが、イベント・ストリームの中で連続的に呼び出されます。
通常、callSerially()
を使用するために serviceRepaints()
を使用するコードは書き直すことができます。
以下にこのテクニックを使用するコードを例示します:
class MyCanvas extends Canvas { void doStuff() { // <断片コード1> serviceRepaints(); // <断片コード2> } }
以下のコードは同じ機能を実装する代替手法です:
class MyClass extends Canvas implements Runnable { void doStuff() { // <断片コード1> callSerially(this); } // 全ての保留された再描画要求の実行後にのみ呼ばれます。 public void run() { // <断片コード2>; } }
List
あるいは ChoiceGroup
の実装は選択の対象の要素にフォーカスをあわせて選択するために、キーボード・ショートカットを含むかもしれませんが、これらのショートカットの使用はアプリケーション・プログラムには見えません。
実装によっては、UI コンポーネント(Screen
と Item
)はネイティブなコンポーネントに基づくでしょう。
Java オブジェクトはそれ以上必要がなくなったときに、使用済みのリソースを開放するように実装する必要があります。
一つの可能な実装シナリオは KVM のガーベジ・コレクタのフックを用いる方法です。
|
Unofficial "CLDC 1.1 + MIDP 2.0" API Reference. (日本語版) |
|||||||||
前のパッケージ 次のパッケージ | フレームあり フレームなし |
公式仕様書原文の著作権表記等(※): Mobile Information Device Profile Specification ("Specification") Version: 2.0 Status: FCS Release: November 5, 2002 Copyright 2002 Sun Microsystems, Inc. and Motorola, Inc. All rights reserved. | ※ただしこの API リファレンスは英語仕様を一語一句正確に翻訳したものではなく、一度私が英語の仕様原文を読んだ上で元の意味と構造をなるべく保つように書き起こしたものです。このため一部は完全に異なる説明となっています。また CLDC 1.1 部分は同仕様の範囲外であるため、まったく参考とはしていません。 ※仕様書のライセンス上、問題は無いと考えておりますが、万が一問題があるとお考えの関係者の方がいらっしゃいましたらメールにて連絡をいただけると幸いに存じます(第一言語に日本語、第二言語に英語を希望しますが、返信は基本的に日本語で行います)。 |