JavaFX 标签不响应鼠标事件处理程序

JavaFX Label not responding to Mouse EventHandler

[![在此处输入图片描述][1]][1] 我有多个标签,它们应该链接到多个场景。我已经实现了 Mouse EventHandlers,并且程序编译正常并且 运行 正确,除了标签没有响应点击。这是代码的一部分:

 package rootPKG;

 // imports here

 public class LandingController extends Application implements EventHandler<ActionEvent>, Initializable
 {
 @FXML
private ImageView avatarImgView;
@FXML
private Image avatar;
 private Button exit;
@FXML
private Label enterRT;


 @Override
public void handle(ActionEvent event)
{
    if(event.getSource() == addVeh)
    {
        // Instantiating the parent that holds the fxml
        Parent vehParent = null;
        try
        {
            vehParent = FXMLLoader.load(getClass().getResource("Vehicles.fxml"));
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }

        // setting the scene
        Scene vehScene = new Scene(vehParent);

        // setting the stage for the scene
        Stage vehStage = (Stage) ((Node) event.getSource()).getScene().getWindow();

        vehStage.setTitle("Create a vehicle");
        vehStage.setScene(vehScene);
        vehStage.setFullScreen(false);
        vehStage.initModality(Modality.APPLICATION_MODAL);
        vehStage.show();
    }


    if(event.getSource() == enterRT)
    {
        enterRT.setOnMouseReleased(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                // Instantiating the parent that holds the fxml
                Parent rTParent = null;
                try
                {
                    rTParent = FXMLLoader.load(getClass().getResource("RealTime.fxml"));
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }

                // setting the scene
                Scene vehScene = new Scene(rTParent);

                // setting the stage for the scene
                Stage rTStage = (Stage) ((Node) event.getSource()).getScene().getWindow();

                rTStage.setTitle("Real Time Mode - Immediate Test");
                rTStage.setScene(vehScene);
                rTStage.setFullScreen(false);
                //rTStage.initModality(Modality.APPLICATION_MODAL);
                rTStage.show();
            }
        });

 @Override
public void initialize(URL location, ResourceBundle resources)
{

}

public static void main(String[] args) {
    launch(args);
}

   }

当我点击 enterRT 标签时控制台的输出:

      Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
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:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
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:497)
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:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 29 more
 Caused by: java.lang.ClassCastException: javafx.scene.input.MouseEvent cannot be cast to javafx.event.ActionEvent
at rootPKG.LandingController.handle(LandingController.java:25)
... 39 more
 Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
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:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
 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:497)
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:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 29 more

 Caused by: java.lang.ClassCastException: javafx.scene.input.MouseEvent cannot be cast to javafx.event.ActionEvent
at rootPKG.LandingController.handle(LandingController.java:25)
... 39 more

从控制台,我认为错误与这些行有关:

 Caused by: java.lang.ClassCastException: javafx.scene.input.MouseEvent cannot be cast to javafx.event.ActionEvent
at rootPKG.LandingController.handle(LandingController.java:28)
... 39 more

 Caused by: java.lang.ClassCastException: javafx.scene.input.MouseEvent cannot be cast to javafx.event.ActionEvent
at rootPKG.LandingController.handle(LandingController.java:28)
... 39 more

