I am writing a code that reads considerably large arxml file and stores data from it. I have a main class ARXMLParser and a class called ParsedDatabase. I am calling a function from main loadFromArxml and passing the path of file as parameter. The function would read and store that data. I want to update Progress bar in main as the function loadFromArxml is reading data.
I am using class Task and performing my function in it. However I don't know how would I update progress from it.
This is my main code
import java.io.File;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import parser.ParsedDatabase;
public class ARXMLParser extends Application {
private ProgressBar progress;
@Override
public void start(Stage primaryStage) {
TextField arxmlPath = new TextField("");
arxmlPath.setEditable(false);
arxmlPath.setFocusTraversable(false);
arxmlPath.setPromptText("ARXMl File");
Label arxmlLbl = new Label("No File Selected");
Button btnArxml = new Button("Browse");
btnArxml.setOnAction(e -> {
FileChooser chooser = new FileChooser();
chooser.setInitialDirectory(new File(System.getProperty("user.dir")));
FileChooser.ExtensionFilter fileExtensions = new FileChooser.ExtensionFilter("ARXML Files (*.arxml)",
"*.arxml");
chooser.getExtensionFilters().add(fileExtensions);
File file = chooser.showOpenDialog(primaryStage);
if (file != null) {
arxmlPath.setText(file.getAbsolutePath());
arxmlLbl.setText(file.getName());
}
});
HBox arxmlHbox = new HBox();
arxmlHbox.setSpacing(10);
arxmlHbox.getChildren().addAll(arxmlPath, btnArxml);
HBox.setHgrow(arxmlPath, Priority.ALWAYS);
HBox.setHgrow(btnArxml, Priority.ALWAYS);
progress = new ProgressBar();
progress.setPrefWidth(Double.MAX_VALUE);
Button btnParse = new Button("Parse");
btnParse.setOnAction(e -> {
ParsedDatabase parsedDatabase = new ParsedDatabase();
if (!arxmlPath.getText().isEmpty()) {
Task<Void> parse = new Task<Void>() {
@Override
protected Void call() throws Exception {
// Function that reads the file
parsedDatabase.loadFromArxml(arxmlPath.getText());
return null;
}
};
progress.progressProperty().bind(parse.progressProperty());
Thread thread = new Thread(parse);
thread.setDaemon(true);
thread.start();
}
});
VBox vBox = new VBox();
vBox.setFillWidth(true);
vBox.setSpacing(15);
vBox.getChildren().addAll(arxmlHbox, arxmlLbl, btnParse, progress);
vBox.setPadding(new Insets(15, 10, 15, 10));
Scene scene = new Scene(vBox, 500, 170);
primaryStage.setTitle("ARXML Parser");
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void setProgressBar(Double value) {
progress.setProgress(value);
}
public double getProgress() {
return progress.getProgress();
}
}
And my ParsedDatabase class
package parser;
import java.io.File;
import java.util.Scanner;
public class ParsedDatabase {
public void loadFromArxml(String arxmlPath) throws Exception {
File file = new File(arxmlPath);
Scanner scan = new Scanner(file);
while (scan.hasNext()) {
System.out.println(scan.nextLine());
// Update progress based on file length
}
scan.close();
// Update progress
exportToExcel();
// Update progress
}
public void exportToExcel() {
// Export to excel
// Update progress
}
}
I was wondering how to update progress from the method. I do know there is a way I can do it. That is if I call both functions from main and from there updating progress is easy. Something like this
updateProgress(0, 1.0);
parsedDatabase.loadFromArxml(arxmlPath.getText());
updateProgress(0.5, 1.0);
parsedDatabase.exportToExcel();
updateProgress(1, 1.0);
However, The progress bar then will not progress smoothly but will go from 0 to 50 and to 100. I want it to be continuous. If there is a better way to achieve the same thing please let me know. This isn't an assignment. I am just learning concurrency at my own.