Is it possible to add a component loaded from an FXML file more than once without rereading it?
fxml, java, javafx
Solution
There's no built-in way to do this. Tom Schindl was working on a project to convert FXML to java source and compile the source at build time. I don't know what the current status of that project is (the link I provided has a download, but he says functionality is not complete).
For a desktop application, this is unlikely to be an issue; at worst (in the vast majority of use cases) it is only going to be done at startup time or in response to user input (which in the latter case is not frequent). So it is probably not an issue.
Having said that, it is a slow process. There are two distinct issues for performance: one is reading the file (or other resource); the second is parsing the fxml (which uses copious amounts of reflection).
If you do have performance issues doing this, you could just move the component that is repeatedly loaded from fxml to Java.
If accessing the resource is the bottleneck (and I really wouldn't do this unless you have strong evidence that this is an issue; I think this is unlikely to be a cause of performance problems unless you are loading FXML from a remote location), and you want to keep it in FXML, you could load the FXML into memory and the let the `FXMLLoader` read from a `ByteArrayInputStream`:
URL fxmlResource = getClass().getResource("/SomeComponent.fxml") ;
InputStream inputStream = fxmlResource.openStream();
byte[] buffer = new byte[8192];
int totalBytes = 0 ;
int bytesRead ;
while((bytesRead = inputStream.read(buffer, totalBytes, buffer.length - totalBytes)) != -1) {
totalBytes += bytesRead ;
if (totalBytes == buffer.length) {
byte[] newBuffer = new byte[2 * buffer.length];
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer ;
}
}
inputStream.close();
byte[] content = new byte[totalBytes];
System.arraycopy(buffer, 0, content, 0, totalBytes);
InputStream fxml = new ByteArrayInputStream(content);
VBox vbox = new VBox(5);
for(int i = 0; i < 8; i++) {
FXMLLoader loader = new FXMLLoader();
fxml.reset();
vBox.getChildren().add(loader.load(fxml));
}
Problem
So I'm getting started with javafx and I was wondering the following: Lets say I have an application with some container inside. For example: `VBox vBox = new VBox();` And I also have an FXML file which contains some other component I want to add to `vBox` multiple times. Now I could do something like: ``` for(int i = 0; i < 8; i++) { vBox.getChildren().add(FXMLLoader.load(getClass().getResource("/someComponent.fxml"))); } ``` But this seems very inefficient to me because every time I add the component, it gets reread from the file. Is there any way to construct a FXMLLoader that reads the file only once, saves it in some way, and lets me generate new instances of the component as definded in the file?