Javafx。控制器初始化方法和spring@PostConstruct不能一起使用
下面是我的javafx项目的控制器。我的目标是在DemoConfig类中配置一些默认值,该类在DemoController中作为bean注入,因此我必须使用@PostConstuct 为了正确初始化值,控制器必须实现初始化方法 以下是DemoController代码: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
@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的一部分,因此