[英]Passing data between two separate .java files
我正在学习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 Noob,我希望有人能启发我为什么会发生这种情况,如果我坚持维护单独的ActionListener类文件,又该如何解决?
第一步是停止思考文件。 您应该在谈论类和对象。
在您的示例中,您定义了两个类(这些定义碰巧放在了两个单独的文件中,但这并不重要)。
在第一类DogYears2
(注意:没有结尾的.java
, 仅用于文件),您在main
方法中创建一个实例(也称为一个对象)。
在第二个类ConvertBtnListener
您在DogYears2
的构造函数中创建两个实例(也称为两个对象)。
ConvertBtnListener
类中的_dogYearsTF
和_humanYearsTF
字段永远不会获得值 ,因此,一旦您尝试对它们进行操作,就会得到NullPointerException
。
你应该知道, _dogYearsTF
在ConvertBtnListener
是完全无关 _dogYearsTF
在DogYears2
! 此外,场_dogYearsTF
中的第一个实例 ConvertBtnListener
是完全无关的字段_dogYearsTF
n中的第二个实例 。
既然我已经告诉了您为什么它不起作用 ,我可能应该告诉您如何使其起作用:
一种方法是将必要的JTextField
对象传递给ConvertBtnListener
对象的构造函数。 为此,您需要在该类中创建一个构造函数,该构造函数接受两个JTextField
引用并将它们分配给适当的字段。
通常的方法是使侦听器成为UI类的内部类,在这种情况下,它可以直接访问UI类字段,并且不需要这样的构造函数(这就是为什么在原始示例中如此)。
在您的侦听器类中,请初始化文本字段变量。 考虑一下:
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;
---编辑构造函数参数顺序
在ConvertBtnListener
您将在此处获得空指针异常:
String dyStr = _dogYearsTF.getText();
... 和这里:
_humanYearsTF.setText("" + humanYears);
您永远不会在ConvertBtnListener;
初始化_dogYearsTF
和_humanYearsTF
ConvertBtnListener;
这些字段与DogYears2
的相同名称无关。
您可以尝试使用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);
}
这将获取触发操作事件的来源。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.