javafx fxml在initialize()之外为null [英] javafx fxml is null outside initialize()

查看:180
本文介绍了javafx fxml在initialize()之外为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此代码中:

public class ESM extends Application {

private Stage primaryStage;

@FXML 
private ToolBar mainToolBar;


@Override
public void start(final Stage stage) throws Exception {
    try{
        this.primaryStage = stage;
        Parent root = FXMLLoader.load(getClass().getResource("/nz/co/great_ape/esm3/main_window.fxml"));

        Scene scene = new Scene(root, 800, 700);            
        //  Setup main stage to be full screen, no min or max buttons.
        //  TODO:  How will this handle multiple screens?  Apparently not well :-(
        Screen screen = Screen.getPrimary();
        Rectangle2D bounds = screen.getVisualBounds();
        primaryStage.setX(bounds.getMinX());
        primaryStage.setY(bounds.getMinY());
        primaryStage.setWidth(bounds.getWidth());
        primaryStage.setHeight(bounds.getHeight());
        primaryStage.initStyle(StageStyle.UNDECORATED); 
        primaryStage.setTitle("ESM three");
        primaryStage.setScene(scene);
        primaryStage.show();
        System.out.println("This will fail because mainToolBar is null.  Why?");
        assert mainToolBar != null : "fx:id=\"mainToolBar\" was null check your FXML ";
    } catch (Exception ex) {
        Logger.getLogger(ESM.class.getName()).log(Level.SEVERE, null, ex);
    }           
}



/**
 * Use initialize() to setup widgets from scenebuilder files, it is
 * called by FXMLLoader.
 */
@FXML
public void initialize(){
    System.out.println("initialize() But when here all is good and mainToolBar is a ToolBar.");
    assert mainToolBar != null : "fx:id=\"mainToolBar\" was null check your FXML ";     
}

/**
 * The main() method is ignored in correctly deployed JavaFX application.
 * main() serves only as fallback in case the application can not be
 * launched through deployment artifacts, e.g., in IDEs with limited FX
 * support. 
 *
 * @param args The command line arguments.
 */
public static void main(String[] args) {
    launch(args);

}

}

我无法理解为什么它在initialise()中有一个值,但在开始时它是null。在调试时很明显,FXMLLOader从start()内部调用initiialize()

I cant see why it's got a value in the initialise() but in the start it's null. When debuging it's clear that initiialize() is called by FXMLLOader from inside start()

我打算发布fxml但它似乎不起作用nothig shows in预览。无论如何,它是一个真正的基本文件,BordePane和ToolBar。

I was going to post the fxml but it does not seem to work as nothig shows in the preview. Any way, it's a real basic file, a BordePane and a ToolBar.

任何线索?

推荐答案

始终为您创建一个新课程FXML Controller,不要尝试将Application类重用为Controller类。

Always create a new class for your FXML Controller, don't try to reuse an Application class as a Controller class.

应用程序实例由JavaFX应用程序启动器创建。

An Application instance is created by the JavaFX application launcher.

一个Controller实例是由JavaFX FXML加载器创建的。

A Controller instance is created by the JavaFX FXML loader.

你不提供你使用的FXML,但我要去猜测它的Controller类被错误地设置为你的应用程序类。

You don't supply the FXML that you use, but I am going to guess that it has it's Controller class erroneously set to be your application class.

所以在你的代码中,会发生什么:

So in your code, what happens is:


  1. 运行程序时(通过启动方法)创建应用程序实例。

  2. 在应用程序启动方法中,调用FXMLLoader,它实例化一个新的Controller(在你的情况下是一个新的应用程序类的实例)。

  3. FXMLLoader将@FXML标记的成员注入到 new 应用程序对象并调用初始化 new 对象。

  4. 但您的原始应用程序对象对新应用程序对象一无所知,因此没有设置菜单栏。

  1. An instance of the application is created when you run the program (via the launch method).
  2. In your application start method, you invoke the FXMLLoader, which instantiates a new Controller (in your case a new instance of the application class).
  3. The FXMLLoader injects the @FXML tagged members into the new application object and invokes the initialize on the new object.
  4. But your original application object doesn't know anything about the new application object and hence doesn't have a menu bar set in it.

总之,为了解决这个问题:

In summary, to fix this:


  1. 创建一个FXMLLoader可以创建的新控制器类实例化。

  2. 更改你的fxml以引用新的控制器类。

如果你的应用程序真的需要引用控制器,然后你可以使用 getController 方法提供了检索所需元素的公共方法(如菜单栏)。有关此方法的更多示例,请参阅我对传递参数JavaFX FXML 的回答。

If your application really needs to reference the controller, then you can use the getController method on the FXML loader and in your controller class provide public methods to retrieve required elements (like your menu bar). See my answer to Passing Parameters JavaFX FXML for some more examples of this method.

import javafx.scene.control.ToolBar;
import javafx.fxml.FXML;

public class ESMController {
  @FXML 
  private ToolBar mainToolBar;
  public  ToolBar getMainToolBar() { return mainToolBar; }

  @FXML
  public void initialize(){
    assert mainToolBar != null : "fx:id=\"mainToolBar\" was null check your FXML ";     
  }
}

这篇关于javafx fxml在initialize()之外为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