2010年4月30日 星期五

Design Pattern : 18 Memonto

當我們希望在所開發的程式裡,可以提供Redo Undo的功能
可以利用Memonto Pattern達到這個目標
把Memonto物件放在要提供Undo功能的程式中(Subject)

參與者
1.Memonto
Memonto本身利用一個陣列來儲存資料,當要restor資料,再
由陣列倒回來

public class Memonto {
    private Vector<String> memos=new Vector<String>();
    public void save(String value){
        memos.add(value);
    }
    public String restoreLast(){
        memos.removeElementAt(memos.size()-1);
        return result;
    }
}

2.Subject
要使用memo功能的主程式
當主程式執行save功能時,是把資料丟給memo去儲存
當要undo時,再利用memo把資料取回,寫回本應用程式的變數中

public class Subject {
    private Memonto memo;
    private String myText;
    public Subject(){
        memo=new Memonto();
    }
    public void save(String value){
        myText=value;
        memo.save(myText);
    }
    public String undo(){
        myText=memo.restoreLast();
        return myText;   
    }
}

3.Main
外部程式,只要呼叫應用程式提供的save跟undo method即可
不用管subject內部memo如何運作

TextField text=new TextField()
Subject subject=new Subject();
儲存
subject.save(text.getText());
Undo
text.setText(subject.undo());


2010年4月28日 星期三

Design Pattern : 17 Observer

在一個程式主體(Generator),如果內部運算後產生一些變化,希望可以把變化的結果,通知外部特定對象,可以把要通知的對象都設定成Observer

在Generator內需要有把observer加入觀察的method(addObserver)
與通知observer的功能(notifyObserver),而在observer內,會需要有一個update的method
可以在接收到Generator的通知後,到Generator內取到結果,這樣當主體程式有所變化,所有設定的observer都會接收到通知,而做適當的訊息處理

參與者
1.Generator
   可以使用Observer的Class
   addObserver:把觀察者加進來的method
   notifyObserver:用來通知所有observer的method
   excute:執行程序,在這類別真正要執行的工作,當工作完成
一定要觸發notifyObserver通知所有的觀察者
   getNumber:這是讓Observer接收到通知後,回來取值得method


public abstract class Generator {
    private Vector<Observer> observers=new Vector<Observer>();   
    private int number;
    public void addObserver(Observer observer){
        observers.add(observer);       
    }
    public void deletObserver(Observer observer){
        observers.remove(observer);
    }
    private void notifyObserver(){
        Iterator<Observer> it=observers.iterator();
        while(it.hasNext()){           
            ((Observer)it.next()).update(this);
        }
    }
    public void excute(){
        Random random=new Random();
        number=random.nextInt(50);
        notifyObserver();
    };
    public int getNumber(){
        return number;
    };
}


2.Observer interface
   Observer可能有很多個,先設定一個所有observer需遵循的統一介面
   update:當obsever被通知,就是被Generator呼叫了這個updtae method
   在這個method內可以利用傳進來的Generator物件,再回去取到變化的值

public interface Observer {
    public abstract void update(Generator gen);
}


3.FirstObserver 實作類別

public class FirstObserver implements Observer {   
    public void update(Generator gen) {
        System.out.println("First:"+gen.getNumber());
    }
}


4.SecondObserver

public class SecondObserver implements Observer {
    public void update(Generator gen) {
        System.out.println("Second:"+gen.getNumber());
    }
}


5.Main外部程式
只要產生Generator,加入關聯的observer後
就可以執行他要做的動作,同時在這動作內也已經
包含了通知observer的功能


Generator gen=new Generator();
gen.addObserver(new FirstObserver());
gen.addObserver(new SecondObserver());
gen.excute();


2010年4月27日 星期二

Design Pattern : 16 Mediator

Mediator的角色,通常都是當作UIComponent的代理人
UIComponent是使用者會直接接觸到的元件
如Button,TextField等,當我們在操作這些UIComponent
UIComponent 只是用來當作View顯示,而不做邏輯處理
也就是說,當接收到使用者的指令,如按鈕,輸入文字..
會把這些事件丟出去,往外通知
UIComponent..只是單純被操作
事件丟出的方式,可以是用dispatchEvent方式廣播
或是通知mediatior來處理
而Mediator的角色,就是主程式與UIComponent間的橋樑

