У меня есть класс контроллера, который загружает сцены соответствующим образом выбранным. Я назвал его "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 ***/
Там меню "продукты", похожее на это.
Когда я печатаю стоимость и устанавливаю прибыль, цена рассчитывается с использованием 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$3.handle(CProductos.java:164)
at ajfmo.sislic.controlador.CProductos$3.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 не учитывает международные представления чисел с плавающей запятой. В javadoc на Double.valueOf указано следующее:
Для интерпретации локализованных строковых представлений значения с плавающей запятой используйте подклассы 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();