Java @FXML批注无法正常工作
我目前正在使用JavaFX进行一个“小型”项目。我使用SceneBuilder创建GUI的第一个草图。它仍然需要一些调整和样式,但我想看看它是否工作到目前为止 我在GUI上有两个超链接,如果用户单击其中一个,默认的系统浏览器将打开一个特定的URL 到目前为止,我得到了这个: Main.java:Java @FXML批注无法正常工作,java,javafx,fxml,fxmlloader,Java,Javafx,Fxml,Fxmlloader,我目前正在使用JavaFX进行一个“小型”项目。我使用SceneBuilder创建GUI的第一个草图。它仍然需要一些调整和样式,但我想看看它是否工作到目前为止 我在GUI上有两个超链接,如果用户单击其中一个,默认的系统浏览器将打开一个特定的URL 到目前为止,我得到了这个: Main.java: public class Main extends Application { @Override public void start(Stage primaryStage) throws Malfo
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws MalformedURLException, IOException {
DataBean dataBean= new DataBean(primaryStage);
Controller controller = new Controller(dataBean);
controller.show();
}
public static void main(String[] args) {
launch(args);
}
}
DataBean.java:
public class DataBean {
private Stage primaryStage;
public DataBean(Stage stage) {
primaryStage = stage;
}
public Stage getPrimaryStage() {
return primaryStage;
}
}
TestautomatView.java:
public class TestautomatView implements Initializable {
@FXML
private ComboBox<String> environmentCombo;
@FXML
private Hyperlink crhl;
@FXML
private Hyperlink help;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
private Scene scene;
private BorderPane root;
public TestautomatView() throws MalformedURLException, IOException {
root = FXMLLoader.load(new URL(TestautomatView.class.getResource("Sample.fxml").toExternalForm()));
scene = new Scene(root);
}
public void show(Stage stage) {
stage.setTitle("CrossReport Testautomat");
stage.setScene(scene);
stage.show();
}
public ComboBox<String> getEnvironmentCombo() {
return environmentCombo;
}
public Hyperlink getCrhl() {
return crhl;
}
public Hyperlink getHelp() {
return help;
}
public Scene getScene() {
return scene;
}
}
公共类TestautomatView实现了可初始化{
@FXML
私有组合框环境组合;
@FXML
私有超链接crhl;
@FXML
私人超链接帮助;
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
}
私密场景;
私有边界根;
public TestautomatView()引发畸形的DurLexException,IOException{
root=fxmloader.load(新URL(TestautomatView.class.getResource(“Sample.fxml”).toExternalForm());
场景=新场景(根);
}
公开演出(舞台){
阶段。设置标题(“交叉报告测试材料”);
舞台场景;
stage.show();
}
公共组合框getEnvironmentCombo(){
返回环境组合;
}
公共超链接getCrhl(){
返回crhl;
}
公共超链接getHelp(){
回报帮助;
}
公共场景getScene(){
返回场景;
}
}
在我的控制器中,我想将ActionHandler设置为超链接,但它不起作用,因为视图中的getter返回null
public class Controller {
private DataBean dataBean;
private TestautomatView view;
public Controller(DataBean databean) throws MalformedURLException, IOException {
this.dataBean = databean;
this.view = new TestautomatView();
setActionHandlers();
}
public void show() throws MalformedURLException, IOException {
view.show(dataBean.getPrimaryStage());
}
private void setActionHandlers() {
// setHyperlink(view.getCrhl(), "www.example.com");
// setHyperlink(view.getHelp(), "www.example2.com");
}
private void setHyperlink(Hyperlink hl, String uri) {
hl.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
//TODO - Open Default Browser
}
});
}
}
公共类控制器{
私有数据库;
私有遗嘱自动生成视图;
公共控制器(DataBean DataBean)引发畸形DurException、IOException{
this.dataBean=dataBean;
this.view=newTestAutoMatView();
setActionHandlers();
}
public void show()引发畸形的DurLexException,IOException{
view.show(dataBean.getPrimaryStage());
}
私有void setActionHandlers(){
//setHyperlink(view.getCrhl(),“www.example.com”);
//setHyperlink(view.getHelp(),“www.example2.com”);
}
私有void setHyperlink(超链接hl,字符串uri){
hl.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
//TODO-打开默认浏览器
}
});
}
}
当我启动我的应用程序时,我可以看到GUI,但是当我想要添加ActionHandler时,我会得到一个NullPointerException
在“Sample.fxml”文件中,超链接是HBox的子项
<Hyperlink fx:id="crhl" text="Report" />
<Hyperlink fx:id="help" text="Help" />
但不仅仅是超链接,甚至当我在调试器中检查我的应用程序时,组合框也是空的
我的错误在哪里?问题是您正在使用
new TestautomatView()
手动创建控制器。它必须由FXMLLoader创建,注释才能工作。您还必须将Sample.fxml
中的fx:controller
属性设置为控制器(TestautomatView
)的完全限定类名
示例代码:
FXMLLoader fl = new FXMLLoader(new URL(TestautomatView.class.getResource("Sample.fxml").toExternalForm()));
root = fl.load();
TestautomatView controller = fl.getController();
PS:您应该将
TestautomatView
重命名为TestautomatController
。FXML文件是您的“视图”。问题是您正在使用newtestAutomatView()
手动创建控制器。它必须由FXMLLoader创建,注释才能工作。您还必须将Sample.fxml
中的fx:controller
属性设置为控制器(TestautomatView
)的完全限定类名
示例代码:
FXMLLoader fl = new FXMLLoader(new URL(TestautomatView.class.getResource("Sample.fxml").toExternalForm()));
root = fl.load();
TestautomatView controller = fl.getController();
PS:您应该将
TestautomatView
重命名为TestautomatController
。FXML文件是您的“视图”。正如另一个答案中指出的,问题是您“手动”创建了一个TestautomatView的实例。FXMLLoader
的默认行为是创建FXML文件中指定的控制器类的实例,并将该实例用作控制器。因此,您有两个TestautomatView
的实例:一个是您创建的(并有一个引用),另一个是由fxmloader
创建的。它是第二个初始化了带有@FXML
注释的字段
您可以通过创建fxmloader
实例并直接在其上设置控制器来更改此默认行为。例如考虑:
public class TestautomatView implements Initializable {
@FXML
private ComboBox<String> environmentCombo;
@FXML
private Hyperlink crhl;
@FXML
private Hyperlink help;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
private Scene scene;
private BorderPane root;
public TestautomatView() throws MalformedURLException, IOException {
FXMLLoader loader = new FXMLLoader(TestautomatView.class.getResource("Sample.fxml"));
loader.setController(this);
root = loader.load();
scene = new Scene(root);
}
// etc...
}
公共类TestautomatView实现了可初始化{
@FXML
私有组合框环境组合;
@FXML
私有超链接crhl;
@FXML
私人超链接帮助;
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
}
私密场景;
私有边界根;
public TestautomatView()引发畸形的DurLexException,IOException{
FXMLLoader=newFXMLLoader(TestautomatView.class.getResource(“Sample.fxml”);
loader.setController(此);
root=loader.load();
场景=新场景(根);
}
//等等。。。
}
由于您直接设置控制器,因此需要从Sample.fxml
文件中删除fx:controller
属性才能正常工作
您可能还对它感兴趣,这与您在这里尝试做的事情非常相似(尽管不完全相同)。正如另一个答案中指出的,问题是您“手动”创建了一个TestautomatView的实例。FXMLLoader
的默认行为是创建FXML文件中指定的控制器类的实例,并将该实例用作控制器。因此,您有两个TestautomatView
的实例:一个是您创建的(并有一个引用),另一个是由fxmloader
创建的。它是第二个初始化了带有@FXML
注释的字段
您可以通过创建fxmloader
实例并直接在其上设置控制器来更改此默认行为。例如考虑:
public class TestautomatView implements Initializable {
@FXML
private ComboBox<String> environmentCombo;
@FXML
private Hyperlink crhl;
@FXML
private Hyperlink help;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
private Scene scene;
private BorderPane root;
public TestautomatView() throws MalformedURLException, IOException {
FXMLLoader loader = new FXMLLoader(TestautomatView.class.getResource("Sample.fxml"));
loader.setController(this);
root = loader.load();
scene = new Scene(root);
}
// etc...
}
公共类TestautomatView实现了可初始化{
@FXML
专用组合框环境Comb