Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javafx。控制器初始化方法和spring@PostConstruct不能一起使用_Java_Spring_Javafx - Fatal编程技术网

Javafx。控制器初始化方法和spring@PostConstruct不能一起使用

Javafx。控制器初始化方法和spring@PostConstruct不能一起使用,java,spring,javafx,Java,Spring,Javafx,下面是我的javafx项目的控制器。我的目标是在DemoConfig类中配置一些默认值,该类在DemoController中作为bean注入,因此我必须使用@PostConstuct 为了正确初始化值,控制器必须实现初始化方法 以下是DemoController代码: @Component public class DemoController implements Initializable { public TextField platformName; public T

下面是我的javafx项目的控制器。我的目标是在DemoConfig类中配置一些默认值,该类在DemoController中作为bean注入,因此我必须使用@PostConstuct

为了正确初始化值,控制器必须实现初始化方法

以下是DemoController代码:

@Component
public class DemoController implements Initializable
{

    public TextField platformName;

    public TextField platformVersion;

    public TextField deviceName;

    public TextField appActivity;

    public TextField appPackage;

    @Autowired
    private DemoConfig demoConfig;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle)
    {
        platformName.setText(demoConfig.getPlatformName());

        platformVersion.setText(demoConfig.getPlatformVersion());

        deviceName.setText(demoConfig.getDeviceName());

        appActivity.setText(demoConfig.getAppActivity());

        appPackage.setText(demoConfig.getAppPackage());
    }

    @PostConstruct
    public void init() {
        platformName = new TextField(demoConfig.getPlatformName());

        platformVersion = new TextField(demoConfig.getPlatformVersion());

        deviceName = new TextField(demoConfig.getDeviceName());

        appActivity = new TextField(demoConfig.getAppActivity());

        appPackage = new TextField(demoConfig.getAppPackage());
    }


}
实际上init()和initialize(URL,ResourceBundle)做的是相同的事情,但是我不能应用@PostConstruct来初始化(URL,ResourceBundle),因为以下异常:

原因:java.lang.IllegalStateException:生命周期方法注释需要无参数方法:

我可以接受这两个方法一起工作,但实际上init()方法只是为了确保在初始化之前正确注入demoConfig bean。我想知道是否有一种更优雅的方式来进行编码?谢谢

您的
init()。正确的控制器类应如下所示:

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class DemoController implements Initializable
{
    @FXML
    private TextField platformName;

    @FXML
    private TextField platformVersion;

    @FXML
    private TextField deviceName;

    @FXML
    private TextField appActivity;

    @FXML
    private TextField appPackage;

    @Autowired
    private DemoConfig demoConfig;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle)
    {
        platformName.setText(demoConfig.getPlatformName());

        platformVersion.setText(demoConfig.getPlatformVersion());

        deviceName.setText(demoConfig.getDeviceName());

        appActivity.setText(demoConfig.getAppActivity());

        appPackage.setText(demoConfig.getAppPackage());
    }

}
关于这个问题的一份报告解释了原因。为了完整起见,我将在此处重复该信息:

假设您未发布的代码中的所有内容都设置正确,当您在
FXMLLoader
上调用
load()
时,将发生以下情况:

  • fxmloader
    将读取FXML文件,并且看到
    fx:controller
    属性,将使用其控制器工厂获取指定类的实例。由于您可能已将控制器工厂配置为使用Spring应用程序上下文来提供控制器,因此它将从应用程序上下文请求
    DemoController
    bean
  • Spring应用程序上下文将实例化
    DemoController
  • Spring应用程序上下文将向
    DemoController
    实例中注入任何依赖项。在本例中,这意味着它将注入
    demoConfig
    字段
  • Spring应用程序上下文将调用任何
    @PostConstruct
    -注释的方法。在原始版本中,这意味着它将调用
    init()
    方法,该方法实例化文本字段并将其文本设置为
    demoConfig
    中的值。由于这些文本字段不是FXML文件中定义的文本字段,因此它们不是UI的一部分,因此没有明显的效果。在上面的正确版本中,没有带注释的
    @PostConstruct
    -方法,此步骤不起任何作用
  • fxmloader
    继续解析FXML文件,实例化其中定义的文本字段。如果它们的
    fx:id
    属性与
    public
    字段或(更好的)
    @FXML
    -注释的非公共字段的名称匹配,则这些字段将由定义为解析FXML文件一部分的文本字段初始化。(这些是作为UI一部分的文本字段。)。因此,在原始版本中,在
    init()
    方法中初始化的文本字段将立即替换为FXML文件中定义的文本字段(因此在
    init()
    方法中完成的所有工作将立即丢失)
  • 在控制器上调用
    initialize()
    方法。在您的版本和我上面发布的版本中,此方法的定义现在将正确文本字段(即,在FXML文件中定义的属于UI的字段)的文本设置为
    demoConfig
    中的值 如您所见,您在
    init()
    方法中所做的一切都是多余的(因为is设置了从未在UI中显示的文本字段的文本),并且无论如何都会立即撤消(因为
    FXMLLoader
    会立即用新文本字段替换它定义的文本字段)

    因此,您只需删除
    init()
    方法,如上所示。如果这不能满足您的要求,那么代码中还有其他错误您没有发布

    注意,我还将控制器的范围更改为
    prototype
    。如果要多次加载FXML文件,每次都会得到一组新的文本字段,并且需要一个新的控制器实例专门用于该组控件。在JavaFX中使用Spring时,所有控制器都应该是原型。

    您的
    init()
    方法是完全冗余的,应该删除。正确的控制器类应如下所示:

    @Component
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public class DemoController implements Initializable
    {
        @FXML
        private TextField platformName;
    
        @FXML
        private TextField platformVersion;
    
        @FXML
        private TextField deviceName;
    
        @FXML
        private TextField appActivity;
    
        @FXML
        private TextField appPackage;
    
        @Autowired
        private DemoConfig demoConfig;
    
        @Override
        public void initialize(URL url, ResourceBundle resourceBundle)
        {
            platformName.setText(demoConfig.getPlatformName());
    
            platformVersion.setText(demoConfig.getPlatformVersion());
    
            deviceName.setText(demoConfig.getDeviceName());
    
            appActivity.setText(demoConfig.getAppActivity());
    
            appPackage.setText(demoConfig.getAppPackage());
        }
    
    }
    
    关于这个问题的一份报告解释了原因。为了完整起见,我将在此处重复该信息:

    假设您未发布的代码中的所有内容都设置正确,当您在
    FXMLLoader
    上调用
    load()
    时,将发生以下情况:

  • fxmloader
    将读取FXML文件,并且看到
    fx:controller
    属性,将使用其控制器工厂获取指定类的实例。由于您可能已将控制器工厂配置为使用Spring应用程序上下文来提供控制器,因此它将从应用程序上下文请求
    DemoController
    bean
  • Spring应用程序上下文将实例化
    DemoController
  • Spring应用程序上下文将向
    DemoController
    实例中注入任何依赖项。在本例中,这意味着它将注入
    demoConfig
    字段
  • Spring应用程序上下文将调用任何
    @PostConstruct
    -注释的方法。在原始版本中,这意味着它将调用
    init()
    方法,该方法实例化文本字段并将其文本设置为
    demoConfig
    中的值。由于这些文本字段不是FXML文件中定义的文本字段,因此它们不属于UI的一部分,因此