fixed loading FlatLaf UI delegate classes when using FlatLaf in special application where multiple class loaders are involved; e.g. in Eclipse plugin or in LibreOffice extension (issues #955 and #851)
Some checks failed
CI / build (11) (push) Has been cancelled
CI / build-on (17, ) (push) Has been cancelled
CI / build-on (21, ) (push) Has been cancelled
CI / build-on (23, ) (push) Has been cancelled
CI / build-on (8, ) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
Karl Tauber
2025-02-12 14:35:35 +01:00
parent 00858002de
commit 5f6cc719ad
2 changed files with 53 additions and 0 deletions

View File

@@ -38,6 +38,9 @@ FlatLaf Change Log
- Linux: Popups (menus and combobox lists) were not hidden when window is moved, - Linux: Popups (menus and combobox lists) were not hidden when window is moved,
resized, maximized, restored, iconified or switched to another window. (issue resized, maximized, restored, iconified or switched to another window. (issue
#962) #962)
- Fixed loading FlatLaf UI delegate classes when using FlatLaf in special
application where multiple class loaders are involved. E.g. in Eclipse plugin
or in LibreOffice extension. (issues #955 and #851)
## 3.5.4 ## 3.5.4

View File

@@ -553,6 +553,9 @@ public abstract class FlatLaf
return UIScale.getUserScaleFactor(); return UIScale.getUserScaleFactor();
} ); } );
// add lazy UI delegate class loading (if necessary)
addLazyUIdelegateClassLoading( defaults );
if( postInitialization != null ) { if( postInitialization != null ) {
postInitialization.accept( defaults ); postInitialization.accept( defaults );
postInitialization = null; postInitialization = null;
@@ -750,6 +753,53 @@ public abstract class FlatLaf
} }
} }
/**
* Handle UI delegate classes if running in special application where multiple class loaders are involved.
* E.g. in Eclipse plugin or in LibreOffice extension.
* <p>
* Problem: Swing runs in Java's system classloader and FlatLaf is loaded in plugin classloader.
* When Swing tries to load UI delegate class in {@link UIDefaults#getUIClass(String, ClassLoader)},
* invoked from {@link UIDefaults#getUI(JComponent)}, it uses the component's classloader,
* which is Java's system classloader for core Swing components,
* and can not find FlatLaf UI delegates.
* <p>
* Solution: Add lazy values for UI delegate class names.
* Those lazy values use FlatLaf classloader to load UI delegate class.
* This is similar to what {@link UIDefaults#getUIClass(String, ClassLoader)} does.
* <p>
* Not using {@code defaults.put( "ClassLoader", FlatLaf.class.getClassLoader() )},
* which would work for FlatLaf UI delegates, but it would break custom
* UI delegates used in other classloaders.
*/
private static void addLazyUIdelegateClassLoading( UIDefaults defaults ) {
if( FlatLaf.class.getClassLoader() == ClassLoader.getSystemClassLoader() )
return; // not necessary
Map<String, LazyValue> map = new HashMap<>();
for( Map.Entry<Object, Object> e : defaults.entrySet() ) {
Object key = e.getKey();
Object value = e.getValue();
if( key instanceof String && ((String)key).endsWith( "UI" ) &&
value instanceof String && !defaults.containsKey( value ) )
{
String className = (String) value;
map.put( className, (LazyValue) t -> {
try {
Class<?> uiClass = FlatLaf.class.getClassLoader().loadClass( className );
if( ComponentUI.class.isAssignableFrom( uiClass ) )
return uiClass;
} catch( ClassNotFoundException ex ) {
// ignore
}
// let UIDefaults.getUIClass() try to load UI delegate class
return null;
} );
}
}
defaults.putAll( map );
}
private void putAATextInfo( UIDefaults defaults ) { private void putAATextInfo( UIDefaults defaults ) {
if ( SystemInfo.isMacOS && SystemInfo.isJetBrainsJVM ) { if ( SystemInfo.isMacOS && SystemInfo.isJetBrainsJVM ) {
// The awt.font.desktophints property suggests sub-pixel anti-aliasing // The awt.font.desktophints property suggests sub-pixel anti-aliasing