簡単な答え:いいえ、違います (JavaFX 2.x および 8.0 の時点)。将来のバージョンになる可能性があります (JFX > 8)
長い回答:
現在、FXMLLoader は、同じアイテムを何度もインスタンス化するテンプレート プロバイダーとして機能するようには設計されていません。むしろ、大規模な GUI の 1 回限りのローダー (またはシリアル化) を意図しています。
FXML ファイルによっては、 を呼び出すたびにload()
、FXMLLoader がリフレクションを介してクラスとそのプロパティを検索する必要があるため、パフォーマンスが低下します。つまり、次のことを意味します。
- import ステートメントごとに、クラスが正常にロードされるまで、各クラスのロードを試みます。
- クラスごとに、このクラスが持つすべてのプロパティを検索し、指定されたパラメータをプロパティに適用しようとする BeanAdapter を作成します。
- プロパティへのパラメーターの適用は、再びリフレクションを介して行われます。
load()
また、コード内で行われる同じ FXML ファイルへの後続の呼び出しについても、現時点では改善されていません。これは、見つかったクラスのキャッシュ、BeanAdapter のキャッシュなどがないことを意味します。
ただし、カスタム クラスローダーを FXMLLoader インスタンスに設定することにより、ステップ 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();
}
}
使用法:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader());
FXMLLoader loader = new FXMLLoader(resource);
loader.setClassLoader(cachingClassLoader);
これにより、パフォーマンスが大幅に高速化されます。ただし、ステップ 2 の回避策はないため、これはまだ問題である可能性があります。
ただし、これについては、公式の JavaFX jira に既に機能要求があります。このリクエストをサポートしていただければ幸いです。
リンク: