diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLibrary.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLibrary.java new file mode 100644 index 00000000..9462f910 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLibrary.java @@ -0,0 +1,99 @@ +/* + * Copyright 2022 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. + */ + +package com.formdev.flatlaf.ui; + +import java.io.File; +import com.formdev.flatlaf.FlatSystemProperties; +import com.formdev.flatlaf.util.LoggingFacade; +import com.formdev.flatlaf.util.NativeLibrary; +import com.formdev.flatlaf.util.SystemInfo; + +/** + * Helper class to load FlatLaf native library (.dll, .so or .dylib), + * if available for current operating system and CPU architecture. + * + * @author Karl Tauber + * @since 2.3 + */ +class FlatNativeLibrary +{ + private static NativeLibrary nativeLibrary; + + /** + * Loads native library (if available) and returns whether loaded successfully. + * Returns {@code false} if no native library is available. + */ + static synchronized boolean isLoaded() { + initialize(); + return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false; + } + + private static void initialize() { + if( nativeLibrary != null ) + return; + + String libraryName; + if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) { + // Windows: requires Windows 10 (x86 or x86_64) + + libraryName = "flatlaf-windows-x86"; + if( SystemInfo.isX86_64 ) + libraryName += "_64"; + + // load jawt native library + loadJAWT(); + } else + return; // no native library available for current OS or CPU architecture + + // load native library + nativeLibrary = createNativeLibrary( libraryName ); + } + + private static NativeLibrary createNativeLibrary( String libraryName ) { + String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH ); + if( libraryPath != null ) { + File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) ); + if( libraryFile.exists() ) + return new NativeLibrary( libraryFile, true ); + else + LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null ); + } + + return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true ); + } + + private static void loadJAWT() { + if( SystemInfo.isJava_9_orLater ) + return; + + // In Java 8, load jawt.dll (part of JRE) explicitly because it + // is not found when running application with /bin/java.exe. + // When using /jre/bin/java.exe, it is found. + // jawt.dll is located in /jre/bin/. + // Java 9 and later do not have this problem. + try { + System.loadLibrary( "jawt" ); + } catch( UnsatisfiedLinkError ex ) { + // log error only if native library jawt.dll not already loaded + String message = ex.getMessage(); + if( message == null || !message.contains( "already loaded in another classloader" ) ) + LoggingFacade.INSTANCE.logSevere( null, ex ); + } catch( Exception ex ) { + LoggingFacade.INSTANCE.logSevere( null, ex ); + } + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowsNativeWindowBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowsNativeWindowBorder.java index 587dff5e..727328f1 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowsNativeWindowBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowsNativeWindowBorder.java @@ -27,7 +27,6 @@ import java.awt.Window; import java.awt.geom.AffineTransform; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.io.File; import java.util.Collections; import java.util.IdentityHashMap; import java.util.List; @@ -38,9 +37,7 @@ import javax.swing.Timer; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.EventListenerList; -import com.formdev.flatlaf.FlatSystemProperties; import com.formdev.flatlaf.util.LoggingFacade; -import com.formdev.flatlaf.util.NativeLibrary; import com.formdev.flatlaf.util.SystemInfo; // @@ -84,7 +81,6 @@ class FlatWindowsNativeWindowBorder private Color colorizationColor; private int colorizationColorBalance; - private static NativeLibrary nativeLibrary; private static FlatWindowsNativeWindowBorder instance; static FlatNativeWindowBorder.Provider getInstance() { @@ -96,31 +92,8 @@ class FlatWindowsNativeWindowBorder if( !SystemInfo.isX86 && !SystemInfo.isX86_64 ) return null; - // load native library - if( nativeLibrary == null ) { - if( !SystemInfo.isJava_9_orLater ) { - // In Java 8, load jawt.dll (part of JRE) explicitly because it - // is not found when running application with /bin/java.exe. - // When using /jre/bin/java.exe, it is found. - // jawt.dll is located in /jre/bin/. - // Java 9 and later does not have this problem. - try { - System.loadLibrary( "jawt" ); - } catch( UnsatisfiedLinkError ex ) { - // log error only if native library jawt.dll not already loaded - String message = ex.getMessage(); - if( message == null || !message.contains( "already loaded in another classloader" ) ) - LoggingFacade.INSTANCE.logSevere( null, ex ); - } catch( Exception ex ) { - LoggingFacade.INSTANCE.logSevere( null, ex ); - } - } - - nativeLibrary = createNativeLibrary(); - } - // check whether native library was successfully loaded - if( !nativeLibrary.isLoaded() ) + if( !FlatNativeLibrary.isLoaded() ) return null; // create new instance @@ -129,23 +102,6 @@ class FlatWindowsNativeWindowBorder return instance; } - private static NativeLibrary createNativeLibrary() { - String libraryName = "flatlaf-windows-x86"; - if( SystemInfo.isX86_64 ) - libraryName += "_64"; - - String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH ); - if( libraryPath != null ) { - File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) ); - if( libraryFile.exists() ) - return new NativeLibrary( libraryFile, true ); - else - LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null ); - } - - return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true ); - } - private FlatWindowsNativeWindowBorder() { }