如何为位于Maven项目的资源文件夹中的FXML文件设置控制器?

huangapple go评论54阅读模式
英文:

How to set a controller for a fxml file that is in the resources folder of a maven project?

问题

我正在尝试开发我的第一个JavaFX桌面应用程序,但我发现自己陷入了僵局。
首先,程序将读取一些包含销售数据的Excel文件,然后创建一个数据库并汇总3名员工的总收款金额。但是,在我为第一个场景创建FXML文件时,无论我做什么,编译器都无法找到该FXML文件。
经过一些研究,我发现如果将FXML文件放在资源文件夹中,它就可以正常工作,但在我这样做之后,FXML文件不再通过fx:controller选项识别Controller,这可能是因为它不再位于相同的目录中了。我继续搜索并找到了一个线索,了解如何修复它,但我无法完全理解如何做。在这个问题中链接中提到可以使用Maven资源插件创建FXML文件的副本,代码如下:

<build>
...
<resources>
    <resource>
        <filtering>false</filtering>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.fxml</include>
        </includes>             
    </resource>
</resources>
...
</build>

但是我该如何做呢?FXML文件必须位于主目录文件夹还是资源文件夹中?如果我使用场景构建器更改一个文件,另一个文件是否也会更改?我需要将这个Maven资源插件添加到porn.xml中吗?

以下是一些图片:

这里是包含文件和完整错误信息的GitHub链接:github

非常感谢您的帮助,同时为英文不太好表示抱歉(英文不是我的母语)。

英文:

I am trying to develop my first javafx desktop app, but i foud myself in a deadlock.
Firstly the program will read some excel files with sales, then create a database and summarise the total collected for 3 employees.But when i was creating a fxml file for the first scene, no matter what i did the compiler didn't locate the fxml file.
After some research i found out that if i put the fxml inside a resouces folder it would work properly, but fater i had done that now i the fxml file doesn't recognize the Controller using the fx:controller option, probably because it isn't in the same directory anymore. i search some more and found a clue to how to fix it but could quite understand how to do it. in this question https://stackoverflow.com/questions/22000423/javafx-and-maven-nullpointerexception-location-is-required/34239165 it says that it is possible to create a copy of the fxml files using the maven resources plugin Code:

&lt;build&gt;
...
&lt;resources&gt;
    &lt;resource&gt;
        &lt;filtering&gt;false&lt;/filtering&gt;
        &lt;directory&gt;src/main/java&lt;/directory&gt;
        &lt;includes&gt;
            &lt;include&gt;**/*.fxml&lt;/include&gt;
        &lt;/includes&gt;             
    &lt;/resource&gt;
&lt;/resources&gt;
...

</build>

But how can i do this? Where does the fxml files have to be the main directory folder or the resources folder? If i alter the data using scene builder of one does the other change as well? Do i need to add this maven resources plugin in the porn.xml?Here is some photos:

Main - Project

balanceus.fxml in the resource folder before trying fx:controller

running fine put without controller

then after add fx:controller

it breaks

And here is a link for the git hub with the files and with .txt of the complete error i get when tring to run:

github

Any Help is appreciated, also sorry for the bad english(not my first language).

答案1

得分: 2

以下是您要翻译的内容:

我下载并分析了您的项目,发现了一些结构上的错误(以及模块信息中缺少一个“open语句”),但在修复了这些错误之后,它仍然不起作用。 如何为位于Maven项目的资源文件夹中的FXML文件设置控制器?

因此,我根据这里的描述创建了一个新的原型项目:
Getting Started with JavaFX > JavaFX and IntelliJ > Modular with Maven

当使用 “javafx-archetype-fxml” 时,您将获得一个基本结构,这是您项目所需的。然后,我将您项目的一些文件复制到了正确的位置,效果如下:

如何为位于Maven项目的资源文件夹中的FXML文件设置控制器?

如您所见,fxml文件不必放在主资源文件夹中。我将它们放在一个名为 fxml 的单独文件夹中。

然后,我复制了您的 App 类,并将其更改为以下内容:

package com.ultrasomma;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.IOException;

public class App extends Application {

    @Override
    public void start(Stage stage) throws IOException {
        Scene scene = new Scene(FXMLLoader.load(App.class.getResource("fxml/balanceus.fxml")));
        scene.getStylesheets().add(App.class.getResource("css/BalanceUS.css").toExternalForm());
        stage.setTitle("BalanceUS");
        stage.getIcons().add(new Image(App.class.getResource("img/BalanceUS.png").toExternalForm()));
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

module-info 如下所示(您需要添加我从中抽象出的其他内容):

module com.ultrasomma {
    requires javafx.controls;
    requires javafx.fxml;

	// 您的项目中缺少此语句:
    opens com.ultrasomma to javafx.fxml;

    exports com.ultrasomma;
}

如果您按照这种方式进行,您的项目也应该可以正常工作(无需更改pom文件)。


我不确定我是否正确理解了您的这个问题:

> 如果我使用场景构建器更改一个数据,另一个数据是否也会更改?

如果您更改了 “balanceus.fxml”,那么 “balanceus2.fxml” 不会更改。


顺便说一下,您在fxml中的控制器引用是正确的:

fx:controller="com.ultrasomma.Controller"
英文:

I downloaded and analyzed your project and found some mistakes in the structure (and that an “open statement” in the module.info is missing) but after fixing them it still didn't work. 如何为位于Maven项目的资源文件夹中的FXML文件设置控制器?

So I created a new project from an archetype as described here:
Getting Started with JavaFX > JavaFX and IntelliJ > Modular with Maven

When using „javafx-archetype-fxml“ you will get a basic structure which you need for your project. Then I copied some files of your project to the right places and it looks like this:

如何为位于Maven项目的资源文件夹中的FXML文件设置控制器?

So as you can see the fxml files don't have to be in the main ressource folder. I put them in a separated folder named fxml.

Then I copied your App class and changed it to this:

package com.ultrasomma;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.IOException;


public class App extends Application {

    @Override
    public void start(Stage stage) throws IOException {
        Scene scene = new Scene(FXMLLoader.load(App.class.getResource(&quot;fxml/balanceus.fxml&quot;)));
        scene.getStylesheets().add(App.class.getResource(&quot;css/BalanceUS.css&quot;).toExternalForm());
        stage.setTitle(&quot;BalanceUS&quot;);
        stage.getIcons().add(new Image(App.class.getResource(&quot;img/BalanceUS.png&quot;).toExternalForm()));
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

The module-info looks like this (you have to add the other stuff I abstracted from):

module com.ultrasomma {
    requires javafx.controls;
    requires javafx.fxml;

	// This statement is missing in your project:
    opens com.ultrasomma to javafx.fxml;

    exports com.ultrasomma;
}

If you do it like this, it should work for you too (no need to manipulate the pom file).


I am not sure if I understand this question of yours correctly:

> If i alter the data using scene builder of one does the other change as well?

If you change "balanceus.fxml" then "balanceus2.fxml" will not change.


The reference for the controller in your fxml is fine btw.:

fx:controller=&quot;com.ultrasomma.Controller&quot;

huangapple
  • 本文由 发表于 2020年8月15日 04:16:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63419498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定