Anurag Sharma Anurag Sharma - 4 years ago 232
Java Question

JavaFX: Disable all components while a process is running and show progress indicator

I have a method that read values from the the database and returns a

Map<Integer,String>.
This method takes some time to return the map.

Till the time values are getting read I want a progress indicator(only loading ring like indicator will be enough,no need for progress bar) to be displayed on screen and all other components should be disabled till the time progress bar is shown.

public void scanDevice() {
ObservableList<TextField> list = FXCollections.observableArrayList(vehicleId, vehicleName, deviceType,
offboardBroker1, offboardBroker2, postfixQueue, pKIServer);
editedValuesMap.clear();
// devicePlugged = true;
if (cbChooseProject.getSelectionModel().getSelectedItem() != null) {
try {
devicePlugged = dsAdapter.getAdapter();
if (devicePlugged) {
if (bScanDevice.isFocused()) {
readMap = new HashMap<Integer, String>();
//Process Start
readMap = dsAdapter.initScan();
//Process End

if (!readMap.isEmpty() && readMap != null) {
isWritten = true;
isDeviceSideEnabled();
editDeviceContents.setDisable(false);
vehicleId.setText(readMap.get(0));
vehicleName.setText(readMap.get(1));
deviceType.setText(readMap.get(2));
offboardBroker1.setText(readMap.get(3));
offboardBroker2.setText(readMap.get(4));
postfixQueue.setText(readMap.get(5));
pKIServer.setText(readMap.get(6));
lContentsSerialNo.setText(readMap.get(7));
}
}
}

Answer Source

You could disabled all nodes with a method like the following but if you are also wanting to wait while something is happening an overlay using StackPanes may be the preferred choice.

public void setNodesDiabled(boolean disable, Node... nodes) {
    for(Node node : nodes) {
        node.setDisable(disable);
    }
}

With an arbitrary node count, you can disable and re-enable as many nodes that are relevant to the process. It also helps to clean up as you won't have several node.setDisable(true); node2.setDisable(true); and so on.

Here in this example you won't need setNodesDisabled() because the StackPane overlay prevents clicking anything other than what's inside it. The background color is gray with 70% alpha so that you can tell it's an overlay.

public class ProgressExample extends Application {

    public StackPane layout, main, progress;

    public StackPane createProgressPane() {
        ProgressIndicator indicator = new ProgressIndicator();
        indicator.setMaxHeight(50);
        indicator.setMaxWidth(50);

        StackPane pane = new StackPane();
        pane.setAlignment(Pos.CENTER);
        pane.setStyle("-fx-background-color: rgba(160,160,160,0.7)");
        pane.getChildren().add(indicator);

        Task<Void> task = new Task<Void>(){
            protected Void call() throws Exception {
                // Your process here.
                // Any changes to UI components must be inside Platform.runLater() or else it will hang.
                Thread.sleep(2000);

                Platform.runLater(() -> {
                    layout.getChildren().remove(pane);
                });
                return null;
            }
        };
        new Thread(task).start();
        return pane;
    }

    public StackPane createMainPane() {
        Label label = new Label("Hello World!");
        label.setFont(Font.font("Tahoma", FontWeight.SEMI_BOLD, 16));

        Button start = new Button("Start Process");
        start.setOnAction(action -> {
            progress = createProgressPane();
            layout.getChildren().add(progress);
        });

        VBox vbox = new VBox(10);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(label, start);
        vbox.setPadding(new Insets(10,10,10,10));

        StackPane pane = new StackPane();
        pane.getChildren().add(vbox);
        return pane;
    }

    public void start(Stage stage) throws Exception {
        main = createMainPane();

        layout = new StackPane();
        layout.getChildren().add(main);

        Scene scene = new Scene(layout, 900, 550);
        stage.setScene(scene);
        stage.setTitle("Progress Example");
        stage.setOnCloseRequest(e -> {
            Platform.exit();
            System.exit(0);
        });
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download