我正在学习 Java,并且碰巧从 Fred Swartz 的 leepoint.net 网页上看到了一个 ActionListener
示例。 DogYears2.java.
为了学习,我尝试将 ActionListener ConvertBtnListener
从 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 新手,为了学习,我希望有人能告诉我为什么会这样,如果我坚持维护一个单独的 ActionListener 类文件,我该如何解决这个问题?
最佳答案
第一步是停止考虑文件。您应该谈论类和对象。
在您的示例中,您定义了两个类(这些定义碰巧放在两个单独的文件中,但这并不重要)。
头等舱DogYears2
(注意:没有结尾 .java
,仅 文件)您在 main
中创建一个实例(也称为一个对象)方法。
二等舱ConvertBtnListener
您在 DogYears2
的构造函数中创建了两个实例(又名两个对象) .
字段 _dogYearsTF
和 _humanYearsTF
在ConvertBtnListener
class 永远不会得到一个值,因此你会得到一个 NullPointerException
一旦您尝试对他们做某事。
你应该知道 _dogYearsTF
在ConvertBtnListener
与 _dogYearsTF
完全无关在DogYears2
!此外,字段 _dogYearsTF
在 ConvertBtnListener
的一审中与字段完全无关 _dogYearsTF
第二个实例。
既然我已经告诉你为什么它不起作用,我可能应该告诉你如何让它起作用:
一种方法是传递必要的 JTextField
对象到 ConvertBtnListener
的构造函数目的。为此,您需要在该类中创建一个接受两个 JTextField
的构造函数。引用并将它们分配给适当的字段。
通常的方法是让监听器成为你的 UI 类的内部类,在这种情况下,它可以直接访问 UI 类字段,不需要这样的构造函数(这就是为什么它在原始示例中有效)。
关于java - 在两个单独的 .java 文件之间传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7280052/