SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Flex基礎講座

Flex基礎講座(パート2):Flex電卓アプリケーションの作成

MXMLとActionScriptの基本的な扱い方の習得

  • X ポスト
  • このエントリーをはてなブックマークに追加

doOperation()メソッドの追加

 doOperation()メソッドはユーザーの指示に従って、加減乗除のいずれかの処理を行います。なお、演算処理を行う前には、ActionScript内蔵のNumber()メソッドを利用して、reg1reg2の値を数値データ型に成型してから、それぞれr1プロパティとr2プロパティに代入します。

 どの演算処理を行うかは、switch-case構文で分岐します。次にActionScriptのswich-case構文を示します。

switch (expression)
{
case value:
[ActionScriptのステートメント]
break; // この行がなければ次のケースに処理が進みます
[その他のケース]
default:
[デフォルトのケース処理]
}

 ActionScriptにおける加減乗除の演算子は次のとおりです。

+ - * /

 次の手順に従って、doOperation()メソッドを追加します。

  1. コンストラクタ関数の後にpublicメソッドのdoOperationを作成し、このメソッドの引数や戻り値は「なし」に設定しておきます。
  2. public function doOperation():Void
    {
    }
    
     
  3. このメソッドのブロックのはじめに、reg1reg2の値を数値型に成型し、それぞれthis.r1this.r2に代入します。
  4. this.r1=Number(reg1);
    this.r2=Number(reg2);
    
     
  5. operationプロパティの値を元に分岐するswitch-caseを追加します。
  6. switch (operation)
    {
    }
    
     
  7. switchブロックの中にaddsubtractmultiplydivideの4つの演算処理用のケースを追加します。各ケースの中には、r1r2に対して適切な演算を行った結果をresultプロパティに代入するための式と、resetAfterOp()メソッドの呼び出しを含め、それぞれのケースをbreakステートメントで閉じます。
  8. case "add":
    
        this.result=r1+r2;
        resetAfterOp();
        break;
    
    case "subtract":
    
        this.result=r1-r2;
        resetAfterOp();
        break;
    
    case "multiply":
    
        this.result=r1*r2;
        resetAfterOp();
        break;
    
    case "divide":
        this.result=r1/r2;
        resetAfterOp();
        break;
    
     
  9. 一切の処理を行わないdefaultのケース(演算処理が設定されていない場合のため)も設定しておきます。
  10. default:
    // 何もしない
    

addNumber()メソッドの追加

 addNumber()メソッドは電卓アプリケーションのビューから渡された数字を文字列として受け取り、この文字列後ろに現在のレジスタの文字列を付加します。ActionScriptの(+)演算子は多重処理をサポートしているので、オペランド同士が文字列の場合はこれらを結合します。

 結合処理自体は簡単ですが、ここでは特別な場面を想定する必要があります。メソッドが演算処理を行った後には、演算結果をreg1にコピーしてから、reg2を現在のレジスタとして設定し、演算結果に対してさらなる演算処理が行われることに対処する必要があります。しかし、ユーザーが結果に対して新たな演算を行わず、代わりに新たな数字を入力する場合は、reg1の内容を消去してreg1を現在のレジスタに設定する必要があります。

 このような条件のチェックを行い、正しい処理を行うにはif文を使用する必要があります。また、ここでは2重の条件をチェックするので、ActionScriptのAND論理演算子、「&&」を使用します(なおOR論理演算子は「||」)。次にif-elseの標準構文を示します。

if (condition[s])
 {
[ActionScript のステートメント]
}[else if (condition) // 0 またはそれ以上
 {
[ActionScript のステートメント]
}else // 0 または 1
 {
[ActionScript のステートメント]
 }]

 次にActionScriptの比較演算子を示します。

演算子 意味
== 等価
< より小さい
> より大きい
<= より小さいか等しい
>= より大きいか等しい
! 否定(NOT)

 このメソッドを作成する際にもう1つ必要なActionScriptの概念は、「ランタイム時の動的評価」です。現在のレジスタがどちらのレジスタであるかは、後ほど作成するsetCurrentRegister()メソッドによってランタイム時に動的に設定します。現在のレジスタがどちらであるかはthis[currentRegister]式を利用することで取得でき、currentRegisterプロパティは常にreg1またはreg2のいずれかのレジスタプロパティ名になります。オブジェクト参照の後にある角括弧([ ])はランタイム時に強制的に動的な評価を実行することを意味し、これを利用することでプロパティ名を動的に設定もしくは取得することができます。

  1. doOperation()メソッドの後にpublicメソッドのaddNumber()を作成して、文字列の引数nを受け付けるようにし、戻り値をなしに設定します。
  2. public function addNumber(n:String):Void
    {
    }
    
     
  3. このメソッドブロックの中にif文を追加し、operationプロパティの値が「none」であり、なおかつcurrentRegisterプロパティが「reg2」であることを評価します。
  4. if (operation=="none"   && currentRegister=="reg2")
    {
    }
    
