我正在尝试一个非常的简单表单,旨在将用户输入带入JTextField并通过弹出对话框显示相同的输入。
我可以使用setText()将JTextField硬编码为具有预设编号。如果我这样做,我的程序可以完美运行。
但是,当我将该字段留空并尝试使用getText()在弹出对话框中显示文本时,我要么得到一个空的弹出框架,要么我得到一个'空字符串'异常(我试图解析要加倍的字符串。)
package buttontest;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class ButtonTest
{
public static void main(String[] args)
{
ButtonFrame frame = new ButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class ButtonFrame extends JFrame
{
@SuppressWarnings("LeakingThisInConstructor")
public ButtonFrame()
{
setTitle("SunStream Loan Calculator v2.0");
setSize(900,900);
ButtonPanel panel = new ButtonPanel();
panel.add(new JLabel("Enter your loan amount:"));
loanAmt = new JTextField(40);
panel.add(loanAmt);
add(panel,BorderLayout.CENTER);
}
public JTextField loanAmt;
class ButtonPanel extends JPanel implements ActionListener
{
private Component frame;
public ButtonPanel()
{
final JButton b2 = new JButton("Calculate");
add(b2, BorderLayout.SOUTH);
b2.setActionCommand("calculate");
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ButtonFrame bf = new ButtonFrame();
if("calculate".equals(e.getActionCommand()))
{
JOptionPane.showMessageDialog(frame, bf.loanAmt.getText());
}
}
});
}
@Override
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
非常感谢任何帮助。我正在使用KeyListener或KeyEvent进行研究,但我不太了解它。
答案 0 :(得分:8)
您正在b2的ActionListener中创建一个“阴影”ButtonFrame变量。是的,bf变量引用的ButtonFrame对象与显示的ButtonFrame对象具有相同的类,但它引用了一个完全不同且不可视化的对象。解决方案的关键是从实际显示的ButtonFrame对象中获取文本,这可以通过ButtonFrame.this
构造从内部类中获取:
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//!! ButtonFrame bf = new ButtonFrame();
if ("calculate".equals(e.getActionCommand())) {
//!! note use of ButtonFrame.this:
JOptionPane.showMessageDialog(frame, ButtonFrame.this.loanAmt.getText());
}
}
});
接下来考虑使用公共getter,而不是直接访问JTextField等字段。这减少了代码导致副作用的可能性,例如无意中更改了JTextField对象的属性。
例如(由// !!评论表示的变化):
import java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class ButtonTest {
public static void main(String[] args) {
ButtonFrame frame = new ButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class ButtonFrame extends JFrame {
private JTextField loanAmt; // !! Make field private
@SuppressWarnings("LeakingThisInConstructor")
public ButtonFrame() {
setTitle("SunStream Loan Calculator v2.0");
setSize(900, 900);
ButtonPanel panel = new ButtonPanel();
panel.add(new JLabel("Enter your loan amount:"));
loanAmt = new JTextField(40);
panel.add(loanAmt);
add(panel, BorderLayout.CENTER);
}
// !! create a public method to get JTextField's text
// !! without exposing the JTextField itself.
public String getLoanAmtText() {
return loanAmt.getText();
}
class ButtonPanel extends JPanel implements ActionListener {
private Component frame;
public ButtonPanel() {
final JButton b2 = new JButton("Calculate");
add(b2, BorderLayout.SOUTH);
b2.setActionCommand("calculate");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// !! ButtonFrame bf = new ButtonFrame();
if ("calculate".equals(e.getActionCommand())) {
//!! call public method on ButtonFrame object
JOptionPane.showMessageDialog(frame,
ButtonFrame.this.getLoanAmtText());
}
}
});
}
@Override
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
答案 1 :(得分:2)
您可以通过 ButtonPanel 本身访问 loanAmt 的唯一方法。因为您将 loanAmt 添加到此按钮吗?
因此,如果您想要访问 loanAmt 。您必须在此按钮面板上获取所有组件。这是我的psudeo代码如何从ButtonPanel类访问 loanAmt 。
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ButtonFrame bf = new ButtonFrame();
if("calculate".equals(e.getActionCommand())) {
// Get all component
java.awt.Component[] componentList = this.getComponents();
JTextField txtField;
String value;
for (int i = 0; i < componentList.length; i++) {
if (componentList[i].getClass().getName().equals("javax.swing.JTextField")) {
txtField = (JTextField) componentList[i];
value = textField.getText();
}
}
if (value != null) JOptionPane.showMessageDialog(frame, value);
}
}
});