2010年10月15日金曜日

Reflect

hide1080さんのブログで asObjectというのを知った。ありがとうございます。ここで自分に重要なのは、

「asObject()メソッドでObjectに変換する」

ということ。as Object でキャストすると、コンパイルは通るが実行時にStageにキャストするところで例外が発生する。ただ、NetBeansIDE上見ると、どちらの場合もクラスがObjectとしか表示されない。当たり前か。これが 1 as String でコンパイルエラーになる( 1.toString()とする )のと同様、コンパイルエラーになるべきか(出来るのか)は分からないが。とにかくasObject()で javafx.reflect.FXLocal.ObjectValueをObjectに変換する必要があるということだった。どうも暗黙の変換に依存しすぎて来た影響で、キャストと変換を混同してしまいがち。まあこの辺は1日で感覚が戻って来ているので、書いていくうち何とかなるだろう。

※余談だが(1).toString()で()を忘れてtoStringだけにしてしまうとtoString関数と見なされ?て実行時エラーとなるので注意。

var mscene = Scene { /*width:400 height:200*/ };
//var mscene:Scene = make("javafx.scene.Scene") as Scene;
var mstage:Stage = make("javafx.stage.Stage") as Stage;

//mstage.scene = mscene;
mstage.title = {"testReflect {1.toString()}"};
mstage.width = 400;
mstage.height = 400;

function make(clsname:String){
var context = FXLocal.getContext();
var cls = context.findClass(clsname);
var ins = cls.allocate();
ins.initialize();
// return ins as Object; これだと実行時に戻ってからのStageへのキャストが失敗する。
return ins.asObject();;
}


また、最初Sceneもreflectで作成しないといけないのかと思ったが、通常の書き方で作成しても大丈夫なよう。別に試しているRectangleがうまくいかなかったのでそう思ったのだが、これもasObject()していなかったから。他にもwidthしか設定してなかったため、heightが0だったとか。

だが不思議な事が1つ。

途中、mstageにsceneを設定しないと、
mstage.width = 400;
が利かなかったので、後からsceneを追加したはずなのに、それをmemoしようとsceneの設定をコメントアウトしたが、今度は問題なくwitdhが利く。なんで? もしやと思い、msceneの宣言をコメントアウトすると再現した。なんだよ・・・。つまり、Stageに設定していなくてもSceneが同じファイル(=クラス?)の中に有ればいいみたい、ではなくて、そもそもSceneの入ってないStageってどうよ、という問題だと思われる。今、たまたまreflectで作ったStageのプロパティ(変数)を変更したいだけなのでSceneを端折っただけなわけで。

それにしても最初にreflectを見た時、initValをintValと見間違えて、「わざわざintって指定するなら意味ないじゃん」と捨ててしまった愚かさよ。さようなら。どうか永遠に。といいつつ最近誤字も多いし脱字も多いし。実は昔からだという話も。

次はJavaのreflectも。

あれ、initValがないと思ったらmake()にクラス名を渡すようにしたからだが、asObject()の逆を探さないと...まあ最悪引きずっていけば良いといえば良いのか。asObject()覚えたからといって、一階上というか普通の(Stageとかの)クラスに変換しなきゃならないかどうかはまだ分からないわけで、というより、そもそも中途半端に面倒になってmstage.widthとやりたかったというのが事の発端なだけだった、よく考えれば。

0 件のコメント:

コメントを投稿