メモ
 上記の条件はdoOperation()resetAfterOp()メソッドを呼び出し、なおかつ、ユーザーが数字のボタンをクリックした場合に「true」になります。
  1. ifブロックの中で、reg1プロパティに空の文字列を代入してから、setCurrentRegister()メソッド(後ほど作成します)を呼び出すようにしておきます。
  2. reg1="";
    setCurrentRegister();
    
     
     
  3. if文の後に、現在のレジスタに「n」の値を付加するためのコードを追加します。
  4. this[currentRegister]+=n;
    
    上記のコードには特定のプログラミング言語に採用されているショートカットを利用しています。このコードは、
    this[currentRegister] = this[currentRegister] + n;
    
    と記述するのと同じです。
     
  5. setDisplay()メソッドの呼び出しを追加し、currentRegisterプロパティを引数として渡します(このメソッドは後ほど作成します)。
  6. setDisplay(currentRegister);
    

clearEntry()メソッドとclearAll()メソッドの追加

 この2つのシンプルなメソッドは似通っているので、同時に解説します。clearEntry()メソッドでは現在のレジスタの内容と画面表示を消去するようにし、clearAll()メソッドでは両方のレジスタの内容と画面表示を消去するとともに、処理待ちの演算を「none」、urrentRegisterプロパティを「reg1」に設定するようにします。

  1. publicメソッドのclearEntry()を追加し、引数と戻り値をなしに設定します。
  2. public function clearEntry():Void
    {
    }
    
     
  3. このメソッドブロックの中で、現在のレジスタに空の文字列を代入し、さらにcurrentRegisterプロパティを引数とするsetDisplay()メソッドの呼び出しを追加します。
  4. this[currentRegister]="";
    setDisplay(currentRegister);
    
     
  5. publicメソッドのclearAll()を追加し、引数と戻り値をなしに設定します。
  6. public function clearAll():Void
    {
    }
    
     
  7. このメソッドブロックの中では、両方のレジスタに空の文字列を代入し、さらに、引数のないsetCurrentRegister()の呼び出し、「none」を引数とするsetOperationの呼び出し、currentRegisterを引数とするsetDisplayの呼び出しを追加します。
  8. reg1="";
    reg2="";
    setCurrentRegister();
    setOperation("none");
    setDisplay(currentRegister);
    

setOperation()メソッドの追加

 このメソッドは単に値を代入するためだけのものです。ここでは処理待ちの演算を設定し、その後にsetCurrentRegister()メソッド(後ほど作成)を利用して、現在のレジスタをリセットします。

  1. publicメソッドのsetOperation()を追加し、Stringタイプの引数、operationを受け付けるようにし、戻り値をなしに設定します。
  2. public function setOperation(operation:String):Void
    {
    }
    
     
  3. このメソッドブロックの中では、引数として受け取ったoperationoperationプロパティの値に代入し、その後setCurrentRegister()メソッドを呼び出します。
  4. this.operation=operation;
    setCurrentRegister();
    

setDisplay()メソッド、setCurrentRegister()メソッド、resetAfterOp()メソッドの追加

 この3つのprivateメソッドも簡単です。setDisplay()メソッドは、引数として受け取ったレジスタ名の値を電卓の表示ラベルのtextプロパティに代入します。setCurrentRegister()メソッドはreg1が空の場合はreg1を現在のレジスタに設定し、それ以外の場合はreg2を現在のレジスタとして設定します。そしてresetAfterOp()メソッドは、演算結果をreg1にコピーし、つぎの演算処理に移れるようにその他の値を設定します。

  1. privateメソッドのsetDisplay()を追加し、Stringタイプの引数、registerを受け付けるようにし、戻り値をなしに設定します。
  2. private function setDisplay(register:String):Void
    {
    }
    
     
  3. このメソッドブロックの中で、calcView.calcDisplay.textプロパティの値に引数として受け取ったレジスタを代入します。
  4. calcView.calcDisplay.text = this[register];
    
     
  5. privateメソッドのsetCurrentRegister()を追加し、引数と戻り値をなしに設定します。
  6. private function setCurrentRegister():Void
    {
    }
    
     
  7. このメソッドのブロックの中にif-else文を追加し、reg1の値が空ストリングの場合はcurrentRegisterプロパティを「reg1」に設定し、それ以外の場合はcurrentRegisterプロパティを「reg2」に設定するようにします。
  8. if (reg1=="")        {            
        currentRegister="reg1";        
    }        else        {            
        currentRegister="reg2";        
    }
    
     
     
  9. privateメソッドのresetAfterOp()を追加し、引数と戻り値をなしに設定します。
  10. private function resetAfterOp():Void
    {
    }
    
     
  11. このメソッドブロックの中で、resultの現在の値をreg1の値に、空の文字列をreg2にそれぞれ代入します。また、reg1を引数とするsetDisplay()の呼び出しと、noneを引数とするsetOperation()メソッドの呼び出しも追加します。
  12. reg1=String(result);
    reg2="";
    setDisplay("reg1");
    setOperation("none");
    
     
  13. ここでファイルを保存しておきます。
