Krótka odpowiedź: Nie, nie jest (jak w przypadku JavaFX 2.x i 8.0). Może to być w przyszłej wersji (JFX> 8)
Długa odpowiedź: FXMLLoader nie jest obecnie przeznaczone do wykonywania jako dostawcy szablonów że instancję sam element w kółko. Raczej ma to być jednorazowy moduł ładujący dla dużych GUI (lub serializować je).
Wydajność jest słaba, ponieważ w zależności od pliku FXML, przy każdym wywołaniu load()
, FXMLLoader musi sprawdzić klasy i jego właściwości za pomocą odbicia. Oznacza to:
- Dla każdej instrukcji importowania, spróbuj załadować każdą klasę, aż klasa może zostać pomyślnie załadowana.
- Dla każdej klasy utwórz element BeanAdapter, który wyszukuje wszystkie właściwości tej klasy i próbuje zastosować podane parametry do właściwości.
- Zastosowanie parametrów do właściwości odbywa się ponownie poprzez odbicie.
Obecnie nie ma poprawy dla kolejnych wywołań do load()
do tego samego pliku FXML wykonanego w kodzie. Oznacza to: brak buforowania znalezionych klas, brak buforowania BeanAdapters i tak dalej.
Istnieje obejście do wykonywania kroku 1, choć przez ustawienie niestandardowej classloader do instancji 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();
}
}
Zastosowanie:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader());
FXMLLoader loader = new FXMLLoader(resource);
loader.setClassLoader(cachingClassLoader);
To znacznie przyspiesza wydajność. Jednak nie ma rozwiązania tego problemu dla kroku 2, więc może to nadal stanowić problem.
Istnieją już jednak prośby o dodanie elementów do oficjalnej javy JavaFX. Miło by było, gdybyś poparł te prośby.
Linki:
http://javafx-jira.kenai.com/browse/RT-23413
http://javafx-jira.kenai.com/browse/RT-23511
Wspaniała odpowiedź Sebastian – jewelsea
Łącza na końcu nie są już ważne. Czy ktoś wie, co kiedyś wskazywali, i może znaleźć zaktualizowany JDK - ??? ID odpowiadający im? – Itai