0

I've written some complex GUIs in Swing and I've never used a graphical tool. I've always just written the Java code. Now I'm writing my first JavaFX GUI, and it will be a large, complex GUI that gets all data values from the cloud. I've started doing the initial work with SceneBuilder, but I've run into a problem where SceneBuilder expects the .fxml and controller .java file to be in the same directory. It seems that the SceneBuilder developers think that JavaFX projects should have all of their files in one directory as if we are building toy demos instead of industrial strength GUIs.

I've also noticed that there are no architectural guidelines as to what should go into controller classes. If there are patterns and idioms that should guide the design and interaction between the .fxml file(s), the controller class(es), and the rest of the GUI classes I haven't been able to find them. Large, complex GUIs need to follow proven idioms or they'll become unmaintainable. A controller class could become several thousand lines long if all business logic and interaction with the cloud was in the controller class. Yet there seems to be no guidelines for what should be in the controller class and what should not be in the controller class.

I worry about large fxml structures becoming unmaintainable. If each .fxml file is one scene a GUI could be composed from multiple .fxml files, but I haven't found good guidance or examples of how to do this.

I'm tempted to drop SceneBuilder now before I invest much more time into .fxml. Have others been able to write large, complex GUIs that rely on all data coming from and being written to the cloud using SceneBuilder?

Thanks.

Community
  • 1
  • 1