參與者
1.Mediator 介面
createColleagus:利用這method把所有的UIComponent登錄到Mediator上
colleagusChanged:當有登錄的UIComponent狀態改變時都會呼叫這method
通知mediator作處理

public interface Mediator {
    public abstract void createColleagus();
    public abstract void colleagusChanged(Colleagus colleagus);
}

2.Colleagus
所有的UIComponent都implement這介面,讓UIComponent都有可以跟
mediator溝通的共同method
setColleagusEnabled:要改變UComponent不要直接去操作到UIComponent,
而是透過一個public API去操作


public interface Colleagus {
    public abstract void setMediator(Mediator mediator);
    public abstract void setColleagusEnabled(boolean enabled);
}

3.ColleagusTextField 實作的Colleagus
本身是TextField,同時也以自己當作TextListener
textValueChanged:當TextEvent被觸發時會執行這method
在這method中通知mediator

public class ColleagusTextField extends TextField implements Colleagus,TextListener{
    private Mediator mediator;
    public ColleagusTextField(String text,int columns){
        super(text,columns);
    }
    @Override
    public void setColleagusEnabled(boolean enabled) {       
        setEnabled(enabled);
        setBackground(enabled?Color.white:Color.gray);
    }
    @Override
    public void setMediator(Mediator mediator) {       
        this.mediator=mediator;
    }
    @Override
    public void textValueChanged(TextEvent arg0) {       
        this.mediator.colleagusChanged(this);
    }
}

4.LoginFrame 實作的Mediator

public class LoginFrame extends Frame implements Mediator,ActionListener{
    private ColleagusTextField textUser;
    public LoginFrame(String title){
        super(title);
        setBackground(Color.lightGray);
        setLayout(new GridLayout(4,2));       
        createColleagus();
        add(textUser);
        pack();
        setVisible(true);       
    }
    @Override
    public void colleagusChanged(Colleagus c) {
       
    }
    @Override
    public void createColleagus() {
        textUser=new ColleagusTextField("input user name",10);
        textUser.setMediator(this);
        textUser.addTextListener(textUser);   
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
           
    }
}

5.Main 外部程式

new LoginFrame("Main Frame");


2010年4月26日 星期一

Android 開發入門注意事項

一.在模擬器安裝apk
    在網路上下載到已經開發好的Android程式(*.apk)
    要如何安裝到模擬器上執行?
    1.先在電腦環境變數內(path)加入Android_SDK/tools目錄
       讓SDK內tools下的指令可以直接執行
    2.在cmd下執行
       adb install xxx.apk,即可把程式安裝到模擬器內
    3.解除安裝
       adb shell rm data/app/xxx,apk

二.Compile錯誤處理
   在Eclipse中Compile Android 是針對Activity Java Compile
   如果不小心在layout xml上compile發生錯誤後
   將產生的out.xml刪除,再到Problems Panel內刪除錯誤的列表
   才可以再重新Compile

三.xml檔案名稱必須要是小寫
   在設計layout xml時,檔案名稱一定要使用全小寫
   loginPage.xml~~這是不允許的
   可改用login_page.xml代替

四.View元件屬性設定不完全錯誤
   若在layout xml內加入 view元件,layout_width與layout_height
   一定要設定,否則即使compile成功,在模擬器上執行一定會發生錯誤

五.將元件參考變數設定在class範圍
   在Activity內會利用findViewById來取得各個view元件參考
   如 TextView mytext=(TextView)findViewById(R.id.myText)
   這些變數,不要當作function內的local變數使用
   最好是宣告在class的變數上,否則,在其他function內是無法操作
   來改變這些view元件的屬性

2010年4月22日 星期四

FlashDevelop 上發布Air Project相關事項

一.設定讓FlashDevelop Air API Auto Complete
    在Project Properties/compiler Option/SWC Include Lib
    加入air swc的路徑
    C:\Program Files\Adobe\Adobe Flash CS4\AIK1.5\frameworks\libs\air\airglobal.swc
    C:\Program Files\Adobe\Adobe Flash CS4\AIK1.5\frameworks\libs\air\servicemonitor.swc

