在两个单独的.java文件之间传递数据

时间:2011-09-02 06:46:00

标签: java swing actionlistener

我正在学习Java,我碰巧遇到了来自Fred Swartz的leepoint.net网页的ActionListener示例。 DogYears2.java。

为了学习,我通过将ConvertBtnListener中的ActionListener DogYears2.java分隔为名为ConvertBtnListener.java的单独顶级类文件进行了实验。

DogYears2.java文件

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;  // Needed for ActionListener

//////////////////////////////////////////////////////// class DogYears2
class DogYears2 extends JFrame {
//======================================================== constants
final static int DOG_YEARS_PER_HUMAN_YEAR = 7;

//=============================================== instance variables
private JTextField _humanYearsTF = new JTextField(3);
private JTextField _dogYearsTF   = new JTextField(3);

//====================================================== constructor
public DogYears2() {
    // 1... Create/initialize components
    JButton convertBtn = new JButton("Convert");
    convertBtn.addActionListener(new ConvertBtnListener());

    _dogYearsTF.addActionListener(new ConvertBtnListener());
    _humanYearsTF.setEditable(false);


    // 2... Create content panel, set layout
    JPanel content = new JPanel();
    content.setLayout(new FlowLayout());

    // 3... Add the components to the content panel.
    content.add(new JLabel("Dog Years"));
    content.add(_dogYearsTF);              // Add input field
    content.add(convertBtn);               // Add button
    content.add(new JLabel("Human Years"));
    content.add(_humanYearsTF);            // Add output field

    // 4... Set this window's attributes, and pack it.
    setContentPane(content);
    pack();                               // Layout components.
    setTitle("Dog Year Converter");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);          // Center window.
}

    //====================================================== method main
public static void main(String[] args) {
    DogYears2 window = new DogYears2();
    window.setVisible(true);
}

}

ConvertBtnListener.java文件

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;  // Needed for ActionListener

class ConvertBtnListener implements ActionListener {
JTextField _dogYearsTF;
JTextField _humanYearsTF;
int DOG_YEARS_PER_HUMAN_YEAR = 7;


    public void actionPerformed(ActionEvent e) {
        //... Get the value from the dog years textfield.
        String dyStr = _dogYearsTF.getText();
        int dogYears = Integer.parseInt(dyStr);

        //... Convert it - each dog year is worth 7 human years.
        int humanYears = dogYears * DOG_YEARS_PER_HUMAN_YEAR;

        //... Convert to string and set human yrs textfield
        _humanYearsTF.setText("" + humanYears);
    }

}

现在,当我运行DogYears.java文件时,GUI弹出,当我输入文本字段中的人年数时,我得到了NullPointerException

为了学习Java菜鸟,我希望有人可以告诉我为什么会这样,如果我INSIST我保持一个单独的ActionListener类文件,我该如何解决这个问题?

4 个答案:

答案 0 :(得分:4)

第一步是停止思考文件。你应该谈论类和对象。

在您的示例中,您已经定义了两个类(那些定义发生将被放置在两个单独的文件中,但这并不重要。)

在第一个班级DogYears2(注意:没有结尾.java,那个文件)中,您在{{1}中创建了一个实例(也称为一个对象)方法。

在第二个类main中,您在ConvertBtnListener的构造函数中创建了两个实例(a.k.a两个对象)。

DogYears2中的字段_dogYearsTF_humanYearsTF永远不会获得值,因此一旦您尝试,您将获得ConvertBtnListener与他们做点什么。

您应该知道NullPointerException_dogYearsTF ConvertBtnListener 完全不相关 _dogYearsTF中的DogYears2!此外,_dogYearsTF第一个实例中的字段ConvertBtnListener 完全不相关秒的字段_dogYearsTF实例

现在我告诉你为什么它不起作用,我应该告诉你如何使它工作:

一种方法是将必要的JTextField对象传递给ConvertBtnListener对象的构造函数。为此,您需要在该类中创建一个构造函数,该构造函数接受两个JTextField引用并将它们分配给相应的字段。

通常的方式是使侦听器成为UI类的内部类,在这种情况下,它可以直接访问UI类字段,并且不需要这样的构造函数(这就是为什么它在最初的例子中起作用。)

答案 1 :(得分:2)

在您的监听器类中,请初始化文本字段变量。考虑一下:

class ConvertBtnListener implements ActionListener {
    ....
    ConvertBtnListener(JTextField humanYearsTF, JTextField dogYearsTF) {
        _dogYearsTF = dogYearsTF;
        _humanYearsTF = humanYearsTF;
    }
    ....
 }

public DogYears2() {
    ActionListener listener = new ConvertBtnListener(_humanYearsTF, _dogYearsTF);         
    JButton convertBtn = new JButton("Convert");
    ...
}

另请参阅什么是匿名类。这是实现此类操作的另一种方式。

---编辑 而不是声明

int DOG_YEARS_PER_HUMAN_YEAR = 7;
ConvertBtnListener类中的

- 只使用之前在DogYears.java中声明的静态字段。所以这应该是正确的方式。

int humanYears = dogYears * DogYears2.DOG_YEARS_PER_HUMAN_YEAR;

---编辑 构造函数参数命令

答案 2 :(得分:0)

ConvertBtnListener中,您会在此处获得空指针异常:

String dyStr = _dogYearsTF.getText();

......在这里:

 _humanYearsTF.setText("" + humanYears);

您永远不会在_dogYearsTF中初始化_humanYearsTFConvertBtnListener;这些字段与DogYears2中的相同名称无关。

答案 3 :(得分:0)

您可以尝试使用getSource()函数

 public void actionPerformed(ActionEvent e) {
        //... Get the value from the dog years textfield.
        String dyStr = _dogYearsTF.getText();
        int dogYears = Integer.parseInt(dyStr);
JTextField _humanYearsTF = (JTextField)e.getSource(); // new line.
        //... Convert it - each dog year is worth 7 human years.
        int humanYears = dogYears * DOG_YEARS_PER_HUMAN_YEAR;

        //... Convert to string and set human yrs textfield
        _humanYearsTF.setText("" + humanYears);
    }

这将获取触发动作事件的源。