diff --git a/CHANGELOG.md b/CHANGELOG.md index 386d74fa..022d0006 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ FlatLaf Change Log constructors. (issue #196) - SplitPane: Hide not applicable expand/collapse buttons. Added tooltips to expand/collapse buttons. (issue #198) +- SplitPane: Added grip to divider. Can be disabled with `UIManager.put( + "SplitPaneDivider.style", "plain" )`. (issue #179) #### Fixed bugs diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java index e8dbd7f9..c5cd21fd 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSplitPaneUI.java @@ -19,6 +19,8 @@ package com.formdev.flatlaf.ui; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; @@ -51,6 +53,11 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault SplitPane.continuousLayout boolean * @uiDefault SplitPaneDivider.oneTouchArrowColor Color * @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color + * @uiDefault SplitPaneDivider.style String grip (default) or plain + * @uiDefault SplitPaneDivider.gripColor Color + * @uiDefault SplitPaneDivider.gripDotCount int + * @uiDefault SplitPaneDivider.gripDotSize int + * @uiDefault SplitPaneDivider.gripGap int * * @author Karl Tauber */ @@ -95,6 +102,12 @@ public class FlatSplitPaneUI protected class FlatSplitPaneDivider extends BasicSplitPaneDivider { + protected final String style = UIManager.getString( "SplitPaneDivider.style" ); + protected final Color gripColor = UIManager.getColor( "SplitPaneDivider.gripColor" ); + protected final int gripDotCount = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotCount", 3 ); + protected final int gripDotSize = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotSize", 3 ); + protected final int gripGap = FlatUIUtils.getUIInt( "SplitPaneDivider.gripGap", 2 ); + protected FlatSplitPaneDivider( BasicSplitPaneUI ui ) { super( ui ); @@ -128,6 +141,25 @@ public class FlatSplitPaneUI } } + @Override + public void paint( Graphics g ) { + super.paint( g ); + + if( "plain".equals( style ) ) + return; + + FlatUIUtils.setRenderingHints( (Graphics2D) g ); + + g.setColor( gripColor ); + paintGrip( g, 0, 0, getWidth(), getHeight() ); + } + + protected void paintGrip( Graphics g, int x, int y, int width, int height ) { + FlatUIUtils.paintGrip( g, x, y, width, height, + splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT, + gripDotCount, gripDotSize, gripGap, true ); + } + protected boolean isLeftCollapsed() { int location = splitPane.getDividerLocation(); Insets insets = splitPane.getInsets(); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarBorder.java index dce83f7a..5f7ffa57 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarBorder.java @@ -16,15 +16,16 @@ package com.formdev.flatlaf.ui; -import static com.formdev.flatlaf.util.UIScale.*; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; +import java.awt.Rectangle; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.UIManager; +import com.formdev.flatlaf.util.UIScale; /** * Border for {@link javax.swing.JToolBar}. @@ -39,7 +40,7 @@ public class FlatToolBarBorder { private static final int DOT_COUNT = 4; private static final int DOT_SIZE = 2; - private static final int GRIP_WIDTH = DOT_SIZE * 3; + private static final int GRIP_SIZE = DOT_SIZE * 3; protected final Color gripColor = UIManager.getColor( "ToolBar.gripColor" ); @@ -64,35 +65,27 @@ public class FlatToolBarBorder } protected void paintGrip( Component c, Graphics g, int x, int y, int width, int height ) { - int dotSize = scale( DOT_SIZE ); - int gapSize = dotSize; - int gripSize = (dotSize * DOT_COUNT) + ((gapSize * (DOT_COUNT - 1))); + Rectangle r = calculateGripBounds( c, x, y, width, height ); + FlatUIUtils.paintGrip( g, r.x, r.y, r.width, r.height, + ((JToolBar)c).getOrientation() == SwingConstants.VERTICAL, + DOT_COUNT, DOT_SIZE, DOT_SIZE, false ); + } - // include toolbar margin in grip position calculation - Insets insets = getBorderInsets( c ); + protected Rectangle calculateGripBounds( Component c, int x, int y, int width, int height ) { + // include toolbar margin in grip bounds calculation + Insets insets = super.getBorderInsets( c, new Insets( 0, 0, 0, 0 ) ); + Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( x, y, width, height ), insets ); - // calculate grip position - boolean horizontal = ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL; - if( horizontal ) { - if( c.getComponentOrientation().isLeftToRight() ) - x += insets.left - (dotSize * 2); - else - x += width - insets.right + dotSize; - y += Math.round( (height - gripSize) / 2f ); - } else { - // vertical - x += Math.round( (width - gripSize) / 2f ); - y += insets.top - (dotSize * 2); - } + // calculate grip bounds + int gripSize = UIScale.scale( GRIP_SIZE ); + if( ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL ) { + if( !c.getComponentOrientation().isLeftToRight() ) + r.x = r.x + r.width - gripSize; + r.width = gripSize; + } else + r.height = gripSize; - // paint dots - for( int i = 0; i < DOT_COUNT; i++ ) { - g.fillOval( x, y, dotSize, dotSize ); - if( horizontal ) - y += dotSize + gapSize; - else - x += dotSize + gapSize; - } + return r; } @Override @@ -101,7 +94,7 @@ public class FlatToolBarBorder // add grip inset if floatable if( c instanceof JToolBar && ((JToolBar)c).isFloatable() ) { - int gripInset = scale( GRIP_WIDTH ); + int gripInset = UIScale.scale( GRIP_SIZE ); if( ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL ) { if( c.getComponentOrientation().isLeftToRight() ) insets.left += gripInset; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index b48e153b..183175b0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -32,6 +32,7 @@ import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.geom.Ellipse2D; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; @@ -390,6 +391,41 @@ public class FlatUIUtils } } + public static void paintGrip( Graphics g, int x, int y, int width, int height, + boolean horizontal, int dotCount, int dotSize, int gap, boolean centerPrecise ) + { + dotSize = UIScale.scale( dotSize ); + gap = UIScale.scale( gap ); + int gripSize = (dotSize * dotCount) + ((gap * (dotCount - 1))); + + // calculate grip position + float gx; + float gy; + if( horizontal ) { + gx = x + Math.round( (width - gripSize) / 2f ); + gy = y + ((height - dotSize) / 2f); + + if( !centerPrecise ) + gy = Math.round( gy ); + } else { + // vertical + gx = x + ((width - dotSize) / 2f); + gy = y + Math.round( (height - gripSize) / 2f ); + + if( !centerPrecise ) + gx = Math.round( gx ); + } + + // paint dots + for( int i = 0; i < dotCount; i++ ) { + ((Graphics2D)g).fill( new Ellipse2D.Float( gx, gy, dotSize, dotSize ) ); + if( horizontal ) + gx += dotSize + gap; + else + gy += dotSize + gap; + } + } + /** * Fill background with parent's background color because the visible component * is smaller than its bounds (for the focus decoration). 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 8399a523..06eb3482 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -532,6 +532,12 @@ SplitPane.oneTouchButtonOffset={scaledInteger}2 SplitPaneDivider.border=null SplitPaneDivider.oneTouchArrowColor=$ComboBox.buttonArrowColor +# allowed values: "grip" (default) or "plain" +SplitPaneDivider.style=grip +SplitPaneDivider.gripColor=@icon +SplitPaneDivider.gripDotCount=3 +SplitPaneDivider.gripDotSize={integer}3 +SplitPaneDivider.gripGap=2 #---- TabbedPane ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt index b0f78b4b..bdea0273 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt @@ -893,8 +893,13 @@ SplitPane.shadow #646464 javax.swing.plaf.ColorUIResource [UI] #---- SplitPaneDivider ---- SplitPaneDivider.draggingColor #646464 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripColor #adadad javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripDotCount 3 +SplitPaneDivider.gripDotSize 3 +SplitPaneDivider.gripGap 2 SplitPaneDivider.oneTouchArrowColor #9a9da1 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #7a7d81 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.style grip #---- SplitPane ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt index 29154cb4..7d648f8d 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt @@ -898,8 +898,13 @@ SplitPane.shadow #c4c4c4 javax.swing.plaf.ColorUIResource [UI] #---- SplitPaneDivider ---- SplitPaneDivider.draggingColor #c4c4c4 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripDotCount 3 +SplitPaneDivider.gripDotSize 3 +SplitPaneDivider.gripGap 2 SplitPaneDivider.oneTouchArrowColor #666666 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #333333 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.style grip #---- SplitPane ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt index c95430f0..7062c92c 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt @@ -886,8 +886,13 @@ SplitPane.shadow #a0a0a0 javax.swing.plaf.ColorUIResource [UI] #---- SplitPaneDivider ---- SplitPaneDivider.draggingColor #880000 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.gripDotCount 3 +SplitPaneDivider.gripDotSize 3 +SplitPaneDivider.gripGap 2 SplitPaneDivider.oneTouchArrowColor #00ff00 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI] +SplitPaneDivider.style grip #---- SplitPane ---- 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 1e5d9edb..22edefc5 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 @@ -629,8 +629,13 @@ SplitPane.oneTouchButtonOffset SplitPane.oneTouchButtonSize SplitPane.shadow SplitPaneDivider.draggingColor +SplitPaneDivider.gripColor +SplitPaneDivider.gripDotCount +SplitPaneDivider.gripDotSize +SplitPaneDivider.gripGap SplitPaneDivider.oneTouchArrowColor SplitPaneDivider.oneTouchHoverArrowColor +SplitPaneDivider.style SplitPaneUI TabbedPane.ancestorInputMap TabbedPane.background