メモ
 これで「CalculatorHandlers.as」ファイルが完成しました。

CalculatorHandlersクラスのインスタンス化

 このチュートリアルの最後のステップは、先程作成したCalculatorHandlersクラスを「calculator.mxml」ファイル内でインスタンス化することです。この処理はタグを利用してできますが、このタグはFlexクラスライブラリに含まれていないので、新しい名前空間を追加する必要があります。名前空間を追加するには、Applicationタグの中に新たなxmlnsプロパティを追加し、このプロパティの値を「"*"」に設定します。この"*"の値は、アプリケーションディレクトリの中にあるすべてのクラスを要素として受け付けることを指示しています。

 なお、ここではCalculatorHandlersクラスがcalcDisplayオブジェクトにアクセスできるよう、電卓アプリケーションのApplicationオブジェクトに参照する必要があることに注意してください。この参照情報を渡すには、CalculatorHandlersオブジェクトのcalcViewプロパティを「{this}」に設定します。MXMLファイルの中のthisApplicationオブジェクト全体への参照を意味します。また、波括弧({ })は、データバインディングを意味し、Flexコンパイラは括弧内のコンテンツを純粋な文字列ではなく、表現式として評価します。

 CalculatorHandlersオブジェクトには、アプリケーション内のその他の要素が参照できるよう、インスタンス名が必要です。インスタンス名は、クラスをインスタンス化する際に使用するタグのid属性で設定します。

  1. 「calculator.mxml」ファイルを開き、Applicationタグの中に新たなxmlnsプロパティを追加し、このプロパティ値に名前空間の値、「"*"」を設定します。この際、接頭辞は不要です。
  2. <mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"
      xmlns="*">
    
     
  3. Applicationタグのブロックの始めにCalculatorHandlersタグを追加し、このタグの属性にid="calcHandlers"calcView="{this}"を追加します。
  4. <CalculatorHandlers id="calcHandlers" calcView="{this}"/>
    
     
  5. ファイルを保存してから、Webブラウザでファイルの動作を確認します。(MXMLファイルのブラウズ方法が分からない場合は、こちらの解説を参照してください。)
