使用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。