2010年7月2日 星期五
事件處理的重複註冊問題
起初我將各個功能視窗的生成,分別製作成 method 以方便管理,並自然而然在各 method 內幫元件進行事件處理的觸發註冊,然而彼此視窗間,時常會有返回先前視窗的動作,此時很容易會產生事件處理重複註冊的 Bug。
為求理解上的方便,故我們直接設定按下按鈕時,會先釋放舊有的視窗並重新產生原本的新視窗,做出類似視窗間重複返回的動作,如下列程式:
public class gui extends JFrame{
Container cp=getContentPane(); //控制容器
JButton btn1 = new JButton();
public void A(){
...... //視窗版面的設置
btn1..addActionListener(new action());} //向action註冊按鈕的事件處理
}
public class action implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton btn= (JButton) e.getSource();
if(btn==gui.btn1){ //按下btn1時
gui.cp.removeAll(); //釋放容器內的所有元件
gui.dispose(); //釋放視窗
gui.A();} //呼叫 A method 重新建立視窗
}
}
視窗看似只有一個,但在第一次按下後重新產生視窗的同時,卻發生 btn1 重複註冊的問題,導致再次按下按鈕時,除了觸發當前視窗的按鈕事件之外,也同時觸發前一個視窗的按鈕事件,造成事件被重複執行兩次。若重複按下按鈕,則事件執行次數會有如 Binary Tree 般增加。
為此避免產生重複註冊的問題,故將上述程式修改為:
public class gui extends JFrame{
Container cp=getContentPane(); //控制容器
JButton btn1 = new JButton();
public gui(){
btn1..addActionListener(new action());} //該物件產生的同時就先行註冊
public void A(){
...... //視窗版面的設定
}
public class action implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton btn= (JButton) e.getSource();
if(btn==gui.btn1){ //按下btn1時
gui.cp.removeAll(); //釋放容器內的所有元件
gui.dispose(); //釋放視窗
gui.A();} //呼叫 A method 重新建立視窗
}
}
其實不侷限於上述方法,重點在於如何避免事件處理重複註冊的問題,除了物件產生時先行註冊之外,也可以在產生視窗的同時,判斷該事件是否有被註冊過,進而避免重複註冊的問題。
參考資料:
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言