ToolBar and ToolBarSeparator implementation

This commit is contained in:
Karl Tauber
2019-09-04 19:10:48 +02:00
parent a15e21b6c1
commit 6512ede8b1
9 changed files with 546 additions and 16 deletions

View File

@@ -39,7 +39,6 @@ import javax.swing.ListCellRenderer;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
@@ -203,16 +202,12 @@ public class FlatComboBoxUI
// is used, then the editor is updated after the combobox and the
// colors are again replaced with default colors
boolean enabled = editor.isEnabled();
editor.setBackground( nonUIResource( enabled ? comboBox.getBackground() : disabledBackground ) );
editor.setForeground( nonUIResource( (enabled || editor instanceof JTextComponent)
editor.setBackground( FlatUIUtils.nonUIResource( enabled ? comboBox.getBackground() : disabledBackground ) );
editor.setForeground( FlatUIUtils.nonUIResource( (enabled || editor instanceof JTextComponent)
? comboBox.getForeground()
: disabledForeground ) );
if( editor instanceof JTextComponent )
((JTextComponent)editor).setDisabledTextColor( nonUIResource( disabledForeground ) );
}
private Color nonUIResource( Color c ) {
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
((JTextComponent)editor).setDisabledTextColor( FlatUIUtils.nonUIResource( disabledForeground ) );
}
@Override

View File

@@ -170,17 +170,13 @@ public class FlatSpinnerUI
// use non-UIResource colors because when SwingUtilities.updateComponentTreeUI()
// is used, then the text field is updated after the spinner and the
// colors are again replaced with default colors
textField.setBackground( nonUIResource( spinner.isEnabled()
textField.setBackground( FlatUIUtils.nonUIResource( spinner.isEnabled()
? spinner.getBackground() : disabledBackground ) );
textField.setForeground( nonUIResource( spinner.getForeground() ) );
textField.setDisabledTextColor( nonUIResource( disabledForeground ) );
textField.setForeground( FlatUIUtils.nonUIResource( spinner.getForeground() ) );
textField.setDisabledTextColor( FlatUIUtils.nonUIResource( disabledForeground ) );
}
}
private Color nonUIResource( Color c ) {
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
}
private JTextField getEditorTextField( JComponent editor ) {
return editor instanceof JSpinner.DefaultEditor
? ((JSpinner.DefaultEditor)editor).getTextField()

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2019 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 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 javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
/**
* Border for {@link javax.swing.JToolBar}.
*
* @uiDefault ToolBar.gripColor Color
*
* @author Karl Tauber
*/
public class FlatToolBarBorder
extends FlatMarginBorder
{
private static final int DOT_COUNT = 4;
private static final int DOT_SIZE = 2;
private static final int GRIP_WIDTH = DOT_SIZE * 3;
protected final Color gripColor = UIManager.getColor( "ToolBar.gripColor" );
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
// paint grip
if( c instanceof JToolBar && ((JToolBar)c).isFloatable() ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
g2.setColor( gripColor );
paintGrip( c, g2, x, y, width, height );
} finally {
g2.dispose();
}
}
}
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)));
boolean horizontal = ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL;
if( horizontal && !c.getComponentOrientation().isLeftToRight() )
x += width - scale( GRIP_WIDTH );
x += horizontal ? dotSize : Math.round( (width - gripSize) / 2f );
y += horizontal ? Math.round( (height - gripSize) / 2f ) : dotSize;
for( int i = 0; i < DOT_COUNT; i++ ) {
g.fillOval( x, y, dotSize, dotSize );
if( horizontal )
y += dotSize + gapSize;
else
x += dotSize + gapSize;
}
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
insets = super.getBorderInsets( c, insets );
// add grip inset if floatable
if( c instanceof JToolBar && ((JToolBar)c).isFloatable() ) {
int gripInset = scale( GRIP_WIDTH );
if( ((JToolBar)c).getOrientation() == SwingConstants.HORIZONTAL ) {
if( c.getComponentOrientation().isLeftToRight() )
insets.left += gripInset;
else
insets.right += gripInset;
} else
insets.top += gripInset;
}
return insets;
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2019 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 static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar.Separator}.
*
* @uiDefault ToolBar.separatorWidth int
* @uiDefault ToolBar.separatorColor Color
*
* @author Karl Tauber
*/
public class FlatToolBarSeparatorUI
extends BasicToolBarSeparatorUI
{
private static final int LINE_WIDTH = 1;
protected int separatorWidth;
protected Color separatorColor;
private static ComponentUI instance;
public static ComponentUI createUI( JComponent c ) {
if( instance == null )
instance = new FlatToolBarSeparatorUI();
return instance;
}
@Override
protected void installDefaults( JSeparator c ) {
super.installDefaults( c );
separatorWidth = UIManager.getInt( "ToolBar.separatorWidth" );
separatorColor = UIManager.getColor( "ToolBar.separatorColor" );
// necessary for vertical toolbars if separator size was set using setSeparatorSize()
// (otherwise there will be a gap on the left side of the vertical toolbar)
c.setAlignmentX( 0 );
}
@Override
public Dimension getPreferredSize( JComponent c ) {
Dimension size = ((JToolBar.Separator)c).getSeparatorSize();
if( size != null )
return scale( size );
// make sure that gap on left and right side of line have same size
int sepWidth = (scale( (separatorWidth - LINE_WIDTH) / 2 ) * 2) + scale( LINE_WIDTH );
boolean vertical = isVertical( c );
return new Dimension( vertical ? sepWidth : 0, vertical ? 0 : sepWidth );
}
@Override
public Dimension getMaximumSize( JComponent c ) {
Dimension size = getPreferredSize( c );
if( isVertical( c ) )
return new Dimension( size.width, Short.MAX_VALUE );
else
return new Dimension( Short.MAX_VALUE, size.height );
}
@Override
public void paint( Graphics g, JComponent c ) {
int width = c.getWidth();
int height = c.getHeight();
float lineWidth = scale( 1f );
float offset = scale( 2f );
FlatUIUtils.setRenderingHints( (Graphics2D) g );
g.setColor( separatorColor );
if( isVertical( c ) )
((Graphics2D)g).fill( new Rectangle2D.Float( Math.round( (width - lineWidth) / 2f ), offset, lineWidth, height - (offset * 2) ) );
else
((Graphics2D)g).fill( new Rectangle2D.Float( offset, Math.round( (height - lineWidth) / 2f ), width - (offset * 2), lineWidth ) );
}
private boolean isVertical( JComponent c ) {
return ((JToolBar.Separator)c).getOrientation() == SwingConstants.VERTICAL;
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright 2019 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 static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
import java.awt.Component;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Objects;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicToolBarUI;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
*
* TODO document used UI defaults of superclass
*
* @uiDefault ToolBar.buttonMargins Insets
*
* @author Karl Tauber
*/
public class FlatToolBarUI
extends BasicToolBarUI
{
private Border rolloverBorder;
private final HashMap<AbstractButton, Color> backgroundTable = new HashMap<>();
/** Cache non-UIResource button color. */
private Color buttonBackground;
public static ComponentUI createUI( JComponent c ) {
return new FlatToolBarUI();
}
@Override
public void uninstallUI( JComponent c ) {
super.uninstallUI( c );
rolloverBorder = null;
buttonBackground = null;
}
@Override
protected Border createRolloverBorder() {
return getRolloverBorder();
}
@Override
protected Border createNonRolloverBorder() {
return getRolloverBorder();
}
@Override
protected Border getNonRolloverBorder( AbstractButton b ) {
return getRolloverBorder();
}
private Border getRolloverBorder() {
if( rolloverBorder == null )
rolloverBorder = new FlatRolloverMarginBorder();
return rolloverBorder;
}
@Override
protected void setBorderToRollover( Component c ) {
super.setBorderToRollover( c );
setToRollover( c );
}
@Override
protected void setBorderToNonRollover( Component c ) {
super.setBorderToNonRollover( c );
setToRollover( c );
}
@Override
protected void setBorderToNormal( Component c ) {
super.setBorderToNormal( c );
setToNormal( c );
}
private void setToRollover( Component c ) {
if( c instanceof AbstractButton ) {
AbstractButton b = (AbstractButton) c;
Color background = backgroundTable.get( b );
if( background == null || background instanceof UIResource )
backgroundTable.put( b, b.getBackground() );
if( b.getBackground() instanceof UIResource )
b.setBackground( getButtonBackground() );
}
}
private void setToNormal( Component c ) {
if( c instanceof AbstractButton ) {
AbstractButton b = (AbstractButton) c;
Color background = backgroundTable.remove( b );
b.setBackground( background );
}
}
private Color getButtonBackground() {
// use toolbar background as button background
// must be not an instance of UIResource
Color toolBarBackground = toolBar.getBackground();
if( !Objects.equals( buttonBackground, toolBarBackground ) )
buttonBackground = FlatUIUtils.nonUIResource( toolBarBackground );
return buttonBackground;
}
//---- class FlatRolloverMarginBorder -------------------------------------
/**
* Uses button margin only if explicitly set.
* Otherwise uses insets specified in constructor.
*/
private static class FlatRolloverMarginBorder
extends EmptyBorder
{
public FlatRolloverMarginBorder() {
super( UIManager.getInsets( "ToolBar.buttonMargins" ) );
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
Insets margin = (c instanceof AbstractButton)
? ((AbstractButton) c).getMargin()
: null;
if( margin == null || margin instanceof UIResource ) {
insets.top = top;
insets.left = left;
insets.bottom = bottom;
insets.right = right;
} else {
// margin explicitly set
insets.top = margin.top;
insets.left = margin.left;
insets.bottom = margin.bottom;
insets.right = margin.right;
}
// scale
insets.top = scale( insets.top );
insets.left = scale( insets.left );
insets.bottom = scale( insets.bottom );
insets.right = scale( insets.right );
return insets;
}
}
}

View File

@@ -27,6 +27,7 @@ import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import com.formdev.flatlaf.util.JavaCompatibility;
import com.formdev.flatlaf.util.UIScale;
@@ -57,6 +58,10 @@ public class FlatUIUtils
return (value instanceof Integer) ? (Integer) value : defaultValue;
}
public static Color nonUIResource( Color c ) {
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
}
/**
* Sets rendering hints used for painting.
*/

View File

@@ -45,6 +45,8 @@ TableHeaderUI=com.formdev.flatlaf.ui.FlatTableHeaderUI
TextAreaUI=com.formdev.flatlaf.ui.FlatTextAreaUI
TextFieldUI=com.formdev.flatlaf.ui.FlatTextFieldUI
TextPaneUI=com.formdev.flatlaf.ui.FlatTextPaneUI
ToolBarUI=com.formdev.flatlaf.ui.FlatToolBarUI
ToolBarSeparatorUI=com.formdev.flatlaf.ui.FlatToolBarSeparatorUI
ToolTipUI=javax.swing.plaf.basic.BasicToolTipUI
TreeUI=com.formdev.flatlaf.ui.FlatTreeUI
ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
@@ -259,6 +261,20 @@ TextPane.background=@textComponentBackground
TextPane.margin=@textComponentMargin
#---- ToolBar ----
ToolBar.border=com.formdev.flatlaf.ui.FlatToolBarBorder
ToolBar.isRollover=true
ToolBar.buttonMargins=3,3,3,3
ToolBar.gripColor=@icon
ToolBar.dockingBackground=@background
ToolBar.floatingBackground=@background
ToolBar.separatorSize=null
ToolBar.separatorWidth=7
ToolBar.separatorColor=@@Separator.foreground
#---- ToolTip ----
ToolTip.border=2,6,2,6,@@Component.borderColor

View File

@@ -126,6 +126,11 @@ public class FlatComponentsTest
JScrollPane scrollPane14 = new JScrollPane();
progressBar3 = new JProgressBar();
progressBar4 = new JProgressBar();
JToolBar toolBar2 = new JToolBar();
JButton button9 = new JButton();
JButton button10 = new JButton();
JButton button11 = new JButton();
JToggleButton toggleButton7 = new JToggleButton();
JLabel scrollBarLabel = new JLabel();
JScrollBar scrollBar1 = new JScrollBar();
JScrollBar scrollBar4 = new JScrollBar();
@@ -142,6 +147,13 @@ public class FlatComponentsTest
indeterminateCheckBox = new JCheckBox();
JLabel toolTipLabel = new JLabel();
JToolTip toolTip1 = new JToolTip();
JLabel toolBarLabel = new JLabel();
JToolBar toolBar1 = new JToolBar();
JButton button4 = new JButton();
JButton button6 = new JButton();
JButton button7 = new JButton();
JButton button8 = new JButton();
JToggleButton toggleButton6 = new JToggleButton();
//======== this ========
setLayout(new MigLayout(
@@ -173,6 +185,7 @@ public class FlatComponentsTest
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- labelLabel ----
@@ -613,6 +626,29 @@ public class FlatComponentsTest
progressBar4.setStringPainted(true);
add(progressBar4, "cell 4 12 1 4,growy");
//======== toolBar2 ========
{
toolBar2.setOrientation(SwingConstants.VERTICAL);
//---- button9 ----
button9.setIcon(UIManager.getIcon("Tree.closedIcon"));
toolBar2.add(button9);
//---- button10 ----
button10.setIcon(UIManager.getIcon("Tree.openIcon"));
toolBar2.add(button10);
toolBar2.addSeparator();
//---- button11 ----
button11.setIcon(UIManager.getIcon("Tree.leafIcon"));
toolBar2.add(button11);
//---- toggleButton7 ----
toggleButton7.setIcon(UIManager.getIcon("Tree.closedIcon"));
toolBar2.add(toggleButton7);
}
add(toolBar2, "cell 4 12 1 4,growy");
//---- scrollBarLabel ----
scrollBarLabel.setText("JScrollBar:");
add(scrollBarLabel, "cell 0 13");
@@ -686,6 +722,39 @@ public class FlatComponentsTest
//---- toolTip1 ----
toolTip1.setTipText("Some text in tool tip.");
add(toolTip1, "cell 1 19 3 1");
//---- toolBarLabel ----
toolBarLabel.setText("JToolBar:");
add(toolBarLabel, "cell 0 20");
//======== toolBar1 ========
{
//---- button4 ----
button4.setIcon(UIManager.getIcon("Tree.closedIcon"));
toolBar1.add(button4);
//---- button6 ----
button6.setIcon(UIManager.getIcon("Tree.openIcon"));
toolBar1.add(button6);
toolBar1.addSeparator();
//---- button7 ----
button7.setIcon(UIManager.getIcon("Tree.leafIcon"));
toolBar1.add(button7);
toolBar1.addSeparator();
//---- button8 ----
button8.setText("Text");
button8.setIcon(UIManager.getIcon("Tree.expandedIcon"));
toolBar1.add(button8);
//---- toggleButton6 ----
toggleButton6.setText("Toggle");
toggleButton6.setIcon(UIManager.getIcon("Tree.leafIcon"));
toolBar1.add(toggleButton6);
}
add(toolBar1, "cell 1 20 3 1,growx");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}

View File

@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3,gap 5 5,ltr"
"$columnConstraints": "[][][][][][]"
"$rowConstraints": "[][][][][][][][][][][][][][][][][][][][]"
"$rowConstraints": "[][][][][][][][][][][][][][][][][][][][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -573,6 +573,31 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 12 1 4,growy"
} )
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
name: "toolBar2"
"orientation": 1
add( new FormComponent( "javax.swing.JButton" ) {
name: "button9"
"icon": &SwingIcon0 new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button10"
"icon": &SwingIcon1 new com.jformdesigner.model.SwingIcon( 2, "Tree.openIcon" )
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator5"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button11"
"icon": &SwingIcon2 new com.jformdesigner.model.SwingIcon( 2, "Tree.leafIcon" )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "toggleButton7"
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 12 1 4,growy"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "scrollBarLabel"
"text": "JScrollBar:"
@@ -690,6 +715,45 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 19 3 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "toolBarLabel"
"text": "JToolBar:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 20"
} )
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
name: "toolBar1"
add( new FormComponent( "javax.swing.JButton" ) {
name: "button4"
"icon": #SwingIcon0
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button6"
"icon": #SwingIcon1
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator3"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button7"
"icon": #SwingIcon2
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button8"
"text": "Text"
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.expandedIcon" )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "toggleButton6"
"text": "Toggle"
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.leafIcon" )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 20 3 1,growx"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 790, 715 )