Dean Schulze
  • 9,633
  • 24
  • 100
  • 165
  • The FXML-controller idiom is basically an implementation of the Model-View-Presenter pattern. (FXML is the view, "controller" is the presenter. Model is application-specific.) [SceneBuilder itself](https://bitbucket.org/gluon-oss/scenebuilder/src/ef68e38ec242?at=default) (which is a reasonably large application) is written with FXML and controllers. – James_D Mar 01 '17 at 20:00
  • You have a few misconceptions here: 1. "It seems that the SceneBuilder developers think that JavaFX projects should have all of their files in one directory." No, not at all: again see SceneBuilder as an example. It's better (imho) to have each FXML, controller, and CSS (if you need it) in a package together, but separate different parts of the UI into separate packages. But you would have arbitrarily many packages with arbitrary structure like this. – James_D Mar 01 '17 at 20:03
  • "A controller class could become several thousand lines long if all business logic and interaction with the cloud was in the controller class." just sounds like you don't have a model, with your services decomposed from the model. Maybe http://www.oracle.com/technetwork/articles/java/javafxinteg-2062777.html is helpful? And perhaps also see http://afterburner.adam-bien.com/ and links from there for some ideas on managing larger projects. – James_D Mar 01 '17 at 20:05
  • If you look closely at the videos in http://afterburner.adam-bien.com/ it looks like Adam Bien has .fxml and .css files in the same directory as his .java files. Are we supposed to break the maven standard directory layout in order to use SceneBuilder? – Dean Schulze Mar 01 '17 at 21:37
  • I cloned the SceneBuilder source code and it has the .fxml files under src/main/resources/ but using the same package structure as the corresponding Java classes do. I did this with my .fxml file (use the same package structure as my controller class uses) but SceneBuilder still can't find my controller. – Dean Schulze Mar 01 '17 at 22:10
  • Yeah I tested it after I wrote that, and it seems like it can't find controllers in different folders. Maybe there's a setting somewhere. But, anyway, you can see that here are FXML files and controllers in multiple folders; there is no requirement for *all* of them to be in a single folder. – James_D Mar 01 '17 at 22:12
  • *"it looks like Adam Bien has .fxml and .css files in the same directory as his .java files. Are we supposed to break the maven standard directory layout".* You're confusing "folder" and "package". The way Adam lays it out (and the way the Scene Builder structure is laid out) is that the FXML, controller, and CSS are in the same *package*. Whether you use a single source folder to map to a package, or multiple source folders (as Maven does) is immaterial. (I don't really accept that Maven's mechanism of source code in one hierarchy and other stuff in a mirrored hierarchy is "standard", but OT) – James_D Mar 02 '17 at 00:35
  • Probably this question has strayed off-topic for this forum. But I guess I would really reconsider criteria for deciding what you are going to use. You want to make choices that result in a nice code base, regardless of the tools you use. So choose FXML vs Java on that basis, regardless of whether or not you will use Scene Builder. (The e(fx)clipse plugin and Netbeans both make it tolerable to write FXML by hand, for example.) I would argue that FXML enforces a good separation between presentation and UI logic, and also its hierarchical structure more closely represents a scene graph than Java – James_D Mar 02 '17 at 02:27
  • After that, choosing tools is secondary. Use Scene Builder if you like it (and are using FXML), use Eclipse otherwise. Use Maven for the build if you like it, or use the e(fx)clipse plugin, which has a wizard interface to javafxpackager, or use gradle for the build, etc. Use Maven for dependency management (which you can do whether or not you use it for the build), etc. – James_D Mar 02 '17 at 02:30
  • FWIW I usually use FXML, with afterburner for medium-sized projects and Spring for large projects. I sometimes use Scene Builder (particularly early in the project) and sometimes just edit the FXML. I usually use Maven for dependency management (particularly with Spring) only, don't use a separate `resources` folder, and build with the Eclipse plugin. – James_D Mar 02 '17 at 02:33
  • @James_D - "[t] here are FXML files and controllers in multiple folders; there is no requirement for all of them to be in a single folder." As you've found out yourself, if you want to use SceneBuilder the controller has to be in the same directory as the .fxml file. That's a big problem when trying to use SceneBuilder. – Dean Schulze Mar 02 '17 at 15:52
  • @James_D - " Whether you use a single source folder to map to a package, or multiple source folders (as Maven does) is immaterial." It's very material if you want to use SceneBuilder, which is an important issue here. – Dean Schulze Mar 02 '17 at 15:55
  • You can still use Scene Builder though. You just lose a small amount of functionality - prepopulating the dropdowns for the controller class and fx:id fields. I'm not sure I would place that small amount of functionality very high on my list of criteria for choosing tools, let along technology. – James_D Mar 02 '17 at 15:58
  • @James_D - "You just lose a small amount of functionality - prepopulating the dropdowns for the controller class and fx:id fields." That "small amount of functionality" is the only thing that synchronizes your .fxml and your controller class. If you have a typo in one of your fx:id s you'll get a runtime error, which creates an onerous testing requirement: You have to click every control to be sure you got the fx:id right. – Dean Schulze Mar 02 '17 at 16:46
  • View the source in eclipse - if you have the e(FX)clipse plugin it will flag anything that doesn't match. – James_D Mar 02 '17 at 18:04
  • You're right. The e(FX)clipse plugin does flag a missing fx:id in the controller class. Finally a useful comment! So between SceneBuilder and the e(FX)clipse plugin I get some safety. Now if there was a maven plugin that would perform the same check at build time that would be great. – Dean Schulze Mar 02 '17 at 20:27

1 Answers1

1

Absolutely.

I have designed a configuration driven UI with almost no coupling. Using FXML I can store the views in the DB and have actions that read those locations and load the UIs, which inject controllers, etc...

We will have hundreds of stages by time this app is done, and FXML and SceneBuilder cut design/development/maintenance time by MONTHS.

I think it's the strength of JavaFX.

Editing to show where you can add the controller...

enter image description here

purring pigeon
  • 4,141
  • 5
  • 35
  • 68
  • How do you deal with SceneBuilder requiring that the controller and .fxml file be in the same directory? – Dean Schulze Mar 01 '17 at 19:56
  • @DeanSchulze To me, having the FXML file and its controller in a single package is very natural. It also makes it very easy (and natural) to get the resource for the FXML file: `FXMLLoader fooLoader = new FXMLLoader(FooController.class.getResource("Foo.fxml"));` (And anyway, is it actually true that Scene Builder requires that?) – James_D Mar 01 '17 at 20:07
  • James_D - Yes, SceneBuilder can't work with a controller in a different directory. Maven expects resources like .fxml files to be in src/main/resources/ and Java files to be in src/main/java/. What do you build your JavaFX projects with? – Dean Schulze Mar 01 '17 at 21:28
  • SceneBuilder doesn't require it in the same directory. Just provide the path to the controller and you are fine. We don't have them in the same directory. For example my package is org.companyname.system.subsystem and I store the FXML in the resources/fxml/subsystem and it works fine – purring pigeon Mar 01 '17 at 23:28
  • Where in SceneBuilder do you provide the path to the controller? – Dean Schulze Mar 02 '17 at 15:47
  • And you can also configure Maven to not insist on this src/resource separation. – mipa Mar 02 '17 at 16:59
  • So because SceneBuilder is stupid about where the controller class is I should break a convention that a widely used convention over configuration tool has always used. – Dean Schulze Mar 02 '17 at 17:55
  • You cannot put the path to the controller class in the Controller class text field as you show above. You put the fully qualified class name in that text field and that gets put into your .fxml file. If your controller class is not in the same directory as your .fxml SceneBuilder can't read it to populate the Code panel with potential fx:ids. – Dean Schulze Mar 02 '17 at 20:21
  • This should work just fine for your purposes - that's what I am doing. My code structure: src/main/java/org/companyname/system/Controller.java FXML is located in src/main/resources/fxml/system/View.fxml I load this way: FXMLLoader loader = new FXMLLoader(); Parent node = loader.load(getClass().getClassLoader().getResource("fxml/system/View.fxml").openStream()); – purring pigeon Mar 02 '17 at 21:39