【问题标题】:JavaFX - how to edit/use variables in scenesJavaFX - 如何在场景中编辑/使用变量
【发布时间】:2018-04-02 13:07:45
【问题描述】:

如何更改 JavaFX 场景中标签的值?我试图找出一种方法来更改按钮单击时标签的文本值,但它不起作用。 我为按钮和标签设置了 fx:id 并设置了它们的控制器(CPCS305_JAVAFX_FXML,类本身。按钮还链接到 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$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.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.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: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$handleMouseEvent$354(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 文件及其控制器、函数,但我将其留待以后处理。我想解决一个场景不能交流的问题,然后再去多场景。

对新学习者有什么想法吗?

编辑:此类的 FXML 文件 http://textuploader.com/d4wgi

EDIT2:已修复。问题在于错误的导入。给大家添麻烦了,谢谢大家的支持。

【问题讨论】:

    标签: java javafx dependencies fxml


    【解决方案1】:

    您需要使用 @FXML 注释 每个实例字段,以便 FXML 加载器分配它。如果不这样做,值将保持为null。此外,FXML 加载器需要知道哪个对象是控制器。您已通过fx:controller="cpcs305_javafx_fxml.CPCS305_JAVAFX_FXML" 在 FXML 中指定了这一点,但这意味着FXMLLoader 将创建您的类的第二个实例,因为它确实有办法将其连接到您当前的类。为此,您可以使用setController 指定控制器,使用setControllerFactory 指定控制器工厂,或者将参数传递给采用静态函数的多个参数之一。

    由于您在 FXML 中定义了类,因此您需要使用控制器工厂。 FXML 加载器将要求控制器工厂实例化它作为参数提供的类的对象。如果您想使用已经实例化的类,只需忽略 class 参数并返回 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");
       }
    }
    

    【讨论】:

    • 我按照你的步骤做了你的建议,但它仍然不起作用。它现在不运行,并且在错误报告的两行中说:“Caused by: java.lang.RuntimeException: Exception in Application start method”和“Caused by: java.lang.ClassCastException: javafx.scene.layout .AnchorPane 无法转换为 javafx.fxml.FXMLLoader"
    【解决方案2】:

    @FXML 注释应该仅位于 FXML 文件中定义的元素之上,例如标签、按钮和锚窗格。

    试试看吧。

    【讨论】:

    • 我尝试按照建议从@FXML 中取出 Scene、Stage 并在顶部定义它们,但结果是“java.lang.reflect.InvocationTargetException”。
    【解决方案3】:

    我在 Scene Builder 上使用的按钮/标签使用了错误的导入。我修复了这些导入,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-18
      • 2020-02-24
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      • 2016-09-09
      相关资源
      最近更新 更多