JavaFX项目结构

31

使用FXML实现JavaFX的MVC模型听起来很棒,但我在组织我的项目包时遇到了困难。

我发现关于JavaFX的每一个教程都太简单和杂乱无章:他们只是创建一个包并把所有东西都放在那里,每个控制器、每个fxml文件、每个css文件。我不想这样做。我希望每个东西都在它们应该在的地方。

然而,JavaFX的“路径”似乎有些限制。使用URL使得如果我想将资源限制为本地文件,则必须执行整个getClass().getResource("foo.fxml").openStream() 的步骤。这很好,但是通过从类路径获取资源,路径是从该类所在的包开始的。我有点想要整个项目的根目录。那会简化我的生活,但是JavaFX似乎不是这样工作的。

让我们看一个实际的例子:

假设我有一个名为“登录屏幕”的FXML。假设我想让该登录屏幕使用一个样式表。理想情况下,那个css文件应该与fxml文件在同一个包中。但是,如果我想在另一个FXML中使用相同的.css呢?那是否意味着我必须将这两个FXML放在同一个包中?显然我“不需要”,但是我该如何做呢?

还有,假设我想在登录成功后更改场景。在FXML控制器的适当事件中,我必须调用“setScene”。如果我将FXML文件放在不同的包中,那么这条路径也将很难获得。似乎要么所有东西都在一个臃肿的包中,要么所有东西都很难访问,除非诉诸于类似“../../dir”的黑科技。

http://docs.oracle.com/javafx/2/best_practices/jfxpub-best_practices.htm中的Henley Sales应用程序似乎是一个组织良好的应用程序示例,尽管该应用程序只有一个TabPane。不幸的是(至少我认为),源代码并没有开放。它的思想就像这样:

client
  Main.class
  styles.css
      client.images
          image.png
      client.screen1
          Screen1.fxml
          Screen1Controller.java
      client.screen2
          Screen2.fxml
          Screen2Controller.java
      ...
这似乎不是一个坏的开始,但它有一些问题(或者至少我认为它们是问题)。
对于 “Henley Sales”,有一个“Main”调用包中一个FXML的智能方法(易于访问,FXML目录在Main类下面)。然而,对于样式表,必须通过 scene.getStylesheets().add(...); 来硬编码。我真的希望能够在FXML中选择我的样式表。毕竟,样式表是视图组件的一部分。使用FXML的URL访问.css文件将很难,因为它们在其目录之上。
此外,采用这种组织方式,我如何完全更改场景?在这个项目中,这并不需要,因为整个项目都是单个TabbedPane。Main 调用它,然后完成了。不需要进行更多的交换。但是简单的登录场景(或任何需要交换整个场景的原因)需要访问FXML路径。
然后还有资源。 CSS 文件可能需要使用图像。该结构通过将.css文件放在顶层,并为.css可能需要的文件创建一个包来解决它。但是,如果我想让特定的FXML具有不同的.css,那么另一个问题就会出现。
它看起来像一个循环。CSS 需要访问共享资源文件夹。FXML 需要访问 CSS。FXML 的控制器需要访问其他 FXML。我希望我对项目结构有所疑问,请帮助我创建一个适用于超过基本应用程序的 JavaFX 项目结构,或将我重定向到一些好的源代码。
哦,顺便说一句,我正在使用 Netbeans。
1个回答

47

在我看来,你不应该根据你的观点创建包。

我对这样的应用程序的处理方法

  • 一个相应视图的控制器的包
  • 如果存在,服务(业务)层和DAO(持久化)层的不同包
  • 用于资源(如图像、CSS 等)的目录
  • 在资源中用于FXML文件的名为view的目录

src/main
  ├──java
     ├── controllers
        ├──Screen1controller.java
        ├──Screen2controller.java
     ├── service
        ├──Service1.java
     ├── dao(persist)
        ├── SaveProducts.java
  ├──resources
     ├──view
        ├──screen1.fxml
        ├──screen2.fxml
     ├──css
        ├──style.css
     ├──images
        ├──img1.jpg
        ├──img2.jpg

上述实现可以考虑用于 Maven 项目。

对于一个简单的项目,您可以查看这里的结构。它是一个maven项目!


嗯,听起来很有趣,尽管从FXML中的URL访问CSS似乎很困难(除非我使用../这种方法,但我有点不喜欢...)。我可以把资源放在视图包之后,这是有意义的,因为这些资源是视图的一部分。不过我不知道Service和DAO是做什么用的,你能给我举个例子吗?(我要创建的应用程序将使用MySQL服务器来获取和存储数据) - Xkynar
为了更清晰,我更新了我的答案! - ItachiUchiha
这种方法的缺点是视图和控制器不在同一个目录中,因此SceneBuilder无法将它们链接起来。如果ScreenBuilder不需要这个,我会把fxml放到资源文件夹中。 - ChrLipp
您可以将fxml文件保存在资源文件夹中,SceneBuilder仍然可以链接所有内容。我完全支持您将fxml文件保存在资源文件夹中的想法。 - ItachiUchiha
你会把数据库文件夹放在资源文件夹里吗?这样它就是:src/main/resources/databases/exampledb.db - Barry Allen
你可以这样做,但最好不要。所有资源都应该是静态文件,在其生命周期内不会发生变化。然而,数据库文件在每次添加或删除数据时都会发生变化。 - ItachiUchiha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接