数据绑定JavaFX中的服务中的值时出现空指针异常

时间:2018-04-24 22:40:40

标签: java multithreading javafx data-binding

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

我已经检查了调试器,并确认该任务实际上是返回值,但我一直得到一个空指针异常,说明对于执行绑定的代码行我“无法绑定到null”,但是,其他属性我已经绑定似乎工作正常

主要类

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();
                    }
                }
            });


服务Impl类

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

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


任务Impl类

/*************************************************************
 * 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.");
    }   
}   

1 个答案:

答案 0 :(得分:3)

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());