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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>