JavaFX ouvrir une nouvelle scène
Je veux que mon code fonctionne de telle manière que lorsque je clique sur un Bouton, une nouvelle scène s'ouvre, mais il ne fonctionne pas et je ne sais pas pourquoi.
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("FXML/LoginScene.fxml"));
scene = new Scene(root,400,400);
openScene = new OpenScene(writer);
window.setScene(scene);
window.show();
}
public static void main(String[] args){
launch(args);
}
@FXML protected void btnConnect(ActionEvent event) {
System.out.println("hallo");
try {
openScene.start(window);
} catch (Exception e) {
e.printStackTrace();
}
}
Le GUI avec succès s'affiche, mais lorsque j'appuie sur le Bouton, il lève une Exception.
public class OpenScene extends Application{
PrintWriter writer;
@Override
public void start(Stage window) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXML/OpenScene.fxml"));
Scene scene = new Scene(root, 200 ,200);
window.setScene(scene);
window.show();
}
public OpenScene(PrintWriter writer){
this.writer = writer;
}
}
Mise à jour
J'ai essayé de séparer la classe d'application à partir de la classe de contrôleur comme dans James_D la réponse ci-dessous, mais j'ai eu l'exception suivante:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1762)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1645)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8216)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1759)
... 43 more
Caused by: java.lang.NullPointerException
at MainController.btnConnect(MainController.java:22)
... 53 more
Sont que vous essayez d'utiliser votre application de classe en tant que contrôleur de classe? Ces devrait vraiment être des classes séparées. Aussi, comme mentionné précédemment, vous devriez vraiment avoir un seul
pourquoi est-ce si important?
Parce que vous allez avoir deux instances de la classe. Celui qui a été créé par
cela ne change rien
Donc ce qui est sur la ligne 22 de
Application
sous-classe par application. (Vous pouvez simplement prendre le extends Application
et @Override
de votre OpenScene
classe, non?) Et enfin, merci de poster la trace de la pile de l'Exception.pourquoi est-ce si important?
Parce que vous allez avoir deux instances de la classe. Celui qui a été créé par
launch
, qui appelle start(...)
pour vous, et celui qui a été créé par le FXMLLoader
. Seul le premier va avoir initialisé le window
champ.cela ne change rien
Donc ce qui est sur la ligne 22 de
MainController
? (Peut-être juste de modifier la question d'inclure la classe et d'identifier la ligne 22.)
OriginalL'auteur | 2015-03-16
Vous devez vous connecter pour publier un commentaire.
Il semble que vous essayez d'utiliser votre application principale de la classe en tant que contrôleur de classe. Cela va être source de confusion, et vous devriez éviter. Voici ce qui arrive:
Lorsque vous démarrez l'application, il appelle
launch(...)
. Lelaunch
méthode, héritée deApplication
, va faire un tas de important "ménage", comme le démarrage de l'JavaFX trousse à outils et le JavaFX Application Thread. Ensuite, il crée une instance de votre application sous-classe, crée une premièreStage
et appelle lastart(...)
dans cette instance.Dans votre
start(...)
méthode, vous avez initialisé un couple de variables d'instance (window
etopenScene
), et chargé un fichier FXML, l'affichage de son contenu. LeFXMLLoader.load(...)
méthode est le suivant:fx:controller
attribut dans le fichier FXML@FXML
annotée des champs dans l'instance du contrôleurNotez que si vous spécifiez le même groupe pour l'application et pour le contrôleur, deux instances de cette classe sera créée. L'un est créé par le
launch
méthode, et on est créée par leFXMLLoader
. Notez que seule l'instance créée par lalaunch
méthode a eu lestart(...)
méthode invoquée. Puisque vous initialiser les variables d'instance dans lestart(...)
méthode, les variables ne sont pas initialisées dans l'instance créée par laFXMLLoader
. Donc dans l'instance créée par laFXMLLoader
(le "contrôleur de l'instance", si vous le souhaitez),window
etopenScene
ne sont pas initialisés. D'où la ligneva jeter un
NullPointerException
.Depuis l'application et le contrôleur ont vraiment des rôles totalement différents, vous devez les séparer en différentes classes. Cela rendra les choses beaucoup moins à confusion. Notez que vous pouvez toujours trouver la fenêtre dans laquelle un nœud est affiché en appelant
donc il n'est pas nécessaire de mettre en cache les
Stage
instance.Donc:
et utiliser une autre classe pour le contrôleur:
Note également qu'il n'est pas nécessaire pour votre
OpenScene
classe pour être unApplication
sous-classe: vous avez seulement besoin d'une telle classe par application:Qu'est-ce que l'exception? La ligne est-il jeté? Nul ne peut éventuellement vous aider si vous gardez en disant: "Elle lève une exception."
OriginalL'auteur James_D