二.產生AIR
1.當設定的Project為AIR
   在Project目錄下會有兩個bat檔CreateCertificate.bat與PackageApplication.bat
2.CreateCertificate.bat 產生認證檔
    編輯
   1.設定Flex SDK路徑
      set PATH=%PATH%;C:\flex_sdk_4\bin
   2.設定這認證pfx檔案的,名字,密碼與輸出檔名
set NAME=MyName
set PASSWORD=MyPassword
set CERTIFICATE=MyName.pfx
這在產生air檔案時,會需要這帳號密碼確認
   3.修改完,執行,即會產生一個pfx檔
3.PackageApplication.bat 封裝AIR
    編輯
    1.設定Flex SDK路徑
set PATH=%PATH%;C:\flex_sdk_4\bin
    2.指定要使用的數位認證檔
       set CERTIFICATE=MyName.pfx
    3.設定要輸出的檔案路徑
       set AIR_FILE=air/FlexTest1.air
    4.執行,即產生AIR檔
4.注意
  若在封裝AIR檔案發生錯誤
  如application.xml error 102:invaid namespace
  請確認,系統安裝的AIRSDK版本,與application.xml
  namespace設定的版本是否相符

三.發布到網頁
1.下載 Badge Sample
Adobe Badge Sample
http://download.macromedia.com/pub/developer/air/badge_install_samples.zip
2.修改網頁參數
   1.flaVar參數
appname:AIR App名稱(需URL encode,也就是經過escape過)
appurl:要下載的air檔案網址
airversion:要跑這個air的 runtime版本需求
imageurl:(非必填)要放到badge內的圖片路徑
buttoncolor:(非必填)按鈕顏色,預設為000000
messagecolor:(非必填)訊息文字顏色,預設為000000

   2.<noscript>內放當不支援flash player時,要提供顯示的文字連結內容

3.手動讓Web Server認得AIR檔案
  在Apache 的http.conf 加入
  <IfModule>
   AddType application/vnd.adobe.air-application-installer-package+zip .air
   </IfModule>
4.若使用Flash Player Detection Kit,可以讓使用者在站上就直接更新flash player
http://www.adobe.com/products/flashplayer/download/detection_kit/
5.執行程序
在網站上點badge安裝時
系統會先檢查,是否有Air RunTime,如果沒有會自動安裝下載
結束後,自動安裝應用程式
若已經安裝過,會檢查版本是否有更新過,如無,則可直接開啟程式
若有新版,則會安裝新版本
6.資料來源
http://www.adobe.com/devnet/air/articles/air_badge_install.html

四.安裝AIR runtime到Ubuntu上
1.下載
     http://airdownload.adobe.com/air/lin/download/1.5/AdobeAIRInstaller.bin
2.設定為可執行檔
     chmod +x AdobeAIRInstaller.bin
3.安裝
     sudo ./AdobeAIRInstaller.bin

五.AIR 自動Update機制
1.AIR Project的Application.xml內設定了這個app的版本
   安裝到client上,client上以這作為已安裝版本依據
2.在發布新的air更新檔,同時要放置一個updateInfo.xml到網站上
   當作一個版本比對的參考,只要有更新AIR版本,就要修改這份XML內容
<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.0</version>
            <url>http://192.168.11.80/air/myApp.air</url>
    <description>
  <text xml:lang="en_US">AIR AutoUpdate</text>
  <text xml:lang="zh_TW">AIR 自動更新</text>
  </description>
</update>
3.當使用者在執行其已安裝的app時,會去連線檢查
server上updateInfo.xml內的版本跟本機的是否一致
如有新版,則自動更新
4.所以,在你的AIR App程式內
需要利用ApplicationUpdater 這Class來載入Server上的updateInfo.xml
讀取版本資料來做比對,並做更新下載




六.另外需要注意的是,在FlashDevelop上開啟AIR Project在Property OutPut的設定上,需使用預定的Run Custom Command,也就是執行
C:\flex_sdk_4.1\bin\adl.exe;application.xml bin
如果只是當作一般SWF輸出到Tab上,AIR相關API會失效