Jam*_*zba 24 java javafx spinner javafx-8
似乎Spinner控件在用户明确按Enter键之前不会更新手动键入的值.因此,他们可以键入一个值(不按回车键)退出控件,并提交表单,并且微调器中显示的值不是微调器的值,它是旧值.
我的想法是为丢失的焦点事件添加一个监听器,但我看不到一种获取输入值的方法?
spinner.focusedProperty().addListener((observable, oldValue, newValue) ->
{
//if focus lost
if(!newValue)
{
//somehow get the text the user typed in?
}
});
Run Code Online (Sandbox Code Playgroud)
这是奇怪的行为,它似乎违反了GUI微调控件的惯例.
kle*_*tra 29
不幸的是,Spinner的行为并不像预期的那样:在大多数操作系统中,它应该在焦点丢失时提交编辑后的值.更不幸的是,它没有提供任何配置选项来轻松使其按预期运行.
因此,我们必须手动将侦听器中的值提交给focusedProperty.从好的方面来看,Spinner已经有代码这样做 - 它是私有的,但是,我们必须对它进行c&p
/**
* c&p from Spinner
*/
private <T> void commitEditorText(Spinner<T> spinner) {
if (!spinner.isEditable()) return;
String text = spinner.getEditor().getText();
SpinnerValueFactory<T> valueFactory = spinner.getValueFactory();
if (valueFactory != null) {
StringConverter<T> converter = valueFactory.getConverter();
if (converter != null) {
T value = converter.fromString(text);
valueFactory.setValue(value);
}
}
}
// useage in client code
spinner.focusedProperty().addListener((s, ov, nv) -> {
if (nv) return;
//intuitive method on textField, has no effect, though
//spinner.getEditor().commitValue();
commitEditorText(spinner);
});
Run Code Online (Sandbox Code Playgroud)
请注意,有一种方法
textField.commitValue()
Run Code Online (Sandbox Code Playgroud)
我原本期望......嗯......提交价值,这没有效果.实现(final!)以更新textFormatter的值(如果可用).即使您使用textFormatter进行验证,也无法在Spinner中工作.可能是一些内部听众丢失或者旋转器还没有更新到相对较新的api - 但是没有挖掘.
更新
虽然有点绕多用的TextFormatter打我注意到一个格式化的保证承诺的focusLost:
当控件失去焦点或提交时,该值会更新(仅限TextField)
这确实有效,因为我们可以在格式化程序的valueProperty中添加一个监听器,以便在提交值时得到通知:
TextField field = new TextField();
TextFormatter fieldFormatter = new TextFormatter(
TextFormatter.IDENTITY_STRING_CONVERTER, "initial");
field.setTextFormatter(fieldFormatter);
fieldFormatter.valueProperty().addListener((s, ov, nv) -> {
// do stuff that needs to be done on commit
} );
Run Code Online (Sandbox Code Playgroud)
提交的触发器:
回到微调器:我们可以使用formatter的值的commit-on-focusLost行为来强制提交spinnerFactory的值.就像是
// normal setup of spinner
SpinnerValueFactory factory = new IntegerSpinnerValueFactory(0, 10000, 0);
spinner.setValueFactory(factory);
spinner.setEditable(true);
// hook in a formatter with the same properties as the factory
TextFormatter formatter = new TextFormatter(factory.getConverter(), factory.getValue());
spinner.getEditor().setTextFormatter(formatter);
// bidi-bind the values
factory.valueProperty().bindBidirectional(formatter.valueProperty());
Run Code Online (Sandbox Code Playgroud)
需要注意的是编辑(无论是打字或以编程方式替换/添加/粘贴文本),并没有引发提交-所以这不能被使用,如果提交上文本变化是必要的.
Ser*_*gio 25
@kleopatra走向正确的方向,但复制粘贴解决方案感觉很尴尬,基于TextFormatter的解决方案根本不适合我.所以这里是一个较短的,它迫使Spinner根据需要调用它的私有commitEditorText():
spinner.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
spinner.increment(0); // won't change value, but will commit editor
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9574 次 |
| 最近记录: |