java - 独立的 JavaFX 属性实现?

标签 java reflection properties javafx-2 javafx

Java FX 属性是一个很好的 API,允许开发人员创建属性而不是使用标准的 get/set 方法语义。它还添加了对更改的订阅、对基本类型和集合的属性表达式支持。尽管属性作为语言的一部分存在于 C# 中,但这些属性仅在 JavaFX 容器内可用。 IE。如果你try listening to changes ,您将遇到一个 IllegalStateException 提示您需要在主 JavaFX 线程中运行您的监听器代码。

那么 Java 世界的其他部分是否有可用的替代方案?

更新

这是一个 IllegalStateException 的例子。我是否滥用了 JavaFX API?

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("s1");
        list.add("s2");

        ObservableList<String> observableList = FXCollections.observableList(list);
        observableList.addListener(new ListChangeListener<String>() {
            @Override
            public void onChanged(Change<? extends String> change) {
                System.out.println("added: " + change.getAddedSubList());
            }
        });

        observableList.add("s3");
    }
}

异常(exception):

Exception in thread "main" java.lang.IllegalStateException
    at com.sun.javafx.collections.NonIterableChange.checkState(NonIterableChange.java:101)
    at com.sun.javafx.collections.NonIterableChange.getPermutation(NonIterableChange.java:81)
    at javafx.collections.ListChangeListener$Change.wasPermutated(ListChangeListener.java:156)
    at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:212)
    at Test$1.onChanged(Test.java:23)
    at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:134)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48)
    at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:97)
    at com.sun.javafx.collections.ObservableListWrapper.add(ObservableListWrapper.java:154)
    at com.sun.javafx.collections.ObservableListWrapper.add(ObservableListWrapper.java:144)
    at Test.main(Test.java:27)

最佳答案

回答

JavaFX 属性可以独立于 JavaFX 系统的其余部分使用,并且不要求不影响 Activity JavaFX 场景图的对象的属性在 JavaFX 应用程序线程上运行其监听器代码。

解释

仅当更改监听器或绑定(bind)影响 Nodes 的属性时,才需要在 JavaFX 应用程序线程上运行监听器代码。在场景图中:

An application must attach nodes to a Scene, and modify nodes that are already attached to a Scene, on the JavaFX Application Thread.

您可以编写使用 JavaFX 属性且没有节点或场景图的 Java 程序。您可以为与场景图没有交互的对象提供属性并更改可在非 JavaFX 线程上执行的监听器。

示例

神谕 JavaFX properties and binding tutorial演示在不使用其他 JavaFX 组件且没有 JavaFX 应用程序线程的程序中使用 JavaFX 属性。

基于评论中问题的附加示例

Thanks, examples in this tutorial work for me. However I tried listening to the ObservableList collection and got this exception. Am I doing something wrong?

你做错了什么。

我尝试在 Java 8 上运行您添加到问题中的示例代码,错误消息更加明确:

Exception in thread "main" java.lang.IllegalStateException: Invalid Change state: next() must be called before inspecting the Change.

当你添加 change.next()调用,您的测试应用程序将按预期运行。

change.next() 的 javadoc 如下:

Go to the next change. In initial state is invalid a require a call to next() before calling other methods. The first next() call will make this object represent the first change.

工作示例代码:

import javafx.collections.*;
import java.util.*;

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("s1");
        list.add("s2");

        ObservableList<String> observableList = FXCollections.observableList(list);
        observableList.addListener(new ListChangeListener<String>() {
            @Override
            public void onChanged(Change<? extends String> change) {
                while (change.next()) {
                    System.out.println("added: " + change.getAddedSubList());
                }
            }
        });

        observableList.add("s3");
    }
}

示例代码的输出:

added: [s3]

关于java - 独立的 JavaFX 属性实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19549091/

相关文章:

java - 多线程中不需要的输出

java - 当设备从纵向/横向旋转时,如何使 ImageView 旋转图像?

java - 当原始 resultSet 从方法返回到新对象时会发生什么?

java - 使用socket连接gmail并发送gmail,但不起作用

c# - 单元测试动态加载代码

spring-boot - 如何让 Intellij 识别 application.yml 中的属性

ios - @synthesize 语法,带和不带等号

reflection - 区分同一包中具有相同名称的结构

scala - Scala反射,查找并实例化具有给定注释的所有类

c# - C# 中的内部属性 setter