java - 在 JavaFX 中对服务中的值进行数据绑定(bind)时出现空指针异常

标签 java multithreading javafx data-binding

我正在尝试获取一个简单的数据绑定(bind)示例,以更好地理解 JavaFX 服务类的使用,并可能将其合并到我正在开发的项目中,但是我无法绑定(bind)应该从中返回的值服务(整数)到调用该服务的类中的整数。

我已检查调试器并确认任务实际上正在返回值,但我不断收到空指针异常,指出我对于执行绑定(bind)的代码行“无法绑定(bind)到 null”,但是其他属性我绑定(bind)的似乎工作正常

主类

public class Main extends Application {

    private Service<ObservableValue<Integer>> service;

           @Override
           public void start(Stage primaryStage){


            /**********************************
             * Start of Multi-Threading Logic
             **********************************/
            service = new EmployeeService();

            ObjectProperty<Integer> size = new SimpleObjectProperty<>(0);

            size.bind(service.getValue()); // Null Pointer Exception Cause

            progressBar.progressProperty().bind(service.progressProperty());
            progressBar.visibleProperty().bind(service.runningProperty());

            progressLabel.textProperty().bind(service.messageProperty());
            progressLabel.setVisible(false);


            /*************************************************************
             * Start Task Button Event Handler
             * 
             * If the service state is succeeded or cancelled
             * then the service must first be reset before starting
             * 
             * if the service state is ready then start the service
             * 
             * if the service state is something other than the above 
             * like running or failed, then do nothing
             *************************************************************/
            startTaskButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {

                    if(service.getState() == Service.State.SUCCEEDED
                            || service.getState() == Service.State.CANCELLED) {
                        service.reset();
                        service.start();
                    }else if(service.getState() == Service.State.READY) {
                        service.start();
                    }else {
                        System.out.println("Not doing anything");
                    }
                }   
            });


            /*************************************************************
             * Cancel Task Button Event Handler
             * 
             * The service should only be canceled if it is currently
             * running, else do nothing. 
             *************************************************************/
            cancelButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    if(service.getState() == Service.State.RUNNING) {
                        service.cancel();
                    }
                }
            });


服务实现类

/*************************************************************
 * Custom Service Impl class that creates the DisplayDataTask
 *************************************************************/
class EmployeeService extends Service<ObservableValue<Integer>>{

    @Override
    protected Task<ObservableValue<Integer>> createTask() {
        return new DisplayDataTask();
    }
}


任务实现类

/*************************************************************
 * Custom Task Impl class that creates a basic list
 * and returns the length of the list in the call method
 *************************************************************/

class DisplayDataTask extends Task<ObservableValue<Integer>> {

    @Override
    protected ObservableValue<Integer> call() throws Exception {

        int randomNum = 71890;

        Thread.sleep(5000); // Sleep for 5 seconds to simulate a task 

        ObjectProperty<Integer> size = new SimpleIntegerProperty(randomNum).asObject();
        return size;
    }

    @Override
    protected void cancelled() {
        super.cancelled();

        updateMessage("Operation Cancelled");
        System.out.println("The " + this.getClass().getSimpleName() + " has been canceled.");
    }   
}   

最佳答案

Service.getValue()返回服务的当前值,在服务完成之前,返回 null。

您几乎肯定不希望服务返回 ObservableValue<Integer>在这里,您希望它返回实际的 Integer 。因此将服务重写为:

class EmployeeService extends Service<Integer>{

    @Override
    protected Task<Integer> createTask() {
        return new DisplayDataTask();
    }
}

class DisplayDataTask extends Task<Integer> {

    @Override
    protected Integer call() throws Exception {

        int randomNum = 71890;

        Thread.sleep(5000); // Sleep for 5 seconds to simulate a task 

        Integer size = randomNum ;
        return size;
    }

    @Override
    protected void cancelled() {
        super.cancelled();

        updateMessage("Operation Cancelled");
        System.out.println("The " + this.getClass().getSimpleName() + " has been canceled.");
    }   
} 

然后你就可以这样做

size.bind(service.valueProperty());

关于java - 在 JavaFX 中对服务中的值进行数据绑定(bind)时出现空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50011675/

相关文章:

java - 转发 : Issues porting application from tomcat 5. 0.28 到 tomcat 7.0.57

java - 如何向后端服务器上的firebase动态链接添加参数?

java - DisplayTag 导出和链接

c# - 安排在特定时间运行方法。

java - 无法在静态方法中将 JavaFx 任务委托(delegate)给新线程

c# - 线程池抛出异常

java - 如何创建自定义 JavaFX 组件库?

java - 每次运行此代码时,可观察列表插入顺序都会发生变化。怎么解决这个问题?

Java多线程: thread safe data structure vs.同步方法

JavaFX 元数据