Javafx2 – poor performance when dynamically adding custom (fxml) panels to grid boards
problem
My attempt I tried to expand from the pane
public class Celli extends Pane{ public Celli() throws IOException{ Parent root = FXMLLoader.load(getClass().getResource("Cell.fxml")); this.getChildren().add(root); } }
... and then use this panel in the add method of the console
@FXML private void textChange(KeyEvent event) { GridPane g = new GridPane(); for (int i=0 : i<100; i++){ g.getChildren().add(new Celli()); } } }
It works, but it performs very, very poor
I'm looking for something. Is there a way to design panels through the JavaFX scene generator (so there are these panels in fxml) and then add them to the grid pane at run time without using this fxmlloader for each instance Because of the fxml loader, I think its performance is very poor When I add standard buttons, such as whitout fxml, it's very fast
Solution
Short answer: No, it's not (starting with JavaFX 2. X and 8.0) It may be in a future version (JFX > 8)
Long answer: fxmlloader is not currently used as a template provider to instantiate the same project one after another Instead, it means being a one - time loader (or serializing) for large GUIs
The performance is poor because fxmlloader must find the class and its attributes through reflection every time the fxml file calls load() This means:
>For each import statement, try to load each class until the class can be loaded successfully. > For each class, create a beanadapter to find all the properties of this class and try to apply the given parameters to the property. > The parameters of the attribute are applied again through reflection
There is no improvement for the subsequent call load () of the same fxml file completed in the code This means: no classes found, no beanadapters cached, etc
However, by setting the custom class loader as the fxmlloader instance, you can solve the performance problem of step 1:
import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; public class MyClassLoader extends ClassLoader{ private final Map<String,Class> classes = new HashMap<String,Class>(); private final ClassLoader parent; public MyClassLoader(ClassLoader parent) { this.parent = parent; } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> c = findClass(name); if ( c == null ) { throw new ClassNotFoundException( name ); } return c; } @Override protected Class<?> findClass( String className ) throws ClassNotFoundException { // System.out.print("try to load " + className); if (classes.containsKey(className)) { Class<?> result = classes.get(className); return result; } else { try { Class<?> result = parent.loadClass(className); // System.out.println(" -> success!"); classes.put(className,result); return result; } catch (ClassNotFoundException ignore) { // System.out.println(); classes.put(className,null); return null; } } } // ========= delegating methods ============= @Override public URL getResource( String name ) { return parent.getResource(name); } @Override public Enumeration<URL> getResources( String name ) throws IOException { return parent.getResources(name); } @Override public String toString() { return parent.toString(); } @Override public void setDefaultAssertionStatus(boolean enabled) { parent.setDefaultAssertionStatus(enabled); } @Override public void setPackageAssertionStatus(String packageName,boolean enabled) { parent.setPackageAssertionStatus(packageName,enabled); } @Override public void setClassAssertionStatus(String className,boolean enabled) { parent.setClassAssertionStatus(className,enabled); } @Override public void clearAssertionStatus() { parent.clearAssertionStatus(); } }
Usage:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader()); FXMLLoader loader = new FXMLLoader(resource); loader.setClassLoader(cachingClassLoader);
This significantly accelerates performance However, step 2 has no solution, so this may still be a problem
However, this function request is already available in the official JavaFX JIRA It is good to support this request
Link:
http://javafx-jira.kenai.com/browse/RT-23413
http://javafx-jira.kenai.com/browse/RT-23511