2012-09-17 81 views
0

我認爲在同一個類中編寫監聽器不是OOP方式。所以,我嘗試在另一個文件中編寫監聽器。該工程ActionListener在相鄰類中的實現

代碼是:

class MyPanel extends JPanel{ 
private String tString = "Test String"; 
private JLabel tLabel; 
public MyPanel(){ 
    tLabel = new JLabel("Label"); 
    JButton tButton = new JButton("Click me"); 

    tButton.addActionListener(new ActionListener(){ 
    public void ActionPerformed(ActionEvent e){ 
    tLabel.setText(tString); 
    } 
    }); 
} 

但是,當我在寫分離文件聽衆:

public class MyListener implements ActionListener{ 
copy code here 
} 

,改變

tButton.addActionListener(new ActionListener(){ 

tButton.addActionListener(new MyListener()); 

它不起作用。 當然,我嘗試過不同的組合。

例如,將「this」發送給偵聽器的構造函數,並從偵聽器類中收到的 對象中調用方法。

錯誤:

MyListener: cannot find symbol "tLabel" 
+3

你能發佈更多關於「它不工作」的細節嗎? – Brian

+0

public void ActionPerformed應該是public void actionPerformed –

+0

Dan,我在這裏做的這個錯字,在代碼中一切正常。 – Danila

回答

2

感謝您編輯你的答案:)

看來你想從你的新聽衆訪問tLabel變量,但它是不可訪問,因爲它可能被宣佈privatetString也可能發生同樣的情況。試試這個:

public class MyListener implements ActionListener{ 

    private MyPanel myPanel; 

    public MyListener(MyPanel myPanel) { 
     this.myPanel = myPanel; 
    } 

    public void ActionPerformed(ActionEvent e) { 
     myPanel.getTLabel().setText(myPanel.getTString()); 
    } 
} 

和每個的tStringtLabel吸氣劑添加到MyPanel

public class MyPanel extends JPanel { 

    // ... 

    public String getTString() { 
     return tString; 
    } 

    public JLabel getTLabel() { 
     return tLabel; 
    } 
} 

當你無法訪問私有字段,通常你添加一個public「吸氣」返回該字段而不是改變字段本身的訪問權限。約定是,例如,如果該字段是String並且被命名爲myField,則獲取者被命名爲getMyField。像這樣,您也可以添加setter來設置該變量。有關吸氣劑和吸附劑的更多信息,請參閱this question

+0

也值得注意的是,沒有一個setter也是可以接受的。這是可以創建[不可變對象](http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html)的一種方式。 – Brian

+0

謝謝!剛纔我發現,在我的監聽器的構造函數中,param是JPanel,但不是MyPanel:D – Danila

2

MyListener類必須有一個構造函數。您可以通過「this」和其他任何您需要的參數在類構造函數中使用。

下面是我的一個項目的例子。

package com.ggl.project.planner.controller; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import com.ggl.project.planner.model.Planner; 
import com.ggl.project.planner.model.Project; 
import com.ggl.project.planner.view.CreateUpdateProjectDialog; 
import com.ggl.project.planner.view.ProjectPlannerFrame; 

public class CreateProjectActionListener implements ActionListener { 

    protected Planner planner; 

    protected Project project; 

    protected ProjectPlannerFrame frame; 

    public CreateProjectActionListener(ProjectPlannerFrame frame, 
      Planner planner, Project project) { 
     this.frame = frame; 
     this.planner = planner; 
     this.project = project; 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
     CreateUpdateProjectDialog dialog = 
       new CreateUpdateProjectDialog(frame, project, true); 
     if (dialog.isOkPressed()) { 
      planner.setProjectOpen(true); 
     } 
    } 

} 
+0

我試圖通過「這個」。 – Danila

+0

或者你的意思是我必須通過我想更改的面板中的每個對象?可能是有用的,我會嘗試。 但如何成爲,如果我想獲得整個面板?例如打電話給她的方法? – Danila

+0

@Danila:我一直通過(JPanel)「這個」。我通常在聆聽者中稱它爲「面板」。您可以在JPanel類中有偵聽器類可以執行的方法。例如,panel.setButton3Text(text); –

2

MyListener類沒有參考tLabel變量。

您可以將它通過構造函數或通過MyPanel參考MyListener並在MyPanel的方法,做在JLabel所需要的東西,可以從MyListener被調用。

+0

謝謝。但如何將MyPanel傳遞給MeListener?我試過「這個」,它不起作用。 – Danila

+0

new MyListener(this); –