我试图基于menuItem单击更改javafx阶段中的场景.这是我的sample.fxml:
这是我的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. } }
这是我的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 HashMapscreens=new HashMap (); @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); } }
当我点击Accounts Menu下的menuItem Manage时,我得到以下异常:
"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
那么如何从菜单项单击事件处理程序中获取包含的舞台/场景?
编辑 该行
Node node= (Node)event.getSource();
在controller.java中是第29行,它给出了问题.
您的实际错误显示在堆栈跟踪的倒数第二行:
Caused by: java.lang.ClassCastException: javafx.scene.control.MenuItem cannot be cast to javafx.scene.Node at sample.Controller.onTweetsMenuActionPerformed(Controller.java:29)
此错误指的是您的控制器中的以下行:
Node node= (Node)event.getSource();
查看JavaFX API Docs,MenuItem和Menu都不是Node的子类. http://docs.oracle.com/javafx/2/api/javafx/scene/control/MenuItem.html http://docs.oracle.com/javafx/2/api/javafx/scene/control/Menu.html
我建议将源作为Object抓取,然后在继续之前检查其类型.另外,我遇到了使用getSource()方法的问题; getTarget()方法对我来说效果更好.无论哪种方式,你仍然需要一种方法来进入舞台.
为此,您可能希望fx:id
在FXML中使用标记而不是id
标记.这将允许您将FXML元素直接注入控制器.例如,您可以通过将MenuBar元素注入控制器,从MenuBar(它是Node的子类)中获取Stage.
在FXML中:
<MenuBar fx:id="myMenuBar" layoutY="0.0" max pref useSystemMenuBar="false" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0">
在控制器中:
public class Controller implements Initializable { @FXML MenuBar myMenuBar; ... @FXML protected void onTweetsMenuActionPerformed(ActionEvent event) { System.out.println("Manage Accbtnclick"); Stage stage = (Stage) myMenuBar.getScene().getWindow(); Scene scene = Main.screens.get("tweet"); stage.setScene(scene); stage.show(); } ... }
你可能需要在这里做一些调整,但希望它有所帮助.