用于javafx微调器控制的正则表达式

时间:2016-08-04 18:37:08

标签: regex javafx spinner

SpinnerValueFactory svf = new SpinnerValueFactory.DoubleSpinnerValueFactory(-500,500,1,0.5);
spiKolicina.setValueFactory(svf);
spiKolicina.setEditable(true);


UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {

    @Override
    public TextFormatter.Change apply(TextFormatter.Change t) {

        if (t.isReplaced())
            if(t.getText().matches("[^0-9]"))
                t.setText(t.getControlText().substring(t.getRangeStart(), t.getRangeEnd()));


        if (t.isAdded()) {
            if (t.getControlText().contains(".")) {
                if (t.getText().matches("[^0-9]")) {
                    t.setText("");
                }
            }


            else if (t.getText().matches("[^0-9.]")) {
                t.setText("");
            }
        }

        return t;
    }
};


spiKolicina.getEditor().setTextFormatter(new TextFormatter<>(filter));

如何更改正则表达式以允许我在微调器文本字段中输入负双数?

此外,当微调器文本字段为空并按向上或向下btn时,它会给出nullPointException,我希望它转到某个默认值

1 个答案:

答案 0 :(得分:1)

我通常会发现从更改中检查生成的文本会更容易;如果正常则返回“as-is”更改,否则返回null。在这里,您希望生成的文本是可选的负号,零个或多个数字,选项小数点分隔符,以及零个或多个数字。 (注意,这允许任何有效的浮点数,空字符串,或负号或数字分隔符本身。)

所以对于过滤器:

    UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {

        @Override
        public TextFormatter.Change apply(TextFormatter.Change t) {

            String newText = t.getControlNewText() ;
            if (newText.matches("-?[0-9]*\\.?[0-9]*")) {
                return t ;
            }
            return null ;
        }
    };

您还可以定义转换器,您可以将其与微调器本身和作为微调器编辑器的文本字段一起使用。这只需要将字符串解析为double,但应该处理-.-.的特殊情况。所以:

    StringConverter<Double> converter = new StringConverter<Double>() {

        @Override
        public String toString(Double object) {
            return object.toString() ;
        }

        @Override
        public Double fromString(String string) {
            if (string.isEmpty() || ".".equals(string) || "-".equals(string) || "-.".equals(string)) {
                return 0.0 ;
            } else {
                return new Double(string);
            }
        }

    };

然后做

    svf.setConverter(converter);

    spinner.getEditor().setTextFormatter(new TextFormatter<>(converter, 0.0, filter));

此转换器将正确处理将空字符串等解释为0.0,因此当编辑器处于该状态时尝试递增或递减时将避免异常。

SSCCE:

import java.util.function.UnaryOperator;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class SpinnerTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        SpinnerValueFactory<Double> svf = new SpinnerValueFactory.DoubleSpinnerValueFactory(-500,500,1,0.5);
        Spinner<Double> spinner = new Spinner<>();
        spinner.setValueFactory(svf);
        spinner.setEditable(true);


        UnaryOperator<TextFormatter.Change> filter = new UnaryOperator<TextFormatter.Change>() {

            @Override
            public TextFormatter.Change apply(TextFormatter.Change t) {

                String newText = t.getControlNewText() ;
                if (newText.matches("-?[0-9]*\\.?[0-9]*")) {
                    return t ;
                }
                return null ;
            }
        };

        StringConverter<Double> converter = new StringConverter<Double>() {

            @Override
            public String toString(Double object) {
                return object.toString() ;
            }

            @Override
            public Double fromString(String string) {
                if (string.isEmpty() || ".".equals(string) || "-".equals(string) || "-.".equals(string)) {
                    return 0.0 ;
                } else {
                    return new Double(string);
                }
            }

        };

        svf.setConverter(converter);

        spinner.getEditor().setTextFormatter(new TextFormatter<>(converter, 0.0, filter));

        StackPane root = new StackPane(spinner);
        primaryStage.setScene(new Scene(root, 180, 80));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}