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,我希望它转到某个默认值
答案 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);
}
}