我刚学会了如何使用带有FXML文件的JavaFX制作GUI应用程序。但有一件事我不明白。当我尝试将KeyListener添加到Label或我的FXML文件中的布局时,代码不会被执行。这是一个简单的任务,如System.out.println("worked");
,没有什么复杂的(最终我想用keylistener移动Label,但现在我只想要一些简单的东西,我可以很容易地看到它是否有效)。我在某处读到你需要在Frame级别添加监听器,但我不知道如何。如果有人可以帮助我,我将非常感激
Main.java:
package sample;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
Scene scene = new Scene(root, 600, 600);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>()
{
@Override
public void handle(KeyEvent event) {
Controller controller = new Controller();
controller.moveLabel(event);
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我的控制器类:
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
public class Controller {
@FXML
private Label label;
@FXML
public void moveLabel(KeyEvent e){
switch (e.getCode()){
case RIGHT:
label.setTranslateX(3);
break;
default:
System.out.println("not possible");
}
}
}
我的FXML文件:
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Label?>
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10"
vgap="10">
<Label text="Text" fx:id="label" ></Label>
</GridPane
错误讯息:
Exception in thread "JavaFX Application Thread"
java.lang.NullPointerException
at sample.Controller.moveLabel(Controller.java:15)
at sample.Main$1.handle(Main.java:22)
at sample.Main$1.handle(Main.java:18)
at
com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handle
BubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent
(CompositeEventHandler.java:80)
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.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$KeyHandler.process(Scene.java:3964)
at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run
(GlassViewEventHandler.java:217)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run
(GlassViewEventHandler.java:149)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$352
(GlassViewEventHandler.java:248)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock
(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent
(GlassViewEventHandler.java:247)
at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
at com.sun.glass.ui.View.notifyKey(View.java:966)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147
(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
答案 0 :(得分:0)
向控制器添加方法以移动标签,例如
public class Controller {
private final double moveDelta = 10 ;
@FXML
private Label labelTest ;
public void moveLabel(int deltaX, int deltaY) {
labelTest.setTranslateX(labelTest.getTranslateX() + moveDelta * deltaX);
labelTest.setTranslateY(labelTest.getTranslateY() + moveDelta * deltaY);
}
}
然后在start()
方法中获取对控制器的引用(您需要使用load()
中的非静态FXMLLoader
方法来执行此操作),并从中调用方法密钥处理程序:
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Hello World");
Scene scene = new Scene(root, 600, 600);
Controller controller = loader.getController();
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
switch(event.getCode()){
case RIGHT:
controller.moveLabel(1, 0);
break;
default:
System.out.println("not possible");
}
}
});
primaryStage.setScene(scene);
primaryStage.show();
}