核心问题:如果绑定属性在声明绑定属性的initialize()
方法之外更新,则binding
对象无效侦听器不会触发。
以JavaFX UI控制器类中声明的initialize()
方法为例:
@FXML
private void initialize() {
final StringProperty stringProperty = textField.textProperty();
stringProperty.addListener(
(observable, oldValue, newValue) -> System.out.println("stringProperty value: " + newValue));
Bindings.createStringBinding(() -> "PREFIX - " + stringProperty.getValue(), stringProperty).addListener(
(observable, oldValue, newValue) -> System.out.println("StringBinding value: " + newValue));
// Editing stringProperty value inside initialize() method
stringProperty.setValue("u");
stringProperty.setValue("ua");
stringProperty.setValue("ua");
stringProperty.setValue("uaa");
}
如您所见,我声明了一个StringBinding
,它依赖于TextField的text属性,称为StringProperty
,并声明了一个ChangeListener
,它在StringBinding
无效时请求计算。
如果我在initialize方法中编辑StringProperty
值,则会触发StringProperty
和StringBinding
更改侦听器,而如果我从UI编辑StringProperty
值,则只会触发StringBinding
更改侦听器。
有人能解释一下为什么会这样吗?
由于不存在对bindings.createStringBinding
创建的StringBinding
的强引用,因此它最终将被垃圾回收。一旦发生这种情况,您添加的侦听器将与它一起被垃圾回收。
我不认为这是重点,因为绑定
对象通过InvalidationListener
侦听它们的依赖项(Observable
对象),并且Obsevable.AddListener(InvalidationListener)
文档指出,“Observable存储对侦听器的强引用,这将防止侦听器被垃圾收集,并可能导致内存泄漏。”
这是正确的,但请看XXXBinding
类使用的侦听器实现:
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.binding;
import java.lang.ref.WeakReference;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.WeakListener;
import javafx.beans.binding.Binding;
public class BindingHelperObserver implements InvalidationListener, WeakListener {
private final WeakReference<Binding<?>> ref;
public BindingHelperObserver(Binding<?> binding) {
if (binding == null) {
throw new NullPointerException("Binding has to be specified.");
}
ref = new WeakReference<Binding<?>>(binding);
}
@Override
public void invalidated(Observable observable) {
final Binding<?> binding = ref.get();
if (binding == null) {
observable.removeListener(this);
} else {
binding.invalidate();
}
}
@Override
public boolean wasGarbageCollected() {
return ref.get() == null;
}
}
如您所见,添加到依赖项的侦听器实例(即可观察
)是WeakListener
,并且只维护对绑定
的弱引用。这允许对绑定
进行垃圾回收,即使它没有被正确释放。这样做是为了在绑定
超出范围但可观察
没有超出范围的情况下防止内存泄漏。
换句话说,Observable
维护对InvalidationListener
的强引用,但InvalidationListener
维护对绑定
的弱引用。
这种行为记录在“远程”位置,包括属性#bind(ObservableValue)
:
为此属性
创建单向绑定。
注意,JavaFX的所有绑定调用都是通过弱监听器实现的。这意味着绑定属性可以被垃圾回收并停止更新。
问题内容: 我昨天在JavaFX中构建了一个小应用程序。我想在Controller类中获取应用程序的场景。每次尝试在控制器类中获取场景时,都会出错。我可以在Controller类的Button上设置OnKeyPressed方法,效果很好。但是,只有在选择Button后,它才能正常工作。我只能在Main类方法replaceSceneContent中获得场景。我已经读过这个问题,但是我在initial
我昨天在JavaFX中构建了一个小应用程序。我想在Controller类中获取应用程序的场景。每次我试图在控制器类中获取场景时,我都会出错。我可以在Controller类中的Button上设置OnKeyPested-method,工作正常。但是只有当按钮被选中时,它才工作正常...我可以只在Main类方法replace eSceneContent中获取场景。我已经读过这个问题了,但是我在初始化方法
问题内容: 我使用Angular组件(this的第一个示例)。当我在组件中绑定对象时,可以在模板中访问它,但不能在控制器中访问它。 js: 的HTML: 模板html(在这里有效): 错误: ReferenceError:未定义英雄 Plunker:https://plnkr.co/edit/U9CJLs6jgrlsZH6tUdr0 问题答案: 您将在上下文中获得价值 虽然以上行不通。因为它不会在
在此代码中: } 我不明白为什么它在initialise()中有一个值,但在start中却是空的。调试时,很明显,initialize()是由FXMLLOader从start()内部调用的 我本来打算发布fxml,但它似乎不起作用,正如预览中没有显示的那样。无论如何,它是一个真正的基本文件,一个BordePane和一个工具栏。 有线索吗?
我正在我的一个项目中使用自动装配。在控制器中运行良好,但我需要在其他类中使用相同的自动装配对象,该类用作石英的任务类。自动装配在那里不起作用。 我尝试了下面列出的这段代码,但没有成功。在所有尝试中,它都为获取。 请提出解决方案,谢谢。
本文向大家介绍Laravel框架路由和控制器的绑定操作方法,包括了Laravel框架路由和控制器的绑定操作方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Laravel框架路由和控制器的绑定操作方法。分享给大家供大家参考,具体如下: 路由和控制器的关系 路由文件地址在\app\Http\routes.php,我们来看两种不同的路由。 以上均为绑定匿名函数的路由,虽然可以返回视图,也可以