【发布时间】:2014-12-18 12:42:44
【问题描述】:
假设我们有一个没有设置日期的 DatePicker。 因此,如果用户想要输入日期,他需要输入整个日期,包括斜线: 2014 年 10 月 11 日
如果用户在输入数字时可以自动包含斜线(输入 10112014 会正确设置日期),那就太好了。
另一件事是,如果日期选择器上已经设置了一个日期(10/11/2014),并且用户想要输入另一个日期(01/11/2014),那么他将光标放在开头文本并键入日期。结果将类似于 01/11/201410/11/2014。如果在日期选择器的字段上输入时,它会自动进入插入模式,这样用户输入的日期会覆盖原始日期。
有没有办法做这些事情?
--- 更新---
感谢 José Pereda,我找到了解决方案。我得到了他的代码并做了一些改动:
public static void enhanceDatePickers(DatePicker... datePickers) {
for (DatePicker datePicker : datePickers) {
datePicker.setConverter(new StringConverter<LocalDate>() {
private final DateTimeFormatter fastFormatter1 = DateTimeFormatter.ofPattern("ddMMuuuu");
private final DateTimeFormatter fastFormatter2 = DateTimeFormatter.ofPattern("d/M/u");
private final DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
@Override
public String toString(LocalDate object) {
return object.format(defaultFormatter);
}
@Override
public LocalDate fromString(String string) {
try{ return LocalDate.parse(string, fastFormatter1); } catch(DateTimeParseException ignored){}
try{ return LocalDate.parse(string, fastFormatter2); } catch(DateTimeParseException ignored){}
return LocalDate.parse(string, defaultFormatter);
}
});
TextField textField = datePicker.getEditor();
textField.addEventHandler(KeyEvent.KEY_TYPED, event -> {
if (!"0123456789/".contains(event.getCharacter())) {
return;
}
if ("/".equals(event.getCharacter()) && (textField.getText().isEmpty() || textField.getText().charAt(textField.getCaretPosition()-1)=='/')) {
//If the users types slash again after it has been added, cancels it.
System.out.println("Cancelando o bagulho!");
event.consume();
}
textField.selectForward();
if (!event.getCharacter().equals("/") && textField.getSelectedText().equals("/")) {
textField.cut();
textField.selectForward();
}
textField.cut();
Platform.runLater(() -> {
String textUntilHere = textField.getText(0, textField.getCaretPosition());
if (textUntilHere.matches("\\d\\d") || textUntilHere.matches("\\d\\d/\\d\\d")) {
String textAfterHere = "";
try { textAfterHere = textField.getText(textField.getCaretPosition()+1, textField.getText().length()); } catch (Exception ignored) {}
int caretPosition = textField.getCaretPosition();
textField.setText(textUntilHere + "/" + textAfterHere);
textField.positionCaret(caretPosition+1);
}
});
});
}
} 然后,为了“增强” DatePicker,我只需调用此方法,将所有我想要的 datePicker 实例作为参数传递
【问题讨论】:
-
有没有办法在多个字段上重用这段代码?还是我必须在任何领域重复同样的事情?
-
当然,只要这样称呼它:
enhanceDatePickers(myFirstDatePicker, anotherDatePicker, andSoOn)。这是有效的,因为该方法使用可变参数(Datepicker... datePickers),它接受你希望传递多少该类型的参数...... -
谢谢,这对我帮助很大,并为我节省了很多代码行。我从 JavaFX 开始,所以我有点迷茫。
-
toString() 应该处理 null LocalDate(如果没有设置日期,则为 NPE)