Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.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
Java @FXML批注无法正常工作_Java_Javafx_Fxml_Fxmlloader - Fatal编程技术网

Java @FXML批注无法正常工作

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

我目前正在使用JavaFX进行一个“小型”项目。我使用SceneBuilder创建GUI的第一个草图。它仍然需要一些调整和样式,但我想看看它是否工作到目前为止

我在GUI上有两个超链接,如果用户单击其中一个,默认的系统浏览器将打开一个特定的URL

到目前为止,我得到了这个:

Main.java:

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