Display Popup with ProgressBar in JavaFX
up vote
7
down vote
favorite
How can I display my progress bar through pop up and automatically close if process is finished. Here is my code.
Task<ProgressForm> task = new Task<ProgressForm>() {
@Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});
Thread th = new Thread(task);
th.run();
Progress form class:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
The problem with this code is
- if i use .show(), displaying pop up is smooth but NO PROGRESS BAR.
- if i use .showAndWait(), displaying pop up requires manual exit for the pop up to close BUT Progress bar displays.
Any thoughts/ideas about this?
javafx popup progress-bar
add a comment |
up vote
7
down vote
favorite
How can I display my progress bar through pop up and automatically close if process is finished. Here is my code.
Task<ProgressForm> task = new Task<ProgressForm>() {
@Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});
Thread th = new Thread(task);
th.run();
Progress form class:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
The problem with this code is
- if i use .show(), displaying pop up is smooth but NO PROGRESS BAR.
- if i use .showAndWait(), displaying pop up requires manual exit for the pop up to close BUT Progress bar displays.
Any thoughts/ideas about this?
javafx popup progress-bar
add a comment |
up vote
7
down vote
favorite
up vote
7
down vote
favorite
How can I display my progress bar through pop up and automatically close if process is finished. Here is my code.
Task<ProgressForm> task = new Task<ProgressForm>() {
@Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});
Thread th = new Thread(task);
th.run();
Progress form class:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
The problem with this code is
- if i use .show(), displaying pop up is smooth but NO PROGRESS BAR.
- if i use .showAndWait(), displaying pop up requires manual exit for the pop up to close BUT Progress bar displays.
Any thoughts/ideas about this?
javafx popup progress-bar
How can I display my progress bar through pop up and automatically close if process is finished. Here is my code.
Task<ProgressForm> task = new Task<ProgressForm>() {
@Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});
Thread th = new Thread(task);
th.run();
Progress form class:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
The problem with this code is
- if i use .show(), displaying pop up is smooth but NO PROGRESS BAR.
- if i use .showAndWait(), displaying pop up requires manual exit for the pop up to close BUT Progress bar displays.
Any thoughts/ideas about this?
javafx popup progress-bar
javafx popup progress-bar
asked Apr 14 '15 at 10:35
user3247087
41117
41117
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
15
down vote
accepted
The two rules for multithreading in JavaFX are:
- Code which modifies the UI (creates a
Stage
or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateException
s or result in unpredictable behavior. - Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm
constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress
properties of the progress bar and indicator to the progress
property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String args) {
launch(args);
}
}
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use100.0/i
instead of100/i
.
– James_D
Dec 14 '16 at 17:04
|
show 5 more comments
up vote
0
down vote
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
@Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
15
down vote
accepted
The two rules for multithreading in JavaFX are:
- Code which modifies the UI (creates a
Stage
or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateException
s or result in unpredictable behavior. - Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm
constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress
properties of the progress bar and indicator to the progress
property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String args) {
launch(args);
}
}
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use100.0/i
instead of100/i
.
– James_D
Dec 14 '16 at 17:04
|
show 5 more comments
up vote
15
down vote
accepted
The two rules for multithreading in JavaFX are:
- Code which modifies the UI (creates a
Stage
or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateException
s or result in unpredictable behavior. - Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm
constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress
properties of the progress bar and indicator to the progress
property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String args) {
launch(args);
}
}
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use100.0/i
instead of100/i
.
– James_D
Dec 14 '16 at 17:04
|
show 5 more comments
up vote
15
down vote
accepted
up vote
15
down vote
accepted
The two rules for multithreading in JavaFX are:
- Code which modifies the UI (creates a
Stage
or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateException
s or result in unpredictable behavior. - Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm
constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress
properties of the progress bar and indicator to the progress
property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String args) {
launch(args);
}
}
The two rules for multithreading in JavaFX are:
- Code which modifies the UI (creates a
Stage
or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateException
s or result in unpredictable behavior. - Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm
constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress
properties of the progress bar and indicator to the progress
property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
@Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String args) {
launch(args);
}
}
answered Apr 14 '15 at 13:18
James_D
138k9156192
138k9156192
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use100.0/i
instead of100/i
.
– James_D
Dec 14 '16 at 17:04
|
show 5 more comments
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use100.0/i
instead of100/i
.
– James_D
Dec 14 '16 at 17:04
1
1
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
good day! tried your code but seems like the stage is not showing my progressbar. the look of it: pasteboard.co/2zCr2Qbx.png
– user3247087
Apr 15 '15 at 2:54
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
You ran the exact code I posted? It worked fine for me. What JDK and OS are you using?
– James_D
Apr 15 '15 at 9:34
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
was able to resolve a lil of my problem. right now i have to fix how to avoid UI block whenever i call waitFor for a certain process. seems like my progress bar is not showing due to waitFor().
– user3247087
Apr 15 '15 at 9:38
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
waitFor() is a blocking call, so if you call it on the FX Application Thread, the UI will become unresponsive (rule 2 above). If the UI is unresponsive, it will not render, so you don't see the contents of the dialog. There is no need to call waitFor(). If there is code you need to execute after the task is done, execute it in the onSucceeded handler.
– James_D
Apr 15 '15 at 9:57
1
1
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use
100.0/i
instead of 100/i
.– James_D
Dec 14 '16 at 17:04
@WesosdeQueso The integer division by zero in the first iteration confuses it. Use
100.0/i
instead of 100/i
.– James_D
Dec 14 '16 at 17:04
|
show 5 more comments
up vote
0
down vote
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
@Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig
add a comment |
up vote
0
down vote
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
@Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig
add a comment |
up vote
0
down vote
up vote
0
down vote
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
@Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
@Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig
answered Nov 11 at 1:36
Amirouche Zeggagh
1,224613
1,224613
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f29625170%2fdisplay-popup-with-progressbar-in-javafx%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown