Pas si complet que cela, un des FXML est coupé avant la fin et il y a des variables non-déclarées ici et là. Et puis plutôt que d'aller éditer d'anciens messages, ce qui rend la discussion difficile à suivre mieux valait reposter le code à la suite. Et comme je l'ai dit, je me contre-fiche d'avoir ton code au complet, ce qui m’intéresse c'est le cœur du problème. Car ça montre bien du coup que toi-même tu es incapable d'isoler la partie de ton code qui de pose du soucis et de réduire le problème à un test simple et donc ça signifie que tu ne comprends pas ton propre programme. De plus, outre ces bonnes pratiques, il n'y a pas de honte non-plus d'indiquer qu'on débute ou qu'on est pas sur de ce qu'on fait plutôt que de balancer toute la sauce en espérant qu'une autre personne arrive à tout dépatouiller à ta place.
Commençons par le commencement de manière à virer la dépendance à AWT.
Dans Main, MyControllerFenetrePrincipale et MyControllerFenetreTuto1, on replace :
par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dimension dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); int h = (int) dimension.getHeight(); int l = (int) dimension.getWidth();
Mais bon ça fait un peut bête d'avoir ça à 3 endroit différents, en général on a besoin de la taille de l'écran que dans l'application et c'est aux autres écrans de se mettre correctement en page à partir de là dans l'espace d'affichage qui leur est attribué.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds(); double h = primaryScreenBounds.getHeight(); double l = primaryScreenBounds.getWidth();
De plus il faudrait quand même tenir compte de la valeur x et y de la bouding box qui indiquent la partie affichage de l'écran (par exemple sur les OS où la barre système n'est pas en bas de l'écran, ces valeurs peuvent être différentes de (0,0)).
D'ailleurs j'avoue que je ne comprends pas du tout l’intérêt d'invoquer relocate() manuellement a plusieurs endroits en fonction de la taille de l'écran mais avec des constantes ... bref, il semble manquer une compréhension du fonctionnement des layouts, d'AnchorPane et de StackPane. Bref, j'ai du en enlever la plus grande partie sinon tout s'affichait en dehors de mon écran .
Pourquoi, mais alors pourquoi test1 est-il déclaré static dans la classe Main ?????????????????????
ces deux lignes sont à supprimer, elles n'ont rien à faire ici :
On va commencer par modifier MyScreenController pour qu'il conserve des références vers les divers contrôleurs (si tu n'arrives pas à voir la différente, utilise un utilitaire de diff genre WinMerge pour comparer les deux versions, la tienne et la mienne) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public static Gestes test1 = new Gestes(); [...] test1.start();
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public class MyScreenController extends AnchorPane { public HashMap<String, Pair<Node, ControlledScreen>> screens = new HashMap<>(); public MyScreenController() { super(); } public void addScreen(String name, Node screen, ControlledScreen controller) { screens.put(name, new Pair<>(screen, controller)); } public Pair<Node, ControlledScreen> getScreen(String name) { return screens.get(name); } public boolean loadScreen(String name, String resource) { try { FXMLLoader myLoader = new FXMLLoader(getClass().getResource( resource)); Parent loadScreen = (Parent) myLoader.load(); ControlledScreen myScreenControler = ((ControlledScreen) myLoader .getController()); myScreenControler.setScreenParent(this); addScreen(name, loadScreen, myScreenControler); return true; } catch (Exception e) { System.out.println(e.getMessage()); return false; } } public boolean setScreen(final String name) { if (screens.get(name) != null) { // screen loaded final DoubleProperty opacity = opacityProperty(); if (!getChildren().isEmpty()) { // if there is more than one screen Timeline fade = new Timeline(new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)), new KeyFrame(new Duration( 800), new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent t) { getChildren().remove(0); // remove the displayed screen getChildren().add(0, screens.get(name).getKey()); // add the // screen Timeline fadeIn = new Timeline(new KeyFrame( Duration.ZERO, new KeyValue(opacity, 0.0)), new KeyFrame(new Duration(800), new KeyValue( opacity, 1.0))); fadeIn.play(); } }, new KeyValue(opacity, 0.0))); fade.play(); } else { setOpacity(0.0); getChildren().add(screens.get(name).getKey()); // no one else been // displayed, then just // show Timeline fadeIn = new Timeline(new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)), new KeyFrame(new Duration( 2500), new KeyValue(opacity, 1.0))); fadeIn.play(); } return true; } else { System.out.println("screen hasn't been loaded!!! \n"); return false; } } }
Maintenant dans MyControllerFenetrePrincipale, on va gérer le passage dans le didacticiel #1 en remplaçant :
Par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 @FXML public void goToScreenTuto1(ActionEvent event) { myController.setScreen(Main.TUTO1_SCREEN); Main.test1.setIsTuto1(true); }
Et voici le squelette de la tâche qui remplace la classe Gestes (vu que je n'ai pas le code pour compiler telle qu'elle l'autre classe, j'avais du tout désactiver ou presque) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 private final List<Service> runningTutorials = new LinkedList(); @FXML public void goToScreenTuto1(ActionEvent event) { myController.setScreen(Main.TUTO1_SCREEN); Service<Void> tutorial = new Service<Void>() { @Override protected Task<Void> createTask() { final MyControllerFenetreTuto1 tuto1Controller = (MyControllerFenetreTuto1) myController.getScreen(Main.TUTO1_SCREEN).getValue(); return new Tuto1Task(tuto1Controller); } }; tutorial.setOnSucceeded(workerStateEvent -> { // Faire des trucs si ça marche. runningTutorials.remove(tutorial); }); tutorial.setOnCancelled(workerStateEvent -> { // Faire des trucs si on annule. runningTutorials.remove(tutorial); }); tutorial.setOnFailed(workerStateEvent -> { // Faire des truc si ça se vautre. runningTutorials.remove(tutorial); }); runningTutorials.add(tutorial); tutorial.start(); }
Ici c'est la classe MyScreenController qui monte manuellement la tâche et lui fourni le contrôleur du tuto1. On aurait aussi pu faire que la tache soit intégralement gérée (instanciée, lancée, gérée au niveau des sorties et des erreurs) directement dans le contrôleur du tuto1.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public class Tuto1Task extends Task<Void> { private MyControllerFenetreTuto1 tuto; public Tuto1Task(MyControllerFenetreTuto1 tuto) { this.tuto = tuto; } @Override protected Void call() throws Exception { updateMessage("démarrage"); while (!isCancelled()) { // Do stuff. showButton(); if (isCancelled()) { return null; } updateMessage("attente"); Thread.sleep(20); updateMessage("redémarrage"); } return null; } private void showButton() { Platform.runLater(() -> tuto.btnVisible()); } }
Partager