FXML 代码:

 <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="630.0" prefWidth="1300.0" styleClass="borderpaneStyle" stylesheets="@homelab.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="rootPKG.LandingController">
 <top>
  <VBox prefHeight="183.0" prefWidth="1300.0" styleClass="universalTranspBg50perc" stylesheets="@homelab.css" BorderPane.alignment="CENTER">
     <children>
        <HBox prefHeight="100.0" prefWidth="1294.0" stylesheets="@homelab.css" VBox.vgrow="NEVER">
           <VBox.margin>
              <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
           </VBox.margin>
        </HBox>
        <HBox layoutX="10.0" layoutY="10.0" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
           <children>
              <HBox maxHeight="60.0" maxWidth="60.0" prefHeight="60.0" prefWidth="60.0" styleClass="avatarHBox" stylesheets="@avatar.css">
                 <children>
                    <HBox HBox.hgrow="NEVER">
                       <HBox.margin>
                          <Insets />
                       </HBox.margin>
                       <children>
                          <ImageView fx:id="avatarImgView" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" smooth="false" styleClass="avatar">
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <image>
                                <Image url="@appEmblems/homelab%20icon%202.png" />
                             </image>
                          </ImageView>
                       </children>
                    </HBox>
                 </children>
                 <HBox.margin>
                    <Insets left="10.0" right="10.0" />
                 </HBox.margin>
              </HBox>
              <HBox>
                 <children>
                    <Label fx:id="fname" styleClass="username" stylesheets="@avatar.css" text="tapiwa" HBox.hgrow="ALWAYS">
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor></Label>
                    <Label fx:id="nick" layoutX="10.0" layoutY="20.0" styleClass="nickname" stylesheets="@avatar.css" text="'tp'" HBox.hgrow="ALWAYS">
                       <HBox.margin>
                          <Insets left="5.0" right="3.0" />
                       </HBox.margin>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                    </Label>
                 </children>
                 <HBox.margin>
                    <Insets right="10.0" />
                 </HBox.margin>
                 <padding>
                    <Insets bottom="10.0" top="10.0" />
                 </padding>
              </HBox>
              <HBox prefHeight="25.0" prefWidth="340.0" styleClass="selectedVehWrapper" stylesheets="@homelab.css" HBox.hgrow="ALWAYS">
                 <HBox.margin>
                    <Insets bottom="20.0" left="40.0" right="15.0" top="20.0" />
                 </HBox.margin>
                 <children>
                    <Label fx:id="chosenVeh" styleClass="selectedVeh" stylesheets="@homelab.css" text="2014 Ducati Monster Diesel" HBox.hgrow="ALWAYS">
                       <HBox.margin>
                          <Insets right="5.0" />
                       </HBox.margin>
                       <padding>
                          <Insets bottom="2.0" left="15.0" right="15.0" top="2.0" />
                       </padding>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                    </Label>
                    <Region prefHeight="25.0" prefWidth="57.0" HBox.hgrow="ALWAYS" />
                    <ComboBox fx:id="chooseVeh" opacity="0.86" prefHeight="25.0" prefWidth="234.0" promptText="click/touch to select vehicle" styleClass="vehListCombo" stylesheets="@homelab.css" HBox.hgrow="ALWAYS">
                       <HBox.margin>
                          <Insets right="5.0" />
                       </HBox.margin>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                    </ComboBox>
                    <Button fx:id="addVeh" mnemonicParsing="false" onAction="#handle" styleClass="buttonAddVeh" stylesheets="@homelab.css" text="add" HBox.hgrow="ALWAYS">
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                       <font>
                          <Font name="System Italic" size="12.0" />
                       </font>
                    </Button>
                 </children>
              </HBox>
              <HBox HBox.hgrow="NEVER">
                 <HBox.margin>
                    <Insets />
                 </HBox.margin>
                 <children>
                    <Button fx:id="exit" mnemonicParsing="false" onAction="#handle" styleClass="buttonExit" stylesheets="@homelab.css" text="  EXIT  " />
                 </children>
                 <padding>
                    <Insets bottom="20.0" top="20.0" />
                 </padding>
              </HBox>
              <HBox>
                 <children>
                    <Label fx:id="onlineStatus" onMouseClicked="#handle" styleClass="onlineStatus" stylesheets="@homelab.css" text="    currently offline    ">
                       <effect>
                          <Glow level="1.0" />
                       </effect>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor></Label>
                 </children>
                 <padding>
                    <Insets bottom="5.0" top="25.0" />
                 </padding>
                 <HBox.margin>
                    <Insets left="50.0" right="100.0" />
                 </HBox.margin>
              </HBox>
           </children>
           <VBox.margin>
              <Insets right="75.0" />
           </VBox.margin></HBox>
        <HBox layoutX="10.0" layoutY="93.0" prefHeight="100.0" prefWidth="1300.0" VBox.vgrow="NEVER" />
        <HBox layoutX="10.0" layoutY="110.0" maxHeight="63.0" prefHeight="63.0" prefWidth="1300.0" VBox.vgrow="NEVER">
           <children>
              <HBox maxWidth="150.0" prefHeight="100.0" prefWidth="150.0" styleClass="appEmblem" stylesheets="@homelab.css" HBox.hgrow="NEVER">
                 <children>
                    <Label styleClass="appEmblemLabel1" stylesheets="@homelab.css" text="home">
                       <font>
                          <Font size="21.0" />
                       </font>
                       <HBox.margin>
                          <Insets left="3.0" top="5.0" />
                       </HBox.margin>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                    </Label>
                    <Label styleClass="appEmblemLabel2" stylesheets="@homelab.css" text="LAB">
                       <font>
                          <Font size="21.0" />
                       </font>
                       <HBox.margin>
                          <Insets top="5.0" />
                       </HBox.margin>
                       <cursor>
                          <Cursor fx:constant="HAND" />
                       </cursor>
                    </Label>
                 </children></HBox>
              <HBox styleClass="shortcutLinksFill" stylesheets="@homelab.css" HBox.hgrow="ALWAYS">
                 <children>
                    <TextFlow textAlignment="CENTER" HBox.hgrow="ALWAYS">
                       <children>
                          <Label fx:id="enterRT" onMouseClicked="#handle" onMousePressed="#handle" onMouseReleased="#handle" stylesheets="@homelab.css" text="  Enter Real-Time Mode  " textFill="AQUA">
                             <font>
                                <Font name="Droid Sans" size="15.0" />
                             </font>
                             <styleClass>
                                <String fx:value="shortcutLinksLabelsColor" />
                                <String fx:value="shortcutLinksLabelsfont" />
                             </styleClass>
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <padding>
                                <Insets left="20.0" right="20.0" />
                             </padding>
                          </Label>
                          <Label fx:id="Notif" stylesheets="@homelab.css" text="  Notifications  " textFill="AQUA">
                             <font>
                                <Font name="Droid Sans" size="15.0" />
                             </font>
                             <styleClass>
                                <String fx:value="shortcutLinksLabelsColor" />
                                <String fx:value="shortcutLinksLabelsfont" />
                             </styleClass>
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <padding>
                                <Insets left="20.0" right="20.0" />
                             </padding>
                          </Label>
                          <Label fx:id="profile" stylesheets="@homelab.css" text="  Profile  " textFill="AQUA">
                             <font>
                                <Font name="Droid Sans" size="15.0" />
                             </font>
                             <styleClass>
                                <String fx:value="shortcutLinksLabelsColor" />
                                <String fx:value="shortcutLinksLabelsfont" />
                             </styleClass>
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <padding>
                                <Insets left="20.0" right="20.0" />
                             </padding>
                          </Label>
                          <Label fx:id="prefs" stylesheets="@homelab.css" text="  Preferences  " textFill="AQUA">
                             <font>
                                <Font name="Droid Sans" size="15.0" />
                             </font>
                             <styleClass>
                                <String fx:value="shortcutLinksLabelsColor" />
                                <String fx:value="shortcutLinksLabelsfont" />
                             </styleClass>
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <padding>
                                <Insets left="20.0" right="20.0" />
                             </padding>
                          </Label>
                          <Label fx:id="help" stylesheets="@homelab.css" text="  Help  " textFill="AQUA">
                             <font>
                                <Font name="Droid Sans" size="15.0" />
                             </font>
                             <styleClass>
                                <String fx:value="shortcutLinksLabelsColor" />
                                <String fx:value="shortcutLinksLabelsfont" />
                             </styleClass>
                             <cursor>
                                <Cursor fx:constant="HAND" />
                             </cursor>
                             <padding>
                                <Insets left="20.0" right="20.0" />
                             </padding>
                          </Label>
                       </children>
                    </TextFlow>
                 </children>
                 <padding>
                    <Insets bottom="10.0" top="10.0" />
                 </padding>
              </HBox>

