无法从 JavaFX 中的 MenuItem 获取场景 [英] Unable to get Scene from MenuItem in JavaFX

查看:40
本文介绍了无法从 JavaFX 中的 MenuItem 获取场景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据 menuItem 单击更改 javafx 阶段中的场景.这是我的 sample.fxml:

I am trying to change the scene in a javafx stage based on menuItem click. Here is my sample.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>

这是我的 Controller.java:

Here is my 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:

Here is my 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);
    }
}

当我点击 Accounts Menu 下的 menuItem Manage 时,出现以下异常:

When I click on the menuItem Manage under Accounts Menu, I get the following exception:

    "C:Program FilesJavajdk1.7.0_17injava" -Didea.launcher.port=7541 "-Didea.launcher.bin.path=C:Program Files (x86)JetBrainsIntelliJ IDEA 12.1.4in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_17jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_17jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_17jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_17jrelibjce.jar;C:Program FilesJavajdk1.7.0_17jrelibjfr.jar;C:Program FilesJavajdk1.7.0_17jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_17jrelibjsse.jar;C:Program FilesJavajdk1.7.0_17jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_17jrelibplugin.jar;C:Program FilesJavajdk1.7.0_17jrelib
esources.jar;C:Program FilesJavajdk1.7.0_17jrelib
t.jar;C:Program FilesJavajdk1.7.0_17jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_17jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_17jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_17jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_17jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_17jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_17jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_17jrelibextzipfs.jar;C:Users
ahulserverIdeaProjectsDrawingTextoutproductionDrawingText;C:Program Files (x86)JetBrainsIntelliJ IDEA 12.1.4libidea_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

那么如何从菜单项单击事件处理程序中获取包含阶段/场景?

So how do I get the containing stage/scene from the menu Item clicked event handler?

编辑线

Node node= (Node)event.getSource();

在 controller.java 中是第 29 行,这会产生问题.

in controller.java is line number 29 which is giving problems.

推荐答案

你真正的错误显示在堆栈跟踪的倒数第二行:

Your real error is shown in the second to last line of the stack trace:

Caused by: java.lang.ClassCastException: javafx.scene.control.MenuItem cannot be cast to javafx.scene.Node
    at sample.Controller.onTweetsMenuActionPerformed(Controller.java:29)

此错误指的是控制器中的以下行:

This error is referring to the following line from your controller:

Node node= (Node)event.getSource();

查看 JavaFX API 文档,MenuItem 和 Menu 都不是 Node 的子类.http://docs.oracle.com/javafx/2/api/javafx/场景/控制/MenuItem.htmlhttp://docs.oracle.com/javafx/2/api/javafx/场景/控制/Menu.html

Looking at the JavaFX API Docs, neither MenuItem nor Menu are subclasses of 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

我建议将源作为对象获取,然后在继续之前检查其类型.另外,我在使用 getSource() 方法时遇到了问题;getTarget() 方法对我来说效果更好.不管怎样,你仍然需要一种方法来进入舞台.

I would suggest grabbing the source as an Object, then checking its type before continuing. Also, I ran into problems using the getSource() method; the getTarget() method worked better for me. Either way, you still need a way to get the to the Stage.

为此,您可能希望在 FXML 中使用 fx:id 标签,而不是 id 标签.这将允许您将 FXML 元素直接注入到您的控制器中.例如,您可以通过将 MenuBar 元素注入控制器来从 MenuBar(它是 Node 的子类)中获取舞台.

To do this, you might want to use the fx:id tag in your FXML instead of the id tag. This will allow you to inject the FXML elements directly into your controller. For example, you could grab the Stage from the MenuBar (which is a subclass of Node) by injecting the MenuBar element into your controller.

在 FXML 中:

<MenuBar fx:id="myMenuBar" layoutY="0.0" maxWidth="1.7976931348623157E308" prefWidth="300.0" 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();
    }
    ...
}

您可能需要在此处进行一些调整,但希望对您有所帮助.

You may need to do a bit of tweaking here, but hopefully it helps.

这篇关于无法从 JavaFX 中的 MenuItem 获取场景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