NumberFormatException: для входной строки: «XXX, XX» в TextField, связанной с локалью

0

У меня есть класс контроллера, который загружает сцены соответствующим образом выбранным. Я назвал его "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, будут ли у меня проблемы Если я изменю эту локаль?

Большое спасибо, заранее за это.

Теги:
javafx
locale
javafx-2

2 ответа

0
Лучший ответ

Чтобы разделить текст на числовое значение в зависимости от языка (включая группировку символов и зависимые от языкового значения десятичные разделители), используйте объект 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
  • 0
    Это добилось цели и решило ошибку, которую я получил. Теперь я получаю ошибку, но это то, что я могу решить самостоятельно, я думаю. Я делаю рефакторинг класса и методов, чтобы увидеть, нет ли проблем с HQL и этим значением с запятой. Большое спасибо за ваш ответ, сэр Saludos, desde Венесуэла, как вы уже знаете!
-1

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();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню