soraなりの日々 - fc2 -

こころにひっかかったもの

[air, abc]jpgloader

10月4日の abc第一回 ワークショップにて、
発表させていただいた時にデモした jpgloader
ソースを公開します。
(url 固定だったり、するんで .air で公開などできず、
 恥をしのんでのソース公開(TT;)

ワークショップ当日まで2日間しかなく、
突貫で作ったアプリなので、、、
 ・mxmlファイルにすべて一発だったり
 ・エラー処理
 ・クラス分け
 ・などなど
において酷さの極みではありますが、
まー、誰かの参考にでもなればな、と。

このエントリーをはてなブックマークに追加
[jpgloader]

jpgloader01.jpg


まずは、今回作成した jpgloader の説明を、、
 単なる jpeg ファイルのローダです。
 ただし、rails の webアプリと連携しており、
 起動時、指定したサーバと接続ができれば
 サーバからのデータを画面に表示します。
 接続できない場合、windows / mac での
 "マイピクチャ" 配下の jpeg ファイルをロード
 して表示します。

[ローカルの jpeg ファイルを表示]
JpgLoader02_lo.jpg

[サーバの jpeg ファイルを表示]
JpgLoader3_ser.jpg


[ソース]
<?xml version="1.0" encoding='utf-8'?>

<mx:WindowedApplication
    xmlns:mx="http://www.adobe.com/2006/mxml"
    width="1020" height="840"
    layout="absolute"
    creationComplete="init()">

    <mx:Script>
    <![CDATA[
        // いろいろと import
        import flash.filesystem.File;
        import mx.events.ListEvent;
        import mx.controls.Alert;
        import flash.utils.*;

        import flash.events.*;
        import adobe.utils.*;

        import flash.net.URLLoader;
        import flash.net.URLRequest;
        import flash.xml.*;
        import flash.events.IOErrorEvent;

        // 各画像のリスト
        private var arrImages:Array = new Array();
        private var arrlstImages:Array = new Array();

        // 画像の切り替えを 5秒間隔で行う
        private var intervalDuration:Number = 5000;
        private var intervalId:uint;    // タイマーID
        private var counter:uint = 0;
        private var counterSize:uint = 0;

        private var externalXML:XML;   
        private var loader:URLLoader;
       
        /**
         * init
         *
         * @description アプリ起動時に実行する
         */
        private function init():void {

            // サーバに接続。ポートは 5000 番
            var request:URLRequest = new URLRequest("http://localhost:5000/jpegs.xml");
            loader = new URLLoader();
            try {
                loader.load(request);
            } catch (error:SecurityError) {
                // エラーの場合の処理
                trace("A SecurityError has occurred.");
            }

            // ロードの成功時、失敗時の関数をそれぞれイベントリスナーに登録
            loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
        }

        /**
         * getImageFiles
         *
         * @param   [in] dir:File    ファイルのオブジェクト
         * @param   [out] arr:Array  画像のリスト
         * @description 指定されたディレクトリ配下の画像をすべて取得する
         */
        private function getImageFiles(dir:File, arr:Array):void {

            // ディレクトリの中身を取得
            var files:Array = dir.getDirectoryListing();
            for (var i:uint=0; i<files.length; i++) {
                if (files[i].isDirectory) {
                    getImageFiles(files[i], arr);   // 子ディレクトリがある場合は再帰する
                }
                var imgFile:File = new File(files[i].nativePath);
                if (imgFile.extension != "jpg" && imgFile.extension != "jpeg"
                    && imgFile.extension != "jpe") {
                    continue;   // jpeg ファイルのみ対応
                }
                // 画像のリストに追加していく
                arr.push(files[i]);
            }
        }

        /**
         * setImageFiles
         *
         * @param   [in] arr:Array  画像のリスト
         * @description 画像のセットを行う関数をタイマーで指定する
         */
        private function setImageFiles(arr:Array):void {
            if (arr.size <= 0) { return }
            counterSize = 0;
            intervalId = setInterval(setImageFile, intervalDuration, arr, "");
        }

        /**
         * setImageFilesUrl
         *
         * @param   [in] arr:Array  画像のリスト
         * @description 画像のセットを行う関数をタイマーで指定する(サーバ側)
         */
        private function setImageFilesUrl(arr:Array):void {
            if (arr.size <= 0) { return }
            counterSize = 0;
            intervalId = setInterval(setImageFileUrl, intervalDuration, arr, "");
        }


        /**
         * loaderCompleteHandler
         *
         * @param   [in] event:Event  イベント
         * @description サーバとの接続が成功した場合に動作する
         *              接続が成功すると、サーバから返却される xml を
         *              解析して画像のリストを作成する
         */
        private function loaderCompleteHandler(event:Event):void {

            try {
                // xml オブジェクトを生成
                var xml:XML = new XML(loader.data);
                var xmlList:XMLList = xml.jpeg; // xml の基点を設定する

                for each (var item:XML in xmlList) {
                    if (item.child("full-path")) {
                        var name:String;
                        var path:String;
                        name = item.child("name");
                        path = item.child("full-path");
                        // 画像リストに設定していく
                        arrlstImages.push({name:name, path:path});
                    }
                }
            } catch (e:TypeError) {
                trace("Could not parse the XML file.");
            }
            // 画像を設定する関数のタイマーを設定する
            setImageFilesUrl(arrlstImages);
        }

        /**
         * errorHandler
         *
         * @param   [in] e:IOErrorEvent  エラーイベント
         * @description サーバとの接続が失敗した場合に動作する
         *              接続がした場合、ローカルの画像ファイルを
         *              参照するように関数を実行する
         */
        private function errorHandler(e:IOErrorEvent):void {

            var userDir:File = File.userDirectory;
            var directory:File = new File(userDir.url + "/Pictures");  // mac のパス
            if (!directory.exists) {
                // windows のパス
                directory = new File(userDir.url + "/My Documents/My Pictures");
            }

            if (!directory.exists) {
                return; // 無ければ、終わり
            }
           
            // 画像のリストを生成する
            getImageFiles(directory, arrImages);
           
            // 画像の表示を行う
            setImageFiles(arrImages);
        }

        /**
         * setImageFile
         *
         * @description リストに従い、画像の表示を行う
         */
        [Bindable]
        private function setImageFile():void {
            var arr:Array = arguments[0];
            frmImageText.text = arr[counterSize].name;
            frmImage.source = arr[counterSize].url;
            counterSize++;
            if (counterSize >= arr.size-1) {
                counterSize = 0;
            }
        }

        /**
         * setImageFileUrl
         *
         * @description リストに従い、画像の表示を行う(サーバ側)
         */
        [Bindable]
        private function setImageFileUrl():void {
            var arr:Array = arguments[0];
            frmImageText.text = arr[counterSize].name;
            frmImage.source = arr[counterSize].path;
            counterSize++;
            if (counterSize >= arr.size-1) {
                counterSize = 0;
            }
        }
    ]]>
    </mx:Script>

    <mx:Panel id="myPanel" title="jpeg loader"
        height="75%" width="75%" horizontalAlign="center"
        paddingTop="10" paddingLeft="10">

        <mx:Label id="frmImageText" color="blue" text="Image embedded in the application."/>
        <mx:Image id="frmImage" source="@Embed('dont_die_stay_with_me_damn_it.jpg')"/>

    </mx:Panel>
</mx:WindowedApplication>


まー、こんなのでも rails アプリとサクッと連携できる
adobe air の強みとか紹介できたんで良かったかな。。。たぶん。

あと、flex builder のトライアル版が切れてるんで、
前に作った xcode テンプレートで今回作ったんだけど、
やっぱ手書きはつらいね。。。


[xcode で開発してるところ]
JpgLoader04.jpg

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

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://sora2hs.blog70.fc2.com/tb.php/392-bff880c0
この記事にトラックバックする(FC2ブログユーザー)