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
并为您注册处理程序,您自己没有必要(而且这是不正确的)。
[![在此处输入图片描述][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
并为您注册处理程序,您自己没有必要(而且这是不正确的)。