Impossible d'obtenir une Scène à partir de MenuItem en JavaFX
Je suis en train de changer la scène en javafx étape sur la base des menuItem cliquez sur. Voici mon exemple.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<AnchorPane prefHeight="-1.0" prefWidth="560.0" styleClass="background" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="sample.Controller">
<children>
<MenuBar layoutY="0.0" maxWidth="1.7976931348623157E308" prefWidth="300.0" useSystemMenuBar="false" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0">
<menus>
<Menu id="manageAccountsMenu" mnemonicParsing="false" onAction="#onManageAccountsMenuActionPerformed" text="Accounts" fx:id="manageAccountsMenu">
<items>
<MenuItem mnemonicParsing="false" onAction="#onTweetsMenuActionPerformed" text="Manage" fx:id="manageAccountsSubmenuItem" />
</items>
</Menu>
<Menu mnemonicParsing="false" onAction="#onTweetsMenuActionPerformed" text="Tweets" fx:id="tweetsMenuItem" />
<Menu mnemonicParsing="false" text="Retweets" />
</menus>
</MenuBar>
<VBox id="VBox" alignment="CENTER" layoutY="24.0" spacing="5.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<ScrollPane id="ScrollPane" fitToHeight="true" fitToWidth="true" prefViewportHeight="400.0" prefViewportWidth="300.0">
<content>
<TableView prefHeight="-1.0" prefWidth="-1.0" tableMenuButtonVisible="true">
<columns>
<TableColumn editable="false" prefWidth="75.0" text="SNO" />
<TableColumn prefWidth="200.0" text="Account" />
<TableColumn prefWidth="200.0" text="Status" />
<TableColumn prefWidth="75.0" text="Actions" />
</columns>
</TableView>
</content>
</ScrollPane>
<Button mnemonicParsing="false" text="Add Account" textAlignment="CENTER">
<graphic>
<ImageView fitHeight="150.0" fitWidth="200.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@addAccount.png" />
</image>
</ImageView>
</graphic>
</Button>
</children>
</VBox>
</children>
<stylesheets>
<URL value="@darkTheme.css" />
</stylesheets>
</AnchorPane>
Voici mon Controller.java:
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.MenuItem;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
protected void onManageAccountsMenuActionPerformed(ActionEvent event) {
System.out.println("Manage Accbtnclick");
// Node node=(Node) event.getSource();
// Stage stage=(Stage) node.getScene().getWindow();
//
// Scene scene = new Scene(root);
// stage.setScene(scene);
// stage.show();
}
@FXML
protected void onTweetsMenuActionPerformed(ActionEvent event) {
System.out.println("Manage Accbtnclick");
Node node= (Node)event.getSource();
Stage stage=(Stage) node.getScene().getWindow();
Scene scene = Main.screens.get("tweet");
stage.setScene(scene);
stage.show();
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
//To change body of implemented methods use File | Settings | File Templates.
}
}
Voici mon Main.java:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.HashMap;
public class Main extends Application {
public static HashMap<String,Scene> screens=new HashMap<String,Scene>();
@Override
public void start(Stage stage) {
try {
Parent accountScreen= FXMLLoader.load(getClass().getResource("sample.fxml"));
Parent tweetScreen=FXMLLoader.load(getClass().getResource("tweetform.fxml"));
//Parent retweetScreen=FXMLLoader.load(getClass().getResource("retweetform.fxml"));
screens.put("account",new Scene(accountScreen));
screens.put("tweet",new Scene(tweetScreen));
//screens.put("retweet",new Scene(retweetScreen));
stage.setTitle("Manage Accounts");
stage.setScene(screens.get("account"));
stage.show();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public static void main(String[] args) {
launch(args);
}
}
Quand je clique sur le menuItem Gérer le Menu accounts (Comptes), j'obtiens l'exception suivante:
"C:\Program Files\Java\jdk1.7.0_17\bin\java" -Didea.launcher.port=7541 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_17\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_17\jre\lib\ext\zipfs.jar;C:\Users\rahulserver\IdeaProjects\DrawingText\out\production\DrawingText;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.4\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain sample.Main
Manage Accbtnclick
Manage Accbtnclick
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1440)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.control.MenuItem.fire(MenuItem.java:456)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1188)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$6.handle(ContextMenuContent.java:1139)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$6.handle(ContextMenuContent.java:1137)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3328)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3168)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3123)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2265)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:55)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:269)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
... 40 more
Caused by: java.lang.ClassCastException: javafx.scene.control.MenuItem cannot be cast to javafx.scene.Node
at sample.Controller.onTweetsMenuActionPerformed(Controller.java:29)
... 50 more
Alors, comment puis-je obtenir le contenant de la scène/scène de l'Élément de menu cliqué gestionnaire d'événement?
MODIFIER
La ligne
Node node= (Node)event.getSource();
dans controller.java est le numéro de ligne 29 qui donne à ces problèmes.
java.lang.NullPointerException at sample.Controller.onTweetsMenuActionPerformed(Controller.java:30)
=> où est la ligne 30 de votre Controller.java de classe?- Étape=(Stade) nœud.getScene().getWindow();
- Ma conjecture est que
node
n'est pas visible par conséquent, ne pas avoir une Fenêtre. Vous pourriez essayer de déboguer le code pour vérifier les variables à ce point. - J'ai révisé stacktrace et le contrôleur. Cela devrait donner u meilleure idée.
- voir le numéro de la ligne 29 de l'éditer à nouveau...
- rahul voir cet exemple: stackoverflow.com/questions/18321167/...
Vous devez vous connecter pour publier un commentaire.
Votre véritable erreur est indiqué dans l'avant-dernière ligne de la trace de la pile:
Cette erreur est en se référant à la ligne suivante à partir de votre contrôleur:
Regardant l'API JavaFX Docs, ni MenuItem ni de Menu sont des sous-classes de Nœud. http://docs.oracle.com/javafx/2/api/javafx/scene/control/MenuItem.html
http://docs.oracle.com/javafx/2/api/javafx/scene/control/Menu.html
Je dirais emparer de la source comme un Objet, puis de vérifier son type avant de continuer. Aussi, j'ai couru dans des problèmes à l'aide de la getSource() la méthode; la getTarget() méthode fonctionne mieux pour moi. De toute façon, vous avez encore besoin d'un moyen d'obtenir de la Scène.
Pour ce faire, vous pouvez utiliser le
fx:id
balise dans votre FXML au lieu de laid
tag. Cela vous permettra d'injecter le FXML éléments directement dans votre contrôleur. Par exemple, vous pouvez prendre la Scène à partir de la barre de menu (qui est une sous-classe de Nœud) par l'injection de la barre de menu de l'élément dans votre contrôleur.Dans le FXML:
Dans le contrôleur:
Vous devrez peut-être faire un peu de peaufinage ici, mais j'espère que ça aide.
Ici est un moyen d'obtenir le
Scene
etWindow
basée sur un élément de menu étant un clic, sans qu'il soit l'injection d'une FXML élément, ou sans faire référence à elle si vous n'avez créer avec FXML. En d'autres termes à l'aide de laEvent
's de la cible.À mon problème que j'ai eu un
MenuButton
avec un menu déroulant (unContextMenu
que j'ai découvert, que je ne savais pas que j'avais créé mon menu dans le FXML) contenantMenuItems
et je voulais ouvrir unFileChooser
, qui a besoin de laWindow
comme un argument, quand le "Sauver"MenuItem
a été cliqué.Normalement je serais allé en bas de la route de l'obtention de l'événement cible, alors le Parent, l'autre Parent, etc. et enfin la Scène, puis la Fenêtre. Comme
Menu
etMenuItem
ne sont pasNode
s et, par conséquent, n'ont pasParent
s Dans ce cas, cependant, je ne les suivants:Ou de, la conversion de la masse en un argument de ligne:
Juste s'adapter à ce que nécessaire en fonction de votre propre scène graphique (c'est à dire la façon dont beaucoup de parents, vous avez besoin pour passer à travers en cas de sous-menus, etc) et ce que vous êtes désireux de le faire une fois que vous avez la
Window
, mais une fois que vous obtenez à laContextMenu
(la liste déroulante deMenuItems
), vous pouvez obtenir leScene
puis de tirer leWindow
.Que d'un côté, voici le FXML j'ai utilisé pour créer mon
MenuButton
, et donc pourquoi je ne savais pas que je devais obtenir leContextMenu
par le biais d'un appel àgetParentPopup()
sans quelques essais et erreurs:Étape = (Scène) ((Noeud) myMenuBar).getScene().getWindow();