JavaFX, how do Label and Progressbar update during the method?
-
I have a static method of downloading the file:
public class Downloader { private static MainLayoutController mlController; private static int doneQuantity = 0;
public static void setController(MainLayoutController c) { mlController = c; } public static void downloadFile(String url, String savePath, int buffSize) { try { /* Get connection */ URL connection = new URL(url); HttpURLConnection urlconn; urlconn = (HttpURLConnection) connection.openConnection(); urlconn.setRequestMethod("GET"); urlconn.connect(); /* Set input stream */ InputStream in = null; in = urlconn.getInputStream(); /* Find file full path */ String[] tempArr = url.split("/"); String fullPath = savePath + tempArr[tempArr.length - 1]; /* Set Labels */ //mlController.downloadingLabel.setText(tempArr[tempArr.length - 1]); //mlController.downloadedLabel.setText(doneQuantity + "/" + mlController.quantity); /*Task task = new Task() { @Override protected Integer call() throws Exception { Platform.runLater(() -> updateTitle(tempArr[tempArr.length - 1])); return 101; } }; mlController.downloadingLabel.textProperty().bind(task.titleProperty()); new Thread(task).start();*/ /* Set write stream */ OutputStream writer = new FileOutputStream(fullPath); byte buffer[] = new byte[buffSize]; // Max bytes per one reception /* Download */ int i = 0; double getted_b = 0.0; long delta_t = System.nanoTime(), i_sum = 0; while ((i = in.read(buffer)) > 0) { getted_b += i; i_sum += i; writer.write(buffer, 0, i); if ((System.nanoTime() - delta_t) >= 1E9) { // If the second was over int kb, mb; mb = new Double(getted_b / (1024 * 1024)).intValue(); kb = new Double((getted_b / 1024) % 1024).intValue(); System.out.println(" >> Speed: " + mb + " " + kb + " Mb/sec"); System.out.println(" >> " + i_sum / (urlconn.getContentLength() / 100) + "%"); delta_t = System.nanoTime(); // Set to zero getted_b = 0.0; } } /* Cleaning */ writer.flush(); writer.close(); in.close(); } catch (IOException e) { System.out.println(e); } }
}
He gets access.
label
- Mm-hmm.progressbar
- and by reference to the controller class.mlController
♪ My unsuccessful attempts to update the labels follow the comment./* Set Labels */
♪
Can you tell me how to do this?
-
The main idea is that your downloadFile method should be generated in a separate flow rather than in JavaFX Application Thread, and changes to UI elements should be made in Platform.runLater() - ... }. It is possible to go further and make a separate Task Force that carries out all the work and has a message and progress that can be combined.
public class App extends Application {
public static void main(String[] args) throws Exception {
launch(args);
}public void start(Stage stage) throws Exception {
VBox rootNode = new VBox();Label label = new Label(); ProgressIndicator progressIndicator = new ProgressIndicator(); Button button = new Button(); button.setOnAction((e) -> { DownloadTask downloadTask = new DownloadTask(); label.textProperty().bind(downloadTask.messageProperty()); progressIndicator.progressProperty().bind(downloadTask.progressProperty()); Thread th = new Thread(downloadTask); th.setDaemon(true); th.start(); }); rootNode.getChildren().add(label); rootNode.getChildren().add(progressIndicator); rootNode.getChildren().add(button); Scene scene = new Scene(rootNode, 400, 200); stage.setTitle("App"); stage.setScene(scene); stage.show();
}
class DownloadTask extends Task<Void> {
@Override protected Void call() throws Exception { for (int i = 0; i < 100; i++) { updateMessage("Progress " + i); updateProgress(i, 100); Thread.sleep(10); } return null; }
}
♪