JavaFX Project Structure

Xkynar picture Xkynar · Jul 25, 2014 · Viewed 19.9k times · Source

JavaFX's MVC Model by using FXML sounds awesome and all but I'm having trouble find out how to organize my project packages.

Every single tutorial i find about JavaFX is way too simple and unorganized: They simply create ONE package and create everything there, every controller, every fxml, every css. I dont want that. I want things to be in their right places.

Still, JavaFX's "pathing" seems... "limitive". The use of URLs make it so that if I want to limit my resources to local files, I have to do the whole getClass().getResource("foo.fxml").openStream() thing. That is great, but by getting resources from a class path, the path is from the package that class is in. I kinda wanted the project's root. That would simplify my life, but JavaFX doesnt seems to work like that.

Lets get to a practical example:

Imagine I have an FXML "Login Screen". Imagine I want that Login Screen to use a stylesheet. Ideally, that css would be in the same package of that fxml. But what if I want to use the same .css in another FXML? Would that mean I have to place both FXML in the same package? Obviously I "dont need to", but how do I do it then?

Also, lets say i want to change scene when I login properly. In the FXML Controller proper event, I would have to call a "setScene". That path would also be difficult to obtain since if I have the FXML's in different packages. It just seems that either everything is in one giant bloated package or everything is hard to access without resorting to hacks like "../../dir".

The Henley Sales application in http://docs.oracle.com/javafx/2/best_practices/jfxpub-best_practices.htm seems to be an example of a well organized application, although the application is a single TabPane. Unfortunatly (at least I think) the source is not open. Its idea is something like this:

client
  Main.class
  styles.css
      client.images
          image.png
      client.screen1
          Screen1.fxml
          Screen1Controller.java
      client.screen2
          Screen2.fxml
          Screen2Controller.java
      ...

This doenst seem like a bad start, but it has a few problems (or at least I see them as problems).

For 'The Henley Sales', Its smart to have a Main which would call one of the packages' FXML (easy access, FXML's directories are below Main class). Still, for the stylesheet, that would have to be hardcoded by scene.getStylesheets().add(...);. I really would prefer to have the choice of choosing my stylesheet in the FXML. Afterall, stylesheet is part of the View component. Accessing the .css file from an URL in the FXML's would be kinda hard with this structure, since its above their directories.

Also, with this organization, how would I change scene competely? In this project, that isnt needed because the whole project is a single TabbedPane. Main calls it, and its done. No need for more swaps. But a simple Log in scene(or whatever is the reason why one would need to swap the entire scene) calls for a need to access FXML paths.

And then there's the resources. Css files might need to use images. That structure solves it by placing the .css file on top, and creating a package just for the files the .css might need. If I wanted a particular FXML to have a different .css, tho, another problem would arrive.

It seems like a cycle. Css needs access to a shared resource folder. FXML needs access to Css. FXML's controllers need access to other FXML's. I hope I was clear about my project structure doubts. Please help me on creating a JavaFX project structure which is powerful enough for a more-than-basic application, or redirect me to some good source code.

Oh, Im using Netbeans by the way.

Answer

ItachiUchiha picture ItachiUchiha · Jul 25, 2014

IMHO, you shouldn't create package's depending on your views.

My approach towards such applications

  • A package for corresponding controllers of these views
  • Different packages for service(business) and dao(persistence) layer, if exists
  • A directory for resources such as images, css etc
  • A directory for FXML files called view in the resources

    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
    

The above implementation can be considered for a Maven project.

For a simple project, you can view a structure here. It is a maven project!