JavaFX - 如何在场景中 edit/use 变量
JavaFX - how to edit/use variables in scenes
如何更改 JavaFX 场景中标签的值?我正在尝试找出一种方法来在单击按钮时更改标签的文本值,但它不起作用。
我已经为按钮和标签设置了 fx:id 并设置了它们的控制器(CPCS305_JAVAFX_FXML,class 本身。该按钮还链接到 handleButtonAction2() 函数。
public class CPCS305_JAVAFX_FXML extends Application {
@FXML
Scene scene;
Stage stage;
Label main_label
Button login_button;
AnchorPane root;
@Override
public void start(Stage stage) throws Exception {
root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
scene = new Scene(root);
stage.setScene(scene);
stage.show();
@FXML
private void handleButtonAction2(ActionEvent event) throws IOException, Exception {
main_label.setText("Hello World");
}
public static void main(String[] args) {
launch(args);
}}
错误报告是这样的:
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:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(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.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:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)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:498)
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:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 moreCaused by: java.lang.NullPointerException
at cpcs305_javafx_fxml.CPCS305_JAVAFX_FXML.handleButtonAction2(CPCS305_JAVAFX_FXML.java:64)
... 55 more
我还有 2 个其他 FXML 文件及其控制器、函数,但我将其留待以后使用。我想先解决一个场景无法交流的问题,然后再进行多个场景。
对新学习者有什么想法吗?
编辑:此 class 的 FXML 文件
http://textuploader.com/d4wgi
EDIT2:已修复。问题在于错误的导入。不好意思给大家添麻烦了,谢谢大家的支持
@FXML 注释应该仅位于 FXML 文件中定义的元素之上,例如标签、按钮和锚定窗格。
试试看吧
您需要使用@FXML 注释每个实例字段,以便由 FXML 加载程序分配它。如果不这样做,值将保持 null
。此外,FXML 加载器需要知道哪个对象是控制器。您已通过 fx:controller="cpcs305_javafx_fxml.CPCS305_JAVAFX_FXML"
在 FXML 中指定,但这意味着 FXMLLoader
将创建您的 class 的第二个实例,因为它确实有办法将其连接到您当前的 class。您可以通过 setController
指定一个控制器,setControllerFactory
指定一个控制器工厂,或者通过将参数传递给采用静态函数的多个参数之一来实现。
由于您在 FXML 中定义了 class,因此您需要使用控制器工厂。 FXML 加载器将要求控制器工厂实例化它作为参数提供的 class 的对象。当您想使用已经实例化的 class 时,只需忽略 class 参数和 return this
.
public class CPCS305_JAVAFX_FXML extends Application {
@FXML // because there is a fx:id="main_label" in the FXML
private Label main_label; // Java naming convention would be mainLabel
@FXML // because there is a fx:id="login_button" in the FXML
private Button login_button; // Java naming convention would be loginButton
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
loader.setControllerFactory(controllerClass -> this); // 'this' object will be the controller.
Parent root = loader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
@FXML // because there is a onAction="#handleButtonAction" in the FXML
private void handleButtonAction() { // parameter is optional
main_label.setText("Hello World");
}
}
我在 Scene Builder 上使用的 button/label 导入错误。我修复了这些导入,一切正常。
如何更改 JavaFX 场景中标签的值?我正在尝试找出一种方法来在单击按钮时更改标签的文本值,但它不起作用。 我已经为按钮和标签设置了 fx:id 并设置了它们的控制器(CPCS305_JAVAFX_FXML,class 本身。该按钮还链接到 handleButtonAction2() 函数。
public class CPCS305_JAVAFX_FXML extends Application {
@FXML
Scene scene;
Stage stage;
Label main_label
Button login_button;
AnchorPane root;
@Override
public void start(Stage stage) throws Exception {
root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
scene = new Scene(root);
stage.setScene(scene);
stage.show();
@FXML
private void handleButtonAction2(ActionEvent event) throws IOException, Exception {
main_label.setText("Hello World");
}
public static void main(String[] args) {
launch(args);
}}
错误报告是这样的:
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:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(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.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:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)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:498)
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:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 moreCaused by: java.lang.NullPointerException
at cpcs305_javafx_fxml.CPCS305_JAVAFX_FXML.handleButtonAction2(CPCS305_JAVAFX_FXML.java:64)
... 55 more
我还有 2 个其他 FXML 文件及其控制器、函数,但我将其留待以后使用。我想先解决一个场景无法交流的问题,然后再进行多个场景。
对新学习者有什么想法吗?
编辑:此 class 的 FXML 文件 http://textuploader.com/d4wgi
EDIT2:已修复。问题在于错误的导入。不好意思给大家添麻烦了,谢谢大家的支持
@FXML 注释应该仅位于 FXML 文件中定义的元素之上,例如标签、按钮和锚定窗格。
试试看吧
您需要使用@FXML 注释每个实例字段,以便由 FXML 加载程序分配它。如果不这样做,值将保持 null
。此外,FXML 加载器需要知道哪个对象是控制器。您已通过 fx:controller="cpcs305_javafx_fxml.CPCS305_JAVAFX_FXML"
在 FXML 中指定,但这意味着 FXMLLoader
将创建您的 class 的第二个实例,因为它确实有办法将其连接到您当前的 class。您可以通过 setController
指定一个控制器,setControllerFactory
指定一个控制器工厂,或者通过将参数传递给采用静态函数的多个参数之一来实现。
由于您在 FXML 中定义了 class,因此您需要使用控制器工厂。 FXML 加载器将要求控制器工厂实例化它作为参数提供的 class 的对象。当您想使用已经实例化的 class 时,只需忽略 class 参数和 return this
.
public class CPCS305_JAVAFX_FXML extends Application {
@FXML // because there is a fx:id="main_label" in the FXML
private Label main_label; // Java naming convention would be mainLabel
@FXML // because there is a fx:id="login_button" in the FXML
private Button login_button; // Java naming convention would be loginButton
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
loader.setControllerFactory(controllerClass -> this); // 'this' object will be the controller.
Parent root = loader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
@FXML // because there is a onAction="#handleButtonAction" in the FXML
private void handleButtonAction() { // parameter is optional
main_label.setText("Hello World");
}
}
我在 Scene Builder 上使用的 button/label 导入错误。我修复了这些导入,一切正常。