I am a novice to JavaFX. Still fiddling around a few samples to try and decide if that works out for the application that we are trying to build. First phase of our app is kind of a data entry phase where the users will be poised with a lot of questions and his responses are recorded. The catch here is that another team is building the question set and these questions are in an XML, like this.
<?xml version="1.0" encoding="UTF-8"?>
<userData>
<question id="Q1" type ="desc">
<text>Enter the name of the Component</text>
</question>
<question id ="Q2" type ="list">
<text>Select mechanism type</text>
<choices>
<choice> Type 1 </choice>
<choice> Type 2 </choice>
<choice> Type 3 </choice>
<choice> Type 4 </choice>
</choices>
</question>
<question id ="Q5" type="yesNo">
<text> Whether the parts have been verified by the supervisor? </text>
</question>
<question id ="Q6" type="yesNo">
<text> Whether the component is available within the domicile </text>
</question>
<question id ="Q7" type="value">
<text> Enter the quantity </text>
</question>
<question id ="Q8" type="value">
<text> Enter the unit price </text>
</question>
</userData>
It corresponds to various fields like having a boolean radio button if its a yesNo type, a dropdown in case of list, a text field for values and so on. These questions can change depending on the user so the user can configure the questions through this file.
The idea is to load this xml during the application start, parse them and build appropriate UI Components on the fly. Can this be achieved through JavaFX? I made a small prototype of this app using an FXML file built through SceneBuilder. But the trick is to generate the FXML file required to build this UI Components for queries programmatic-ally after parsing the Questions XML file which was loaded during the start up.
What is a good starting to point in achieving this functionality?
There are a couple of approaches you can take to this.
One is to simply parse the XML file, and create the FX controls in Java code as you go. This isn't too bad an approach, but you will not have any FXML at all. The basic idea is that you create a
DocumentBuilder
, use it to parse your xml file to aDocument
, which is an in-memory model of the xml document. You can use that to iterate through the xml elements, and create the appropriate JavaFX UI element for each xml element, adding them to somePane
.The other approach is to use an Extensible Stylesheet Language Transformation to transform your
XML
file intoFXML
. I am certainly no expert in this technology, but the idea is pretty straightforward:Define an
xsl
file that basically defines what yourFXML
file should look like based on the contents of yourxml
file. Again, I am not really familiar with the details ofxsl
, but something like this appears to work for your example:Now you just need to create a
Transformer
from thatxsl
file (I named itxml2fxml.xsl
). Thetransform
method will read thexml
file, transform it according to the rules in thexsl
file, and send the output to an output stream. You just need a little trickery to pipe that to an input stream and instruct theFXMLLoader
to read the generatedfxml
from it:Update: (Also note slight updates to the
xsl
above)While this is quite slick, it is almost too transparent in that it makes it difficult to get access to the form controls in the controller. You need to do a bit of ugly examination of the contents of the root element of the FXML-defined scene graph in order to find the correct elements.
This example uses some reflection to get at the values; you could also do it with a lot of
instanceof
tests and some casting. It also gets at the controls by "knowing" that they are all in column 1, which really violates the separation of view and controller; it might be better to have some convention on theid
assigned to the controls (that distinguishes them from theLabel
s) and use that instead.