Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX中现有javabean的异步绑定_Java_Asynchronous_Javafx_Javafx 8 - Fatal编程技术网

JavaFX中现有javabean的异步绑定

JavaFX中现有javabean的异步绑定,java,asynchronous,javafx,javafx-8,Java,Asynchronous,Javafx,Javafx 8,我正在将现有的Swing项目迁移到JavaFX。该项目有许多使用PropertyChangeSupport的旧式JavaBean,这些都是在各种后台线程上更新的 我想使用bean适配器(javafx.beans.property.adapter)连接新视图。但是,这会失败,因为模型没有在FX应用程序线程上更新 理想情况下,我希望保留更新模型的现有代码,而不是将其包装在Platform.runLater中 到目前为止,我的解决方案是使用我自己的类AsyncBinding,该类接受由beans适

我正在将现有的Swing项目迁移到JavaFX。该项目有许多使用PropertyChangeSupport的旧式JavaBean,这些都是在各种后台线程上更新的

  • 我想使用bean适配器(javafx.beans.property.adapter)连接新视图。但是,这会失败,因为模型没有在FX应用程序线程上更新

  • 理想情况下,我希望保留更新模型的现有代码,而不是将其包装在Platform.runLater中

到目前为止,我的解决方案是使用我自己的类AsyncBinding,该类接受由beans适配器创建的现有ObservalEvalue,侦听它,并在适当的线程上触发更改,但是如果要在任何地方添加它,都会让人觉得很麻烦

  • 有没有什么我不知道的内在方法
  • 我可以采取更干净的方法吗
典型视图 典型豆
到目前为止,我的最佳解决方案

  • 创建一个实用程序类AsyncBinding,它代理ObservalEvalue
  • 监听底层的可观察对象,在正确的线程上发送给侦听器
用法 异步绑定
公共类AsyncBinding实现ObservalEvalue{
私人可观察价值;
私有失效监听器失效监听器;
私有交换侦听器交换侦听器;
私有列表无效侦听器=新建ArrayList(
1);

private ListRelated(但不同)问题:。执行了类似的操作,但实现了完整的属性:
public class AsyncIssue extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        FooBean bean = new FooBean();
        TextField field = new TextField();

        field.textProperty().bind(
                JavaBeanIntegerPropertyBuilder.create().bean(bean).name("x")
                        .build().asString("%03d"));
        primaryStage.setScene(new Scene(new VBox(field)));
        primaryStage.show();

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> {
            try {
                // simulate background work
                bean.setX(bean.getX() + 1);
            } catch (Throwable e) {
                // Executors consume exception by default
                e.printStackTrace();
                throw e;
            }
        }, 0, 1, TimeUnit.SECONDS);

    }
}
public class FooBean {
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    public static final String PROPERTY_X = "x";
    private int x;
    public int getX() {
        return x;
    }
    public void setX(int x) {
        int oldValue = this.x;
        this.x = x;
        pcs.firePropertyChange(PROPERTY_X, oldValue, x);
    }
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);
    }
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcs.removePropertyChangeListener(listener);
    }
}
field.textProperty().bind(
        AsyncBinding.bind(JavaBeanIntegerPropertyBuilder.create()
                .bean(bean).name("x").build().asString("%03d")));
public class AsyncBinding<T> implements ObservableValue<T> {

    private ObservableValue<T> value;
    private InvalidationListener invalidationListener;
    private ChangeListener<T> changeListener;
    private List<InvalidationListener> invalidationListeners = new ArrayList<InvalidationListener>(
            1);
    private List<ChangeListener<? super T>> changeListeners = new ArrayList<ChangeListener<? super T>>(
            1);

    public static <T> ObservableValue<T> bind(ObservableValue<T> toWrap) {
        return new AsyncBinding<T>(toWrap);
    }

    private AsyncBinding(ObservableValue<T> value) {
        this.value = value;
        invalidationListener = new InvalidationListener() {
            @Override
            public void invalidated(Observable observable) {
                Runnable fire = () -> {
                    synchronized (invalidationListeners) {
                        for (InvalidationListener listener : invalidationListeners) {
                            listener.invalidated(observable);
                        }
                    }
                };
                if (Platform.isFxApplicationThread()) {
                    fire.run();
                } else {
                    Platform.runLater(fire);
                }
            }
        };
        value.addListener(invalidationListener);

        changeListener = new ChangeListener<T>() {
            @Override
            public void changed(ObservableValue<? extends T> observable,
                    T oldValue, T newValue) {
                Runnable fire = () -> {
                    synchronized (changeListeners) {
                        for (ChangeListener<? super T> listener : changeListeners) {
                            listener.changed(observable, oldValue, newValue);
                        }
                    }
                };
                if (Platform.isFxApplicationThread()) {
                    fire.run();
                } else {
                    Platform.runLater(fire);
                }
            }
        };

        value.addListener(changeListener);
    }

    @Override
    public void addListener(InvalidationListener listener) {
        invalidationListeners.add(listener);
    }

    @Override
    public void removeListener(InvalidationListener listener) {
        invalidationListeners.remove(listener);
    }

    @Override
    public void addListener(ChangeListener<? super T> listener) {
        changeListeners.add(listener);
    }

    @Override
    public void removeListener(ChangeListener<? super T> listener) {
        changeListeners.remove(listener);
    }

    @Override
    public T getValue() {
        return value.getValue();
    }
}