爲按鈕數組註冊監聽

在完成“別踩白塊”的課設時,遇到了按鈕數組註冊監聽的問題,現將問題和解決辦法記錄如下:

問題

如下設置監聽會提示:從內部引用的本地變量必須是最終變量或實際上的最終變量(使用final修飾的變量)此處的錯誤爲變量i,並非mBolk數組。

for(int i=0;i<mBolk.length;i++){
    mBolk[i] = new Bolk();
    mBolk[i].addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
            if( mBolk[i].getValue()){
                mBolk[i].setValue(false);
                mBolk[i].set_Color();
            }
        }  
    });
    panel.add(mBolk[i]);
} 

問題分析

這個問題在內部類的使用過程中比較常見,爲內部類調用外部變量時必須保證外部變量時final類型的,即爲最終變量。此處調用的爲局部變量,局部變量不存放在對象所在的存儲區中,即不予actionPerformed()方法共享存儲區,在形式上來說即爲方法中的方法調用了存放在運行棧上的局部變量(某種意義上來說感覺像內部類調用棧上的變量),所以需要將局部變量設置爲最終變量,但是設置爲最終變量後,變量i將失去原有的功能,所以在此處進入一個死循環。

解決方式

錯誤思路:設置監聽的時候就決定該按鈕監聽方法,在監聽方法中,希望傳入按鈕,對按鈕進行操作,即通過傳入不同的按鈕,來實現不同的方法。
解決思路:在監聽方法獲取響應的按鈕,然後對按鈕執行操作。
區別:解決思路中所有的按鈕只需要註冊同一個監聽方法,在方法中判斷按鈕需要執行的操作,錯誤思路中將不同的按鈕都註冊監聽,造成了代碼的無必要重複。

for(int i=0;i<mBolk.length;i++){
    mBolk[i] = new Bolk();
    mBolk[i].addActionListener(this);
    panel.add(mBolk[i]);
}
public void actionPerformed(ActionEvent event){
    Bolk bolk = (Bolk)event.getSource();
    if(Game.isSuccess(bolk)){
        grade++;
    }else{
        System.out.println(grade);
    }
} 

源碼地址:https://github.com/cartridge1024/WhiteAndBlack

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章