Je veux gérer les événements de scène (c'est-à-dire cacher) de ma classe de contrôleur. Donc tout ce que j'ai à faire est d'ajouter un auditeur via
((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);
mais le problème est que l'initialisation commence juste après
Parent root = FXMLLoader.load(getClass().getResource("MyGui.fxml"));
et avant
Scene scene = new Scene(root);
stage.setScene(scene);
ainsi .getScene () renvoie null.
La seule solution de contournement que j'ai trouvée par moi-même est d'ajouter un écouteur à myPane.sceneProperty (), et quand il devient non nul, j'obtiens une scène, ajoutez-y .windowProperty () my! Goddamn! la manipulation de l'auditeur que je récupère enfin stage. Et tout se termine par la mise en scène des auditeurs souhaités. Je pense qu'il y a trop d'auditeurs. Est-ce la seule façon de résoudre mon problème?
load()
méthode. (De plus, le javadoc surgetController
sonne comme s'il devrait êtresetController
Tout ce dont vous avez besoin est de donner
AnchorPane
un identifiant, puis vous pouvez l'obtenirStage
.De là, vous pouvez ajouter le
Listener
dont vous avez besoin.Edit: Comme indiqué par EarthMind ci-dessous, il n'est pas nécessaire que ce soit l'
AnchorPane
élément; cela peut être n'importe quel élément que vous avez défini.la source
element
peut être un élément avec unfx:id
dans cette fenêtre:Stage stage = (Stage) element.getScene().getWindow();
. Par exemple, si vous n'avez qu'unButton
avec unfx:id
dans vos fenêtres, utilisez-le pour accéder à la scène.getScene()
revient toujoursnull
.bgimage.sceneProperty().addListener((observableScene, oldScene, newScene) -> { if (oldScene == null && newScene != null) { bgimage.fitWidthProperty().bind(newScene.widthProperty()); ... } });
Je sais que ce n'est pas la réponse que vous voulez, mais à l'OMI, les solutions proposées ne sont pas bonnes (et à votre façon). Pourquoi? Parce qu'ils dépendent de l'état de l'application. Dans JavaFX, un contrôle, une scène et une étape ne dépendent pas les uns des autres. Cela signifie qu'un contrôle peut vivre sans être ajouté à une scène et qu'une scène peut exister sans être attachée à une scène. Et puis, à un instant t1, le contrôle peut s'attacher à une scène et à l'instant t2, cette scène peut être ajoutée à une étape (et cela explique pourquoi ce sont des propriétés observables l'une de l'autre).
Ainsi, l'approche qui suggère d'obtenir la référence du contrôleur et d'appeler une méthode, en lui passant l'étape ajoute un état à votre application. Cela signifie que vous devez appeler cette méthode au bon moment, juste après la création de la scène. En d'autres termes, vous devez maintenant suivre un ordre: 1- Créez l'étape 2- Passez cette étape créée au contrôleur via une méthode.
Vous ne pouvez pas (ou ne devez pas) modifier cet ordre dans cette approche. Vous avez donc perdu l'apatridie. Et dans les logiciels, en général, l'état est mauvais. Idéalement, les méthodes ne devraient nécessiter aucun ordre d'appel.
Alors, quelle est la bonne solution? Il existe deux alternatives:
1- Votre approche, dans les propriétés d'écoute du contrôleur pour obtenir la scène. Je pense que c'est la bonne approche. Comme ça:
2- Vous faites ce que vous devez faire là où vous créez le
Stage
(et ce n'est pas ce que vous voulez):la source
pane
à une scène qui est déjà attachée à une scène, cela ne fonctionnera pas, non? Ne devrait-il pas y avoir une vérification dans l'sceneProperty
écouteur et ajouter seulement l'stageProperty
écouteur si l'étape est toujours nulle? Sinon, fais ce dont j'ai besoin tout de suite?Le moyen le plus simple d'obtenir un objet de scène dans le contrôleur est:
Ajoutez une méthode supplémentaire dans la propre classe de contrôleur créée comme (ce sera une méthode de setter pour définir la scène dans la classe de contrôleur),
Obtenez le contrôleur dans la méthode de démarrage et définissez la scène
Vous pouvez maintenant accéder à la scène dans le contrôleur
la source
stage
comme ça.Assignez fx: id ou déclarez une variable à / de n'importe quel nœud: anchorpane, bouton, etc. Ajoutez ensuite un gestionnaire d'événements et dans ce gestionnaire d'événements, insérez le code donné ci-dessous:
J'espère que cela fonctionne pour toi!!
la source
Platform.runLater empêche l'exécution tant que l'initialisation n'est pas terminée. Dans ce cas, je souhaite actualiser une vue de liste chaque fois que je redimensionne la largeur de la fenêtre.
dans ton cas
la source
Vous pouvez obtenir avec
node.getScene
, si vous n'appelez pas dePlatform.runLater
, le résultat est une valeur nulle.exemple de valeur nulle:
exemple aucune valeur nulle:
la source