String with numbers and letters to double javafx

后端 未结 1 750
北恋
北恋 2020-12-10 20:41

Hi I am trying to read a the numbers from a text field that shows a price e.g. £3.00, and convert the value of the price to a double. Is there a way to do

Do         


        
相关标签:
1条回答
  • 2020-12-10 20:54

    There is some TextFormatter and change filter handling logic built into the JavaFX TextField API, you could make use of that.

    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.StringConverter;
    
    import java.text.DecimalFormat;
    import java.text.ParseException;
    
    class CurrencyFormatter extends TextFormatter<Double> {
        private static final double DEFAULT_VALUE = 5.00d;
        private static final String CURRENCY_SYMBOL = "\u00A3"; // british pound
    
        private static final DecimalFormat strictZeroDecimalFormat  
            = new DecimalFormat(CURRENCY_SYMBOL + "###,##0.00");
    
        CurrencyFormatter() {
            super(
                    // string converter converts between a string and a value property.
                    new StringConverter<Double>() {
                        @Override
                        public String toString(Double value) {
                            return strictZeroDecimalFormat.format(value);
                        }
    
                        @Override
                        public Double fromString(String string) {
                            try {
                                return strictZeroDecimalFormat.parse(string).doubleValue();
                            } catch (ParseException e) {
                                return Double.NaN;
                            }
                        }
                    },
                    DEFAULT_VALUE,
                    // change filter rejects text input if it cannot be parsed.
                    change -> {
                        try {
                            strictZeroDecimalFormat.parse(change.getControlNewText());
                            return change;
                        } catch (ParseException e) {
                            return null;
                        }
                    }
            );
        }
    }
    
    public class FormattedTextField extends Application {
    
        public static void main(String[] args) { launch(args); }
    
        @Override
        public void start(final Stage stage) {
            TextField textField = new TextField();
            textField.setTextFormatter(new CurrencyFormatter());
    
            Label text = new Label();
            text.textProperty().bind(
                    Bindings.concat(
                            "Text: ",
                            textField.textProperty()
                    )
            );
    
            Label value = new Label();
            value.textProperty().bind(
                    Bindings.concat(
                            "Value: ",
                            textField.getTextFormatter().valueProperty().asString()
                    )
            );
    
            VBox layout = new VBox(
                    10,
                    textField,
                    text,
                    value,
                    new Button("Apply")
            );
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
    }
    

    The exact rules for DecimalFormat and the filter could get a little tricky if you are very particular about user experience (e.g. can the user enter the currency symbol? what happens if the user does not enter a currency symbol? are empty values permitted? etc.) The above example offers a compromise between a reasonable user experience and a (relatively) easy to program solution. For an actual production level application, you might wish to tweak the logic and behavior a bit more to fit your particular application.

    Note, the apply button doesn't actually need to do anything to apply the change. Changes are applied when the user changes focus away from the text field (as long as they pass the change filter). So if the user clicks on the apply button, it gains, focus, the text field loses focus and the change is applied if applicable.

    The above example treats the currency values as doubles (to match with the question), but those serious about currency may wish to look to BigDecimal.

    For a simpler solution using similar concepts, see also:

    • Java 8 U40 TextFormatter (JavaFX) to restrict user input only for decimal number
    0 讨论(0)
提交回复
热议问题