JavaFX Project Structure

24,046

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!

Share:
24,046
Xkynar
Author by

Xkynar

Updated on June 08, 2020

Comments

  • Xkynar
    Xkynar almost 4 years

    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.

  • Xkynar
    Xkynar almost 10 years
    Hmm that sounds interesting, although the css seems hard to reach from an URL in an FXML (unless i do the ../ thing which i somewhat dislike...). I could put the resources after the view package tho, It makes sense since the resources are part of the View. I dont know what Service and DAO are for tho, can you give me an example? (The application Im going to create uses a MySQL server for fetching and storing data)
  • ItachiUchiha
    ItachiUchiha almost 10 years
    Updated my answer for more clarity !
  • ChrLipp
    ChrLipp about 9 years
    The downside of this approach is that view and controllers are not in the same directory and therefor SceneBuilder is not capable of linking them. If the ScreenBuilder wouldn't require it, I would put the fxml into the resources folder.
  • ItachiUchiha
    ItachiUchiha about 9 years
    You can keep the fxml in the resources folder and scenebuilder would still link everything. I would certainly second your thought of keeping the fxml in the resources folder.
  • Barry Allen
    Barry Allen over 3 years
    Would you place a database folder be in the resources folder? So it'd be: src/main/resources/databases/exampledb.db
  • ItachiUchiha
    ItachiUchiha over 3 years
    You can, but should not. All resources should be static files which do not change over their lifetime. However, db files change ever time a data is added or deleted from it.