完成した「calculator.mxml」ファイルのコード
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"
xmlns="*">
<!-- calculator のコントローラー --> <CalculatorHandlers id="calcHandlers" calcView="{this}"/> <!-- calculator のビュー --> <mx:Panel title="Calculator"> <!-- calculator のディスプレイ --> <mx:Label id="calcDisplay" width="150" textAlign="right"/> <!-- calculator のコントロール群 --> <mx:Grid> <mx:GridRow> <mx:GridItem colSpan="2"> <mx:Button width="70" label="Clear"
click="calcHandlers.clearAll()"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="C/E"
click="calcHandlers.clearEntry()"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="+"
click="calcHandlers.setOperation('add')"/>
</mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem> <mx:Button width="30" label="1"
click="calcHandlers.addNumber('1')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="2"
click="calcHandlers.addNumber('2')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="3"
click="calcHandlers.addNumber('3')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="-"
click="calcHandlers.setOperation('subtract')"/>
</mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem> <mx:Button width="30" label="4"
click="calcHandlers.addNumber('4')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="5"
click="calcHandlers.addNumber('5')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="6"
click="calcHandlers.addNumber('6')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="*"
click="calcHandlers.setOperation('multiply')"/>
</mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem> <mx:Button width="30" label="7"
click="calcHandlers.addNumber('7')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="8"
click="calcHandlers.addNumber('8')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="9"
click="calcHandlers.addNumber('9')"/>
</mx:GridItem> <mx:GridItem> <mx:Button width="30" label="/"
click="calcHandlers.setOperation('divide')"/>
</mx:GridItem> </mx:GridRow> <mx:GridRow> <mx:GridItem> <mx:Button width="30" label="0"
click="calcHandlers.addNumber('0')"/>
</mx:GridItem> <mx:GridItem > <mx:Button width="30" label="."
click="calcHandlers.addNumber('.')"/>
</mx:GridItem> <mx:GridItem colSpan="2"> <mx:Button width="70" label="="
click="calcHandlers.doOperation()"/>
</mx:GridItem> </mx:GridRow> </mx:Grid> </mx:Panel> </mx:Application>
完成した「CalculatorHandlers.as」ファイルのコード
/*
Calculator Controller
*/
class CalculatorHandlers { // プロパティ // ビューオブジェクトへの参照を保持するためのオブジェクト public var calcView:Object; // 演算処理待ちの一時的な値を保持するためのレジスタ private var reg1:String=""; private var reg2:String=""; // 演算処理の結果 private var result:Number; // 現在使用中のレジスタの名前 private var currentRegister:String="reg1"; // 次に処理する演算の名前 private var operation:String="none"; // レジスタの文字列値を数値に変換して保持 private var r1:Number; private var r2:Number; // コンストラクタ関数 public function CalculatorHandlers() {} // メソッド // 2 つのレジスタに対して現在の指定演算を実行 public function doOperation():Void { // レジスタの値を数値型に成型 r1=Number(reg1); r2=Number(reg2); switch (operation) { case "add": result=r1+r2; resetAfterOp(); break; case "subtract": result=r1-r2; resetAfterOp(); break; case "multiply": result=r1*r2; resetAfterOp(); break; case "divide": result=r1/r2; resetAfterOp(); break; default: // 何もしない } } // 現在のレジスタの値に数字を付加 public function addNumber(n:String):Void { if (operation=="none" && currentRegister=="reg2") { reg1=""; setCurrentRegister(); } this[currentRegister]+=n; setDisplay(currentRegister); } // 現在のレジスタをクリヤー public function clearEntry():Void { this[currentRegister]=""; setDisplay(currentRegister); } // 2 つのレジスタと現在の指定演算をクリヤー public function clearAll():Void { reg1=""; reg2=""; setCurrentRegister(); setOperation("none"); setDisplay(currentRegister); } // 現在の指定演算を設定 public function setOperation(operation:String):Void { this.operation=operation; setCurrentRegister(); } // ディスプレイに表示される値を設定 private function setDisplay(register:String):Void { calcView.calcDisplay.text = this[register]; } // 現在のレジスタがどちらのレジスタであるかを設定 private function setCurrentRegister():Void { if (reg1=="") { currentRegister="reg1"; } else { currentRegister="reg2"; } } // 演算処理後に値をリセット private function resetAfterOp():Void { reg1=String(result); reg2=""; setDisplay("reg1"); setOperation("none"); } }

つぎのステップ

 このチュートリアルで作成した電卓アプリケーションはシンプルなものでしたが、このアプリケーションに手を加えれば容易に多彩な機能の備わった電卓アプリケーションが作成できます。またActionScriptには数々の静的Mathクラスが含まれており、これらのメソッドを利用すれば開発時の手間が省けます。ここで重要なのは、これでMXMLとActionScriptの基礎要素の扱い方が習得できたことです。さらに高度なアプリケーションの開発にもチャレンジしてみてください。

 是非つぎのチュートリアルに進み、さらにFlexの習得を深めてください。

 このチュートリアルの内容にご関心をお持ちいただけた場合は、Flexにデフォルトで含まれているサンプルアプリケーションなども一度目を通すようにしてください。Flexの搭載機能をデモするサンプルが多数収録されています。

「FlexではじめるRIA開発」特集、絶賛公開中!

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Flex基礎講座連載記事一覧

もっと読む

この記事の著者

Robert Crooks(Robert Crooks)

Macromedia所属カリキュラム開発担当ディレクター。これまでに、『Fast Track to Macromedia Flex』を含む、インターネットアプリケーション開発関連の数々の教材を執筆。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

マクロメディア株式会社(マクロメディアカブシキガイシャ)

Macromediaは、先端的なソフトウェア会社であり、オープンで統合性のあるWeb開発プラットフォームを通じて、Webプロフェッショナルが魅力あるユーザー体験を提供するためのサービスを提供している。主な製品に「Flash MX 2004」「Dreamweaver MX 2004」「Director...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/107 2009/10/20 16:59

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング