mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-15 08:17:12 -06:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde25f6ac8 | ||
|
|
c989b97ffa | ||
|
|
5f5c225300 | ||
|
|
36e4071b7f | ||
|
|
1068884bce | ||
|
|
32d102dbc9 | ||
|
|
4e1f092b98 | ||
|
|
bd60a18ff4 | ||
|
|
3b3d7d76eb | ||
|
|
ec76448e9f | ||
|
|
872c84974c | ||
|
|
5dd2008969 | ||
|
|
55ddac2bc7 | ||
|
|
a62dd22f83 | ||
|
|
a503879858 | ||
|
|
14f19dd735 | ||
|
|
9a727f68ce | ||
|
|
d26819d268 | ||
|
|
44752cc9aa | ||
|
|
11e0757387 | ||
|
|
1f1ebc3c44 | ||
|
|
4be97b6ea6 | ||
|
|
3facca5499 |
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -32,10 +32,11 @@ jobs:
|
||||
- 8
|
||||
- 11 # LTS
|
||||
- 17 # LTS
|
||||
- 21 # LTS
|
||||
toolchain: [""]
|
||||
include:
|
||||
- java: 17
|
||||
toolchain: 21 # latest
|
||||
- java: 21
|
||||
toolchain: 22 # latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -47,7 +48,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: temurin # Java 8, 11 and 17 are pre-installed on ubuntu-latest
|
||||
distribution: temurin # Java 8, 11, 17 and 21 are pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Check with Error Prone
|
||||
|
||||
31
CHANGELOG.md
31
CHANGELOG.md
@@ -1,6 +1,37 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 3.4.1
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- SplitPane: Update divider when client property `JSplitPane.expandableSide`
|
||||
changed.
|
||||
- TabbedPane: Fixed swapped back and forward scroll buttons when using
|
||||
`TabbedPane.scrollButtonsPlacement = trailing` (regression in FlatLaf 3.3).
|
||||
- Fixed missing window top border on Windows 10 in "full window content" mode.
|
||||
(issue 809)
|
||||
- Extras:
|
||||
- `FlatSVGIcon` color filters now support linear gradients. (PR #817)
|
||||
- `FlatSVGIcon`: Use log level `CONFIG` instead of `SEVERE` and allow
|
||||
disabling logging. (issue #823)
|
||||
- Added support for `JSplitPane.expandableSide` client property to
|
||||
`FlatSplitPane`.
|
||||
- Native libraries: Added API version check to test whether native library
|
||||
matches the JAR (bad builds could e.g. ship a newer JAR with an older
|
||||
incompatible native library) and to test whether native methods can be invoked
|
||||
(some security software allows loading native library but blocks method
|
||||
invocation).
|
||||
- macOS: Fixed crash when running in WebSwing. (issue #826; regression in 3.4)
|
||||
|
||||
#### Incompatibilities
|
||||
|
||||
- File names of custom properties files for nested Laf classes now must include
|
||||
name of enclosing class name. E.g. nested Laf class `IntelliJTheme.ThemeLaf`
|
||||
used `ThemeLaf.properties` in previous versions, but now needs to be named
|
||||
`IntelliJTheme$ThemeLaf.properties`.
|
||||
|
||||
|
||||
## 3.4
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
@@ -311,6 +311,9 @@ Applications using FlatLaf
|
||||
|
||||
-  
|
||||
[BGBlitz](https://www.bgblitz.com/) (**commercial**) - professional Backgammon
|
||||
-  [MCreator](https://github.com/MCreator/MCreator) -
|
||||
software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons,
|
||||
and data packs without programming knowledge
|
||||
-  [MapTool](https://github.com/RPTools/maptool) - virtual
|
||||
Tabletop for playing role-playing games
|
||||
- [MegaMek](https://github.com/MegaMek/megamek),
|
||||
|
||||
@@ -27,7 +27,7 @@ library {
|
||||
}
|
||||
with( linkTask.get() ) {
|
||||
if( name.contains( "Release" ) )
|
||||
debuggable.set( false )
|
||||
debuggable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,34 +44,34 @@ publishing {
|
||||
|
||||
pom {
|
||||
afterEvaluate {
|
||||
this@pom.name.set( extension.name )
|
||||
this@pom.description.set( extension.description )
|
||||
this@pom.name = extension.name
|
||||
this@pom.description = extension.description
|
||||
}
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
url = "https://github.com/JFormDesigner/FlatLaf"
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name.set( "The Apache License, Version 2.0" )
|
||||
url.set( "https://www.apache.org/licenses/LICENSE-2.0.txt" )
|
||||
name = "The Apache License, Version 2.0"
|
||||
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
name.set( "Karl Tauber" )
|
||||
organization.set( "FormDev Software GmbH" )
|
||||
organizationUrl.set( "https://www.formdev.com/" )
|
||||
name = "Karl Tauber"
|
||||
organization = "FormDev Software GmbH"
|
||||
organizationUrl = "https://www.formdev.com/"
|
||||
}
|
||||
}
|
||||
|
||||
scm {
|
||||
connection.set( "scm:git:git://github.com/JFormDesigner/FlatLaf.git" )
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf" )
|
||||
connection = "scm:git:git://github.com/JFormDesigner/FlatLaf.git"
|
||||
url = "https://github.com/JFormDesigner/FlatLaf"
|
||||
}
|
||||
|
||||
issueManagement {
|
||||
system.set( "GitHub" )
|
||||
url.set( "https://github.com/JFormDesigner/FlatLaf/issues" )
|
||||
system = "GitHub"
|
||||
url = "https://github.com/JFormDesigner/FlatLaf/issues"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,6 @@ plugins {
|
||||
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||
if( !toolchainJavaVersion.isNullOrEmpty() ) {
|
||||
java.toolchain {
|
||||
languageVersion.set( JavaLanguageVersion.of( toolchainJavaVersion ) )
|
||||
languageVersion = JavaLanguageVersion.of( toolchainJavaVersion )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ plugins {
|
||||
val sigtest = configurations.create( "sigtest" )
|
||||
|
||||
dependencies {
|
||||
testImplementation( libs.bundles.junit )
|
||||
testRuntimeOnly( libs.junit.engine )
|
||||
testImplementation( libs.junit )
|
||||
testRuntimeOnly( libs.junit.launcher )
|
||||
|
||||
// https://github.com/jtulach/netbeans-apitest
|
||||
sigtest( libs.sigtest )
|
||||
@@ -42,11 +42,11 @@ java {
|
||||
tasks {
|
||||
compileJava {
|
||||
// generate JNI headers
|
||||
options.headerOutputDirectory.set( layout.buildDirectory.dir( "generated/jni-headers" ) )
|
||||
options.headerOutputDirectory = layout.buildDirectory.dir( "generated/jni-headers" )
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveBaseName = "flatlaf"
|
||||
|
||||
doLast {
|
||||
ReorderJarEntries.reorderJarEntries( outputs.files.singleFile );
|
||||
@@ -54,20 +54,20 @@ tasks {
|
||||
}
|
||||
|
||||
named<Jar>( "sourcesJar" ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveBaseName = "flatlaf"
|
||||
}
|
||||
|
||||
named<Jar>( "javadocJar" ) {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveBaseName = "flatlaf"
|
||||
}
|
||||
|
||||
register<Zip>( "jarNoNatives" ) {
|
||||
group = "build"
|
||||
dependsOn( "jar" )
|
||||
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
archiveClassifier.set( "no-natives" )
|
||||
archiveExtension.set( "jar" )
|
||||
archiveBaseName = "flatlaf"
|
||||
archiveClassifier = "no-natives"
|
||||
archiveExtension = "jar"
|
||||
destinationDirectory = layout.buildDirectory.dir( "libs" )
|
||||
|
||||
from( zipTree( jar.get().archiveFile.get().asFile ) )
|
||||
|
||||
@@ -102,6 +102,17 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String BUTTON_TYPE_BORDERLESS = "borderless";
|
||||
|
||||
/**
|
||||
* Specifies whether the button preferred size will be made square (quadratically).
|
||||
* <p>
|
||||
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String SQUARE_SIZE = "JButton.squareSize";
|
||||
|
||||
|
||||
//---- JCheckBox ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Specifies selected state of a checkbox.
|
||||
* <p>
|
||||
@@ -118,14 +129,6 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String SELECTED_STATE_INDETERMINATE = "indeterminate";
|
||||
|
||||
/**
|
||||
* Specifies whether the button preferred size will be made square (quadratically).
|
||||
* <p>
|
||||
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String SQUARE_SIZE = "JButton.squareSize";
|
||||
|
||||
|
||||
//---- JComponent ---------------------------------------------------------
|
||||
|
||||
@@ -984,7 +987,7 @@ public interface FlatClientProperties
|
||||
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Integer} or {@link java.lang.String}<br>
|
||||
* <strong>Allowed Values</strong>
|
||||
* {@link SwingConstants#LEADING} (default)
|
||||
* {@link SwingConstants#LEADING} (default),
|
||||
* {@link SwingConstants#TRAILING},
|
||||
* {@link SwingConstants#CENTER},
|
||||
* {@link #TABBED_PANE_ALIGN_LEADING} (default),
|
||||
@@ -1096,7 +1099,7 @@ public interface FlatClientProperties
|
||||
* <strong>Allowed Values</strong>
|
||||
* {@link SwingConstants#LEFT},
|
||||
* {@link SwingConstants#RIGHT},
|
||||
* {@link #TABBED_PANE_TAB_ROTATION_NONE}, (default)
|
||||
* {@link #TABBED_PANE_TAB_ROTATION_NONE} (default),
|
||||
* {@link #TABBED_PANE_TAB_ROTATION_AUTO},
|
||||
* {@link #TABBED_PANE_TAB_ROTATION_LEFT} or
|
||||
* {@link #TABBED_PANE_TAB_ROTATION_RIGHT}
|
||||
@@ -1345,8 +1348,8 @@ public interface FlatClientProperties
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||
* <strong>SupportedValues:</strong>
|
||||
* {@link SwingConstants#BOTTOM} (default)
|
||||
* <strong>Allowed Values</strong>
|
||||
* {@link SwingConstants#BOTTOM} (default),
|
||||
* {@link SwingConstants#TOP},
|
||||
* {@link SwingConstants#LEFT} or
|
||||
* {@link SwingConstants#RIGHT}
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class FlatDefaultsAddon
|
||||
public InputStream getDefaults( Class<?> lafClass ) {
|
||||
Class<?> addonClass = this.getClass();
|
||||
String propertiesName = '/' + addonClass.getPackage().getName().replace( '.', '/' )
|
||||
+ '/' + lafClass.getSimpleName() + ".properties";
|
||||
+ '/' + UIDefaultsLoader.simpleClassName( lafClass ) + ".properties";
|
||||
return addonClass.getResourceAsStream( propertiesName );
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ class UIDefaultsLoader
|
||||
classLoader = FlatLaf.class.getClassLoader();
|
||||
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
String propertiesName = packageName + '/' + lafClass.getSimpleName() + ".properties";
|
||||
String propertiesName = packageName + '/' + simpleClassName( lafClass ) + ".properties";
|
||||
try( InputStream in = classLoader.getResourceAsStream( propertiesName ) ) {
|
||||
if( in != null )
|
||||
properties.load( in );
|
||||
@@ -171,7 +171,7 @@ class UIDefaultsLoader
|
||||
// load from package URL
|
||||
URL packageUrl = (URL) source;
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
URL propertiesUrl = new URL( packageUrl + lafClass.getSimpleName() + ".properties" );
|
||||
URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
|
||||
|
||||
try( InputStream in = propertiesUrl.openStream() ) {
|
||||
properties.load( in );
|
||||
@@ -183,7 +183,7 @@ class UIDefaultsLoader
|
||||
// load from folder
|
||||
File folder = (File) source;
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
File propertiesFile = new File( folder, lafClass.getSimpleName() + ".properties" );
|
||||
File propertiesFile = new File( folder, simpleClassName( lafClass ) + ".properties" );
|
||||
if( !propertiesFile.isFile() )
|
||||
continue;
|
||||
|
||||
@@ -294,6 +294,14 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to Class.getSimpleName(), but includes enclosing class for nested classes.
|
||||
*/
|
||||
static String simpleClassName( Class<?> cls ) {
|
||||
String className = cls.getName();
|
||||
return className.substring( className.lastIndexOf( '.' ) + 1 );
|
||||
}
|
||||
|
||||
static void logParseError( String key, String value, RuntimeException ex, boolean severe ) {
|
||||
String message = "FlatLaf: Failed to parse: '" + key + '=' + value + '\'';
|
||||
if( severe )
|
||||
|
||||
@@ -37,16 +37,18 @@ class FlatNativeLibrary
|
||||
private static boolean initialized;
|
||||
private static NativeLibrary nativeLibrary;
|
||||
|
||||
private native static int getApiVersion();
|
||||
|
||||
/**
|
||||
* Loads native library (if available) and returns whether loaded successfully.
|
||||
* Returns {@code false} if no native library is available.
|
||||
*/
|
||||
static synchronized boolean isLoaded() {
|
||||
initialize();
|
||||
static synchronized boolean isLoaded( int apiVersion ) {
|
||||
initialize( apiVersion );
|
||||
return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false;
|
||||
}
|
||||
|
||||
private static void initialize() {
|
||||
private static void initialize( int apiVersion ) {
|
||||
if( initialized )
|
||||
return;
|
||||
initialized = true;
|
||||
@@ -104,7 +106,26 @@ class FlatNativeLibrary
|
||||
return; // no native library available for current OS or CPU architecture
|
||||
|
||||
// load native library
|
||||
nativeLibrary = createNativeLibrary( classifier, ext );
|
||||
NativeLibrary nativeLibrary = createNativeLibrary( classifier, ext );
|
||||
if( !nativeLibrary.isLoaded() )
|
||||
return;
|
||||
|
||||
// check API version (and check whether library works)
|
||||
try {
|
||||
int actualApiVersion = getApiVersion();
|
||||
if( actualApiVersion != apiVersion ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Wrong API version in native library (expected "
|
||||
+ apiVersion + ", actual " + actualApiVersion + "). Ignoring native library.", null );
|
||||
return;
|
||||
}
|
||||
} catch( Throwable ex ) {
|
||||
// could be a UnsatisfiedLinkError in case that loading native library
|
||||
// from temp directory was blocked by some OS security mechanism
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to get API version of native library. Ignoring native library.", ex );
|
||||
return;
|
||||
}
|
||||
|
||||
FlatNativeLibrary.nativeLibrary = nativeLibrary;
|
||||
}
|
||||
|
||||
private static NativeLibrary createNativeLibrary( String classifier, String ext ) {
|
||||
@@ -118,9 +139,9 @@ class FlatNativeLibrary
|
||||
if( library.isLoaded() )
|
||||
return library;
|
||||
|
||||
LoggingFacade.INSTANCE.logSevere( "Did not find library '" + System.mapLibraryName( libraryName )
|
||||
+ "' in java.library.path '" + System.getProperty( "java.library.path" )
|
||||
+ "', using extracted library instead", null );
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '" + System.mapLibraryName( libraryName )
|
||||
+ "' not found in java.library.path '" + System.getProperty( "java.library.path" )
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
} else {
|
||||
// try standard library naming scheme
|
||||
// (same as in flatlaf.jar in package 'com/formdev/flatlaf/natives')
|
||||
@@ -139,11 +160,11 @@ class FlatNativeLibrary
|
||||
return new NativeLibrary( libraryFile2, true );
|
||||
}
|
||||
|
||||
LoggingFacade.INSTANCE.logSevere( "Did not find library '"
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '"
|
||||
+ libraryFile.getName()
|
||||
+ (libraryName2 != null ? ("' or '" + libraryName2) : "")
|
||||
+ "' in '" + libraryFile.getParentFile().getAbsolutePath()
|
||||
+ "', using extracted library instead", null );
|
||||
+ "' not found in '" + libraryFile.getParentFile().getAbsolutePath()
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
class FlatNativeLinuxLibrary
|
||||
{
|
||||
private static int API_VERSION_LINUX = 3001;
|
||||
|
||||
/**
|
||||
* Checks whether native library is loaded/available.
|
||||
* <p>
|
||||
@@ -42,7 +44,7 @@ class FlatNativeLinuxLibrary
|
||||
* method of this class. Otherwise, the native library may not be loaded.
|
||||
*/
|
||||
static boolean isLoaded() {
|
||||
return SystemInfo.isLinux && FlatNativeLibrary.isLoaded();
|
||||
return SystemInfo.isLinux && FlatNativeLibrary.isLoaded( API_VERSION_LINUX );
|
||||
}
|
||||
|
||||
// direction for _NET_WM_MOVERESIZE message
|
||||
|
||||
@@ -44,6 +44,8 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class FlatNativeMacLibrary
|
||||
{
|
||||
private static int API_VERSION_MACOS = 2001;
|
||||
|
||||
/**
|
||||
* Checks whether native library is loaded/available.
|
||||
* <p>
|
||||
@@ -51,7 +53,7 @@ public class FlatNativeMacLibrary
|
||||
* method of this class. Otherwise, the native library may not be loaded.
|
||||
*/
|
||||
public static boolean isLoaded() {
|
||||
return SystemInfo.isMacOS && FlatNativeLibrary.isLoaded();
|
||||
return SystemInfo.isMacOS && FlatNativeLibrary.isLoaded( API_VERSION_MACOS );
|
||||
}
|
||||
|
||||
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class FlatNativeWindowsLibrary
|
||||
{
|
||||
private static int API_VERSION_WINDOWS = 1001;
|
||||
|
||||
private static long osBuildNumber = Long.MIN_VALUE;
|
||||
|
||||
/**
|
||||
@@ -39,7 +41,7 @@ public class FlatNativeWindowsLibrary
|
||||
* method of this class. Otherwise, the native library may not be loaded.
|
||||
*/
|
||||
public static boolean isLoaded() {
|
||||
return SystemInfo.isWindows && FlatNativeLibrary.isLoaded();
|
||||
return SystemInfo.isWindows && FlatNativeLibrary.isLoaded( API_VERSION_WINDOWS );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -270,6 +270,7 @@ public class FlatRootPaneUI
|
||||
// layer title pane under frame content layer to allow placing menu bar over title pane
|
||||
protected final static Integer TITLE_PANE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 1;
|
||||
private final static Integer TITLE_PANE_MOUSE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 2;
|
||||
private final static Integer WINDOW_TOP_BORDER_LAYER = Integer.MAX_VALUE;
|
||||
|
||||
// for fullWindowContent mode, layer title pane over frame content layer to allow placing title bar buttons over content
|
||||
/** @since 3.4 */
|
||||
@@ -285,11 +286,15 @@ public class FlatRootPaneUI
|
||||
if( titlePane != null ) {
|
||||
layeredPane.remove( titlePane );
|
||||
layeredPane.remove( titlePane.mouseLayer );
|
||||
if( titlePane.windowTopBorderLayer != null )
|
||||
layeredPane.remove( titlePane.windowTopBorderLayer );
|
||||
}
|
||||
|
||||
if( newTitlePane != null ) {
|
||||
layeredPane.add( newTitlePane, getLayerForTitlePane() );
|
||||
layeredPane.add( newTitlePane.mouseLayer, TITLE_PANE_MOUSE_LAYER );
|
||||
if( newTitlePane.windowTopBorderLayer != null && newTitlePane.isWindowTopBorderNeeded() && isFullWindowContent( rootPane ) )
|
||||
layeredPane.add( newTitlePane.windowTopBorderLayer, WINDOW_TOP_BORDER_LAYER );
|
||||
}
|
||||
|
||||
titlePane = newTitlePane;
|
||||
@@ -446,6 +451,13 @@ public class FlatRootPaneUI
|
||||
case FlatClientProperties.FULL_WINDOW_CONTENT:
|
||||
if( titlePane != null ) {
|
||||
rootPane.getLayeredPane().setLayer( titlePane, getLayerForTitlePane() );
|
||||
if( titlePane.windowTopBorderLayer != null ) {
|
||||
JLayeredPane layeredPane = rootPane.getLayeredPane();
|
||||
if( titlePane.isWindowTopBorderNeeded() && isFullWindowContent( rootPane ) )
|
||||
layeredPane.add( titlePane.windowTopBorderLayer, WINDOW_TOP_BORDER_LAYER );
|
||||
else
|
||||
layeredPane.remove( titlePane.windowTopBorderLayer );
|
||||
}
|
||||
titlePane.updateIcon();
|
||||
titlePane.updateVisibility();
|
||||
titlePane.updateFullWindowContentButtonsBoundsProperty();
|
||||
@@ -591,6 +603,12 @@ public class FlatRootPaneUI
|
||||
titlePane.setBounds( 0, 0, width, prefHeight );
|
||||
|
||||
titlePane.mouseLayer.setBounds( 0, 0, width, prefHeight );
|
||||
if( titlePane.windowTopBorderLayer != null ) {
|
||||
boolean show = isFullWindowContent && !titlePane.isWindowMaximized() && !isFullScreen;
|
||||
if( show )
|
||||
titlePane.windowTopBorderLayer.setBounds( 0, 0, width, 1 );
|
||||
titlePane.windowTopBorderLayer.setVisible( show );
|
||||
}
|
||||
|
||||
if( !isFullWindowContent )
|
||||
nextY += prefHeight;
|
||||
|
||||
@@ -301,6 +301,10 @@ public class FlatSplitPaneUI
|
||||
// necessary to show/hide one-touch buttons on expand/collapse
|
||||
doLayout();
|
||||
break;
|
||||
|
||||
case FlatClientProperties.SPLIT_PANE_EXPANDABLE_SIDE:
|
||||
revalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3767,9 +3767,20 @@ debug*/
|
||||
boolean hideDisabledScrollButtons = (scrollButtonsPolicy == AS_NEEDED_SINGLE && scrollButtonsPlacement == BOTH);
|
||||
boolean trailingScrollButtons = (scrollButtonsPlacement == TRAILING);
|
||||
|
||||
// for right-to-left always use "more tabs" button for horizontal scrolling
|
||||
// For right-to-left, always use "more tabs" button for horizontal scrolling
|
||||
// because methods scrollForward() and scrollBackward() in class
|
||||
// BasicTabbedPaneUI.ScrollableTabSupport do not work for right-to-left
|
||||
// BasicTabbedPaneUI.ScrollableTabSupport do not work for right-to-left.
|
||||
//
|
||||
// One problem is that BasicTabbedPaneUI.getClosestTab(), which is used
|
||||
// to compute leadingTabIndex, does not work for right-to-left because is uses "binary" search
|
||||
// on rects[] to find tab, but rects[] is ordered in reverse order for right-to-left.
|
||||
// So leadingTabIndex is either zero or tabCount.
|
||||
// Therefore increasing/decreasing leadingTabIndex in scrollForward()
|
||||
// and scrollBackward() does not work as expected.
|
||||
// Also backward/forward scroll buttons are not correctly enabled/disabled.
|
||||
//
|
||||
// Fixing this would require replacing nearly whole functionality of class
|
||||
// BasicTabbedPaneUI.ScrollableTabSupport, which is not possible because it is private.
|
||||
boolean leftToRight = isLeftToRight();
|
||||
if( !leftToRight && isHorizontalTabPlacement( tabPane.getTabPlacement() ) ) {
|
||||
useMoreTabsButton = true;
|
||||
@@ -3851,6 +3862,8 @@ debug*/
|
||||
w -= buttonWidth;
|
||||
moreTabsButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout scroll buttons
|
||||
if( useScrollButtons ) {
|
||||
// the tabViewport view size is set in
|
||||
// BasicTabbedPaneUI.TabbedPaneScrollLayout.calculateTabRects(),
|
||||
@@ -3858,30 +3871,28 @@ debug*/
|
||||
Point viewPosition = tabViewport.getViewPosition();
|
||||
Dimension viewSize = tabViewport.getViewSize();
|
||||
|
||||
// layout forward button on trailing side
|
||||
if( !hideDisabledScrollButtons || viewSize.width - viewPosition.x > w ) {
|
||||
int buttonWidth = forwardButton.getPreferredSize().width;
|
||||
forwardButton.setBounds( x + w - buttonWidth, y, buttonWidth, h );
|
||||
w -= buttonWidth;
|
||||
forwardButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout backward button
|
||||
if( !hideDisabledScrollButtons || viewPosition.x > 0 ) {
|
||||
int buttonWidth = backwardButton.getPreferredSize().width;
|
||||
if( trailingScrollButtons ) {
|
||||
// on trailing side
|
||||
backwardButton.setBounds( leftToRight ? (x + w - buttonWidth) : x, y, buttonWidth, h );
|
||||
x += leftToRight ? 0 : buttonWidth;
|
||||
backwardButton.setBounds( x + w - buttonWidth, y, buttonWidth, h );
|
||||
} else {
|
||||
// on leading side
|
||||
backwardButton.setBounds( leftToRight ? x : (x + w - buttonWidth), y, buttonWidth, h );
|
||||
x += leftToRight ? buttonWidth : 0;
|
||||
backwardButton.setBounds( x, y, buttonWidth, h );
|
||||
x += buttonWidth;
|
||||
}
|
||||
w -= buttonWidth;
|
||||
backwardButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout forward button on trailing side
|
||||
if( !hideDisabledScrollButtons || viewSize.width - viewPosition.x > w ) {
|
||||
int buttonWidth = forwardButton.getPreferredSize().width;
|
||||
forwardButton.setBounds( leftToRight ? (x + w - buttonWidth) : x, y, buttonWidth, h );
|
||||
x += leftToRight ? 0 : buttonWidth;
|
||||
w -= buttonWidth;
|
||||
forwardButtonVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3927,6 +3938,8 @@ debug*/
|
||||
h -= buttonHeight;
|
||||
moreTabsButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout scroll buttons
|
||||
if( useScrollButtons ) {
|
||||
// the tabViewport view size is set in
|
||||
// BasicTabbedPaneUI.TabbedPaneScrollLayout.calculateTabRects(),
|
||||
@@ -3934,6 +3947,14 @@ debug*/
|
||||
Point viewPosition = tabViewport.getViewPosition();
|
||||
Dimension viewSize = tabViewport.getViewSize();
|
||||
|
||||
// layout forward button on bottom side
|
||||
if( !hideDisabledScrollButtons || viewSize.height - viewPosition.y > h ) {
|
||||
int buttonHeight = forwardButton.getPreferredSize().height;
|
||||
forwardButton.setBounds( x, y + h - buttonHeight, w, buttonHeight );
|
||||
h -= buttonHeight;
|
||||
forwardButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout backward button
|
||||
if( !hideDisabledScrollButtons || viewPosition.y > 0 ) {
|
||||
int buttonHeight = backwardButton.getPreferredSize().height;
|
||||
@@ -3948,14 +3969,6 @@ debug*/
|
||||
h -= buttonHeight;
|
||||
backwardButtonVisible = true;
|
||||
}
|
||||
|
||||
// layout forward button on bottom side
|
||||
if( !hideDisabledScrollButtons || viewSize.height - viewPosition.y > h ) {
|
||||
int buttonHeight = forwardButton.getPreferredSize().height;
|
||||
forwardButton.setBounds( x, y + h - buttonHeight, w, buttonHeight );
|
||||
h -= buttonHeight;
|
||||
forwardButtonVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ public class FlatTitlePane
|
||||
extends JComponent
|
||||
{
|
||||
static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
|
||||
private static final boolean isWindows_10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
|
||||
|
||||
/** @since 2.5 */ protected final Font titleFont;
|
||||
protected final Color activeBackground;
|
||||
@@ -166,6 +167,16 @@ public class FlatTitlePane
|
||||
*/
|
||||
final JPanel mouseLayer;
|
||||
|
||||
/**
|
||||
* This panel paint a border at the top of the window in fullWindowContent mode,
|
||||
* if FlatLaf window decorations are enabled.
|
||||
* Only used on Windows 10.
|
||||
* <p>
|
||||
* This panel is not a child of the title pane.
|
||||
* Instead it is added by FlatRootPaneUI to the layered pane at a layer over all other layers.
|
||||
*/
|
||||
final JPanel windowTopBorderLayer;
|
||||
|
||||
public FlatTitlePane( JRootPane rootPane ) {
|
||||
this.rootPane = rootPane;
|
||||
|
||||
@@ -207,6 +218,14 @@ public class FlatTitlePane
|
||||
mouseLayer.addMouseListener( handler );
|
||||
mouseLayer.addMouseMotionListener( handler );
|
||||
|
||||
if( isWindows_10 && FlatNativeWindowBorder.isSupported() ) {
|
||||
windowTopBorderLayer = new JPanel();
|
||||
windowTopBorderLayer.setVisible( false );
|
||||
windowTopBorderLayer.setOpaque( false );
|
||||
windowTopBorderLayer.setBorder( FlatUIUtils.nonUIResource( FlatNativeWindowBorder.WindowTopBorder.getInstance() ) );
|
||||
} else
|
||||
windowTopBorderLayer = null;
|
||||
|
||||
applyComponentOrientation( rootPane.getComponentOrientation() );
|
||||
}
|
||||
|
||||
@@ -919,6 +938,10 @@ public class FlatTitlePane
|
||||
return window != null && FlatNativeWindowBorder.hasCustomDecoration( window );
|
||||
}
|
||||
|
||||
boolean isWindowTopBorderNeeded() {
|
||||
return isWindows_10 && hasNativeCustomDecoration();
|
||||
}
|
||||
|
||||
// used to invoke updateNativeTitleBarHeightAndHitTestSpots() only once from latest invokeLater()
|
||||
private int laterCounter;
|
||||
|
||||
@@ -1146,7 +1169,7 @@ public class FlatTitlePane
|
||||
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
|
||||
insets.bottom += UIScale.scale( 1 );
|
||||
|
||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||
if( isWindowTopBorderNeeded() && !isWindowMaximized() )
|
||||
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
|
||||
|
||||
return insets;
|
||||
@@ -1165,7 +1188,7 @@ public class FlatTitlePane
|
||||
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
|
||||
}
|
||||
|
||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||
if( isWindowTopBorderNeeded() && !isWindowMaximized() && !isFullWindowContent() )
|
||||
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
||||
}
|
||||
|
||||
@@ -1329,7 +1352,7 @@ public class FlatTitlePane
|
||||
activeChanged( true );
|
||||
updateNativeTitleBarHeightAndHitTestSpots();
|
||||
|
||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() )
|
||||
if( isWindowTopBorderNeeded() )
|
||||
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
|
||||
repaintWindowBorder();
|
||||
@@ -1340,7 +1363,7 @@ public class FlatTitlePane
|
||||
activeChanged( false );
|
||||
updateNativeTitleBarHeightAndHitTestSpots();
|
||||
|
||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() )
|
||||
if( isWindowTopBorderNeeded() )
|
||||
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
|
||||
repaintWindowBorder();
|
||||
|
||||
@@ -89,7 +89,7 @@ class FlatWindowsNativeWindowBorder
|
||||
return null;
|
||||
|
||||
// check whether native library was successfully loaded
|
||||
if( !FlatNativeLibrary.isLoaded() )
|
||||
if( !FlatNativeWindowsLibrary.isLoaded() )
|
||||
return null;
|
||||
|
||||
// create new instance
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,6 +25,7 @@ import java.awt.Image;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RGBImageFilter;
|
||||
import java.io.File;
|
||||
@@ -62,6 +63,8 @@ public class FlatSVGIcon
|
||||
extends ImageIcon
|
||||
implements DisabledIconProvider
|
||||
{
|
||||
private static boolean loggingEnabled = true;
|
||||
private static boolean svgCacheEnabled = true;
|
||||
// cache that uses soft references for values, which allows freeing SVG documents if no longer used
|
||||
private static final SoftCache<String, SVGDocument> svgCache = new SoftCache<>();
|
||||
private static final SVGLoader svgLoader = new SVGLoader();
|
||||
@@ -271,7 +274,8 @@ public class FlatSVGIcon
|
||||
|
||||
if( document == null ) {
|
||||
loadFailed = true;
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load SVG icon from input stream", null );
|
||||
if( loggingEnabled )
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: failed to load SVG icon from input stream", null );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,8 +453,9 @@ public class FlatSVGIcon
|
||||
* @param colorFilter The color filter
|
||||
* @since 1.2
|
||||
*/
|
||||
public void setColorFilter( ColorFilter colorFilter ) {
|
||||
public FlatSVGIcon setColorFilter( ColorFilter colorFilter ) {
|
||||
this.colorFilter = colorFilter;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
@@ -474,7 +479,8 @@ public class FlatSVGIcon
|
||||
|
||||
if( url == null ) {
|
||||
loadFailed = true;
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null );
|
||||
if( loggingEnabled )
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -484,6 +490,9 @@ public class FlatSVGIcon
|
||||
}
|
||||
|
||||
static synchronized SVGDocument loadSVG( URL url ) {
|
||||
if( !svgCacheEnabled )
|
||||
return loadSVGUncached( url );
|
||||
|
||||
// get from our cache
|
||||
String cacheKey = url.toString();
|
||||
SVGDocument document = svgCache.get( cacheKey );
|
||||
@@ -491,18 +500,25 @@ public class FlatSVGIcon
|
||||
return document;
|
||||
|
||||
// load SVG document
|
||||
document = svgLoader.load( url );
|
||||
|
||||
if( document == null ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + url + "'", null );
|
||||
return null;
|
||||
}
|
||||
document = loadSVGUncached( url );
|
||||
|
||||
svgCache.put( cacheKey, document );
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
private static SVGDocument loadSVGUncached( URL url ) {
|
||||
SVGDocument document = svgLoader.load( url );
|
||||
|
||||
if( document == null ) {
|
||||
if( loggingEnabled )
|
||||
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: failed to load '" + url + "'", null );
|
||||
return null;
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
private URL getIconURL( String name, boolean dark ) {
|
||||
if( dark ) {
|
||||
int dotIndex = name.lastIndexOf( '.' );
|
||||
@@ -611,7 +627,10 @@ public class FlatSVGIcon
|
||||
}
|
||||
|
||||
private void paintSvgError( Graphics2D g, int x, int y ) {
|
||||
g.setColor( Color.red );
|
||||
if( g instanceof GraphicsFilter )
|
||||
((GraphicsFilter)g).setColorUnfiltered( Color.red );
|
||||
else
|
||||
g.setColor( Color.red );
|
||||
g.fillRect( x, y, getIconWidth(), getIconHeight() );
|
||||
}
|
||||
|
||||
@@ -692,6 +711,34 @@ public class FlatSVGIcon
|
||||
darkLaf = FlatLaf.isLafDark();
|
||||
}
|
||||
|
||||
/** @since 3.4.1 */
|
||||
public static boolean isLoggingEnabled() {
|
||||
return loggingEnabled;
|
||||
}
|
||||
|
||||
/** @since 3.4.1 */
|
||||
public static void setLoggingEnabled( boolean loggingEnabled ) {
|
||||
FlatSVGIcon.loggingEnabled = loggingEnabled;
|
||||
}
|
||||
|
||||
/** @since 3.4.1 */
|
||||
public static boolean isSVGDocumentEnabled() {
|
||||
return svgCacheEnabled;
|
||||
}
|
||||
|
||||
/** @since 3.4.1 */
|
||||
public static void setSVGDocumentEnabled( boolean svgCacheEnabled ) {
|
||||
FlatSVGIcon.svgCacheEnabled = svgCacheEnabled;
|
||||
|
||||
if( !svgCacheEnabled )
|
||||
clearSVGDocumentCache();
|
||||
}
|
||||
|
||||
/** @since 3.4.1 */
|
||||
public static void clearSVGDocumentCache() {
|
||||
svgCache.clear();
|
||||
}
|
||||
|
||||
//---- class ColorFilter --------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -978,10 +1025,23 @@ public class FlatSVGIcon
|
||||
super.setColor( filterColor( c ) );
|
||||
}
|
||||
|
||||
void setColorUnfiltered( Color c ) {
|
||||
super.setColor( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint( Paint paint ) {
|
||||
if( paint instanceof Color )
|
||||
paint = filterColor( (Color) paint );
|
||||
else if( paint instanceof LinearGradientPaint ) {
|
||||
LinearGradientPaint oldPaint = (LinearGradientPaint) paint;
|
||||
Color[] newColors = filterColors( oldPaint.getColors() );
|
||||
if( newColors != null ) {
|
||||
paint = new LinearGradientPaint( oldPaint.getStartPoint(), oldPaint.getEndPoint(),
|
||||
oldPaint.getFractions(), newColors, oldPaint.getCycleMethod(),
|
||||
oldPaint.getColorSpace(), oldPaint.getTransform() );
|
||||
}
|
||||
}
|
||||
super.setPaint( paint );
|
||||
}
|
||||
|
||||
@@ -1001,5 +1061,15 @@ public class FlatSVGIcon
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private Color[] filterColors( Color[] colors ) {
|
||||
Color[] newColors = new Color[colors.length];
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < colors.length; i++ ) {
|
||||
newColors[i] = filterColor( colors[i] );
|
||||
changed = (changed || newColors[i] != colors[i]);
|
||||
}
|
||||
return changed ? newColors : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.extras.components;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import javax.swing.JSplitPane;
|
||||
|
||||
/**
|
||||
@@ -26,6 +27,29 @@ import javax.swing.JSplitPane;
|
||||
*/
|
||||
public class FlatSplitPane
|
||||
extends JSplitPane
|
||||
implements FlatStyleableComponent
|
||||
implements FlatComponentExtension, FlatStyleableComponent
|
||||
{
|
||||
// NOTE: enum names must be equal to allowed strings
|
||||
/** @since 3.4.1 */ public enum ExpandableSide { both, left, right }
|
||||
|
||||
/**
|
||||
* Returns what side of the spilt pane is allowed to expand
|
||||
* via one-touch expanding arrow buttons.
|
||||
*
|
||||
* @since 3.4.1
|
||||
*/
|
||||
public ExpandableSide getExpandableSide() {
|
||||
return getClientPropertyEnumString( SPLIT_PANE_EXPANDABLE_SIDE, ExpandableSide.class,
|
||||
null, ExpandableSide.both );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies what side of the spilt pane is allowed to expand
|
||||
* via one-touch expanding arrow buttons.
|
||||
*
|
||||
* @since 3.4.1
|
||||
*/
|
||||
public void setExpandableSide( ExpandableSide expandableSide ) {
|
||||
putClientPropertyEnumString( SPLIT_PANE_EXPANDABLE_SIDE, expandableSide );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ plugins {
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
|
||||
testImplementation( libs.bundles.junit )
|
||||
testRuntimeOnly( libs.junit.engine )
|
||||
testImplementation( libs.junit )
|
||||
testRuntimeOnly( libs.junit.launcher )
|
||||
}
|
||||
|
||||
flatlafModuleInfo {
|
||||
@@ -73,8 +73,8 @@ publishing {
|
||||
pom {
|
||||
licenses {
|
||||
license {
|
||||
name.set( "SIL OPEN FONT LICENSE Version 1.1" )
|
||||
url.set( "https://choosealicense.com/licenses/ofl-1.1/" )
|
||||
name = "SIL OPEN FONT LICENSE Version 1.1"
|
||||
url = "https://choosealicense.com/licenses/ofl-1.1/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ plugins {
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
|
||||
testImplementation( libs.bundles.junit )
|
||||
testRuntimeOnly( libs.junit.engine )
|
||||
testImplementation( libs.junit )
|
||||
testRuntimeOnly( libs.junit.launcher )
|
||||
}
|
||||
|
||||
flatlafModuleInfo {
|
||||
@@ -73,8 +73,8 @@ publishing {
|
||||
pom {
|
||||
licenses {
|
||||
license {
|
||||
name.set( "SIL OPEN FONT LICENSE Version 1.1" )
|
||||
url.set( "https://choosealicense.com/licenses/ofl-1.1/" )
|
||||
name = "SIL OPEN FONT LICENSE Version 1.1"
|
||||
url = "https://choosealicense.com/licenses/ofl-1.1/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ plugins {
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
|
||||
testImplementation( libs.bundles.junit )
|
||||
testRuntimeOnly( libs.junit.engine )
|
||||
testImplementation( libs.junit )
|
||||
testRuntimeOnly( libs.junit.launcher )
|
||||
}
|
||||
|
||||
flatlafModuleInfo {
|
||||
|
||||
@@ -33,8 +33,8 @@ plugins {
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
|
||||
testImplementation( libs.bundles.junit )
|
||||
testRuntimeOnly( libs.junit.engine )
|
||||
testImplementation( libs.junit )
|
||||
testRuntimeOnly( libs.junit.launcher )
|
||||
}
|
||||
|
||||
flatlafModuleInfo {
|
||||
|
||||
@@ -21,11 +21,14 @@ plugins {
|
||||
}
|
||||
|
||||
flatlafJniHeaders {
|
||||
headers = listOf( "com_formdev_flatlaf_ui_FlatNativeLinuxLibrary.h" )
|
||||
headers = listOf(
|
||||
"com_formdev_flatlaf_ui_FlatNativeLibrary.h",
|
||||
"com_formdev_flatlaf_ui_FlatNativeLinuxLibrary.h"
|
||||
)
|
||||
}
|
||||
|
||||
library {
|
||||
targetMachines.set( listOf( machines.linux.x86_64 ) )
|
||||
targetMachines = listOf( machines.linux.x86_64 )
|
||||
}
|
||||
|
||||
var javaHome = System.getProperty( "java.home" )
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "com_formdev_flatlaf_ui_FlatNativeLibrary.h"
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
|
||||
|
||||
// increase this version if changing API or functionality of native library
|
||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeLinuxLibrary
|
||||
#define API_VERSION_LINUX 3001
|
||||
|
||||
|
||||
//---- JNI methods ------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
( JNIEnv* env, jclass cls )
|
||||
{
|
||||
return API_VERSION_LINUX;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_formdev_flatlaf_ui_FlatNativeLibrary */
|
||||
|
||||
#ifndef _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#define _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
* Method: getApiVersion
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -26,14 +26,17 @@ plugins {
|
||||
}
|
||||
|
||||
flatlafJniHeaders {
|
||||
headers = listOf( "com_formdev_flatlaf_ui_FlatNativeMacLibrary.h" )
|
||||
headers = listOf(
|
||||
"com_formdev_flatlaf_ui_FlatNativeLibrary.h",
|
||||
"com_formdev_flatlaf_ui_FlatNativeMacLibrary.h"
|
||||
)
|
||||
}
|
||||
|
||||
library {
|
||||
targetMachines.set( listOf(
|
||||
targetMachines = listOf(
|
||||
machines.macOS.architecture( "arm64" ),
|
||||
machines.macOS.x86_64
|
||||
) )
|
||||
)
|
||||
}
|
||||
|
||||
var javaHome = System.getProperty( "java.home" )
|
||||
|
||||
@@ -42,5 +42,5 @@
|
||||
|
||||
|
||||
jclass findClass( JNIEnv *env, const char* className, bool globalRef );
|
||||
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField );
|
||||
jfieldID getFieldID( JNIEnv *env, jclass cls, const char* fieldName, const char* fieldSignature, bool staticField );
|
||||
jmethodID getMethodID( JNIEnv *env, jclass cls, const char* methodName, const char* methodSignature, bool staticMethod );
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_formdev_flatlaf_ui_FlatNativeLibrary */
|
||||
|
||||
#ifndef _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#define _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
* Method: getApiVersion
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "com_formdev_flatlaf_ui_FlatNativeLibrary.h"
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
|
||||
|
||||
// increase this version if changing API or functionality of native library
|
||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeMacLibrary
|
||||
#define API_VERSION_MACOS 2001
|
||||
|
||||
|
||||
//---- JNI methods ------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
( JNIEnv* env, jclass cls )
|
||||
{
|
||||
return API_VERSION_MACOS;
|
||||
}
|
||||
@@ -38,10 +38,9 @@ jclass findClass( JNIEnv *env, const char* className, bool globalRef ) {
|
||||
return cls;
|
||||
}
|
||||
|
||||
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField ) {
|
||||
// NSLog( @"getFieldID %s %s %s", className, fieldName, fieldSignature );
|
||||
jfieldID getFieldID( JNIEnv *env, jclass cls, const char* fieldName, const char* fieldSignature, bool staticField ) {
|
||||
// NSLog( @"getFieldID %s %s", fieldName, fieldSignature );
|
||||
|
||||
jclass cls = findClass( env, className, false );
|
||||
if( cls == NULL )
|
||||
return NULL;
|
||||
|
||||
@@ -49,7 +48,7 @@ jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName,
|
||||
? env->GetStaticFieldID( cls, fieldName, fieldSignature )
|
||||
: env->GetFieldID( cls, fieldName, fieldSignature );
|
||||
if( fieldID == NULL ) {
|
||||
NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s' in class '%s'", fieldName, fieldSignature, className );
|
||||
NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s'", fieldName, fieldSignature );
|
||||
env->ExceptionDescribe(); // print stack trace
|
||||
env->ExceptionClear();
|
||||
return NULL;
|
||||
|
||||
@@ -52,21 +52,27 @@ NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
||||
if( window == NULL )
|
||||
return NULL;
|
||||
|
||||
// initialize class IDs (done only once because variables are static)
|
||||
static jclass lwWindowPeerClass = findClass( env, "sun/lwawt/LWWindowPeer", true );
|
||||
static jclass cfRetainedResourceClass = findClass( env, "sun/lwawt/macosx/CFRetainedResource", true );
|
||||
if( lwWindowPeerClass == NULL || cfRetainedResourceClass == NULL )
|
||||
return NULL;
|
||||
|
||||
// initialize field IDs (done only once because variables are static)
|
||||
static jfieldID peerID = getFieldID( env, "java/awt/Component", "peer", "Ljava/awt/peer/ComponentPeer;", false );
|
||||
static jfieldID platformWindowID = getFieldID( env, "sun/lwawt/LWWindowPeer", "platformWindow", "Lsun/lwawt/PlatformWindow;", false );
|
||||
static jfieldID ptrID = getFieldID( env, "sun/lwawt/macosx/CFRetainedResource", "ptr", "J", false );
|
||||
static jfieldID peerID = getFieldID( env, findClass( env, "java/awt/Component", false ), "peer", "Ljava/awt/peer/ComponentPeer;", false );
|
||||
static jfieldID platformWindowID = getFieldID( env, lwWindowPeerClass, "platformWindow", "Lsun/lwawt/PlatformWindow;", false );
|
||||
static jfieldID ptrID = getFieldID( env, cfRetainedResourceClass, "ptr", "J", false );
|
||||
if( peerID == NULL || platformWindowID == NULL || ptrID == NULL )
|
||||
return NULL;
|
||||
|
||||
// get field java.awt.Component.peer
|
||||
jobject peer = env->GetObjectField( window, peerID );
|
||||
if( peer == NULL )
|
||||
if( peer == NULL || !env->IsInstanceOf( peer, lwWindowPeerClass ) )
|
||||
return NULL;
|
||||
|
||||
// get field sun.lwawt.LWWindowPeer.platformWindow
|
||||
jobject platformWindow = env->GetObjectField( peer, platformWindowID );
|
||||
if( platformWindow == NULL )
|
||||
if( platformWindow == NULL || !env->IsInstanceOf( platformWindow, cfRetainedResourceClass ) )
|
||||
return NULL;
|
||||
|
||||
// get field sun.lwawt.macosx.CFRetainedResource.ptr
|
||||
|
||||
@@ -22,6 +22,7 @@ plugins {
|
||||
|
||||
flatlafJniHeaders {
|
||||
headers = listOf(
|
||||
"com_formdev_flatlaf_ui_FlatNativeLibrary.h",
|
||||
"com_formdev_flatlaf_ui_FlatNativeWindowsLibrary.h",
|
||||
"com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder.h",
|
||||
"com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc.h"
|
||||
@@ -29,11 +30,11 @@ flatlafJniHeaders {
|
||||
}
|
||||
|
||||
library {
|
||||
targetMachines.set( listOf(
|
||||
targetMachines = listOf(
|
||||
machines.windows.x86,
|
||||
machines.windows.x86_64,
|
||||
machines.windows.architecture( "aarch64" )
|
||||
) )
|
||||
)
|
||||
}
|
||||
|
||||
var javaHome = System.getProperty( "java.home" )
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "com_formdev_flatlaf_ui_FlatNativeLibrary.h"
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
|
||||
|
||||
// increase this version if changing API or functionality of native library
|
||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeWindowsLibrary
|
||||
#define API_VERSION_WINDOWS 1001
|
||||
|
||||
|
||||
//---- JNI methods ------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
( JNIEnv* env, jclass cls )
|
||||
{
|
||||
return API_VERSION_WINDOWS;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_formdev_flatlaf_ui_FlatNativeLibrary */
|
||||
|
||||
#ifndef _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#define _Included_com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_formdev_flatlaf_ui_FlatNativeLibrary
|
||||
* Method: getApiVersion
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLibrary_getApiVersion
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -24,6 +24,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.util.Random;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
@@ -178,6 +179,20 @@ public class FlatContainerTest
|
||||
tabbedPane.addTab( "Tab 4", new JLabel( "non-opaque content", SwingConstants.CENTER ) );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
tabbedPane.addTab( "Tab 5", new JLabel( "random background content", SwingConstants.CENTER ) {
|
||||
Random random = new Random();
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( new Color( random.nextInt() ) );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
|
||||
super.paintComponent( g );
|
||||
}
|
||||
} );
|
||||
break;
|
||||
|
||||
default:
|
||||
int index = tabbedPane.getTabCount() + 1;
|
||||
tabbedPane.addTab( "Tab " + index, createTab( "tab content " + index ) );
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.testing.extras;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.extras.*;
|
||||
import com.formdev.flatlaf.extras.components.*;
|
||||
@@ -75,6 +76,12 @@ public class FlatExtrasTest
|
||||
disabledTabbedPane2.setIconAt( 0, icon );
|
||||
disabledTabbedPane2.setDisabledIconAt( 0, disabledIcon );
|
||||
|
||||
addJSVGIcon( "linearGradient.svg", 64, 128 );
|
||||
addJSVGIcon( "stripes.svg", 128, 128 );
|
||||
addJSVGIcon( "gradientText0.svg", 128, 128 );
|
||||
addJSVGIcon( "gradientText1.svg", 128, 128 );
|
||||
addJSVGIcon( "gradientText2.svg", 128, 128 );
|
||||
|
||||
disabledChanged();
|
||||
}
|
||||
|
||||
@@ -82,6 +89,10 @@ public class FlatExtrasTest
|
||||
svgIconsPanel.add( new JLabel( new FlatSVGIcon( "com/formdev/flatlaf/demo/extras/svg/" + name ) ) );
|
||||
}
|
||||
|
||||
private void addJSVGIcon( String name, int width, int height ) {
|
||||
gradientIconsPanel.add( new JLabel( new FlatSVGIcon( "com/formdev/flatlaf/testing/extras/jsvg/" + name, width, height ) ) );
|
||||
}
|
||||
|
||||
private void triStateCheckBox1Changed() {
|
||||
triStateLabel1.setText( triStateCheckBox1.getState().toString() );
|
||||
}
|
||||
@@ -104,6 +115,9 @@ public class FlatExtrasTest
|
||||
disabledLabel2.setEnabled( enabled );
|
||||
disabledButton2.setEnabled( enabled );
|
||||
disabledTabbedPane2.setEnabledAt( 0, enabled );
|
||||
|
||||
for( Component c : gradientIconsPanel.getComponents() )
|
||||
c.setEnabled( enabled );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,6 +155,7 @@ public class FlatExtrasTest
|
||||
disabledButton2 = new JButton();
|
||||
disabledTabbedPane2 = new JTabbedPane();
|
||||
label6 = new JLabel();
|
||||
gradientIconsPanel = new JPanel();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
@@ -156,6 +171,7 @@ public class FlatExtrasTest
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- label1 ----
|
||||
@@ -251,6 +267,12 @@ public class FlatExtrasTest
|
||||
label6.setText("setIcon() and setDisabledIcon()");
|
||||
label6.setEnabled(false);
|
||||
add(label6, "cell 1 6 2 1,gapx 20");
|
||||
|
||||
//======== gradientIconsPanel ========
|
||||
{
|
||||
gradientIconsPanel.setLayout(new FlowLayout());
|
||||
}
|
||||
add(gradientIconsPanel, "cell 1 7 2 1");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
@@ -275,5 +297,6 @@ public class FlatExtrasTest
|
||||
private JButton disabledButton2;
|
||||
private JTabbedPane disabledTabbedPane2;
|
||||
private JLabel label6;
|
||||
private JPanel gradientIconsPanel;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.3.1.342" Java: "15" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -6,7 +6,7 @@ new FormModel {
|
||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][][left]"
|
||||
"$rowConstraints": "[][][][][][][]"
|
||||
"$rowConstraints": "[][][][][][][][]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -143,9 +143,14 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 6 2 1,gapx 20"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "gradientIconsPanel"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 7 2 1"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 595, 470 )
|
||||
"size": new java.awt.Dimension( 645, 470 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.testing.jideoss;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Random;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
@@ -140,6 +141,20 @@ public class FlatJideOssContainerTest
|
||||
tabbedPane.addTab( "Tab 4", new JLabel( "non-opaque content", SwingConstants.CENTER ) );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
tabbedPane.addTab( "Tab 5", new JLabel( "random background content", SwingConstants.CENTER ) {
|
||||
Random random = new Random();
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( new Color( random.nextInt() ) );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
|
||||
super.paintComponent( g );
|
||||
}
|
||||
} );
|
||||
break;
|
||||
|
||||
default:
|
||||
int index = tabbedPane.getTabCount() + 1;
|
||||
tabbedPane.addTab( "Tab " + index, createTab( "tab content " + index ) );
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
The SVG icons in this folder are from JSVG,
|
||||
which is licensed under the MIT License
|
||||
See: https://github.com/weisJ/jsvg
|
||||
@@ -0,0 +1,12 @@
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="none">
|
||||
<defs>
|
||||
<linearGradient id="myGradient"
|
||||
gradientTransform="rotate(90)">
|
||||
<stop offset="5%" stop-color="gold" />
|
||||
<stop offset="95%" stop-color="red" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="50" width="100" height="40" fill="url(#myGradient)" />
|
||||
<text x="0" y="50" fill="url(#myGradient)">Hello lovely World!</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 417 B |
@@ -0,0 +1,14 @@
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="none">
|
||||
<defs>
|
||||
<linearGradient id="myGradient">
|
||||
<stop offset="5%" stop-color="gold" />
|
||||
<stop offset="95%" stop-color="red" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<text x="0" y="50">
|
||||
Hello
|
||||
<tspan fill="url(#myGradient)">lovely</tspan>
|
||||
World!
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 336 B |
@@ -0,0 +1,14 @@
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="none">
|
||||
<defs>
|
||||
<linearGradient id="myGradient">
|
||||
<stop offset="5%" stop-color="gold" />
|
||||
<stop offset="95%" stop-color="red" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<text x="0" y="50" fill="url(#myGradient)">
|
||||
Hello
|
||||
<tspan>lovely</tspan>
|
||||
World!
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 336 B |
@@ -0,0 +1,23 @@
|
||||
<svg width="120" height="240" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="Gradient1"
|
||||
gradientUnits="objectBoundingBox">
|
||||
<stop offset="0%" stop-color="red" />
|
||||
<stop offset="50%" stop-color="black" stop-opacity="0" />
|
||||
<stop offset="100%" stop-color="blue" />
|
||||
</linearGradient>
|
||||
<linearGradient id="Gradient2" x1="0" x2="0" y1="0"
|
||||
y2="1">
|
||||
<stop offset="0%" stop-color="red" />
|
||||
<stop offset="50%" stop-color="black" stop-opacity="0" />
|
||||
<stop offset="100%" stop-color="blue" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<rect id="rect1" x="10" y="10" rx="15" ry="15" width="100"
|
||||
height="100" fill="url(#Gradient1)" />
|
||||
<rect x="10" y="120" rx="15" ry="15" width="100" height="100"
|
||||
fill="url(#Gradient2)" />
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 767 B |
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500px" height="500px">
|
||||
<defs>
|
||||
<linearGradient id="stripes">
|
||||
<stop offset="0%" stop-color="red" />
|
||||
<stop offset="10%" stop-color="red" />
|
||||
<stop offset="10%" stop-color="orange" />
|
||||
<stop offset="20%" stop-color="orange" />
|
||||
<stop offset="20%" stop-color="yellow" />
|
||||
<stop offset="30%" stop-color="yellow" />
|
||||
<stop offset="30%" stop-color="lightgreen" />
|
||||
<stop offset="40%" stop-color="lightgreen" />
|
||||
<stop offset="40%" stop-color="green" />
|
||||
<stop offset="50%" stop-color="green" />
|
||||
<stop offset="50%" stop-color="purple" />
|
||||
<stop offset="60%" stop-color="purple" />
|
||||
<stop offset="60%" stop-color="blue" />
|
||||
<stop offset="70%" stop-color="blue" />
|
||||
<stop offset="70%" stop-color="skyblue" />
|
||||
<stop offset="80%" stop-color="skyblue" />
|
||||
<stop offset="80%" stop-color="pink" />
|
||||
<stop offset="90%" stop-color="pink" />
|
||||
<stop offset="90%" stop-color="white" />
|
||||
<stop offset="100%" stop-color="white" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#stripes)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
flatlaf.releaseVersion = 3.4
|
||||
flatlaf.releaseVersion = 3.4.1
|
||||
flatlaf.developmentVersion = 3.5-SNAPSHOT
|
||||
|
||||
org.gradle.parallel = true
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
|
||||
[versions]
|
||||
junit = "5.10.0"
|
||||
junit = "5.10.2"
|
||||
|
||||
|
||||
[libraries]
|
||||
@@ -24,10 +24,10 @@ junit = "5.10.0"
|
||||
sigtest = "org.netbeans.tools:sigtest-maven-plugin:1.7"
|
||||
|
||||
# flatlaf-extras
|
||||
jsvg = "com.github.weisj:jsvg:1.2.0"
|
||||
jsvg = "com.github.weisj:jsvg:1.4.0"
|
||||
|
||||
# flatlaf-jide-oss
|
||||
jide-oss = "com.formdev:jide-oss:3.7.14"
|
||||
jide-oss = "com.formdev:jide-oss:3.7.15"
|
||||
|
||||
# flatlaf-swingx
|
||||
swingx-all = "org.swinglabs.swingx:swingx-all:1.6.5-1"
|
||||
@@ -50,16 +50,12 @@ jna = "net.java.dev.jna:jna:5.12.1"
|
||||
jna-platform = "net.java.dev.jna:jna-platform:5.12.1"
|
||||
|
||||
# junit
|
||||
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
|
||||
junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
|
||||
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
|
||||
junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
|
||||
junit-launcher = { module = "org.junit.platform:junit-platform-launcher" }
|
||||
|
||||
# errorprone
|
||||
errorprone = "com.google.errorprone:error_prone_core:2.20.0"
|
||||
|
||||
|
||||
[bundles]
|
||||
junit = [ "junit-api", "junit-params" ]
|
||||
|
||||
[plugins]
|
||||
errorprone = { id = "net.ltgt.errorprone", version = "3.1.0" }
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
20
gradlew.bat
vendored
20
gradlew.bat
vendored
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user