mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
Merge PR #534: ToolBar: hover effect for button groups
This commit is contained in:
@@ -20,6 +20,7 @@ import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
@@ -45,8 +46,10 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.plaf.ButtonUI;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.ToolBarUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonListener;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
@@ -797,5 +800,20 @@ public class FlatButtonUI
|
||||
super.propertyChange( e );
|
||||
FlatButtonUI.this.propertyChange( b, e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e ) {
|
||||
super.stateChanged( e );
|
||||
|
||||
// if button is in toolbar, repaint button groups
|
||||
AbstractButton b = (AbstractButton) e.getSource();
|
||||
Container parent = b.getParent();
|
||||
if( parent instanceof JToolBar ) {
|
||||
JToolBar toolBar = (JToolBar) parent;
|
||||
ToolBarUI ui = toolBar.getUI();
|
||||
if( ui instanceof FlatToolBarUI )
|
||||
((FlatToolBarUI)ui).repaintButtonGroup( b );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,24 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.ContainerListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.DefaultButtonModel;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.LayoutFocusTraversalPolicy;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
@@ -37,6 +46,7 @@ import javax.swing.plaf.basic.BasicToolBarUI;
|
||||
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.JToolBar}.
|
||||
@@ -58,6 +68,8 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
* @uiDefault ToolBar.focusableButtons boolean
|
||||
* @uiDefault ToolBar.arrowKeysOnlyNavigation boolean
|
||||
* @uiDefault ToolBar.floatable boolean
|
||||
* @uiDefault ToolBar.hoverButtonGroupArc int
|
||||
* @uiDefault ToolBar.hoverButtonGroupBackground Color
|
||||
*
|
||||
* <!-- FlatToolBarBorder -->
|
||||
*
|
||||
@@ -72,6 +84,8 @@ public class FlatToolBarUI
|
||||
{
|
||||
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
||||
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
||||
/** @since 3 */ @Styleable protected int hoverButtonGroupArc;
|
||||
/** @since 3 */ @Styleable protected Color hoverButtonGroupBackground;
|
||||
|
||||
// for FlatToolBarBorder
|
||||
@Styleable protected Insets borderMargins;
|
||||
@@ -119,6 +133,8 @@ public class FlatToolBarUI
|
||||
|
||||
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
|
||||
arrowKeysOnlyNavigation = UIManager.getBoolean( "ToolBar.arrowKeysOnlyNavigation" );
|
||||
hoverButtonGroupArc = UIManager.getInt( "ToolBar.hoverButtonGroupArc" );
|
||||
hoverButtonGroupBackground = UIManager.getColor( "ToolBar.hoverButtonGroupBackground" );
|
||||
|
||||
// floatable
|
||||
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
||||
@@ -132,6 +148,8 @@ public class FlatToolBarUI
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
hoverButtonGroupBackground = null;
|
||||
|
||||
if( oldFloatable != null ) {
|
||||
toolBar.setFloatable( oldFloatable );
|
||||
oldFloatable = null;
|
||||
@@ -329,6 +347,99 @@ public class FlatToolBarUI
|
||||
super.setOrientation( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
super.paint( g, c );
|
||||
|
||||
paintButtonGroup( g );
|
||||
}
|
||||
|
||||
/**@since 3 */
|
||||
protected void paintButtonGroup( Graphics g ) {
|
||||
if( hoverButtonGroupBackground == null )
|
||||
return;
|
||||
|
||||
// find hovered button that is part of a button group
|
||||
ButtonGroup group = null;
|
||||
for( Component b : toolBar.getComponents() ) {
|
||||
if( b instanceof AbstractButton && ((AbstractButton)b).getModel().isRollover() ) {
|
||||
group = getButtonGroup( (AbstractButton) b );
|
||||
if( group != null )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( group == null )
|
||||
return;
|
||||
|
||||
// get bounds of buttons in group
|
||||
ArrayList<Rectangle> rects = new ArrayList<>();
|
||||
Enumeration<AbstractButton> e = group.getElements();
|
||||
while( e.hasMoreElements() ) {
|
||||
AbstractButton gb = e.nextElement();
|
||||
if( gb.getParent() == toolBar )
|
||||
rects.add( gb.getBounds() );
|
||||
}
|
||||
|
||||
// sort button bounds
|
||||
boolean horizontal = (toolBar.getOrientation() == JToolBar.HORIZONTAL);
|
||||
rects.sort( (r1, r2) -> horizontal ? r1.x - r2.x : r1.y - r2.y );
|
||||
|
||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||
g.setColor( FlatUIUtils.deriveColor( hoverButtonGroupBackground, toolBar.getBackground() ) );
|
||||
|
||||
// paint button group hover background
|
||||
int maxSepWidth = UIScale.scale( 10 );
|
||||
Rectangle gr = null;
|
||||
for( Rectangle r : rects ) {
|
||||
if( gr == null ) {
|
||||
// first button
|
||||
gr = r;
|
||||
} else if( horizontal ? (gr.x + gr.width + maxSepWidth >= r.x) : (gr.y + gr.height + maxSepWidth >= r.y) ) {
|
||||
// button joins previous button
|
||||
gr = gr.union( r );
|
||||
} else {
|
||||
// paint group
|
||||
FlatUIUtils.paintComponentBackground( (Graphics2D) g, gr.x, gr.y, gr.width, gr.height, 0, UIScale.scale( hoverButtonGroupArc ) );
|
||||
gr = r;
|
||||
}
|
||||
}
|
||||
if( gr != null )
|
||||
FlatUIUtils.paintComponentBackground( (Graphics2D) g, gr.x, gr.y, gr.width, gr.height, 0, UIScale.scale( hoverButtonGroupArc ) );
|
||||
|
||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||
}
|
||||
|
||||
/**@since 3 */
|
||||
protected void repaintButtonGroup( AbstractButton b ) {
|
||||
if( hoverButtonGroupBackground == null )
|
||||
return;
|
||||
|
||||
ButtonGroup group = getButtonGroup( b );
|
||||
if( group == null )
|
||||
return;
|
||||
|
||||
// compute union bounds of all buttons in group (including separators)
|
||||
Rectangle gr = null;
|
||||
Enumeration<AbstractButton> e = group.getElements();
|
||||
while( e.hasMoreElements() ) {
|
||||
AbstractButton gb = e.nextElement();
|
||||
Container parent = gb.getParent();
|
||||
if( parent == toolBar )
|
||||
gr = (gr != null) ? gr.union( gb.getBounds() ) : gb.getBounds();
|
||||
}
|
||||
|
||||
// repaint button group
|
||||
if( gr != null )
|
||||
toolBar.repaint( gr );
|
||||
}
|
||||
|
||||
private ButtonGroup getButtonGroup( AbstractButton b ) {
|
||||
ButtonModel model = b.getModel();
|
||||
return (model instanceof DefaultButtonModel)
|
||||
? ((DefaultButtonModel)model).getGroup()
|
||||
: null;
|
||||
}
|
||||
|
||||
//---- class FlatToolBarFocusTraversalPolicy ------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -349,6 +349,11 @@ ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,3%,de
|
||||
ToggleButton.toolbar.selectedBackground = lighten($ToggleButton.background,7%,derived)
|
||||
|
||||
|
||||
#---- ToolBar ----
|
||||
|
||||
ToolBar.hoverButtonGroupBackground = lighten($ToolBar.background,3%,derived)
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.border = 4,6,4,6
|
||||
|
||||
@@ -847,6 +847,7 @@ ToolBar.borderMargins = 2,2,2,2
|
||||
ToolBar.isRollover = true
|
||||
ToolBar.focusableButtons = false
|
||||
ToolBar.arrowKeysOnlyNavigation = true
|
||||
ToolBar.hoverButtonGroupArc = 8
|
||||
ToolBar.floatable = false
|
||||
ToolBar.gripColor = @icon
|
||||
ToolBar.dockingBackground = darken($ToolBar.background,5%)
|
||||
|
||||
@@ -356,6 +356,11 @@ ToggleButton.disabledSelectedBackground = darken($ToggleButton.background,13%,de
|
||||
ToggleButton.toolbar.selectedBackground = $ToggleButton.selectedBackground
|
||||
|
||||
|
||||
#---- ToolBar ----
|
||||
|
||||
ToolBar.hoverButtonGroupBackground = darken($ToolBar.background,3%,derived)
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.border = 4,6,4,6,shade(@background,40%)
|
||||
|
||||
@@ -899,6 +899,8 @@ public class TestFlatStyleableInfo
|
||||
Map<String, Class<?>> expected = expectedMap(
|
||||
"focusableButtons", boolean.class,
|
||||
"arrowKeysOnlyNavigation", boolean.class,
|
||||
"hoverButtonGroupArc", int.class,
|
||||
"hoverButtonGroupBackground", Color.class,
|
||||
|
||||
"borderMargins", Insets.class,
|
||||
"gripColor", Color.class
|
||||
|
||||
@@ -1102,6 +1102,8 @@ public class TestFlatStyling
|
||||
|
||||
ui.applyStyle( "focusableButtons: true" );
|
||||
ui.applyStyle( "arrowKeysOnlyNavigation: true" );
|
||||
ui.applyStyle( "hoverButtonGroupArc: 12" );
|
||||
ui.applyStyle( "hoverButtonGroupBackground: #fff" );
|
||||
|
||||
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
||||
ui.applyStyle( "gripColor: #fff" );
|
||||
|
||||
Reference in New Issue
Block a user