diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
index e6aa98f0..542fe963 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
@@ -146,8 +146,8 @@ public interface FlatClientProperties
String STYLE = "FlatLaf.style";
/**
- * Specifies the style class(es) of a component as String
- * or as {@link java.util.List}<String>.
+ * Specifies the style class(es) of a component as String (single class or multiple classes separated by space characters)
+ * or as {@code String[]} or {@link java.util.List}<String> (multiple classes).
*
* The style rules must be defined in UI defaults either as strings (in CSS syntax)
* or as {@link java.util.Map}<String, Object> (with binary values).
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
index de2b9d5c..6f21ba2b 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java
@@ -127,7 +127,7 @@ public class FlatStylingSupport
* UIManager.get( "[style]Button.foo" ) );
* }
*
- * @param styleClass the style class(es) either as string (single class)
+ * @param styleClass the style class(es) either as string (single class or multiple classes separated by space characters)
* or as {@code String[]} or {@link java.util.List}<String> (multiple classes)
* @param type the type of the component
* @return the styles
@@ -136,8 +136,11 @@ public class FlatStylingSupport
if( styleClass == null )
return null;
+ if( styleClass instanceof String && ((String)styleClass).indexOf( ' ' ) >= 0 )
+ styleClass = StringUtils.split( (String) styleClass, ' ', true, true );
+
if( styleClass instanceof String )
- return getStyleForClass( (String) styleClass, type );
+ return getStyleForClass( ((String)styleClass).trim(), type );
else if( styleClass instanceof String[] ) {
Object style = null;
for( String cls : (String[]) styleClass )
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/StringUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/StringUtils.java
index df184d1e..2f952014 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/StringUtils.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/StringUtils.java
@@ -17,6 +17,7 @@
package com.formdev.flatlaf.util;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -46,16 +47,50 @@ public class StringUtils
}
public static List split( String str, char delim ) {
- ArrayList strs = new ArrayList<>();
+ return split( str, delim, false, false );
+ }
+
+ /**
+ * Splits a string at the specified delimiter.
+ * If trimming is enabled, then leading and trailing whitespace characters are removed.
+ * If excludeEmpty is {@code true}, then only non-empty strings are returned.
+ *
+ * @since 2
+ */
+ public static List split( String str, char delim, boolean trim, boolean excludeEmpty ) {
int delimIndex = str.indexOf( delim );
+ if( delimIndex < 0 ) {
+ if( trim )
+ str = str.trim();
+ return !excludeEmpty || !str.isEmpty()
+ ? Collections.singletonList( str )
+ : Collections.emptyList();
+ }
+
+ ArrayList strs = new ArrayList<>();
int index = 0;
while( delimIndex >= 0 ) {
- strs.add( str.substring( index, delimIndex ) );
+ add( strs, str, index, delimIndex, trim, excludeEmpty );
index = delimIndex + 1;
delimIndex = str.indexOf( delim, index );
}
- strs.add( str.substring( index ) );
+ add( strs, str, index, str.length(), trim, excludeEmpty );
return strs;
}
+
+ private static void add( List strs, String str, int begin, int end, boolean trim, boolean excludeEmpty ) {
+ if( trim ) {
+ // skip leading whitespace
+ while( begin < end && str.charAt( begin ) <= ' ' )
+ begin++;
+
+ // skip trailing whitespace
+ while( begin < end && str.charAt( end - 1 ) <= ' ' )
+ end--;
+ }
+
+ if( !excludeEmpty || end > begin )
+ strs.add( str.substring( begin, end ) );
+ }
}
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java
index d96036f1..20bb9ebe 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Color;
import java.awt.Dimension;
+import java.util.Arrays;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import org.junit.jupiter.api.AfterAll;
@@ -114,10 +115,25 @@ public class TestFlatStyleClasses
assertEquals(
FlatStylingSupport.concatStyles( BUTTON_PRIMARY, SECONDARY ),
- FlatStylingSupport.getStyleForClasses( new String[] { "primary", "secondary" }, "Button" ) );
+ FlatStylingSupport.getStyleForClasses( "primary secondary", "Button" ) );
+ assertEquals(
+ FlatStylingSupport.concatStyles( SECONDARY, BUTTON_PRIMARY ),
+ FlatStylingSupport.getStyleForClasses( "secondary primary", "Button" ) );
+
+ // String
+ assertEquals(
+ FlatStylingSupport.concatStyles( SECONDARY, BUTTON_PRIMARY ),
+ FlatStylingSupport.getStyleForClasses( " secondary primary bla blu ", "Button" ) );
+
+ // String[]
assertEquals(
FlatStylingSupport.concatStyles( SECONDARY, BUTTON_PRIMARY ),
FlatStylingSupport.getStyleForClasses( new String[] { "secondary", "primary" }, "Button" ) );
+
+ // List
+ assertEquals(
+ FlatStylingSupport.concatStyles( SECONDARY, BUTTON_PRIMARY ),
+ FlatStylingSupport.getStyleForClasses( Arrays.asList( "secondary", "primary" ), "Button" ) );
}
@Test
@@ -132,7 +148,7 @@ public class TestFlatStyleClasses
@Test
void apply2() {
JButton c = new JButton();
- c.putClientProperty( FlatClientProperties.STYLE_CLASS, new String[] { "primary", "secondary" } );
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "primary secondary" );
assertEquals( new Color( 0x00ff88 ), c.getBackground() );
assertEquals( Color.white, c.getForeground() );
@@ -141,7 +157,7 @@ public class TestFlatStyleClasses
@Test
void apply3() {
JButton c = new JButton();
- c.putClientProperty( FlatClientProperties.STYLE_CLASS, new String[] { "secondary", "primary" } );
+ c.putClientProperty( FlatClientProperties.STYLE_CLASS, "secondary primary" );
assertEquals( new Color( 0x0088ff ), c.getBackground() );
assertEquals( Color.white, c.getForeground() );
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/util/TestStringUtils.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/util/TestStringUtils.java
new file mode 100644
index 00000000..136ebbcf
--- /dev/null
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/util/TestStringUtils.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2021 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.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Karl Tauber
+ */
+public class TestStringUtils
+{
+ @Test
+ void split() {
+ // empty
+ assertEquals(
+ Arrays.asList( "" ),
+ StringUtils.split( "", ',' ) );
+
+ // not empty
+ assertEquals(
+ Arrays.asList( "a" ),
+ StringUtils.split( "a", ',' ) );
+ assertEquals(
+ Arrays.asList( "a", "b" ),
+ StringUtils.split( "a,b", ',' ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a,b,c", ',' ) );
+
+ // empty parts
+ assertEquals(
+ Arrays.asList( "", "b", "c" ),
+ StringUtils.split( ",b,c", ',' ) );
+ assertEquals(
+ Arrays.asList( "a", "", "c" ),
+ StringUtils.split( "a,,c", ',' ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "" ),
+ StringUtils.split( "a,b,", ',' ) );
+
+ // parts with leading/trailing spaces
+ assertEquals(
+ Arrays.asList( "a", " b", " c" ),
+ StringUtils.split( "a, b, c", ',' ) );
+ assertEquals(
+ Arrays.asList( " a", "b", "c " ),
+ StringUtils.split( " a,b,c ", ',' ) );
+ assertEquals(
+ Arrays.asList( " a", " b ", "c " ),
+ StringUtils.split( " a, b ,c ", ',' ) );
+
+ // space delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a b c", ' ' ) );
+ assertEquals(
+ Arrays.asList( "a", "", "", "b", "", "c" ),
+ StringUtils.split( "a b c", ' ' ) );
+
+ // new line delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a\nb\nc", '\n' ) );
+ assertEquals(
+ Arrays.asList( "a", "", "", "b", "", "c" ),
+ StringUtils.split( "a\n\n\nb\n\nc", '\n' ) );
+ }
+
+ @Test
+ void splitTrim() {
+ // empty
+ assertEquals(
+ Arrays.asList( "" ),
+ StringUtils.split( "", ',', true, false ) );
+
+ // not empty
+ assertEquals(
+ Arrays.asList( "a" ),
+ StringUtils.split( "a", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "b" ),
+ StringUtils.split( "a,b", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a,b,c", ',', true, false ) );
+
+ // empty parts
+ assertEquals(
+ Arrays.asList( "", "b", "c" ),
+ StringUtils.split( ",b,c", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "", "c" ),
+ StringUtils.split( "a,,c", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "" ),
+ StringUtils.split( "a,b,", ',', true, false ) );
+
+ // parts with leading/trailing spaces
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a, b, c", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( " a,b,c ", ',', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( " a, b ,c ", ',', true, false ) );
+
+ // space delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a b c", ' ', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "", "", "b", "", "c" ),
+ StringUtils.split( "a b c", ' ', true, false ) );
+
+ // new line delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a\nb\nc", '\n', true, false ) );
+ assertEquals(
+ Arrays.asList( "a", "", "", "b", "", "c" ),
+ StringUtils.split( "a\n\n\nb\n\nc", '\n', true, false ) );
+ }
+
+ @Test
+ void splitTrimAndExcludeEmpty() {
+ // empty
+ assertEquals(
+ Arrays.asList(),
+ StringUtils.split( "", ',', true, true ) );
+
+ // not empty
+ assertEquals(
+ Arrays.asList( "a" ),
+ StringUtils.split( "a", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b" ),
+ StringUtils.split( "a,b", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a,b,c", ',', true, true ) );
+
+ // empty parts
+ assertEquals(
+ Arrays.asList( "b", "c" ),
+ StringUtils.split( ",b,c", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "c" ),
+ StringUtils.split( "a,,c", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b" ),
+ StringUtils.split( "a,b,", ',', true, true ) );
+
+ // parts with leading/trailing spaces
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a, b, c", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( " a,b,c ", ',', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( " a, b ,c ", ',', true, true ) );
+
+ // space delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a b c", ' ', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a b c", ' ', true, true ) );
+
+ // new line delimiter
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a\nb\nc", '\n', true, true ) );
+ assertEquals(
+ Arrays.asList( "a", "b", "c" ),
+ StringUtils.split( "a\n\n\nb\n\nc", '\n', true, true ) );
+ }
+}