Flash 8のNumericStepperインスタンスに、つぎのような[パラメータ]設定をしてみましょう(図001)。maximum = 10、minimum = 1、stepSize = 2、value = 1。[ムービープレビュー]してNumericStepperインスタンスを操作すると、値はどのように変化するでしょう?
図001■NumericStepperの[パラメータ]設定
最初の表示は、valueに設定した「1」です。上向き三角[▲]ボタンをクリックすると、stepSizeの「2」が加算されて、「3」になると予想するのが普通でしょう。ところが、値は「2」になります(図002)。そして、その後は2ずつカウントアップされて、「偶数表示」になってしまいます。
図002■値は1から2にカウントアップ
[パラメータ]の設定や、あるいはスクリプトによる処理などどう試しても、「1」→「3」→「5」→「7」→「9」といったいわゆる「奇数表示」ができません[*1]。これは、NumericStepperクラス[*2]に定義されているcheckValidValue()メソッドに問題があるようです。
そこで、NumericStepper.checkValidValue()メソッドを、修正してみます。ただし、ActionScript 2.0クラス定義ファイルを直接変更することは、念のため避けました。ActionScript 1.0のFunction.prototypeによる継承[*3]を利用すれば、当該ムーピー内でのみクラスのメソッドを書替えることができます(スクリプト001)。
[注記] 以下の修正スクリプトは、一応のテストはしています。しかし、その動作を保証するものではありません。利用する場合には、自己の責任にてお願いします。
スクリプト001■NumericStepper.checkValidValue()メソッドの修正
// フレームアクション
// NumericStepper.checkValidValue()メソッドの修正
import mx.controls.NumericStepper;
NumericStepper.prototype.checkValidValue = function(val:Number):Number {
var stepS:Number = this.stepSize;
var minVal:Number = this.minimum;
var maxVal:Number = this.maximum;
var initDiv:Number = (val-minVal)/this.stepSize+minVal;
var roundD:Number = Math.floor(initDiv-minVal)+minVal;
if (val>minVal && val<maxVal) {
if (initDiv-roundD == 0) {
return val;
} else {
var tmpV:Number = Math.floor((val-minVal)/stepS);
var stepDownV:Number = tmpV*stepS+minVal;
if ((val-stepDownV>=stepS/2 && maxVal>=stepDownV+stepS && minVal<=stepDownV-stepS) || (val+stepS == maxVal && maxVal-stepDownV-stepS>0.00000000000001)) {
stepDownV += stepS;
}
return stepDownV;
}
} else {
// [追記] 2007.03.20 数値評価したvalの値がNaNの場合
// trace([val, maxVal, minVal]); // 確認用
if (isNaN(val)) {
val = 0;
}
// [追記]ここまで
if (val>=maxVal) {
return maxVal;
} else {
return minVal;
}
}
};
NumericStepper.checkValidValue()メソッドの修正スクリプト001は、たとえば以下のスクリプトでテストすることができます(スクリプト002)。NumericStepperはスクリプトで動的に作成しますので、ステージに予め配置しなくて構いません。ただし、[ライブラリ]にはNumericStepperコンポーネントを格納しておく必要があります。
スクリプト002■修正スクリプトのテスト例
// テスト例
// フレームアクション
// NumericStepperコンポーネントを[ライブラリ]に格納
// (タイムラインには何も配置しなくてよい)
// NumericStepperインスタンスを動的に配置
import mx.managers.DepthManager;
var myNumericStepper:mx.controls.NumericStepper =
this.createClassChildAtDepth(mx.controls.NumericStepper, DepthManager.kTop);
// 初期設定
myNumericStepper.move(10, 10);
myNumericStepper.minimum = 1;
myNumericStepper.maximum = 10;
myNumericStepper.stepSize = 2;
myNumericStepper.value = myNumericStepper.minimum;
[追記] 2007.03.20
NumericStepperインスタンスに値をキー入力する場合、数字以外を設定することはできません。しかし、値を削除する操作は可能です。その場合、最大値maxnumが自動的に設定されます。
空文字列("")を数値評価するとNaNに変換され、上記スクリプト001でif条件(val>=maxVal)はtrueと評価されるからです。動作結果は必ずしも問題とはいえないものの、NaNを数値比較する処理は十分考慮されたものではないでしょう。
そこで、スクリプト001にステートメントを追加し、NumericStepperの値が削除された場合は0とみなすことにしました。最小値minimumが0より大きい場合には、NumericStepperインスタンスの値は最小値に設定されます。この仕様については、他にも考え方はあるでしょう。
[*1] この問題は、FLASH-japan「NumericStepperでの奇数表示」で報告されました。
[*2] コンポーネントのクラスは、グローパルなクラスパス$(LocalData)/Classesのmxフォルダに格納されています。NumericStepperクラスは、Classes/mx/controls/NumericStepper.asに定義ファイルがあります。
[*3] ActionScript 1.0の継承の仕方につきましては、「ActionScript 2.0と1.0の継承について」をご参照ください。