Java 8 DatePicker和可编辑的ComboBox行为在8u51和8u60之间更改 [英] Java 8 DatePicker and editable ComboBox behavior change between 8u51 and 8u60

查看:256
本文介绍了Java 8 DatePicker和可编辑的ComboBox行为在8u51和8u60之间更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经搜索过这个论坛和网络,没有发现任何与这个问题相关的东西,所以我觉得不得不在这里发布这个问题...



我们有观察到在Java 8 u51和u60发行版之间的JavaFX8 DatePicker和可编辑的ComboBox元素的功能方面的主要行为变化。



在u51下运行,您可以在DatePicker中输入日期,如12/30/1970,并在下一个U.I.元素和数据将自动保存,如果日期绑定到年龄计算TextField,则年龄将更新。对于可编辑的ComboBox元素也是如此。但是在u60下运行时,用户必须在DatePicker或可编辑的ComboBox上的数据更改后按 ENTER ,否则数据不会保存。翻译到下一个U.I.元素或鼠标单击。



所以我的问题是,有没有人注意到这个关键的行为变化,如果这样感觉这是u60中的一个错误或者一个方向Oracle故意采取某种原因?



最后是一个工作,也许以一个事件处理程序的形式可以在丢失这些元素的焦点之前模拟ENTER键?



提前感谢您的考虑。


< comboBoxPopupControl的实现(实际上是所有类似combo的控件的相关基础皮肤)改变了u40和u60之间的某处:textField - 包括所有内部布线 - 被从混凝土皮肤(像fi ComboBoxListViewSkin)拉到基地。



除了这个纯粹的技术性,ENTER的处理程序已更改:




  • :将组合接收到的所有keyEvent转发到
    textField

  • is:handle并使用基本外观中的ENTER。此实现手动将字段中的输入文本提交到组合的值。



一个脏的(!因为需要访问内部包com.sun.whatever.skin)到focusProperty并调用commit方法,例如:

  public class MyComboSkin< T& extends ComboBoxListViewSkin< T> {

public MyComboSkin(ComboBox< T> comboBox){
super(comboBox);
getSkinnable()。focusedProperty()。addListener((source,ov,nv) - > {
if(!nv){
setTextFromTextFieldIntoComboBoxValue();
}
});
}
}

应用自定义外观的优点是通过添加styleSheet应用一次每个场景:

  //在css中定义皮肤mycomboskin.css 
。组合框{
-fx-skin:mypackage.MyComboSkin;
}

//适用于场景
String commitCSS = getClass()。getResource(mycomboskin.css)。toExternalForm();
scene.getStylesheets()。add(commitCSS);

//或应用程序(再次使用内部api ;-)
StyleManager.getInstance()。addUserAgentStylesheet(commitCSS)

BTW:我认为在核心的新实现是相当肮脏的 - 所有keyBindings 应该在XXBehaviour或者 - 级别的孩子(像textField本身)。

更新

/ p>

另一种方法是在组合的编辑器上使用TextFormatter,然后将它的valueProperty与组合的valueProperty进行绑定,如下所示:

  TextFormatter formatter = 
new TextFormatter<>(comboBox.getConverter());
comboBox.getEditor()。setTextFormatter(formatter);
comboBox.valueProperty()。bindBidirectional(formatter.valueProperty());

这样工作,因为格式化程序保证提交 - aka:将自己的值同步到textField的文本 - on focusLost(更多细节类似于 Spinner 的要求)请注意,此方法的副作用是文本是承诺在导航内的下拉,这可能是或不可接受的,取决于上下文。此外,它比使用TextFormatter更多的实验,而不是专门的解决方法 - 需要相同的每个实例manistution作为解决方案在 Scott的其他解决方案






错误是固定在jdk9和backported 8u72,所以任何解决方法希望是短暂的,选择一次或其他,去脏如有必要可能是一个问题的味道: )


We have searched this forum and the web extensively and have not found anything related to this issue so I felt compelled to post this question here...

We have observed a major behavioral change with regard to the functionality of both the JavaFX8 DatePicker and editable ComboBox elements between the release of Java 8 u51 and u60.

Running under u51 you could enter a date such as 12/30/1970 in a DatePicker and tab to the next U.I. element and the data would automatically be saved and if the date was bound to an age calculation TextField the age would update. The same for editable ComboBox elements. However running under u60 the user MUST press ENTER after a data change on either the DatePicker or editable ComboBox, otherwise the data is not saved. Tabbing to the next U.I. element or a mouse click outside of the U.I. element and the data is lost, replaced by what was previously saved in that element prior to the edit.

So my question is, has anyone else noticed this critical behavioral change and if so feel this is a bug in u60 or a direction Oracle is deliberately taking for some reason?

Finally is there a work around, perhaps in the form of an event handler that can simulate an 'ENTER' key press prior to loss of focus of these elements?

Thank you in advance for your consideration.

解决方案

The implementation of ComboBoxPopupControl (which in fact is the relevant base skin for all combo-like controls) changed somewhere between u40 and u60: the textField - including all internal wirings - was pulled up from the concrete skins (like f.i. ComboBoxListViewSkin) into the base.

Along with this mere technicality the handler for ENTER was changed:

  • was: forward all keyEvents that are received by the combo to the textField
  • is: handle and consume the ENTER in the base skin. This implementation manually commits the input text from the field to the combo's value.

A dirty (!because needs access to the internal package com.sun.whatever.skin) way out is a custom skin that listens to the focusProperty and calls the commit method, something like:

public class MyComboSkin<T> extends ComboBoxListViewSkin<T> {

    public MyComboSkin(ComboBox<T> comboBox) {
        super(comboBox);
        getSkinnable().focusedProperty().addListener((source, ov, nv) -> {
            if (!nv) {
                setTextFromTextFieldIntoComboBoxValue();
            }
        });
    }
}

The advantage of applying a custom skin is that it can be applied once per scene by adding a styleSheet:

// defining the skin in a css mycomboskin.css 
.combo-box {
    -fx-skin: "mypackage.MyComboSkin";
}

// apply to a scene
String commitCSS = getClass().getResource("mycomboskin.css").toExternalForm();
scene.getStylesheets().add(commitCSS);

// or to the application (using internal api again ;-)
StyleManager.getInstance().addUserAgentStylesheet(commitCSS) 

BTW: I think the new implementation in core is rather dirty - all keyBindings should be handled either in the XXBehaviour or alternatively left to the lower-level children (like the textField itself). The change in behaviour (verified against 8u45) might be considered a bug.


Update

An alternative trick is using a TextFormatter on the combo's editor and bidi-bind it's valueProperty to the combo's valueProperty, something like:

TextFormatter formatter = 
        new TextFormatter<>(comboBox.getConverter());
comboBox.getEditor().setTextFormatter(formatter);
comboBox.valueProperty().bindBidirectional(formatter.valueProperty());

This does work because the formatter guarantees to commit - aka: sync its own value to the textField's text - on focusLost (more details in a similar requirement for Spinner) Note that a side-effect of this approach is that the text is committed on navigation inside the drop-down which might or not be acceptable depending on context. Also, it's more experimenting with TextFormatters than a dedicated workaround - needs the same per-instance manipalution as the workaround in the other solution by Scott.


The bug is fixed in jdk9 and backported 8u72, so any workaround hopefully is short-lived, choosing the once or other and going as dirty as necessary is likely a matter of taste :-)

这篇关于Java 8 DatePicker和可编辑的ComboBox行为在8u51和8u60之间更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