簡短回答:不,它不是(從JavaFX 2.x和8.0開始)。這可能是在未來的版本(JFX> 8)
龍答: 的FXMLLoader目前沒有設計爲一遍遍實例相同的項目模板提供商執行。相反,它意味着成爲大型GUI的一次性裝載器(或者將其序列化)。
性能很差,因爲取決於FXML文件,在每次調用load()
時,FXMLLoader必須通過反射來查找類及其屬性。這意味着:
- 對於每個導入語句,嘗試加載每個類,直到類可以成功加載。
- 對於每個類,創建一個BeanAdapter,查找此類所有的屬性並嘗試將給定的參數應用於屬性。
- 將參數應用到屬性是通過反射再次完成的。
目前對代碼中完成的同一個FXML文件的後續調用load()
也沒有任何改進。這意味着:沒有找到類的緩存,沒有緩存BeanAdapter等等。
沒有爲步驟1中的表現要解決此問題,不過,通過自定義類加載器設置爲FXMLLoader實例:
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();
}
}
用法:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader());
FXMLLoader loader = new FXMLLoader(resource);
loader.setClassLoader(cachingClassLoader);
這顯著加速性能。但是,步驟2沒有解決方法,所以這可能仍然是一個問題。
但是,官方的JavaFX jira已經有這方面的功能請求。你會很高興支持這些請求。
鏈接:
http://javafx-jira.kenai.com/browse/RT-23413
http://javafx-jira.kenai.com/browse/RT-23511
很棒的回答Sebastian – jewelsea 2012-07-31 07:36:22
到最後的鏈接不再有效。有誰知道他們以前指向什麼,並可以找到更新的JDK - ? ID對應他們? – Itai 2016-02-04 21:40:43