由于正文限制遗漏了一些代码,但包含了关键代码。

您将错误的事件类型作为 handle 方法的参数。鼠标按下和鼠标释放事件生成 MouseEvent 秒,而不是 ActionEvent 秒。因此,您会得到 class 转换异常,因为当 FXML 加载程序创建的处理程序将事件对象(MouseEvent)传递给方法时,它会尝试将其转换为 ActionEvent

不过,总的来说,您从根本上误解了控制器 class 中事件处理的设置方式。您的控制器无需实现 EventHandler。当 FXML 加载器加载 fxml 文件时,它将为您创建必要的事件处理程序,其 handle 方法调用您在 fxml 中指定的方法,并将这些处理程序注册到您定义的节点。所以你需要做的就是编写一个方法来处理 "mouse pressed" 事件,以及一个方法来处理 "mouse released" 事件,并在 fxml 中指定这些方法。您指定的处理程序方法可以有任何名称,并且可以有零个参数,或者可以有一个参数用于适当的事件类型(即本例中的 MouseEvent)。所以你的控制器应该是这样的:

public class LandingController extends Application implements Initializable {

    @FXML
    private ImageView avatarImgView;
    @FXML
    private Image avatar;
    @FXML
    private Button exit;
    @FXML
    private Label enterRT;

    @FXML
    private void handleMousePress(MouseEvent event) {
        // code in this method is executed when the mouse is pressed
        // on a node with onMousePressed="#handleMousePress"
    }

    @FXML
    private void handleMouseRelease(MouseEvent event) {
        // code in this method is executed when the mouse is released
        // on a node with onMousePressed="#handleMouseRelease"
    }

    @FXML
    private void add(ActionEvent event) {
        // code in this method is executed when an action event
        // occurs on a node with onAction="#add"
    }


    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }

}

现在对于感兴趣的标签,只需在 FXML 文件中指定 onMousePress="#handleMousePress"onMouseRelease="handleMouseRelease",或 select 在 Scene Builder 的相应框中指定方法。同样,FXMLLoader 会负责实施 EventHandler 并为您注册处理程序,您自己没有必要(而且这是不正确的)。