diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ced8c11..7f2609b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,13 @@ FlatLaf Change Log
## 3.7-SNAPSHOT
+#### New features and improvements
+
+- If using `FlatLaf.registerCustomDefaultsSource( "com.myapp.themes" )` and
+ named Java modules, it is no longer necessary to add `opens com.myapp.themes;`
+ to `module-info.java`. (issue #1026)
+
+
#### Fixed bugs
- Tree and List: Fixed painting of rounded drop backgrounds. (issue #1023)
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
index 06601bc1..dfa9764f 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
@@ -911,8 +911,7 @@ public abstract class FlatLaf
*
* Invoke this method before setting the look and feel.
*
- * If using Java modules, the package must be opened in {@code module-info.java}.
- * Otherwise, use {@link #registerCustomDefaultsSource(URL)}.
+ * If using Java modules, it is not necessary to open the package in {@code module-info.java}.
*
* @param packageName a package name (e.g. "com.myapp.resources")
*/
@@ -959,9 +958,9 @@ public abstract class FlatLaf
*
* See {@link #registerCustomDefaultsSource(String)} for details.
*
- * This method is useful if using Java modules and the package containing the properties files
- * is not opened in {@code module-info.java}.
* E.g. {@code FlatLaf.registerCustomDefaultsSource( MyApp.class.getResource( "/com/myapp/themes/" ) )}.
+ *
+ * If using Java modules, it is not necessary to open the package in {@code module-info.java}.
*
* @param packageUrl a package URL
* @since 2
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
index b13906b5..07313141 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java
@@ -205,20 +205,37 @@ class UIDefaultsLoader
if( classLoader != null && !addonClassLoaders.contains( classLoader ) )
addonClassLoaders.add( classLoader );
- packageName = packageName.replace( '.', '/' );
if( classLoader == null )
classLoader = FlatLaf.class.getClassLoader();
+ // Get package URL using ClassLoader.getResource(...) because this works
+ // also in named Java modules, even without opening the package in module-info.java.
+ // This extra step is necessary because ClassLoader.getResource("/.properties")
+ // does not work for named Java modules.
+ URL url = classLoader.getResource( packageName.replace( '.', '/' ) );
+ if( url == null ) {
+ LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to find package '"
+ + packageName + "' to load properties files.", null );
+ continue;
+ }
+ String packageUrl = url.toExternalForm();
+ if( !packageUrl.endsWith( "/" ) )
+ packageUrl = packageUrl.concat( "/" );
+
for( Class> lafClass : lafClasses ) {
- String propertiesName = packageName + '/' + simpleClassName( lafClass ) + ".properties";
- try( InputStream in = classLoader.getResourceAsStream( propertiesName ) ) {
- if( in != null )
- properties.load( in );
+ URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
+
+ try( InputStream in = propertiesUrl.openStream() ) {
+ properties.load( in );
+ } catch( FileNotFoundException ex ) {
+ // ignore
}
}
} else if( source instanceof URL ) {
// load from package URL
- URL packageUrl = (URL) source;
+ String packageUrl = ((URL)source).toExternalForm();
+ if( !packageUrl.endsWith( "/" ) )
+ packageUrl = packageUrl.concat( "/" );
for( Class> lafClass : lafClasses ) {
URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/FlatModularAppTest JAR.launch b/flatlaf-testing/flatlaf-testing-modular-app/FlatModularAppTest JAR.launch
index 10856322..10461ba4 100644
--- a/flatlaf-testing/flatlaf-testing-modular-app/FlatModularAppTest JAR.launch
+++ b/flatlaf-testing/flatlaf-testing-modular-app/FlatModularAppTest JAR.launch
@@ -7,6 +7,8 @@
+
+
@@ -17,11 +19,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/build.gradle.kts b/flatlaf-testing/flatlaf-testing-modular-app/build.gradle.kts
index bfaf1244..dea250f2 100644
--- a/flatlaf-testing/flatlaf-testing-modular-app/build.gradle.kts
+++ b/flatlaf-testing/flatlaf-testing-modular-app/build.gradle.kts
@@ -30,3 +30,20 @@ flatlafModuleInfo {
dependsOn( ":flatlaf-extras:jar" )
dependsOn( ":flatlaf-fonts-inter:jar" )
}
+
+tasks {
+ register( "build-for-debugging" ) {
+ group = "build"
+
+ dependsOn( "build" )
+
+ doLast {
+ copy {
+ from( project.tasks["jar"].outputs )
+ from( configurations.runtimeClasspath )
+ into( "run" )
+ rename( "-[0-9][0-9.]*[0-9]", "-999" )
+ }
+ }
+ }
+}
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/src/main/java/com/formdev/flatlaf/testing/modular/app/FlatModularAppTest.java b/flatlaf-testing/flatlaf-testing-modular-app/src/main/java/com/formdev/flatlaf/testing/modular/app/FlatModularAppTest.java
index 301c5e6d..41ce4cb0 100644
--- a/flatlaf-testing/flatlaf-testing-modular-app/src/main/java/com/formdev/flatlaf/testing/modular/app/FlatModularAppTest.java
+++ b/flatlaf-testing/flatlaf-testing-modular-app/src/main/java/com/formdev/flatlaf/testing/modular/app/FlatModularAppTest.java
@@ -38,8 +38,12 @@ public class FlatModularAppTest
SwingUtilities.invokeLater( () -> {
FlatInterFont.installBasic();
+ FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.modular.app.themes" );
+ FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.modular.app.themes2",
+ FlatModularAppTest.class.getClassLoader() );
FlatLaf.registerCustomDefaultsSource(
- FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/themes/" ) );
+ FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/themes3" ) );
+
FlatLightLaf.setup();
JButton button1 = new JButton( "Hello" );
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes/FlatLightLaf.properties b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes/FlatLightLaf.properties
index 4b52328e..7393aef8 100644
--- a/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes/FlatLightLaf.properties
+++ b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes/FlatLightLaf.properties
@@ -14,7 +14,4 @@
# limitations under the License.
#
-@background = #fff
@foreground = #f00
-
-ButtonUI = com.formdev.flatlaf.testing.modular.app.plaf.MyButtonUI
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes2/FlatLightLaf.properties b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes2/FlatLightLaf.properties
new file mode 100644
index 00000000..e077d510
--- /dev/null
+++ b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes2/FlatLightLaf.properties
@@ -0,0 +1,17 @@
+#
+# Copyright 2025 FormDev Software GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+@background = #efe
diff --git a/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes3/FlatLightLaf.properties b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes3/FlatLightLaf.properties
new file mode 100644
index 00000000..f5f606a2
--- /dev/null
+++ b/flatlaf-testing/flatlaf-testing-modular-app/src/main/resources/com/formdev/flatlaf/testing/modular/app/themes3/FlatLightLaf.properties
@@ -0,0 +1,17 @@
+#
+# Copyright 2025 FormDev Software GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ButtonUI = com.formdev.flatlaf.testing.modular.app.plaf.MyButtonUI