J'essaie actuellement de créer un écran de démarrage pour mon programme, car il faut un certain temps pour démarrer. Le problème est qu'il faut du temps pour créer l'interface graphique (création de dialogues, mise à jour de tables, etc.). Et je ne peux pas déplacer la création de l'interface graphique vers un thread d'arrière-plan (comme la classe "Task"), car j'obtiendrai une exception "Not on FXApplication Thread". J'ai essayé d'utiliser:Chargement de l'interface graphique JavaFX en arrière-plan
Platform.runLater(new Runnable() {
public void run() {
//create GUI
}
}
Et la méthode « appel » d'une tâche:
public class InitWorker extends Task<Void> {
private Model model;
private ViewJFX view;
public InitWorker(Model model) {
this.model = model;
}
@Override
protected Void call() throws Exception {
View view = new View();
Collection collection = new Collection();
//do stuff
}
}
Quand j'ai écrit le programme Swing je pouvais afficher et mettre à jour l'écran de démarrage sur le EventDispatchThread, sans tout réel concordance. Le code ressemblait à ceci:
public void build() {
MainOld.updateProgressBar(MainOld.PROGRESSBAR_VALUE++, "Creating Menus");
menuCreator = new MenuCreatorOld (model, this);
menuCreator.createMenu();
MainOld.updateProgressBar(MainOld.PROGRESSBAR_VALUE, "Creating Toolbar");
toolBar = menuCreator.createToolBar();
createWesternPanelToolBar();
shoppingPanel = new ShoppingListOld(model, this, collectionController, shoppingController, controller);
centerTabbedPane = new JTabbedPane();
MainOld.updateProgressBar(MainOld.PROGRESSBAR_VALUE++, "Creating Collection");
collectionPanel = new CollectionOld(model, collectionController, this, controller);
MainOld.updateProgressBar(MainOld.PROGRESSBAR_VALUE++, "Creating Wish List");
wishPanel = new WishListOld(model, this, collectionController, wishController, controller);
MainOld.updateProgressBar(MainOld.PROGRESSBAR_VALUE++, "Creating Folders Table");
//and so on
}
public static void updateProgressBar(int progressValue, String text) {
System.out.println("Loading Bar Value:"+progressValue);
progressBar.setValue(progressValue);
loadingLabel.setText(text);
progressBar.setString(text);
}
Est-il possible de créer l'interface graphique en arrière-plan tout en affichant un écran d'accueil avec une barre de chargement?
Edit:
J'ai regardé mon code et a été en mesure de réduire le temps de démarrage de 5 secondes. La plupart des boîtes de dialogue extraient des données de la base de données lors de leur création. J'ai donc déplacé la création des dialogues dans leurs méthodes getter. Cela a entraîné une amélioration de 3 secondes. Mais j'aimerais quand même savoir s'il y a moyen de créer l'interface graphique sur un thread d'arrière-plan.
Edit:
Comme suggéré, j'ai essayé également d'utiliser "RunLater" dans une "tâche". De cette façon, je peux créer l'interface graphique et afficher le SplashScreen, mais je ne peux pas mettre à jour la barre de progression et l'étiquette de progression, car la création de l'interface graphique bloque le thread d'application JavaFX. La barre de progression et l'étiquette sont mises à jour uniquement après la création complète de l'interface graphique.
Voici un exemple que vous les gars peuvent courir (je l'ai enlevé l'écran de démarrage et seulement gardé la barre de progression et l'étiquette de progrès):
public class InitWorker extends Task<Void> {
private static ProgressBar progressBar;
private static Label progressLabel;
private static double PROGRESS_MAX = 5;
private double loadingValue;
public InitWorker() {
loadingValue = 0;
}
@Override
protected void succeeded() {
System.out.println("Succeeded");
}
@Override
protected void failed() {
System.out.println("Failed");
}
@Override
protected Void call() throws Exception {
System.out.println("RUNNING");
Platform.runLater(new Runnable() {
public void run() {
displaySplashScreen();
for(int i=0; i<10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateProgressBar(loadingValue++, "Label "+i);
Stage stage = new Stage();
Label label = new Label("Label " + i);
VBox panel = new VBox();
panel.getChildren().add(label);
Scene scene = new Scene(panel);
stage.setScene(scene);
stage.centerOnScreen();
stage.show();
}
// updateProgressBar(1, "Initializing...");
}});
return null;
}
public void updateProgressBar(double loadingValue, String text) {
progressBar.setProgress(loadingValue/PROGRESS_MAX);
progressLabel.setText(text);
}
public static void displaySplashScreen() {
Stage progressBarStage = new Stage();
progressBar = new ProgressBar();
Scene progressBarScene = new Scene(progressBar);
progressBarStage.setScene(progressBarScene);
Stage progressLabelStage = new Stage();
progressLabel = new Label("Loading...");
progressLabel.setPadding(new Insets(5));
progressLabel.setStyle("-fx-background-color: red");
Scene progressLabelScene = new Scene(progressLabel);
progressLabelStage.setScene(progressLabelScene);
double progressBarWidth = 500;
double progressBarHeight = 75;
//muss angezeigt werden, um sie abhängig von Größe zu positionieren
progressBarStage.show();
progressLabelStage.show();
//
progressBarStage.setWidth(progressBarWidth);
progressBarStage.setHeight(progressBarHeight);
progressBarStage.centerOnScreen();
progressBarStage.centerOnScreen();
progressLabelStage.setY(progressLabelStage.getY() + 25);
}
}
La création de l'interface graphique ne devrait pas prendre beaucoup de temps. Cela peut prendre du temps pour récupérer les données, etc., que vous allez afficher dans l'interface graphique, mais vous pouvez le faire sur le fil d'arrière-plan. Êtes-vous sûr que la création de l'interface graphique réelle prend du temps? –
J'ai regardé mon code et j'ai été capable de réduire le temps de démarrage de 5 secondes. La plupart des boîtes de dialogue extraient des données de la base de données lors de leur création. J'ai donc déplacé la création des dialogues dans leurs méthodes getter. Cela a entraîné une amélioration de 3 secondes. Mais j'aimerais quand même savoir s'il existe en général un moyen de créer l'interface graphique dans un thread d'arrière-plan. – maumau
Quel matériel et système d'exploitation utilisez-vous? Pouvez-vous fournir un [mcve] exposant le problème? – Itai