diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a1b28fd..774ed4e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ FlatLaf Change Log
- Native libraries: Added `libflatlaf-macos-arm64.dylib` and
`libflatlaf-macos-x86_64.dylib`. See also
https://www.formdev.com/flatlaf/native-libraries/.
+- ScrollPane: Support rounded border. (PR #713)
- ToolBar: Added styling properties `separatorWidth` and `separatorColor`.
#### Fixed bugs
@@ -20,6 +21,8 @@ FlatLaf Change Log
and #750)
- OptionPane: Fixed styling custom panel background in `JOptionPane`. (issue
#761)
+- ScrollPane: Styling ScrollPane border properties did not work if view
+ component is a Table.
- Table: Fixed background of `boolean` columns when using alternating row
colors. (issue #780)
- Fixed broken rendering after resizing window to minimum size and then
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java
index 11d2cbfb..2903998d 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatBorder.java
@@ -28,7 +28,6 @@ import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
-import javax.swing.JViewport;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicBorders;
import com.formdev.flatlaf.FlatClientProperties;
@@ -195,8 +194,7 @@ public class FlatBorder
protected boolean isEnabled( Component c ) {
if( c instanceof JScrollPane ) {
// check whether view component is disabled
- JViewport viewport = ((JScrollPane)c).getViewport();
- Component view = (viewport != null) ? viewport.getView() : null;
+ Component view = FlatScrollPaneUI.getView( (JScrollPane) c );
if( view != null && !isEnabled( view ) )
return false;
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneBorder.java
new file mode 100644
index 00000000..ec8c0a41
--- /dev/null
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneBorder.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2023 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
+ *
+ * http://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.awt.Component;
+import java.awt.Insets;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTree;
+import javax.swing.UIManager;
+import javax.swing.text.JTextComponent;
+import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
+import com.formdev.flatlaf.util.UIScale;
+
+/**
+ * Border for {@link javax.swing.JScrollPane}.
+ *
+ * @uiDefault ScrollPane.arc int
+ * @uiDefault ScrollPane.List.arc int
+ * @uiDefault ScrollPane.Table.arc int
+ * @uiDefault ScrollPane.TextComponent.arc int
+ * @uiDefault ScrollPane.Tree.arc int
+
+ * @author Karl Tauber
+ * @since 3.3
+ */
+public class FlatScrollPaneBorder
+ extends FlatBorder
+{
+ @Styleable protected int arc = UIManager.getInt( "ScrollPane.arc" );
+
+ private boolean isArcStyled;
+ private final int listArc = FlatUIUtils.getUIInt( "ScrollPane.List.arc", -1 );
+ private final int tableArc = FlatUIUtils.getUIInt( "ScrollPane.Table.arc", -1 );
+ private final int textComponentArc = FlatUIUtils.getUIInt( "ScrollPane.TextComponent.arc", -1 );
+ private final int treeArc = FlatUIUtils.getUIInt( "ScrollPane.Tree.arc", -1 );
+
+ @Override
+ public Object applyStyleProperty( String key, Object value ) {
+ Object oldValue = super.applyStyleProperty( key, value );
+
+ if( "arc".equals( key ) )
+ isArcStyled = true;
+
+ return oldValue;
+ }
+
+ @Override
+ public Insets getBorderInsets( Component c, Insets insets ) {
+ insets = super.getBorderInsets( c, insets );
+
+ // if view is rounded, increase left and right insets to avoid that the viewport
+ // is painted over the rounded border on the corners
+ int padding = getLeftRightPadding( c );
+ if( padding > 0 ) {
+ insets.left += padding;
+ insets.right += padding;
+ }
+
+ return insets;
+ }
+
+ @Override
+ protected int getArc( Component c ) {
+ if( isCellEditor( c ) )
+ return 0;
+
+ if( isArcStyled )
+ return arc;
+
+ if( c instanceof JScrollPane ) {
+ Component view = FlatScrollPaneUI.getView( (JScrollPane) c );
+ if( listArc >= 0 && view instanceof JList )
+ return listArc;
+ if( tableArc >= 0 && view instanceof JTable )
+ return tableArc;
+ if( textComponentArc >= 0&& view instanceof JTextComponent )
+ return textComponentArc;
+ if( treeArc >= 0 && view instanceof JTree )
+ return treeArc;
+ }
+
+ return arc;
+ }
+
+ /**
+ * Returns the scaled left/right padding used when arc is larger than zero.
+ *
+ * This is the distance from the inside of the left border to the left side of the view component.
+ * On the right side, this is the distance between the right side of the view component and
+ * the vertical scrollbar. Or the inside of the right border if the scrollbar is hidden.
+ */
+ public int getLeftRightPadding( Component c ) {
+ // Subtract lineWidth from radius because radius is given for the outside
+ // of the painted line, but insets from super already include lineWidth.
+ // Reduce padding by 10% to make padding slightly smaller because it is not recognizable
+ // when the view is minimally painted over the beginning of the border curve.
+ int arc = getArc( c );
+ return (arc > 0)
+ ? Math.max( Math.round( UIScale.scale( ((arc / 2f) - getLineWidth( c )) * 0.9f ) ), 0 )
+ : 0;
+ }
+}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
index a62e8369..f563af65 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatScrollPaneUI.java
@@ -17,9 +17,12 @@
package com.formdev.flatlaf.ui;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Graphics;
+import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
+import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
@@ -41,16 +44,19 @@ import javax.swing.JTree;
import javax.swing.JViewport;
import javax.swing.LookAndFeel;
import javax.swing.ScrollPaneConstants;
+import javax.swing.ScrollPaneLayout;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollPaneUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade;
+import com.formdev.flatlaf.util.UIScale;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
@@ -97,7 +103,13 @@ public class FlatScrollPaneUI
super.installUI( c );
int focusWidth = UIManager.getInt( "Component.focusWidth" );
- LookAndFeel.installProperty( c, "opaque", focusWidth == 0 );
+ int arc = UIManager.getInt( "ScrollPane.arc" );
+ LookAndFeel.installProperty( c, "opaque", focusWidth == 0 && arc == 0 );
+
+ // install layout manager
+ LayoutManager layout = c.getLayout();
+ if( layout != null && layout.getClass() == ScrollPaneLayout.UIResource.class )
+ c.setLayout( createScrollPaneLayout() );
installStyle();
@@ -108,6 +120,10 @@ public class FlatScrollPaneUI
public void uninstallUI( JComponent c ) {
MigLayoutVisualPadding.uninstall( scrollpane );
+ // uninstall layout manager
+ if( c.getLayout() instanceof FlatScrollPaneLayout )
+ c.setLayout( new ScrollPaneLayout.UIResource() );
+
super.uninstallUI( c );
oldStyleValues = null;
@@ -130,6 +146,13 @@ public class FlatScrollPaneUI
handler = null;
}
+ /**
+ * @since 3.3
+ */
+ protected FlatScrollPaneLayout createScrollPaneLayout() {
+ return new FlatScrollPaneLayout();
+ }
+
@Override
protected MouseWheelListener createMouseWheelListener() {
MouseWheelListener superListener = super.createMouseWheelListener();
@@ -290,8 +313,7 @@ public class FlatScrollPaneUI
Object corner = e.getNewValue();
if( corner instanceof JButton &&
((JButton)corner).getBorder() instanceof FlatButtonBorder &&
- scrollpane.getViewport() != null &&
- scrollpane.getViewport().getView() instanceof JTable )
+ getView( scrollpane ) instanceof JTable )
{
((JButton)corner).setBorder( BorderFactory.createEmptyBorder() );
((JButton)corner).setFocusable( false );
@@ -308,6 +330,18 @@ public class FlatScrollPaneUI
scrollpane.revalidate();
scrollpane.repaint();
break;
+
+ case "border":
+ Object newBorder = e.getNewValue();
+ if( newBorder != null && newBorder == UIManager.getBorder( "Table.scrollPaneBorder" ) ) {
+ // JTable.configureEnclosingScrollPaneUI() replaces the scrollpane border
+ // with another one --> re-apply style on new border
+ borderShared = null;
+ installStyle();
+ scrollpane.revalidate();
+ scrollpane.repaint();
+ }
+ break;
}
};
}
@@ -334,9 +368,10 @@ public class FlatScrollPaneUI
/** @since 2 */
protected Object applyStyleProperty( String key, Object value ) {
- if( key.equals( "focusWidth" ) ) {
+ if( key.equals( "focusWidth" ) || key.equals( "arc" ) ) {
int focusWidth = (value instanceof Integer) ? (int) value : UIManager.getInt( "Component.focusWidth" );
- LookAndFeel.installProperty( scrollpane, "opaque", focusWidth == 0 );
+ int arc = (value instanceof Integer) ? (int) value : UIManager.getInt( "ScrollPane.arc" );
+ LookAndFeel.installProperty( scrollpane, "opaque", focusWidth == 0 && arc == 0 );
}
if( borderShared == null )
@@ -402,13 +437,46 @@ public class FlatScrollPaneUI
c.getHeight() - insets.top - insets.bottom );
}
+ // if view is rounded, paint rounded background with view background color
+ // to ensure that free areas at left and right have same color as view
+ Component view;
+ float arc = getBorderArc( scrollpane );
+ if( arc > 0 && (view = getView( scrollpane )) != null ) {
+ float focusWidth = FlatUIUtils.getBorderFocusWidth( c );
+
+ g.setColor( view.getBackground() );
+
+ Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
+ FlatUIUtils.paintComponentBackground( (Graphics2D) g, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
+ FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
+ }
+
paint( g, c );
}
+ @Override
+ public void paint( Graphics g, JComponent c ) {
+ Border viewportBorder = scrollpane.getViewportBorder();
+ if( viewportBorder != null ) {
+ Rectangle r = scrollpane.getViewportBorderBounds();
+ int padding = getBorderLeftRightPadding( scrollpane );
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ if( padding > 0 &&
+ vsb != null && vsb.isVisible() &&
+ scrollpane.getLayout() instanceof FlatScrollPaneLayout &&
+ ((FlatScrollPaneLayout)scrollpane.getLayout()).canIncreaseViewportWidth( scrollpane ) )
+ {
+ boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();
+ int extraWidth = Math.min( padding, vsb.getWidth() );
+ viewportBorder.paintBorder( scrollpane, g, r.x - (ltr ? 0 : extraWidth), r.y, r.width + extraWidth, r.height );
+ } else
+ viewportBorder.paintBorder( scrollpane, g, r.x, r.y, r.width, r.height );
+ }
+ }
+
/** @since 1.3 */
public static boolean isPermanentFocusOwner( JScrollPane scrollPane ) {
- JViewport viewport = scrollPane.getViewport();
- Component view = (viewport != null) ? viewport.getView() : null;
+ Component view = getView( scrollPane );
if( view == null )
return false;
@@ -428,6 +496,25 @@ public class FlatScrollPaneUI
return false;
}
+ static Component getView( JScrollPane scrollPane ) {
+ JViewport viewport = scrollPane.getViewport();
+ return (viewport != null) ? viewport.getView() : null;
+ }
+
+ private static float getBorderArc( JScrollPane scrollPane ) {
+ Border border = scrollPane.getBorder();
+ return (border instanceof FlatScrollPaneBorder)
+ ? UIScale.scale( (float) ((FlatScrollPaneBorder)border).getArc( scrollPane ) )
+ : 0;
+ }
+
+ private static int getBorderLeftRightPadding( JScrollPane scrollPane ) {
+ Border border = scrollPane.getBorder();
+ return (border instanceof FlatScrollPaneBorder)
+ ? ((FlatScrollPaneBorder)border).getLeftRightPadding( scrollPane )
+ : 0;
+ }
+
//---- class Handler ------------------------------------------------------
/**
@@ -450,13 +537,71 @@ public class FlatScrollPaneUI
@Override
public void focusGained( FocusEvent e ) {
// necessary to update focus border
- scrollpane.repaint();
+ if( scrollpane.getBorder() instanceof FlatBorder )
+ scrollpane.repaint();
}
@Override
public void focusLost( FocusEvent e ) {
// necessary to update focus border
- scrollpane.repaint();
+ if( scrollpane.getBorder() instanceof FlatBorder )
+ scrollpane.repaint();
+ }
+ }
+
+ //---- class FlatScrollPaneLayout -----------------------------------------
+
+ /**
+ * @since 3.3
+ */
+ protected static class FlatScrollPaneLayout
+ extends ScrollPaneLayout.UIResource
+ {
+ @Override
+ public void layoutContainer( Container parent ) {
+ super.layoutContainer( parent );
+
+ JScrollPane scrollPane = (JScrollPane) parent;
+ int padding = getBorderLeftRightPadding( scrollPane );
+ if( padding > 0 && vsb != null && vsb.isVisible() ) {
+ // move vertical scrollbar to trailing edge
+ Insets insets = scrollPane.getInsets();
+ Rectangle r = vsb.getBounds();
+ int y = Math.max( r.y, insets.top + padding );
+ int y2 = Math.min( r.y + r.height, scrollPane.getHeight() - insets.bottom - padding );
+ boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();
+
+ vsb.setBounds( r.x + (ltr ? padding : -padding), y, r.width, y2 - y );
+
+ // increase width of viewport, column header and horizontal scrollbar
+ if( canIncreaseViewportWidth( scrollPane ) ) {
+ int extraWidth = Math.min( padding, vsb.getWidth() );
+ resizeViewport( viewport, extraWidth, ltr );
+ resizeViewport( colHead, extraWidth, ltr );
+ resizeViewport( hsb, extraWidth, ltr );
+ }
+ }
+ }
+
+ boolean canIncreaseViewportWidth( JScrollPane scrollPane ) {
+ return scrollPane.getComponentOrientation().isLeftToRight()
+ ? !isCornerVisible( upperRight ) && !isCornerVisible( lowerRight )
+ : !isCornerVisible( upperLeft ) && !isCornerVisible( lowerLeft );
+ }
+
+ private static boolean isCornerVisible( Component corner ) {
+ return corner != null &&
+ corner.getWidth() > 0 &&
+ corner.getHeight() > 0 &&
+ corner.isVisible();
+ }
+
+ private static void resizeViewport( Component c, int extraWidth, boolean ltr ) {
+ if( c == null )
+ return;
+
+ Rectangle vr = c.getBounds();
+ c.setBounds( vr.x - (ltr ? 0 : extraWidth), vr.y, vr.width + extraWidth, vr.height );
}
}
}
diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
index 2b0124e0..f8a13fcb 100644
--- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
+++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
@@ -600,10 +600,15 @@ ScrollBar.allowsAbsolutePositioning = true
#---- ScrollPane ----
-ScrollPane.border = com.formdev.flatlaf.ui.FlatBorder
+ScrollPane.border = com.formdev.flatlaf.ui.FlatScrollPaneBorder
ScrollPane.background = $ScrollBar.track
ScrollPane.fillUpperCorner = true
ScrollPane.smoothScrolling = true
+ScrollPane.arc = 0
+#ScrollPane.List.arc = -1
+#ScrollPane.Table.arc = -1
+#ScrollPane.TextComponent.arc = -1
+#ScrollPane.Tree.arc = -1
#---- SearchField ----
@@ -734,7 +739,7 @@ Table.showVerticalLines = false
Table.showTrailingVerticalLine = false
Table.consistentHomeEndKeyBehavior = true
Table.intercellSpacing = 0,0
-Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatBorder
+Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatScrollPaneBorder
Table.ascendingSortIcon = com.formdev.flatlaf.icons.FlatAscendingSortIcon
Table.descendingSortIcon = com.formdev.flatlaf.icons.FlatDescendingSortIcon
Table.sortIconColor = @icon
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
index 645dc920..ebdfef72 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
@@ -601,7 +601,7 @@ public class TestFlatStyleableInfo
);
// border
- flatBorder( expected );
+ flatScrollPaneBorder( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) );
}
@@ -1008,17 +1008,23 @@ public class TestFlatStyleableInfo
expectedMap( expected,
"arc", int.class,
-
"roundRect", Boolean.class
);
}
+ private void flatScrollPaneBorder( Map> expected ) {
+ flatBorder( expected );
+
+ expectedMap( expected,
+ "arc", int.class
+ );
+ }
+
private void flatTextBorder( Map> expected ) {
flatBorder( expected );
expectedMap( expected,
"arc", int.class,
-
"roundRect", Boolean.class
);
}
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java
index a7199f71..6c8161b7 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java
@@ -625,7 +625,7 @@ public class TestFlatStyleableValue
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
// border
- flatBorder( c, ui );
+ flatScrollPaneBorder( c, ui );
testBoolean( c, ui, "showButtons", true );
}
@@ -968,15 +968,19 @@ public class TestFlatStyleableValue
flatBorder( c, ui );
testInteger( c, ui, "arc", 123 );
-
testBoolean( c, ui, "roundRect", true );
}
+ private void flatScrollPaneBorder( JComponent c, StyleableUI ui ) {
+ flatBorder( c, ui );
+
+ testInteger( c, ui, "arc", 123 );
+ }
+
private void flatTextBorder( JComponent c, StyleableUI ui ) {
flatBorder( c, ui );
testInteger( c, ui, "arc", 123 );
-
testBoolean( c, ui, "roundRect", true );
}
@@ -1037,6 +1041,17 @@ public class TestFlatStyleableValue
// FlatRoundBorder extends FlatBorder
flatBorder( border );
+ testValue( border, "arc", 6 );
+ testValue( border, "roundRect", true );
+ }
+
+ @Test
+ void flatScrollPaneBorder() {
+ FlatScrollPaneBorder border = new FlatScrollPaneBorder();
+
+ // FlatScrollPaneBorder extends FlatBorder
+ flatBorder( border );
+
testValue( border, "arc", 6 );
}
@@ -1048,6 +1063,7 @@ public class TestFlatStyleableValue
flatBorder( border );
testValue( border, "arc", 6 );
+ testValue( border, "roundRect", true );
}
@Test
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
index 927086c3..e0e20175 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
@@ -760,7 +760,7 @@ public class TestFlatStyling
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
// border
- flatBorder( style -> ui.applyStyle( style ) );
+ flatScrollPaneBorder( style -> ui.applyStyle( style ) );
ui.applyStyle( "showButtons: true" );
@@ -1237,15 +1237,19 @@ public class TestFlatStyling
flatBorder( applyStyle );
applyStyle.accept( "arc: 6" );
-
applyStyle.accept( "roundRect: true" );
}
+ private void flatScrollPaneBorder( Consumer applyStyle ) {
+ flatBorder( applyStyle );
+
+ applyStyle.accept( "arc: 6" );
+ }
+
private void flatTextBorder( Consumer applyStyle ) {
flatBorder( applyStyle );
applyStyle.accept( "arc: 6" );
-
applyStyle.accept( "roundRect: true" );
}
diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarculaLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarculaLaf_1.8.0.txt
index 8291260a..cba7171f 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatDarculaLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatDarculaLaf_1.8.0.txt
@@ -87,8 +87,8 @@
#---- ScrollPane ----
-- ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
-+ ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+- ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
++ ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
#---- Spinner ----
@@ -99,8 +99,8 @@
#---- Table ----
-- Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
-+ Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+- Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
++ Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
#---- TextField ----
diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
index d2dcd9c6..2aa1aa49 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
@@ -906,8 +906,9 @@ ScrollBarUI com.formdev.flatlaf.ui.FlatScrollBarUI
#---- ScrollPane ----
+ScrollPane.arc 0
ScrollPane.background #3e4244 HSL 200 5 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
-ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
ScrollPane.fillUpperCorner true
ScrollPane.font [active] $defaultFont [UI]
ScrollPane.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
@@ -1118,7 +1119,7 @@ Table.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.Colo
Table.gridColor #5a5e60 HSL 200 3 36 javax.swing.plaf.ColorUIResource [UI]
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
Table.rowHeight 20
-Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
Table.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI]
Table.selectionForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
Table.selectionInactiveBackground #0f2a3d HSL 205 61 15 javax.swing.plaf.ColorUIResource [UI]
diff --git a/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0.txt
index f579ab89..7b2d2fd2 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0.txt
@@ -107,8 +107,8 @@
#---- ScrollPane ----
-- ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
-+ ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+- ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
++ ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
#---- Spinner ----
@@ -119,8 +119,8 @@
#---- Table ----
-- Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
-+ Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+- Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
++ Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
#---- TextField ----
diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
index 7871f3ee..33980206 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
@@ -911,8 +911,9 @@ ScrollBarUI com.formdev.flatlaf.ui.FlatScrollBarUI
#---- ScrollPane ----
+ScrollPane.arc 0
ScrollPane.background #f5f5f5 HSL 0 0 96 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
-ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
ScrollPane.fillUpperCorner true
ScrollPane.font [active] $defaultFont [UI]
ScrollPane.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
@@ -1123,7 +1124,7 @@ Table.foreground #000000 HSL 0 0 0 javax.swing.plaf.Colo
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
Table.rowHeight 20
-Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
Table.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI]
Table.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Table.selectionInactiveBackground #d3d3d3 HSL 0 0 83 javax.swing.plaf.ColorUIResource [UI]
diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt
index 14e4925f..bb3b8735 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt
@@ -915,8 +915,9 @@ ScrollBarUI com.formdev.flatlaf.ui.FlatScrollBarUI
#---- ScrollPane ----
+ScrollPane.arc 0
ScrollPane.background #282828 HSL 0 0 16 javax.swing.plaf.ColorUIResource [UI]
-ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
ScrollPane.fillUpperCorner true
ScrollPane.font [active] $defaultFont [UI]
ScrollPane.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
@@ -1128,7 +1129,7 @@ Table.foreground #dddddd HSL 0 0 87 javax.swing.plaf.Colo
Table.gridColor #3c3c3c HSL 0 0 24 javax.swing.plaf.ColorUIResource [UI]
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
Table.rowHeight 20
-Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
Table.selectionBackground #0054cc HSL 215 100 40 javax.swing.plaf.ColorUIResource [UI]
Table.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Table.selectionInactiveBackground #464646 HSL 0 0 27 javax.swing.plaf.ColorUIResource [UI]
diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt
index 4b09126d..0265f954 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt
@@ -919,8 +919,9 @@ ScrollBarUI com.formdev.flatlaf.ui.FlatScrollBarUI
#---- ScrollPane ----
+ScrollPane.arc 0
ScrollPane.background #fafafa HSL 0 0 98 javax.swing.plaf.ColorUIResource [UI]
-ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+ScrollPane.border [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
ScrollPane.fillUpperCorner true
ScrollPane.font [active] $defaultFont [UI]
ScrollPane.foreground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI]
@@ -1132,7 +1133,7 @@ Table.foreground #262626 HSL 0 0 15 javax.swing.plaf.Colo
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
Table.rowHeight 20
-Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatBorder [UI]
+Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
Table.selectionBackground #005fe6 HSL 215 100 45 javax.swing.plaf.ColorUIResource [UI]
Table.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Table.selectionInactiveBackground #dcdcdc HSL 0 0 86 javax.swing.plaf.ColorUIResource [UI]
diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
index 3ff67dd1..14b8ec41 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
@@ -932,8 +932,9 @@ ScrollBarUI com.formdev.flatlaf.ui.FlatScrollBarUI
#---- ScrollPane ----
+ScrollPane.arc 20
ScrollPane.background #88ff88 HSL 120 100 77 javax.swing.plaf.ColorUIResource [UI]
-ScrollPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+ScrollPane.border [lazy] 1,9,1,9 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
ScrollPane.fillUpperCorner true
ScrollPane.font [active] $defaultFont [UI]
ScrollPane.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
@@ -1154,7 +1155,7 @@ Table.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
Table.gridColor #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
Table.rowHeight 25
-Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatBorder [UI]
+Table.scrollPaneBorder [lazy] 1,9,1,9 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
Table.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI]
Table.selectionForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
Table.selectionInactiveBackground #888888 HSL 0 0 53 javax.swing.plaf.ColorUIResource [UI]
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.java
new file mode 100644
index 00000000..ebea0428
--- /dev/null
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2023 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.testing;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.MatteBorder;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.tree.*;
+import com.formdev.flatlaf.FlatClientProperties;
+import com.formdev.flatlaf.ui.FlatScrollPaneBorder;
+import com.formdev.flatlaf.util.UIScale;
+import net.miginfocom.swing.*;
+
+/**
+ * @author Karl Tauber
+ */
+public class FlatRoundedScrollPaneTest
+ extends FlatTestPanel
+{
+ private JScrollPane[] allJScrollPanes;
+
+ public static void main( String[] args ) {
+ SwingUtilities.invokeLater( () -> {
+ FlatTestFrame frame = FlatTestFrame.create( args, "FlatRoundedScrollPaneTest" );
+ frame.useApplyComponentOrientation = true;
+ frame.showFrame( FlatRoundedScrollPaneTest::new );
+ } );
+ }
+
+ FlatRoundedScrollPaneTest() {
+ initComponents();
+
+ allJScrollPanes = new JScrollPane[] {
+ listScrollPane, treeScrollPane, tableScrollPane,
+ textAreaScrollPane, textPaneScrollPane, editorPaneScrollPane, customScrollPane
+ };
+
+ ArrayList items = new ArrayList<>();
+ for( char ch = '0'; ch < 'z'; ch++ ) {
+ if( (ch > '9' && ch < 'A') || (ch > 'Z' && ch < 'a') )
+ continue;
+
+ char[] chars = new char[ch - '0' + 1];
+ Arrays.fill( chars, ch );
+ items.add( new String( chars ) );
+ }
+
+ // list model
+ list.setModel( new AbstractListModel() {
+ @Override
+ public int getSize() {
+ return items.size();
+ }
+ @Override
+ public String getElementAt( int index ) {
+ return items.get( index );
+ }
+ } );
+
+ // tree model
+ DefaultMutableTreeNode root = new DefaultMutableTreeNode( items.get( 0 ) );
+ DefaultMutableTreeNode last = null;
+ for( int i = 1; i < items.size(); i++ ) {
+ DefaultMutableTreeNode node = new DefaultMutableTreeNode( items.get( i ) );
+ if( i % 5 == 1 ) {
+ root.add( node );
+ last = node;
+ } else
+ last.add( node );
+ }
+ tree.setModel( new DefaultTreeModel( root ) );
+ for( int row = tree.getRowCount() - 1; row >= 0; row-- )
+ tree.expandRow( row );
+
+ // table model
+ table.setModel( new AbstractTableModel() {
+ @Override
+ public int getRowCount() {
+ return items.size();
+ }
+ @Override
+ public int getColumnCount() {
+ return 4;
+ }
+ @Override
+ public Object getValueAt( int rowIndex, int columnIndex ) {
+ if( columnIndex > 0 )
+ rowIndex = (items.size() + rowIndex - ((items.size() / 4) * columnIndex)) % items.size();
+ return items.get( rowIndex );
+ }
+ } );
+
+ // select some rows to better see smooth scrolling issues
+ for( int i = 5; i < items.size(); i += 10 ) {
+ list.addSelectionInterval( i, i );
+ tree.addSelectionInterval( i, i );
+ table.addRowSelectionInterval( i, i );
+ }
+
+ // text components
+ String longText = items.stream().collect( Collectors.joining( " " ) ) + ' '
+ + items.stream().limit( 20 ).collect( Collectors.joining( " " ) );
+ String text = items.stream().collect( Collectors.joining( "\n" ) ) + '\n';
+ textArea.setText( longText + '\n' + text );
+ textPane.setText( text );
+ editorPane.setText( text );
+
+ textArea.select( 0, 0 );
+ textPane.select( 0, 0 );
+ editorPane.select( 0, 0 );
+
+ arcSliderChanged();
+
+ EventQueue.invokeLater( () -> {
+ EventQueue.invokeLater( () -> {
+ list.requestFocusInWindow();
+ } );
+ } );
+ }
+
+ private void autoResizeModeChanged() {
+ table.setAutoResizeMode( autoResizeModeCheckBox.isSelected() ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_OFF );
+ }
+
+ private void cornersChanged() {
+ boolean sel = cornersCheckBox.isSelected();
+ for( JScrollPane scrollPane : allJScrollPanes ) {
+ scrollPane.setCorner( JScrollPane.UPPER_LEADING_CORNER, sel ? new Corner( Color.magenta ) : null );
+ scrollPane.setCorner( JScrollPane.UPPER_TRAILING_CORNER, sel ? new Corner( Color.red ) : null );
+ scrollPane.setCorner( JScrollPane.LOWER_LEADING_CORNER, sel ? new Corner( Color.cyan ) : null );
+ scrollPane.setCorner( JScrollPane.LOWER_TRAILING_CORNER, sel ? new Corner( Color.pink ) : null );
+ }
+ }
+
+ private void columnHeaderChanged() {
+ boolean sel = columnHeaderCheckBox.isSelected();
+ for( JScrollPane scrollPane : allJScrollPanes ) {
+ if( scrollPane == tableScrollPane )
+ continue;
+
+ JViewport header = null;
+ if( sel ) {
+ header = new JViewport();
+ Corner view = new Corner( Color.cyan );
+ view.setPreferredSize( new Dimension( 0, UIScale.scale( 20 ) ) );
+ header.setView( view );
+ }
+ scrollPane.setColumnHeader( header );
+ }
+ }
+
+ private void rowHeaderChanged() {
+ boolean sel = rowHeaderCheckBox.isSelected();
+ for( JScrollPane scrollPane : allJScrollPanes ) {
+ JViewport header = null;
+ if( sel ) {
+ header = new JViewport();
+ Corner view = new Corner( Color.yellow );
+ view.setPreferredSize( new Dimension( UIScale.scale( 20 ), 0 ) );
+ header.setView( view );
+ }
+ scrollPane.setRowHeader( header );
+ }
+ }
+
+ private void horizontalScrollBarChanged() {
+ int policy = horizontalScrollBarCheckBox.isSelected()
+ ? JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
+ : JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;
+
+ for( JScrollPane scrollPane : allJScrollPanes )
+ scrollPane.setHorizontalScrollBarPolicy( policy );
+ }
+
+ private void verticalScrollBarChanged() {
+ int policy = verticalScrollBarCheckBox.isSelected()
+ ? JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
+ : JScrollPane.VERTICAL_SCROLLBAR_NEVER;
+
+ for( JScrollPane scrollPane : allJScrollPanes )
+ scrollPane.setVerticalScrollBarPolicy( policy );
+ }
+
+ private void arcSliderChanged() {
+ int arc = arcSlider.getValue();
+ for( JScrollPane scrollPane : allJScrollPanes )
+ scrollPane.putClientProperty( FlatClientProperties.STYLE, "arc: " + arc );
+
+ Border border = allJScrollPanes[0].getBorder();
+ paddingField.setText( border instanceof FlatScrollPaneBorder
+ ? Integer.toString( ((FlatScrollPaneBorder)border).getLeftRightPadding( allJScrollPanes[0] ) )
+ : "?" );
+ }
+
+ private void viewportBorderChanged() {
+ Border viewportBorder = viewportBorderCheckBox.isSelected()
+ ? new CompoundBorder(
+ new MatteBorder( 1, 1, 0, 0, Color.red ),
+ new MatteBorder( 0, 0, 1, 1, Color.blue ) )
+ : null;
+ for( JScrollPane scrollPane : allJScrollPanes ) {
+ scrollPane.setViewportBorder( viewportBorder );
+ scrollPane.revalidate();
+ scrollPane.repaint();
+ }
+ }
+
+ private void initComponents() {
+ // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
+ splitPane2 = new JSplitPane();
+ panel1 = new FlatTestPanel();
+ listLabel = new JLabel();
+ paddingLabel = new JLabel();
+ paddingField = new JLabel();
+ treeLabel = new JLabel();
+ tableLabel = new JLabel();
+ autoResizeModeCheckBox = new JCheckBox();
+ listScrollPane = new JScrollPane();
+ list = new JList<>();
+ treeScrollPane = new JScrollPane();
+ tree = new JTree();
+ tableScrollPane = new JScrollPane();
+ table = new JTable();
+ panel2 = new FlatTestPanel();
+ textAreaLabel = new JLabel();
+ textPaneLabel = new JLabel();
+ editorPaneLabel = new JLabel();
+ customLabel = new JLabel();
+ textAreaScrollPane = new JScrollPane();
+ textArea = new JTextArea();
+ textPaneScrollPane = new JScrollPane();
+ textPane = new JTextPane();
+ editorPaneScrollPane = new JScrollPane();
+ editorPane = new JEditorPane();
+ customScrollPane = new JScrollPane();
+ button1 = new JButton();
+ panel3 = new JPanel();
+ JLabel arcLabel = new JLabel();
+ arcSlider = new JSlider();
+ cornersCheckBox = new JCheckBox();
+ columnHeaderCheckBox = new JCheckBox();
+ horizontalScrollBarCheckBox = new JCheckBox();
+ viewportBorderCheckBox = new JCheckBox();
+ rowHeaderCheckBox = new JCheckBox();
+ verticalScrollBarCheckBox = new JCheckBox();
+
+ //======== this ========
+ setLayout(new MigLayout(
+ "ltr,insets dialog,hidemode 3",
+ // columns
+ "[200,grow,fill]",
+ // rows
+ "[grow,fill]" +
+ "[]"));
+
+ //======== splitPane2 ========
+ {
+ splitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
+ splitPane2.setResizeWeight(0.5);
+
+ //======== panel1 ========
+ {
+ panel1.setLayout(new MigLayout(
+ "ltr,insets 3,hidemode 3",
+ // columns
+ "[200,grow,fill]" +
+ "[200,grow,fill]" +
+ "[200,grow,fill]" +
+ "[200,grow,fill]",
+ // rows
+ "[]0" +
+ "[200,grow,fill]"));
+
+ //---- listLabel ----
+ listLabel.setText("JList:");
+ listLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel1.add(listLabel, "cell 0 0,aligny top,growy 0");
+
+ //---- paddingLabel ----
+ paddingLabel.setText("Padding:");
+ panel1.add(paddingLabel, "cell 0 0,alignx trailing,growx 0");
+
+ //---- paddingField ----
+ paddingField.setText("0");
+ panel1.add(paddingField, "cell 0 0,alignx trailing,growx 0");
+
+ //---- treeLabel ----
+ treeLabel.setText("JTree:");
+ treeLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel1.add(treeLabel, "cell 1 0");
+
+ //---- tableLabel ----
+ tableLabel.setText("JTable:");
+ tableLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel1.add(tableLabel, "cell 2 0 2 1");
+
+ //---- autoResizeModeCheckBox ----
+ autoResizeModeCheckBox.setText("Auto-resize mode");
+ autoResizeModeCheckBox.setSelected(true);
+ autoResizeModeCheckBox.addActionListener(e -> autoResizeModeChanged());
+ panel1.add(autoResizeModeCheckBox, "cell 2 0 2 1,alignx right,growx 0");
+
+ //======== listScrollPane ========
+ {
+ listScrollPane.setViewportView(list);
+ }
+ panel1.add(listScrollPane, "cell 0 1,growx");
+
+ //======== treeScrollPane ========
+ {
+ treeScrollPane.setViewportView(tree);
+ }
+ panel1.add(treeScrollPane, "cell 1 1");
+
+ //======== tableScrollPane ========
+ {
+ tableScrollPane.setViewportView(table);
+ }
+ panel1.add(tableScrollPane, "cell 2 1 2 1,width 100,height 100");
+ }
+ splitPane2.setTopComponent(panel1);
+
+ //======== panel2 ========
+ {
+ panel2.setLayout(new MigLayout(
+ "ltr,insets 3,hidemode 3",
+ // columns
+ "[200,grow,fill]" +
+ "[200,grow,fill]" +
+ "[200,grow,fill]" +
+ "[200,grow,fill]",
+ // rows
+ "[]0" +
+ "[200,grow,fill]"));
+
+ //---- textAreaLabel ----
+ textAreaLabel.setText("JTextArea:");
+ textAreaLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel2.add(textAreaLabel, "cell 0 0");
+
+ //---- textPaneLabel ----
+ textPaneLabel.setText("JTextPane:");
+ textPaneLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel2.add(textPaneLabel, "cell 1 0");
+
+ //---- editorPaneLabel ----
+ editorPaneLabel.setText("JEditorPane:");
+ editorPaneLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+ panel2.add(editorPaneLabel, "cell 2 0");
+
+ //---- customLabel ----
+ customLabel.setText("Custom:");
+ panel2.add(customLabel, "cell 3 0");
+
+ //======== textAreaScrollPane ========
+ {
+ textAreaScrollPane.setViewportView(textArea);
+ }
+ panel2.add(textAreaScrollPane, "cell 0 1");
+
+ //======== textPaneScrollPane ========
+ {
+ textPaneScrollPane.setViewportView(textPane);
+ }
+ panel2.add(textPaneScrollPane, "cell 1 1");
+
+ //======== editorPaneScrollPane ========
+ {
+ editorPaneScrollPane.setViewportView(editorPane);
+ }
+ panel2.add(editorPaneScrollPane, "cell 2 1");
+
+ //======== customScrollPane ========
+ {
+
+ //---- button1 ----
+ button1.setText("I'm a large button, but do not implement Scrollable interface");
+ button1.setPreferredSize(new Dimension(800, 800));
+ button1.setHorizontalAlignment(SwingConstants.LEADING);
+ button1.setVerticalAlignment(SwingConstants.TOP);
+ customScrollPane.setViewportView(button1);
+ }
+ panel2.add(customScrollPane, "cell 3 1");
+ }
+ splitPane2.setBottomComponent(panel2);
+ }
+ add(splitPane2, "cell 0 0");
+
+ //======== panel3 ========
+ {
+ panel3.setLayout(new MigLayout(
+ "hidemode 3",
+ // columns
+ "[fill]" +
+ "[grow,fill]para" +
+ "[]" +
+ "[]" +
+ "[]",
+ // rows
+ "[]" +
+ "[]"));
+
+ //---- arcLabel ----
+ arcLabel.setText("Arc:");
+ panel3.add(arcLabel, "cell 0 0");
+
+ //---- arcSlider ----
+ arcSlider.setMaximum(40);
+ arcSlider.setValue(20);
+ arcSlider.setSnapToTicks(true);
+ arcSlider.setMajorTickSpacing(10);
+ arcSlider.setMinorTickSpacing(1);
+ arcSlider.setPaintTicks(true);
+ arcSlider.setPaintLabels(true);
+ arcSlider.addChangeListener(e -> arcSliderChanged());
+ panel3.add(arcSlider, "cell 1 0 1 2");
+
+ //---- cornersCheckBox ----
+ cornersCheckBox.setText("Corners");
+ cornersCheckBox.addActionListener(e -> cornersChanged());
+ panel3.add(cornersCheckBox, "cell 2 0");
+
+ //---- columnHeaderCheckBox ----
+ columnHeaderCheckBox.setText("Column Header");
+ columnHeaderCheckBox.addActionListener(e -> columnHeaderChanged());
+ panel3.add(columnHeaderCheckBox, "cell 3 0");
+
+ //---- horizontalScrollBarCheckBox ----
+ horizontalScrollBarCheckBox.setText("Horizontal ScrollBar");
+ horizontalScrollBarCheckBox.setSelected(true);
+ horizontalScrollBarCheckBox.addActionListener(e -> horizontalScrollBarChanged());
+ panel3.add(horizontalScrollBarCheckBox, "cell 4 0");
+
+ //---- viewportBorderCheckBox ----
+ viewportBorderCheckBox.setText("Viewport border");
+ viewportBorderCheckBox.addActionListener(e -> viewportBorderChanged());
+ panel3.add(viewportBorderCheckBox, "cell 2 1");
+
+ //---- rowHeaderCheckBox ----
+ rowHeaderCheckBox.setText("Row Header");
+ rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
+ panel3.add(rowHeaderCheckBox, "cell 3 1");
+
+ //---- verticalScrollBarCheckBox ----
+ verticalScrollBarCheckBox.setText("Vertical ScrollBar");
+ verticalScrollBarCheckBox.setSelected(true);
+ verticalScrollBarCheckBox.addActionListener(e -> verticalScrollBarChanged());
+ panel3.add(verticalScrollBarCheckBox, "cell 4 1");
+ }
+ add(panel3, "cell 0 1");
+ // JFormDesigner - End of component initialization //GEN-END:initComponents
+ }
+
+ // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
+ private JSplitPane splitPane2;
+ private FlatTestPanel panel1;
+ private JLabel listLabel;
+ private JLabel paddingLabel;
+ private JLabel paddingField;
+ private JLabel treeLabel;
+ private JLabel tableLabel;
+ private JCheckBox autoResizeModeCheckBox;
+ private JScrollPane listScrollPane;
+ private JList list;
+ private JScrollPane treeScrollPane;
+ private JTree tree;
+ private JScrollPane tableScrollPane;
+ private JTable table;
+ private FlatTestPanel panel2;
+ private JLabel textAreaLabel;
+ private JLabel textPaneLabel;
+ private JLabel editorPaneLabel;
+ private JLabel customLabel;
+ private JScrollPane textAreaScrollPane;
+ private JTextArea textArea;
+ private JScrollPane textPaneScrollPane;
+ private JTextPane textPane;
+ private JScrollPane editorPaneScrollPane;
+ private JEditorPane editorPane;
+ private JScrollPane customScrollPane;
+ private JButton button1;
+ private JPanel panel3;
+ private JSlider arcSlider;
+ private JCheckBox cornersCheckBox;
+ private JCheckBox columnHeaderCheckBox;
+ private JCheckBox horizontalScrollBarCheckBox;
+ private JCheckBox viewportBorderCheckBox;
+ private JCheckBox rowHeaderCheckBox;
+ private JCheckBox verticalScrollBarCheckBox;
+ // JFormDesigner - End of variables declaration //GEN-END:variables
+
+ //---- class Corner -------------------------------------------------------
+
+ private static class Corner
+ extends JPanel
+ {
+ Corner( Color color ) {
+ super.setBackground( color );
+ }
+
+ @Override
+ public void setBackground( Color bg ) {
+ // do not change background when checkbox "explicit colors" is selected
+ }
+ }
+}
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.jfd
new file mode 100644
index 00000000..ffaf2a6a
--- /dev/null
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatRoundedScrollPaneTest.jfd
@@ -0,0 +1,249 @@
+JFDML JFormDesigner: "8.1.1.0.298" Java: "19.0.2" encoding: "UTF-8"
+
+new FormModel {
+ contentType: "form/swing"
+ root: new FormRoot {
+ add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
+ "$layoutConstraints": "ltr,insets dialog,hidemode 3"
+ "$columnConstraints": "[200,grow,fill]"
+ "$rowConstraints": "[grow,fill][]"
+ } ) {
+ name: "this"
+ add( new FormContainer( "javax.swing.JSplitPane", new FormLayoutManager( class javax.swing.JSplitPane ) ) {
+ name: "splitPane2"
+ "orientation": 0
+ "resizeWeight": 0.5
+ add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
+ "$columnConstraints": "[200,grow,fill][200,grow,fill][200,grow,fill][200,grow,fill]"
+ "$rowConstraints": "[]0[200,grow,fill]"
+ "$layoutConstraints": "ltr,insets 3,hidemode 3"
+ } ) {
+ name: "panel1"
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "listLabel"
+ "text": "JList:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0,aligny top,growy 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "paddingLabel"
+ "text": "Padding:"
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0,alignx trailing,growx 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "paddingField"
+ "text": "0"
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0,alignx trailing,growx 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "treeLabel"
+ "text": "JTree:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "tableLabel"
+ "text": "JTable:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 0 2 1"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "autoResizeModeCheckBox"
+ "text": "Auto-resize mode"
+ "selected": true
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "autoResizeModeChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 0 2 1,alignx right,growx 0"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "listScrollPane"
+ add( new FormComponent( "javax.swing.JList" ) {
+ name: "list"
+ auxiliary() {
+ "JavaCodeGenerator.typeParameters": "String"
+ "JavaCodeGenerator.variableLocal": false
+ }
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 1,growx"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "treeScrollPane"
+ add( new FormComponent( "javax.swing.JTree" ) {
+ name: "tree"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 1"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "tableScrollPane"
+ add( new FormComponent( "javax.swing.JTable" ) {
+ name: "table"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 1 2 1,width 100,height 100"
+ } )
+ }, new FormLayoutConstraints( class java.lang.String ) {
+ "value": "left"
+ } )
+ add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
+ "$columnConstraints": "[200,grow,fill][200,grow,fill][200,grow,fill][200,grow,fill]"
+ "$rowConstraints": "[]0[200,grow,fill]"
+ "$layoutConstraints": "ltr,insets 3,hidemode 3"
+ } ) {
+ name: "panel2"
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "textAreaLabel"
+ "text": "JTextArea:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "textPaneLabel"
+ "text": "JTextPane:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "editorPaneLabel"
+ "text": "JEditorPane:"
+ "horizontalTextPosition": 10
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 0"
+ } )
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "customLabel"
+ "text": "Custom:"
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 3 0"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "textAreaScrollPane"
+ add( new FormComponent( "javax.swing.JTextArea" ) {
+ name: "textArea"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 1"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "textPaneScrollPane"
+ add( new FormComponent( "javax.swing.JTextPane" ) {
+ name: "textPane"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 1"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "editorPaneScrollPane"
+ add( new FormComponent( "javax.swing.JEditorPane" ) {
+ name: "editorPane"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 1"
+ } )
+ add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
+ name: "customScrollPane"
+ add( new FormComponent( "javax.swing.JButton" ) {
+ name: "button1"
+ "text": "I'm a large button, but do not implement Scrollable interface"
+ "preferredSize": new java.awt.Dimension( 800, 800 )
+ "horizontalAlignment": 10
+ "verticalAlignment": 1
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 3 1"
+ } )
+ }, new FormLayoutConstraints( class java.lang.String ) {
+ "value": "right"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0"
+ } )
+ add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
+ "$layoutConstraints": "hidemode 3"
+ "$columnConstraints": "[fill][grow,fill]para[][][]"
+ "$rowConstraints": "[][]"
+ } ) {
+ name: "panel3"
+ add( new FormComponent( "javax.swing.JLabel" ) {
+ name: "arcLabel"
+ "text": "Arc:"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": true
+ }
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 0"
+ } )
+ add( new FormComponent( "javax.swing.JSlider" ) {
+ name: "arcSlider"
+ "maximum": 40
+ "value": 20
+ "snapToTicks": true
+ "majorTickSpacing": 10
+ "minorTickSpacing": 1
+ "paintTicks": true
+ "paintLabels": true
+ addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "arcSliderChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 0 1 2"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "cornersCheckBox"
+ "text": "Corners"
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "cornersChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "columnHeaderCheckBox"
+ "text": "Column Header"
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "columnHeaderChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 3 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "horizontalScrollBarCheckBox"
+ "text": "Horizontal ScrollBar"
+ "selected": true
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "horizontalScrollBarChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 4 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "viewportBorderCheckBox"
+ "text": "Viewport border"
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "viewportBorderChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 2 1"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "rowHeaderCheckBox"
+ "text": "Row Header"
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "rowHeaderChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 3 1"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "verticalScrollBarCheckBox"
+ "text": "Vertical ScrollBar"
+ "selected": true
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "verticalScrollBarChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 4 1"
+ } )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 1"
+ } )
+ }, new FormLayoutConstraints( null ) {
+ "location": new java.awt.Point( 0, 0 )
+ "size": new java.awt.Dimension( 875, 715 )
+ } )
+ }
+}
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java
index f61ea237..50676208 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java
@@ -657,6 +657,14 @@ public class FlatTestFrame
JViewport columnHeader = ((JScrollPane)c).getColumnHeader();
if( columnHeader != null )
action.accept( columnHeader.getView(), "columnHeader" );
+ } else if( c instanceof JSplitPane ) {
+ JSplitPane splitPane = (JSplitPane) c;
+ Component left = splitPane.getLeftComponent();
+ Component right = splitPane.getRightComponent();
+ if( left instanceof Container )
+ updateComponentsRecur( (Container) left, action );
+ if( right instanceof Container )
+ updateComponentsRecur( (Container) right, action );
} else if( c instanceof JTabbedPane ) {
JTabbedPane tabPane = (JTabbedPane)c;
int tabCount = tabPane.getTabCount();
diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties
index d8c6d942..6a60b729 100644
--- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties
+++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties
@@ -331,6 +331,11 @@ ScrollBar.hoverTrackColor = #0f0
ScrollBar.hoverThumbColor = #f00
+#---- ScrollPane ----
+
+ScrollPane.arc = 20
+
+
#---- Separator ----
Separator.foreground = #0b0
diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
index 9ada45ac..ab4fa76c 100644
--- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
+++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
@@ -720,8 +720,13 @@ ScrollBar.trackHighlight
ScrollBar.trackInsets
ScrollBar.width
ScrollBarUI
+ScrollPane.List.arc
+ScrollPane.Table.arc
+ScrollPane.TextComponent.arc
+ScrollPane.Tree.arc
ScrollPane.ancestorInputMap
ScrollPane.ancestorInputMap.RightToLeft
+ScrollPane.arc
ScrollPane.background
ScrollPane.border
ScrollPane.fillUpperCorner