The next JAVA library(4)
次は、キー入力の、機種依存部分について考えてみます。
auとVodafoneは、MIDPなので、同じ形で処理することが出来ますが、DoCoMoは独自仕様のため、別の書き方をしなければなりません。
//au,vodafone public void keyPressed(int keyCode){ //キーが押されたときの処理 } public void keyReleased(int keyCode){ //キーが離されたときの処理 } //DoCoMo public void processEvent(int type, int param){ if(type==Display.KEY_PRESSED_EVENT){ //キーが押されたときの処理 else if(type==Display.KEY_RELEASED_EVENT){ //キーが離されたときの処理 } }
分け方は、プリプロセッサで分けます。
自分の場合であれば、それぞれの機種用のMakefileからプリプロセッサをかける際に、-Dオプションに、機種判別用の名前を定義しています。
これでキー入力の機種ごとの操作はおしまい。
……そんなわけありません(・∀・)
ここで問題になるのが、ソフトキーの入力。
DoCoMoは、processEventから取得できますが、MIDPは、CommandListenerというインターフェースクラスに、ソフトキーの入力が入ってきます。
しかも、ソフトキー1、ソフトキー2という形で入ってくるのではなく、MIDPのソフトキーの実体である、Commandクラスが渡されます。
なので、処理的には、
public void commandAction(Command c, Displayable d){ if(c == /*ソフトキー1*/ ){ realKey |= CKEY_SOFT1; }else if(c == /*ソフトキー2*/ ){ realKey |= CKEY_SOFT2; } }
こんな感じになります。
しかし、問題は、どうやってソフトキー1とソフトキー2を判定させるかです。
もし、コマンドの数だけ最初に用意すると、判定分が少々ややこしくなりますし、それに汎用的では無くなるので、ライブラリとして成り立ちません。
なので、ここは、最初からCommandを2つしか用意しないことにします。
そして、ラベルの変更の仕方ですが、addCommandやremoveCommandは機種依存の機能なのでこの方法ではやりません。それに、これって相当使い勝手が悪いです(;´Д`)
どっちかっていうと、DoCoMoのsetSoftLabelの方が優れていると思うので、そちらの方法に合わせます。
//au,Vodafone用の処理 #define ef else if //2つしか使わない private Command[] command = { new Command("", Command.SCREEN, 1), new Command("", Command.BACK, 2), }; //リスナのセットと、何も書いていないコマンドをaddCommand()する { setCommandListener(this); addCommand(command[0]); addCommand(command[1]); } public void commandAction(Command c, Displayable d){ if(c == command[0]){ keyPressed(CKEY_SOFT1); }ef(c == command[1]){ keyPressed(CKEY_SOFT2); } } public void _setLabel(int n, String s){ if(n == CKEY_SOFT1) n = 0; ef(n == CKEY_SOFT2) n = 1; else return; if(n == 1){ removeCommand(command[1]); command[1] = new Command(s, Command.BACK, 2); addCommand(command[1]); }ef(n == 0){ //CKEY_SOFT1の場合は両方ともremoveCommand() //してからaddCommand()する removeCommand(command[1]); removeCommand(command[0]); command[0] = new Command(s, Command.SCREEN, 1); addCommand(command[0]); addCommand(command[1]); } } protected void _remLabel(int n){ _setLabel(n, ""); } protected String _getLabel(int n){ if(n == CKEY_SOFT1) n = 0; ef(n == CKEY_SOFT2) n = 1; return command[n].getLabel(); }
//DoCoMo用の処理 private String[] labelName = new String[2]; protected void _setLabel(int n, String s){ if(n == CKEY_SOFT1) n = 0; ef(n == CKEY_SOFT2) n = 1; else return; labelName[n] = s; if(n == 1){ setSoftLabel(Frame.SOFT_KEY_2, s); }ef(n == 0){ setSoftLabel(Frame.SOFT_KEY_1, s); } } protected void _remLabel(int n){ _setLabel(n, ""); } protected String _getLabel(int n){ if(n == CKEY_SOFT1) n = 0; ef(n == CKEY_SOFT2) n = 1; return labelName[n]; }
長い(;´Д`)
まあ、これで、_setLabel()と_remLabel()と_getLabel()を使って、共通のソフトキーの処理が出来るようになりました。
あ、MIDP側の処理で、CKEY_SOFT1の場合に、両方ともremoveCommandしているのは、ソフトキー1側のCommandは、優先順位が高いため、こいつを先にremoveCommandしてしまうと、ソフトキー2側にあったCommandがずれてきて、ソフトキー1側に来てしまうからです。それも直ぐにremoveCommandされるのですけど、一瞬だけ画面に表示されて、おかしく見えてしまいます。それを防ぐために、先にソフトキー2側のCommandをremoveCommandしているのです。
これで大体の作業は終わりですが、まだ問題があります。
それは、ソフトキーが離されたことを感知する機能が、MIDPには無い、ということです。
これはどうしようもないことなので、とりあえず、_keyUpdate()を実行する際に、こいつをクリアしましょう。
protected void _keyUpdate(){ oldKey = fixKey; fixKey = frameKey; //ソフトキーのクリア realKey &= ~(CKEY_SOFT1|CKEY_SOFT2); }
ということは、当然_isKeyPress()で、ソフトキーを判定することは出来ません。
まあ、ソフトキーに対して_isKeyPress()っていうのはそうそう無いと思うので、これで我慢しておきます。
あと、蛇足ですが、昨日、キーの入力を拡張したいときは、オーバーライドをすればいいと書きましたが、keyPressed()や、processEvent()等のメソッドは、機種依存の名前なので、別々にオーバーライドしないといけません。
出来る限りそういったのは意識したくないので、これらは全てfinal宣言をしておいて、このメソッドから、共通のメソッドを呼び出します。
//共通 protected void _pushDown(int keyCode){ realKey |= k; } protected void _pushUp(int keyCode){ realKey &= ~k; } //au,Vodafone final public void keyPressed(int keyCode){ _pushDown(keyCommon(keyCode)); } final public void keyReleased(int keyCode){ _pushUp(keyCommon(keyCode)); } //keyCodeを、CKEY_xxxxに変換するメソッド private void keyCommon(int keyCode){ //au,Vodafone用keyCommon } //DoCoMo final public void processEvent(int type, int param){ if(type==Display.KEY_PRESSED_EVENT) _pushDown(keyCommon(param)); ef(type==Display.KEY_RELEASED_EVENT) _pushUp(keyCommon(param)); } private void keyCommon(int keyCode){ //DoCoMo用keyCommon }
これで、必要に応じて_pushDown()と_pushUp()をオーバーライドすれば、機種を気にすることなくプログラムを書くことが出来ます。
今日のはいつにもまして長かったなぁ……(;´Д`)