SplitPane: added grip to divider (issue #179)

This commit is contained in:
Karl Tauber
2020-11-04 11:52:50 +01:00
parent a7e2a10403
commit 18d8c7d086
9 changed files with 118 additions and 29 deletions

View File

@@ -41,6 +41,8 @@ FlatLaf Change Log
constructors. (issue #196) constructors. (issue #196)
- SplitPane: Hide not applicable expand/collapse buttons. Added tooltips to - SplitPane: Hide not applicable expand/collapse buttons. Added tooltips to
expand/collapse buttons. (issue #198) expand/collapse buttons. (issue #198)
- SplitPane: Added grip to divider. Can be disabled with `UIManager.put(
"SplitPaneDivider.style", "plain" )`. (issue #179)
#### Fixed bugs #### Fixed bugs

View File

@@ -19,6 +19,8 @@ package com.formdev.flatlaf.ui;
import java.awt.Color; import java.awt.Color;
import java.awt.Container; import java.awt.Container;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
@@ -51,6 +53,11 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault SplitPane.continuousLayout boolean * @uiDefault SplitPane.continuousLayout boolean
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color * @uiDefault SplitPaneDivider.oneTouchArrowColor Color
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor 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 * @author Karl Tauber
*/ */
@@ -95,6 +102,12 @@ public class FlatSplitPaneUI
protected class FlatSplitPaneDivider protected class FlatSplitPaneDivider
extends BasicSplitPaneDivider 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 ) { protected FlatSplitPaneDivider( BasicSplitPaneUI ui ) {
super( 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() { protected boolean isLeftCollapsed() {
int location = splitPane.getDividerLocation(); int location = splitPane.getDividerLocation();
Insets insets = splitPane.getInsets(); Insets insets = splitPane.getInsets();

View File

@@ -16,15 +16,16 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JToolBar; import javax.swing.JToolBar;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.util.UIScale;
/** /**
* Border for {@link javax.swing.JToolBar}. * 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_COUNT = 4;
private static final int DOT_SIZE = 2; 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" ); 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 ) { protected void paintGrip( Component c, Graphics g, int x, int y, int width, int height ) {
int dotSize = scale( DOT_SIZE ); Rectangle r = calculateGripBounds( c, x, y, width, height );
int gapSize = dotSize; FlatUIUtils.paintGrip( g, r.x, r.y, r.width, r.height,
int gripSize = (dotSize * DOT_COUNT) + ((gapSize * (DOT_COUNT - 1))); ((JToolBar)c).getOrientation() == SwingConstants.VERTICAL,
DOT_COUNT, DOT_SIZE, DOT_SIZE, false );
}
// include toolbar margin in grip position calculation protected Rectangle calculateGripBounds( Component c, int x, int y, int width, int height ) {
Insets insets = getBorderInsets( c ); // 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 // calculate grip bounds
boolean horizontal = ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL; int gripSize = UIScale.scale( GRIP_SIZE );
if( horizontal ) { if( ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL ) {
if( c.getComponentOrientation().isLeftToRight() ) if( !c.getComponentOrientation().isLeftToRight() )
x += insets.left - (dotSize * 2); r.x = r.x + r.width - gripSize;
else r.width = gripSize;
x += width - insets.right + dotSize; } else
y += Math.round( (height - gripSize) / 2f ); r.height = gripSize;
} else {
// vertical
x += Math.round( (width - gripSize) / 2f );
y += insets.top - (dotSize * 2);
}
// paint dots return r;
for( int i = 0; i < DOT_COUNT; i++ ) {
g.fillOval( x, y, dotSize, dotSize );
if( horizontal )
y += dotSize + gapSize;
else
x += dotSize + gapSize;
}
} }
@Override @Override
@@ -101,7 +94,7 @@ public class FlatToolBarBorder
// add grip inset if floatable // add grip inset if floatable
if( c instanceof JToolBar && ((JToolBar)c).isFloatable() ) { 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( ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL ) {
if( c.getComponentOrientation().isLeftToRight() ) if( c.getComponentOrientation().isLeftToRight() )
insets.left += gripInset; insets.left += gripInset;

View File

@@ -32,6 +32,7 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D; 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 * Fill background with parent's background color because the visible component
* is smaller than its bounds (for the focus decoration). * is smaller than its bounds (for the focus decoration).

View File

@@ -532,6 +532,12 @@ SplitPane.oneTouchButtonOffset={scaledInteger}2
SplitPaneDivider.border=null SplitPaneDivider.border=null
SplitPaneDivider.oneTouchArrowColor=$ComboBox.buttonArrowColor 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 ---- #---- TabbedPane ----

View File

@@ -893,8 +893,13 @@ SplitPane.shadow #646464 javax.swing.plaf.ColorUIResource [UI]
#---- SplitPaneDivider ---- #---- SplitPaneDivider ----
SplitPaneDivider.draggingColor #646464 javax.swing.plaf.ColorUIResource [UI] 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.oneTouchArrowColor #9a9da1 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.oneTouchHoverArrowColor #7a7d81 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #7a7d81 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.style grip
#---- SplitPane ---- #---- SplitPane ----

View File

@@ -898,8 +898,13 @@ SplitPane.shadow #c4c4c4 javax.swing.plaf.ColorUIResource [UI]
#---- SplitPaneDivider ---- #---- SplitPaneDivider ----
SplitPaneDivider.draggingColor #c4c4c4 javax.swing.plaf.ColorUIResource [UI] 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.oneTouchArrowColor #666666 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.oneTouchHoverArrowColor #333333 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #333333 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.style grip
#---- SplitPane ---- #---- SplitPane ----

View File

@@ -886,8 +886,13 @@ SplitPane.shadow #a0a0a0 javax.swing.plaf.ColorUIResource [UI]
#---- SplitPaneDivider ---- #---- SplitPaneDivider ----
SplitPaneDivider.draggingColor #880000 javax.swing.plaf.ColorUIResource [UI] 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.oneTouchArrowColor #00ff00 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.oneTouchHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI] SplitPaneDivider.oneTouchHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI]
SplitPaneDivider.style grip
#---- SplitPane ---- #---- SplitPane ----

View File

@@ -629,8 +629,13 @@ SplitPane.oneTouchButtonOffset
SplitPane.oneTouchButtonSize SplitPane.oneTouchButtonSize
SplitPane.shadow SplitPane.shadow
SplitPaneDivider.draggingColor SplitPaneDivider.draggingColor
SplitPaneDivider.gripColor
SplitPaneDivider.gripDotCount
SplitPaneDivider.gripDotSize
SplitPaneDivider.gripGap
SplitPaneDivider.oneTouchArrowColor SplitPaneDivider.oneTouchArrowColor
SplitPaneDivider.oneTouchHoverArrowColor SplitPaneDivider.oneTouchHoverArrowColor
SplitPaneDivider.style
SplitPaneUI SplitPaneUI
TabbedPane.ancestorInputMap TabbedPane.ancestorInputMap
TabbedPane.background TabbedPane.background