Button: basic border and background

This commit is contained in:
Karl Tauber
2019-08-20 11:13:03 +02:00
parent 85cfd9750c
commit 8ba5c9a39c
10 changed files with 390 additions and 8 deletions

View File

@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.swing.UIDefaults;
import javax.swing.UIDefaults.LazyValue;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.basic.BasicLookAndFeel;
@@ -202,6 +203,10 @@ public abstract class FlatLaf
case "true": return true;
}
// borders
if( key.endsWith( ".border" ) )
return parseBorder( value );
// colors
ColorUIResource color = parseColor( value );
if( color != null )
@@ -211,6 +216,17 @@ public abstract class FlatLaf
return value;
}
private Object parseBorder( String value ) {
return (LazyValue) t -> {
try {
return Class.forName( value ).newInstance();
} catch( InstantiationException | IllegalAccessException | ClassNotFoundException ex ) {
ex.printStackTrace();
return null;
}
};
}
private ColorUIResource parseColor( String value ) {
try {
if( value.length() == 6 ) {

View File

@@ -0,0 +1,87 @@
/*
* 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 java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicBorders;
/**
* Border for {@link javax.swing.JButton}.
*
* @author Karl Tauber
*/
public class FlatButtonBorder
extends BasicBorders.MarginBorder
{
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
float focusWidth = getFocusWidth();
float lineWidth = getLineWidth();
float arc = 6; //TODO
g2.setPaint( getBorderColor( c ) );
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, lineWidth, arc );
} finally {
g2.dispose();
}
}
public Paint getBorderColor( Component c ) {
if( c.isEnabled() ) {
Color startColor = UIManager.getColor( "Button.startBorderColor" );
Color endColor = UIManager.getColor( "Button.endBorderColor" );
return (startColor.equals( endColor ) )
? startColor
: new GradientPaint( 0, getFocusWidth(), startColor,
0, c.getHeight() - getFocusWidth() - 1f, endColor );
} else
return UIManager.getColor( "Button.disabledBorderColor" );
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
int w = Math.round( getFocusWidth() + getLineWidth() );
insets = super.getBorderInsets( c, insets );
insets.top += w;
insets.left += w;
insets.bottom += w;
insets.right += w;
return insets;
}
protected float getFocusWidth() {
//TODO
return 2;
}
protected float getLineWidth() {
//TODO
return 1;
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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 java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
*
* @author Karl Tauber
*/
public class FlatButtonUI
extends BasicButtonUI
{
private static ComponentUI instance;
public static ComponentUI createUI( JComponent c ) {
if( instance == null )
instance = new FlatButtonUI();
return instance;
}
@Override
public void update( Graphics g, JComponent c ) {
if( c.isOpaque() ) {
FlatUIUtils.paintParentBackground( g, c );
if( c.isEnabled() ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
//TODO
float focusWidth = 2;
float arc = 6;
g2.setColor( c.getBackground() );
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
} finally {
g2.dispose();
}
}
}
paint( g, c );
}
}

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 java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JComponent;
/**
* Utility methods for UI delegates.
*
* @author Karl Tauber
*/
public class FlatUIUtils
{
public static final boolean MAC_USE_QUARTZ = Boolean.getBoolean( "apple.awt.graphics.UseQuartz" );
/**
* Sets rendering hints used for painting.
*/
public static void setRenderingHints( Graphics2D g ) {
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL,
MAC_USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE );
}
/**
* Draws a round rectangle.
*/
public static void drawRoundRectangle( Graphics2D g, int x, int y, int width, int height,
float focusWidth, float lineWidth, float arc )
{
float arc2 = arc > lineWidth ? arc - lineWidth : 0f;
RoundRectangle2D.Float r1 = new RoundRectangle2D.Float(
x + focusWidth, y + focusWidth,
width - focusWidth * 2, height - focusWidth * 2, arc, arc );
RoundRectangle2D.Float r2 = new RoundRectangle2D.Float(
r1.x + lineWidth, r1.y + lineWidth,
r1.width - lineWidth * 2, r1.height - lineWidth * 2, arc2, arc2 );
Path2D border = new Path2D.Float( Path2D.WIND_EVEN_ODD );
border.append( r1, false );
border.append( r2, false );
g.fill( border );
}
/**
* Fills a round rectangle.
*/
public static void fillRoundRectangle( Graphics2D g, int x, int y, int width, int height,
float focusWidth, float arc )
{
g.fill( new RoundRectangle2D.Float(
x + focusWidth, y + focusWidth,
width - focusWidth * 2, height - focusWidth * 2, arc, arc ) );
}
/**
* Fill background with parent's background color because the visible component
* is smaller than its bounds (for the focus decoration).
*/
public static void paintParentBackground( Graphics g, JComponent c ) {
Container parent = findOpaqueParent( c );
if( parent != null ) {
g.setColor( parent.getBackground() );
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
}
}
/**
* Find the first parent that is opaque.
*/
private static Container findOpaqueParent( Container c ) {
while( (c = c.getParent()) != null ) {
if( c.isOpaque() )
return c;
}
return null;
}
}

View File

@@ -42,6 +42,15 @@ textText=@foreground
window=@background
#---- Button ----
Button.background=4c5052
Button.startBorderColor=5e6060
Button.endBorderColor=5e6060
Button.disabledBorderColor=5e6060
#---- Label ----
Label.disabledForeground=808080

View File

@@ -16,4 +16,10 @@
#---- UI delegates ----
ButtonUI=com.formdev.flatlaf.ui.FlatButtonUI
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
#---- Button ----
Button.border=com.formdev.flatlaf.ui.FlatButtonBorder

View File

@@ -42,6 +42,15 @@ textText=@foreground
window=@background
#---- Button ----
Button.background=ffffff
Button.startBorderColor=bfbfbf
Button.endBorderColor=b3b3b3
Button.disabledBorderColor=cfcfcf
#---- Label ----
Label.disabledForeground=777777