JavaFX Cell失焦取消编辑逻辑:为何内部控件获焦不触发cancelEdit?
问题
查看javafx.scene.control.Cell中的这段代码:
super.focusedProperty().addListener(new InvalidationListener() { @Override public void invalidated(Observable property) { pseudoClassStateChanged(PSEUDO_CLASS_FOCUSED, isFocused()); // TODO is this necessary?? // The user has shifted focus, so we should cancel the editing on this cell if (!isFocused() && isEditing()) { cancelEdit(); } } });
这段代码逻辑是当Cell失去焦点时取消编辑,但实际使用中,可编辑Cell内部的TextField获得焦点时,我们依然能正常输入,并不会触发cancelEdit()。明明此时TextField拥有焦点,按代码逻辑Cell应该失去焦点才对,这是为什么?背后的机制是什么?
回答
这是JavaFX焦点机制在Cell编辑场景下的特殊设计导致的:
- 当Cell进入编辑状态后,即使内部子控件(比如TextField)获得了实际输入焦点,Cell自身的
isFocused()方法依然会返回true。 - 在JavaFX的焦点体系中,容器类控件如果包含了当前拥有焦点的子控件,会保持自己的
focusedProperty处于激活状态,以此标识自己是焦点所在的上下文容器。 - 只有当焦点完全离开Cell的整个控件树(比如点击Cell外部的其他控件)时,Cell的
isFocused()才会变为false,这时才会触发代码里的cancelEdit()逻辑。
这样设计的目的是为了避免用户在编辑Cell内部控件时,误触发取消编辑的操作,保证编辑流程的连贯性。
内容的提问来源于stack exchange,提问作者SilverCube
相关产品推荐
相关产品推荐

