简体   繁体   中英

JavaFX Label not responding to Mouse EventHandler

[![enter image description here][1]][1] I have multiple labels which should be links to multiple Scenes. I've implemented Mouse EventHandlers and the program is compiling fine and running properly except the labels are not responding to clicks. Here's part of the code:

 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);
}

   }

The output from console when I click the enterRT label:

      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.access$1500(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$handleMouseEvent$354(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$null$148(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.access$1500(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$handleMouseEvent$354(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$null$148(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

From the console, I think the error has to do with these lines:

 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 code:

 <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>

Left out some code due to body limit but the crucial code is included.

You have the wrong event type as a parameter to your handle method. Mouse pressed and mouse released events generate MouseEvent s, not ActionEvent s. Hence you get the class cast exception, because when the handler created by the FXML loader passes the event object (a MouseEvent ) to the method, it tries to cast it to an ActionEvent .

In general, though, you have fundamentally misunderstood how event handling in a controller class is set up. There is no need for your controller to implement EventHandler . When the FXML loader loads the fxml file, it will create the necessary event handlers for you, whose handle methods invoke the methods you specify in the fxml, and it will register those handlers with the nodes you define. So all you need to do is to write a method to handle the "mouse pressed" event, and a method to handle the "mouse released" event, and specify those methods in the fxml. The handler methods you specify can have any name, and can either have zero parameters, or can have a single parameter for the appropriate event type (ie MouseEvent in this case). So your controller should look like:

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) {

    }

}

and now for the label(s) of interest, simply specify onMousePress="#handleMousePress" and onMouseRelease="handleMouseRelease" in the FXML file, or select the methods in the appropriate boxes in Scene Builder. Again, the FXMLLoader takes care of implementing EventHandler and registering the handlers for you, there is no need (and it's incorrect) to do this yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM