2012-07-18 53 views
0

編輯:謝謝你所有的答案,真的幫助了很多和一些不錯的提示。hiddenText = ca.a.getText();給NullPointerException?

大家好, 我在這裏是新來的,Java編程新手,所以我會盡力提供任何相關信息。我的問題是我想創建兩個類,第一類(ClassA)是一個GUI,第二個(ClassB)是(ClassA)的邏輯。

我的代碼一個簡單的例子是: -

ClassA的

import javax.swing.*; 
import java.awt.*; 

public class ClassA extends JFrame { 


JTextField a = new JTextField(); 

JButton but = new JButton("Click"); 

ClassB cb = new ClassB(); 


public ClassA() { 
    setTitle("Test"); 
    setLookAndFeel(); 
    setSize(250, 100); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    GridLayout mainGrid = new GridLayout(1, 1, 20, 20); 
    setLayout(mainGrid); 


    add(a); 
    add(but); 
    but.addActionListener(cb); 
    setVisible(true); 
} 


private void setLookAndFeel() { 
    try { 
     UIManager.setLookAndFeel(
       "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel" 
       ); 
    } catch (Exception exc) { 
     //ignore error 
    } 
} 

public static void main(String[] args) { 
    ClassA Alch = new ClassA(); 
} 

} 

ClassB的

import java.awt.event.*; 

public class ClassB implements ActionListener{ 
String command; 
String text; 

ClassA ca; 



@Override 
public void actionPerformed(ActionEvent event) { 
    command = event.getActionCommand(); 
    if (command.equals("Click")) { 
     text = ca.a.getText(); 
     System.out.println(text); 
    } 

} 
} 

我有越來越ClassB的閱讀的JTextField 的問題

如果我刪除線

text = ca.a.getText(); 

,並使用

System.out.println(command); 

它輸出點擊使代碼的其餘部分似乎工作,但只要我添加

text = ca.a.getText(); 

當我使用「單擊」按鈕時,我得到一個NullPointerException。

所以問題是我應該如何編寫代碼來讓ClassB讀取JTextField並輸出它?

回答

1

你有ClassA變量ca但你還沒有初始化它。所以首先你需要初始化ca變量才能使用它。

ClassA ca - new ClassA(); 

沒有相應和你的問題,但正如你說你是新來的Java等等。永遠記得永遠不要在你的邏輯類中有你的接口類的實例變量。它是一個糟糕的設計。

我建議你找到關於MVC設計模式的一些好文章,然後再進入到面向對象的。它始終是更好地創建強大的基礎:)

1

ca變量從未被初始化。您需要在您的ClassB添加類似ClassA ca = new ClassA()地方 - 可能在構造函數中。

澄清編輯

根據註釋:

如果變量被構造函數初始化內,這將需要使用ca = new ClassA(),否則變量將只在構造函數作用域。因此,舉例來說:

public ClassB() { 
    ca = new ClassA(); 
} 

但是,如果你不希望添加無論什麼原因,構造函數,你也可以修改變量的現有聲明:

public class ClassB implements ActionListener{ 
    String command; 
    String text; 
    ClassA ca = new ClassA(); 
    ... 
} 
+0

如果您在ClassB的構造函數中執行'ClassA ca = new ClassA()',您將創建一個變量作用域以覆蓋該類中'ca **'字段**的構造函數。 – 2012-07-18 15:35:51

+0

這就是* *所表示的詞。顯然,如果它在構造函數中,它應該是'ca = new ClassA()',而OP可以修改變量聲明爲'ClassA ca = new ClassA();'。但是由於OP確實聲稱是該語言的新手,我會更新我的文章以使其更清晰。 – 2012-07-18 15:41:40

0

首先,你必須創建一個實例ClassA的ClassB中的:

ClassA ca = new ClassA(); 

,那麼你應該知道,CA是一個實例變量,如果你不初始化一個實例變量,它得到空值。

提示:最好是讓你的實例變量的私人和getter和setter方法訪問它們:

private JTextField txtField1 = new JTextField(); 

private JButton btnAction1 = new JButton("Click"); 

private ClassB cb = new ClassB(); 

public JTextField getTxtField1() { 
    return txtField1; 
} 
0

你可以通過調用cb.ca = this初始化ClassA的的構造函數的場ClassB的的ca,但這是一種骯髒。田野應該幾乎總是私人的,我。即無法從課外進行訪問。

解決此問題的最佳方法是忘記ClassB並使用匿名類代替它。在ClassA的構造函數中添加ActionListener的新匿名實現。

but.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent event) { 
     command = event.getActionCommand(); 
     if (command.equals("Click")) { 
      String text = a.getText(); 
      System.out.println(text); 
     } 
}); 

或者,您可以提供標籤作爲參數傳遞給ClassB的一個構造器,並將其保存到(ClassB的的)的字段。

private JTextField field; 

public ClassB(JTextField field) { 
    this.field = field; 
} 
相關問題