正确处理多个文本字段的异常
Proper exception handling with multiple Textfields
程序图片:
program image
这是“+”按钮调用方法的代码
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Calc extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField tf_1; // contains first operand
private JTextField tf_2; // contains second operand
private JTextField tf_3; // result
private JButton bu_1; // plus operation
private JButton bu_2; // multiplication
/**
* Create the frame.
*/
public Calc() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 387, 143);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
tf_1 = new JTextField();
tf_1.setBounds(20, 35, 60, 20);
contentPane.add(tf_1);
tf_1.setColumns(10);
tf_2 = new JTextField();
tf_2.setBounds(90, 35, 60, 20);
contentPane.add(tf_2);
tf_2.setColumns(10);
tf_3 = new JTextField();
tf_3.setBounds(272, 35, 70, 20);
contentPane.add(tf_3);
tf_3.setColumns(10);
//button 1
bu_1 = new JButton("+");
bu_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addOperands();
}
});
bu_1.setBounds(160, 34, 41, 23);
contentPane.add(bu_1);
//button 2
bu_2 = new JButton("*");
bu_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
multiplyOperands();
}
});;
bu_2.setBounds(211, 34, 41, 23);
contentPane.add(bu_2);
}
private void addOperands() {
double value_1, value_2;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
tf_3.setText(String.valueOf(value_1 + value_2));
}
private void multiplyOperands() {
// TODO implement multiply operation
}
}
目前我正在努力正确找出哪个 textField 抛出异常。
上面的代码不起作用,因为双精度值未初始化。
但是如果 tf_X 值不是数字,我不想只用 0 来计算。
我也试过 addOperands()
到 return 一个双但是
returning null
在异常情况下是不可能的。
我想要的:
- 如果任何值不是数字,则不计算结果(抛出 NumberFormatException)
- 将包含 NaN 值的文本字段的背景设置为红色
- 清除 tf_3 的当前值:
tf_3.setText("");
有人可以帮我解决这个问题吗?
在你的代码中 addOperands
private void addOperands() {
double value_1, value_2;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
tf_3.setText(String.valueOf(value_1 + value_2));
}
当你在第一个时 catch
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
// here you know that tf_1 is non-double
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
您知道第一个输入包含错误输入。第二个输入也一样。如果您不想显示 0 作为结果,您有 2 个选择:通过简单地将 return
放在 catch
子句中来停止处理第一个错误,或者添加标志以查看是否一切正常很好
private void addOperands() {
double value_1, value_2;
boolean good = true;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
good = false;
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
good = false;
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
if(good)
tf_3.setText(String.valueOf(value_1 + value_2));
else
tf_3.setText("Bad input");
}
更新
如果你想分解你的代码(通常这是个好主意),你可以这样做
private Double readDoubleOrHighlight(JTextField tf) {
try {
double res = Double.parseDouble(tf.getText());
tf.setBackground(whatever-default-background-is);
return res;
} catch (NumberFormatException e) {
tf.setBackground(Color.red);
tf.requestFocus();
return null;
}
}
private void addOperands() {
Double value_1 = readDoubleOrHighlight(tf_1);
Double value_2 = readDoubleOrHighlight(tf_2);
if((value_1 != null) && (value_2 != null))
tf_3.setText(String.valueOf(value_1 + value_2));
else
tf_3.setText("Bad input");
}
注意:这里我有效地使用 Double
作为 Option[double]
,无论如何 Java 都不支持(提示:google Option
,这是一个强大的想法或从 Option type in wiki) 开始。
更新 #2
这次介绍高阶函数。
如果你添加一段这样的代码
static interface BinaryOp {
double calc(double arg1, double arg2);
}
private void applyBinaryOp(BinaryOp op) {
Double value_1 = readDoubleOrHighlight(tf_1);
Double value_2 = readDoubleOrHighlight(tf_2);
if((value_1 != null) && (value_2 != null)) {
double res = op.calc(value_1, value_2);
tf_3.setText(res);
}
else
tf_3.setText("Bad input");
}
您可以将点击侦听器简化为类似这样的东西
bu_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyBinaryOp(new BinaryOp(){
public double calc(double arg1, double arg2) {
return arg1 * arg2;
}
});
}
});
并且使用 Java 8 lambda 语法,它甚至更简单。
程序图片: program image
这是“+”按钮调用方法的代码
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Calc extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField tf_1; // contains first operand
private JTextField tf_2; // contains second operand
private JTextField tf_3; // result
private JButton bu_1; // plus operation
private JButton bu_2; // multiplication
/**
* Create the frame.
*/
public Calc() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 387, 143);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
tf_1 = new JTextField();
tf_1.setBounds(20, 35, 60, 20);
contentPane.add(tf_1);
tf_1.setColumns(10);
tf_2 = new JTextField();
tf_2.setBounds(90, 35, 60, 20);
contentPane.add(tf_2);
tf_2.setColumns(10);
tf_3 = new JTextField();
tf_3.setBounds(272, 35, 70, 20);
contentPane.add(tf_3);
tf_3.setColumns(10);
//button 1
bu_1 = new JButton("+");
bu_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addOperands();
}
});
bu_1.setBounds(160, 34, 41, 23);
contentPane.add(bu_1);
//button 2
bu_2 = new JButton("*");
bu_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
multiplyOperands();
}
});;
bu_2.setBounds(211, 34, 41, 23);
contentPane.add(bu_2);
}
private void addOperands() {
double value_1, value_2;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
tf_3.setText(String.valueOf(value_1 + value_2));
}
private void multiplyOperands() {
// TODO implement multiply operation
}
}
目前我正在努力正确找出哪个 textField 抛出异常。 上面的代码不起作用,因为双精度值未初始化。 但是如果 tf_X 值不是数字,我不想只用 0 来计算。
我也试过 addOperands()
到 return 一个双但是
returning null
在异常情况下是不可能的。
我想要的:
- 如果任何值不是数字,则不计算结果(抛出 NumberFormatException)
- 将包含 NaN 值的文本字段的背景设置为红色
- 清除 tf_3 的当前值:
tf_3.setText("");
有人可以帮我解决这个问题吗?
在你的代码中 addOperands
private void addOperands() {
double value_1, value_2;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
tf_3.setText(String.valueOf(value_1 + value_2));
}
当你在第一个时 catch
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
// here you know that tf_1 is non-double
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
您知道第一个输入包含错误输入。第二个输入也一样。如果您不想显示 0 作为结果,您有 2 个选择:通过简单地将 return
放在 catch
子句中来停止处理第一个错误,或者添加标志以查看是否一切正常很好
private void addOperands() {
double value_1, value_2;
boolean good = true;
try {
value_1 = Double.parseDouble(tf_1.getText());
} catch (NumberFormatException e) {
good = false;
tf_1.setBackground(Color.red);
tf_1.requestFocus();
}
try {
value_2 = Double.parseDouble(tf_2.getText());
} catch (Exception e) {
good = false;
tf_2.setBackground(Color.red);
tf_2.requestFocus();
}
if(good)
tf_3.setText(String.valueOf(value_1 + value_2));
else
tf_3.setText("Bad input");
}
更新
如果你想分解你的代码(通常这是个好主意),你可以这样做
private Double readDoubleOrHighlight(JTextField tf) {
try {
double res = Double.parseDouble(tf.getText());
tf.setBackground(whatever-default-background-is);
return res;
} catch (NumberFormatException e) {
tf.setBackground(Color.red);
tf.requestFocus();
return null;
}
}
private void addOperands() {
Double value_1 = readDoubleOrHighlight(tf_1);
Double value_2 = readDoubleOrHighlight(tf_2);
if((value_1 != null) && (value_2 != null))
tf_3.setText(String.valueOf(value_1 + value_2));
else
tf_3.setText("Bad input");
}
注意:这里我有效地使用 Double
作为 Option[double]
,无论如何 Java 都不支持(提示:google Option
,这是一个强大的想法或从 Option type in wiki) 开始。
更新 #2
这次介绍高阶函数。 如果你添加一段这样的代码
static interface BinaryOp {
double calc(double arg1, double arg2);
}
private void applyBinaryOp(BinaryOp op) {
Double value_1 = readDoubleOrHighlight(tf_1);
Double value_2 = readDoubleOrHighlight(tf_2);
if((value_1 != null) && (value_2 != null)) {
double res = op.calc(value_1, value_2);
tf_3.setText(res);
}
else
tf_3.setText("Bad input");
}
您可以将点击侦听器简化为类似这样的东西
bu_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyBinaryOp(new BinaryOp(){
public double calc(double arg1, double arg2) {
return arg1 * arg2;
}
});
}
});
并且使用 Java 8 lambda 语法,它甚至更简单。