NumberFormatException:对于输入字符串:TextField 中的 "XXX,XX",与语言环境相关
NumberFormatException: For input string: "XXX,XX" in TextField, related to locale
我有一个控制器 class 可以加载相应选择的场景。我称它为 "CMenu".
/*** Other methods that load other menu entries ***/
/**
* Menu de Usuarios
*
* @param event
* @throws Exception
*/
public void menuUsuarios(ActionEvent event) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Usuarios.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de usuarios");
stage.setScene(scene);
stage.setResizable(false);
// Llamamos a la ventana de menu
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Menu de Inventario
*
* @param event
* @throws Exception
*/
public void menuProductos(ActionEvent event) throws Exception {
try {
Locale.setDefault(new Locale("es"));
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Productos.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de Productos");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Menu de Empleados
*
* @param event
* @throws Exception
*/
public void menuEmpleados(ActionEvent event) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Empleados.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de Empleados");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/*** Other methods that load other menu entries ***/
有 "products" 菜单,看起来像这样。
Product menu
当我输入成本并设置利润时,使用 onKeyEvent 计算价格,格式为:“123.456,99”。反之亦然。
txtUtil.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (txtCosto.getText() != null && txtUtil.getText() != null && txtPrecio.getText() != null) {
try {
costo = Double.parseDouble(txtCosto.getText());
util = Double.parseDouble(txtUtil.getText());
precio = (costo / (((util / 100) - 1) * (-1)));
txtPrecio.setText(String.valueOf(String.format("%.2f", precio)));
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "error en algo");
}
}
});
txtPrecio.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (txtCosto.getText() != null && txtUtil.getText() != null && txtPrecio.getText() != null) {
try {
costo = Double.parseDouble(txtCosto.getText());
precio = Double.parseDouble(txtPrecio.getText());
util = ((costo / precio) - 1) * -100;
txtUtil.setText(String.valueOf((double) Math.round(util * 100) / 100));
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "error");
}
}
});
}
因此,当我在价格 TextField 中释放密钥时,出现此错误(还有其他错误,但此处未提及)。
java.lang.NumberFormatException: For input string: "21428,57"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at ajfmo.sislic.controlador.CProductos.handle(CProductos.java:164)
at ajfmo.sislic.controlador.CProductos.handle(CProductos.java:1)
我看到问题出在 ajfmo.sislic.controlador.CProductos$3.handle(CProductos.java:164),但我发现真正的问题是场景获取的默认语言环境,我更改为 en 并且问题消失了,但是如果 我想保留我的默认语言环境而不出现该错误怎么办?
除了记录被保存到 MySQL 数据库之外,如果我更改了语言环境,我会有问题吗?
非常感谢您提前阅读本文。
要以与语言环境相关的方式(包括分组字符和与语言环境相关的小数点分隔符)将文本解析为数值,请使用 DecimalFormat
对象。
这是一个非常快速的演示,应该很容易适应您的应用程序:
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class DecimalFormatTest {
public static void main(String[] args) throws ParseException {
// use system default locale:
// NumberFormat format = DecimalFormat.getInstance();
// or specify the locale explicitly:
NumberFormat format = DecimalFormat.getInstance(new Locale("es", "VE"));
String text = "123.456,01" ;
double value = format.parse(text).doubleValue();
System.out.println("Parsed value as double: " +value);
System.out.println("Value formatted again as text: " + format.format(value));
}
}
这给出了输出
Parsed value as double: 123456.01
Value formatted again as text: 123.456,01
Double.valueOf,并扩展为 Double.parseDouble,不考虑浮点数的国际表示。 Double.valueOf 上的 javadoc 声明如下:
要解释浮点值的本地化字符串表示,请使用 java.text.NumberFormat.
的子类
要获取 NumberFormat 的本地化版本,请使用它的 getInstance 方法。所以,你代码中的以下两行,
costo = Double.parseDouble(txtCosto.getText());
precio = Double.parseDouble(txtPrecio.getText());
应该改为,
NumberFormat nf = NumberFormat.getNumberInstance(); // Use JVM default locale
costco = nf.parse(txtCosto.getText()).doubleValue();
precio = nf.parse(txtPrecio.getText()).doubleValue();
我有一个控制器 class 可以加载相应选择的场景。我称它为 "CMenu".
/*** Other methods that load other menu entries ***/
/**
* Menu de Usuarios
*
* @param event
* @throws Exception
*/
public void menuUsuarios(ActionEvent event) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Usuarios.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de usuarios");
stage.setScene(scene);
stage.setResizable(false);
// Llamamos a la ventana de menu
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Menu de Inventario
*
* @param event
* @throws Exception
*/
public void menuProductos(ActionEvent event) throws Exception {
try {
Locale.setDefault(new Locale("es"));
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Productos.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de Productos");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Menu de Empleados
*
* @param event
* @throws Exception
*/
public void menuEmpleados(ActionEvent event) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Empleados.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/styles/application.css").toExternalForm());
Stage stage = new Stage();
stage.setTitle("Menu de Empleados");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/*** Other methods that load other menu entries ***/
有 "products" 菜单,看起来像这样。
Product menu
当我输入成本并设置利润时,使用 onKeyEvent 计算价格,格式为:“123.456,99”。反之亦然。
txtUtil.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (txtCosto.getText() != null && txtUtil.getText() != null && txtPrecio.getText() != null) {
try {
costo = Double.parseDouble(txtCosto.getText());
util = Double.parseDouble(txtUtil.getText());
precio = (costo / (((util / 100) - 1) * (-1)));
txtPrecio.setText(String.valueOf(String.format("%.2f", precio)));
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "error en algo");
}
}
});
txtPrecio.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (txtCosto.getText() != null && txtUtil.getText() != null && txtPrecio.getText() != null) {
try {
costo = Double.parseDouble(txtCosto.getText());
precio = Double.parseDouble(txtPrecio.getText());
util = ((costo / precio) - 1) * -100;
txtUtil.setText(String.valueOf((double) Math.round(util * 100) / 100));
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "error");
}
}
});
}
因此,当我在价格 TextField 中释放密钥时,出现此错误(还有其他错误,但此处未提及)。
java.lang.NumberFormatException: For input string: "21428,57"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at ajfmo.sislic.controlador.CProductos.handle(CProductos.java:164)
at ajfmo.sislic.controlador.CProductos.handle(CProductos.java:1)
我看到问题出在 ajfmo.sislic.controlador.CProductos$3.handle(CProductos.java:164),但我发现真正的问题是场景获取的默认语言环境,我更改为 en 并且问题消失了,但是如果 我想保留我的默认语言环境而不出现该错误怎么办?
除了记录被保存到 MySQL 数据库之外,如果我更改了语言环境,我会有问题吗?
非常感谢您提前阅读本文。
要以与语言环境相关的方式(包括分组字符和与语言环境相关的小数点分隔符)将文本解析为数值,请使用 DecimalFormat
对象。
这是一个非常快速的演示,应该很容易适应您的应用程序:
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class DecimalFormatTest {
public static void main(String[] args) throws ParseException {
// use system default locale:
// NumberFormat format = DecimalFormat.getInstance();
// or specify the locale explicitly:
NumberFormat format = DecimalFormat.getInstance(new Locale("es", "VE"));
String text = "123.456,01" ;
double value = format.parse(text).doubleValue();
System.out.println("Parsed value as double: " +value);
System.out.println("Value formatted again as text: " + format.format(value));
}
}
这给出了输出
Parsed value as double: 123456.01
Value formatted again as text: 123.456,01
Double.valueOf,并扩展为 Double.parseDouble,不考虑浮点数的国际表示。 Double.valueOf 上的 javadoc 声明如下:
要解释浮点值的本地化字符串表示,请使用 java.text.NumberFormat.
的子类要获取 NumberFormat 的本地化版本,请使用它的 getInstance 方法。所以,你代码中的以下两行,
costo = Double.parseDouble(txtCosto.getText());
precio = Double.parseDouble(txtPrecio.getText());
应该改为,
NumberFormat nf = NumberFormat.getNumberInstance(); // Use JVM default locale
costco = nf.parse(txtCosto.getText()).doubleValue();
precio = nf.parse(txtPrecio.getText()).doubleValue();