独立的JavaFX属性实现?

问题描述 投票:5回答:1

Java FX properties是一个很好的API,允许开发者创建属性,而不是使用标准的getset方法语义。它还增加了对变化的订阅,属性表达式对基本类型和集合的支持。虽然属性在C#中作为语言的一部分存在,但这些属性只在JavaFX容器内可用。即,如果你 听风就是雨,你会遇到 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 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)
java reflection properties javafx-2 javafx
1个回答
6
投票

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

解释

在JavaFX应用线程上运行监听器代码,只有当变更监听器或绑定影响到以下属性时才需要。节点 场景图中的节点。

一个应用程序必须在JavaFX应用程序线程上将节点附加到一个场景,并修改已经附加到场景的节点。

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

示例

神谕 JavaFX属性和绑定教程 演示在没有使用其他JavaFX组件和没有JavaFX应用线程的程序中使用JavaFX属性。

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

谢谢,这个教程中的例子对我来说很有用。但是我试着监听ObservableList集合,得到了这个异常。我是不是做错了什么?

你是做错了什么。

我试着在Java 8上运行你在问题中添加的示例代码,错误信息更加明确。

"main "线程出现异常 java.lang.IllegalStateException: Invalid Change state: next() Invalid Change state: next() must be called before inspecting the Change.

当你添加一个 change.next() 调用,你的测试应用程序的功能就会像你所期望的那样。

的javadoc。change.next() 改为。

转到下一个变化。在初始状态下是无效的一个需要在调用其他方法之前调用next()。第一次调用next()将使这个对象代表第一个变化。

工作示例代码。

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]
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.