mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 06:57:13 -06:00
Merge branch 'master' of https://github.com/JFormDesigner/FlatLaf into bug-60
This commit is contained in:
@@ -48,7 +48,7 @@ public interface FlatClientProperties
|
||||
* <p>
|
||||
* <strong>Components</strong> {@link javax.swing.JToggleButton}
|
||||
*
|
||||
* @see #TOGGLE_BUTTON_TYPE
|
||||
* @see #BUTTON_TYPE
|
||||
*/
|
||||
String BUTTON_TYPE_TAB = "tab";
|
||||
|
||||
@@ -141,10 +141,44 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight";
|
||||
|
||||
/**
|
||||
* Specifies whether all text is selected when the text component gains focus.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
|
||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||
* <strong>Allowed Values</strong> {@link #SELECT_ALL_ON_FOCUS_POLICY_NEVER},
|
||||
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ONCE} (default) or
|
||||
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS}
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY = "JTextField.selectAllOnFocusPolicy";
|
||||
|
||||
/**
|
||||
* Never select all text when the text component gains focus.
|
||||
*
|
||||
* @see #SELECT_ALL_ON_FOCUS_POLICY
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never";
|
||||
|
||||
/**
|
||||
* Select all text when the text component gains focus for the first time
|
||||
* and selection was not modified (is at end of text).
|
||||
* This is the default.
|
||||
*
|
||||
* @see #SELECT_ALL_ON_FOCUS_POLICY
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once";
|
||||
|
||||
/**
|
||||
* Always select all text when the text component gains focus.
|
||||
*
|
||||
* @see #SELECT_ALL_ON_FOCUS_POLICY
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always";
|
||||
|
||||
/**
|
||||
* Placeholder text that is only painted if the text field is empty.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTextField} or {@link javax.swing.JComboBox}<br>
|
||||
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses) or {@link javax.swing.JComboBox}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.String}
|
||||
*/
|
||||
String PLACEHOLDER_TEXT = "JTextField.placeholderText";
|
||||
|
||||
@@ -288,10 +288,9 @@ public abstract class FlatLaf
|
||||
|
||||
// override fonts
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && ((String)key).endsWith( ".font" ) )
|
||||
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
|
||||
defaults.put( key, uiFont );
|
||||
}
|
||||
defaults.put( "MenuItem.acceleratorFont", uiFont );
|
||||
|
||||
// use smaller font for progress bar
|
||||
defaults.put( "ProgressBar.font", UIScale.scaleFont( uiFont, 0.85f ) );
|
||||
|
||||
@@ -221,7 +221,8 @@ class UIDefaultsLoader
|
||||
return resolveValue( properties, newValue );
|
||||
}
|
||||
|
||||
private enum ValueType { UNKNOWN, STRING, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, SCALEDINTEGER, INSTANCE, CLASS }
|
||||
private enum ValueType { UNKNOWN, STRING, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
|
||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS }
|
||||
|
||||
static Object parseValue( String key, String value ) {
|
||||
return parseValue( key, value, v -> v, Collections.emptyList() );
|
||||
@@ -299,6 +300,9 @@ class UIDefaultsLoader
|
||||
case DIMENSION: return parseDimension( value );
|
||||
case COLOR: return parseColorOrFunction( value, resolver, true );
|
||||
case SCALEDINTEGER: return parseScaledInteger( value );
|
||||
case SCALEDFLOAT: return parseScaledFloat( value );
|
||||
case SCALEDINSETS: return parseScaledInsets( value );
|
||||
case SCALEDDIMENSION:return parseScaledDimension( value );
|
||||
case INSTANCE: return parseInstance( value, addonClassLoaders );
|
||||
case CLASS: return parseClass( value, addonClassLoaders );
|
||||
case UNKNOWN:
|
||||
@@ -629,6 +633,27 @@ class UIDefaultsLoader
|
||||
};
|
||||
}
|
||||
|
||||
private static ActiveValue parseScaledFloat( String value ) {
|
||||
float val = parseFloat( value, true );
|
||||
return (ActiveValue) t -> {
|
||||
return UIScale.scale( val );
|
||||
};
|
||||
}
|
||||
|
||||
private static ActiveValue parseScaledInsets( String value ) {
|
||||
Insets insets = parseInsets( value );
|
||||
return (ActiveValue) t -> {
|
||||
return UIScale.scale( insets );
|
||||
};
|
||||
}
|
||||
|
||||
private static ActiveValue parseScaledDimension( String value ) {
|
||||
Dimension dimension = parseDimension( value );
|
||||
return (ActiveValue) t -> {
|
||||
return UIScale.scale( dimension );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string and trim parts.
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ public class FlatAscendingSortIcon
|
||||
g.setColor( sortIconColor );
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,5, 5,1, 9,5 );
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,4, 5,0, 9,4 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
|
||||
@@ -47,7 +47,7 @@ public class FlatDescendingSortIcon
|
||||
g.setColor( sortIconColor );
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 9,1 );
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,0, 5,4, 9,0 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Base class for internal frame icons.
|
||||
*
|
||||
* @uiDefault InternalFrame.buttonHoverBackground Color
|
||||
* @uiDefault InternalFrame.buttonPressedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatInternalFrameAbstractIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color hoverBackground;
|
||||
private final Color pressedBackground;
|
||||
|
||||
public FlatInternalFrameAbstractIcon() {
|
||||
this( UIManager.getDimension( "InternalFrame.buttonSize" ),
|
||||
UIManager.getColor( "InternalFrame.buttonHoverBackground" ),
|
||||
UIManager.getColor( "InternalFrame.buttonPressedBackground" ) );
|
||||
}
|
||||
|
||||
public FlatInternalFrameAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) {
|
||||
super( size.width, size.height, null );
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
}
|
||||
|
||||
protected void paintBackground( Component c, Graphics2D g ) {
|
||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||
if( background != null ) {
|
||||
FlatUIUtils.setColor( g, background, c.getBackground() );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,30 +17,42 @@
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
|
||||
/**
|
||||
* "close" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @uiDefault InternalFrame.iconColor Color
|
||||
* @uiDefault InternalFrame.buttonHoverBackground Color
|
||||
* @uiDefault InternalFrame.buttonPressedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameCloseIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
private final Color hoverForeground = UIManager.getColor( "InternalFrame.closeHoverForeground" );
|
||||
private final Color pressedForeground = UIManager.getColor( "InternalFrame.closePressedForeground" );
|
||||
|
||||
public FlatInternalFrameCloseIcon() {
|
||||
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||
super( UIManager.getDimension( "InternalFrame.buttonSize" ),
|
||||
UIManager.getColor( "InternalFrame.closeHoverBackground" ),
|
||||
UIManager.getColor( "InternalFrame.closePressedBackground" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
float mx = 8;
|
||||
float my = 8;
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground ) );
|
||||
|
||||
float mx = width / 2;
|
||||
float my = height / 2;
|
||||
float r = 3.25f;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
|
||||
@@ -18,24 +18,23 @@ package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* "iconify" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @uiDefault InternalFrame.iconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameIconifyIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameIconifyIcon() {
|
||||
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.fillRect( 3, 8, 10, 1 );
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
g.fillRect( (width / 2) - 4, height / 2, 8, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,25 +18,24 @@ package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "maximize" icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @uiDefault InternalFrame.iconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameMaximizeIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameMaximizeIcon() {
|
||||
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.fill( FlatUIUtils.createRectangle( 3, 3, 10, 10, 1 ) );
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
g.fill( FlatUIUtils.createRectangle( (width / 2) - 4, (height / 2) - 4, 8, 8, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,30 +21,32 @@ import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "minimize" (actually "restore") icon for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* @uiDefault InternalFrame.iconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameMinimizeIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatInternalFrameAbstractIcon
|
||||
{
|
||||
public FlatInternalFrameMinimizeIcon() {
|
||||
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
Path2D r1 = FlatUIUtils.createRectangle( 5, 3, 8, 8, 1 );
|
||||
Path2D r2 = FlatUIUtils.createRectangle( 3, 5, 8, 8, 1 );
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( c.getForeground() );
|
||||
|
||||
int x = (width / 2) - 4;
|
||||
int y = (height / 2) - 4;
|
||||
Path2D r1 = FlatUIUtils.createRectangle( x + 1, y - 1, 8, 8, 1 );
|
||||
Path2D r2 = FlatUIUtils.createRectangle( x - 1, y + 1, 8, 8, 1 );
|
||||
|
||||
Area area = new Area( r1 );
|
||||
area.subtract( new Area( new Rectangle2D.Float( 3, 5, 8, 8 ) ) );
|
||||
area.subtract( new Area( new Rectangle2D.Float( x - 1, y + 1, 8, 8 ) ) );
|
||||
g.fill( area );
|
||||
|
||||
g.fill( r2 );
|
||||
|
||||
128
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java
Normal file
128
flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.FlatClientProperties.*;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.text.DefaultCaret;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
/**
|
||||
* Caret that can select all text on focus gained.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class FlatCaret
|
||||
extends DefaultCaret
|
||||
implements UIResource
|
||||
{
|
||||
private final String selectAllOnFocusPolicy;
|
||||
|
||||
private boolean wasFocused;
|
||||
private boolean wasTemporaryLost;
|
||||
private boolean isMousePressed;
|
||||
|
||||
FlatCaret( String selectAllOnFocusPolicy ) {
|
||||
this.selectAllOnFocusPolicy = selectAllOnFocusPolicy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install( JTextComponent c ) {
|
||||
super.install( c );
|
||||
|
||||
// the dot and mark are lost when switching LaF
|
||||
// --> move dot to end of text so that all text may be selected when it gains focus
|
||||
Document doc = c.getDocument();
|
||||
if( doc != null && getDot() == 0 && getMark() == 0 ) {
|
||||
int length = doc.getLength();
|
||||
if( length > 0 )
|
||||
setDot( length );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained( FocusEvent e ) {
|
||||
if( !wasTemporaryLost && !isMousePressed )
|
||||
selectAllOnFocusGained();
|
||||
wasTemporaryLost = false;
|
||||
wasFocused = true;
|
||||
|
||||
super.focusGained( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost( FocusEvent e ) {
|
||||
wasTemporaryLost = e.isTemporary();
|
||||
super.focusLost( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
isMousePressed = true;
|
||||
super.mousePressed( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
isMousePressed = false;
|
||||
super.mouseReleased( e );
|
||||
}
|
||||
|
||||
private void selectAllOnFocusGained() {
|
||||
JTextComponent c = getComponent();
|
||||
Document doc = c.getDocument();
|
||||
if( doc == null || !c.isEnabled() || !c.isEditable() )
|
||||
return;
|
||||
|
||||
Object selectAllOnFocusPolicy = c.getClientProperty( SELECT_ALL_ON_FOCUS_POLICY );
|
||||
if( selectAllOnFocusPolicy == null )
|
||||
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
|
||||
|
||||
if( SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
|
||||
return;
|
||||
|
||||
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) {
|
||||
// policy is "once" (or null or unknown)
|
||||
|
||||
// was already focused?
|
||||
if( wasFocused )
|
||||
return;
|
||||
|
||||
// check whether selection was modified before gaining focus
|
||||
int dot = getDot();
|
||||
int mark = getMark();
|
||||
if( dot != mark || dot != doc.getLength() )
|
||||
return;
|
||||
}
|
||||
|
||||
// select all
|
||||
if( c instanceof JFormattedTextField ) {
|
||||
EventQueue.invokeLater( () -> {
|
||||
setDot( 0 );
|
||||
moveDot( doc.getLength() );
|
||||
} );
|
||||
} else {
|
||||
setDot( 0 );
|
||||
moveDot( doc.getLength() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyVetoException;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.event.MouseInputAdapter;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicDesktopIconUI;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame.JDesktopIcon}.
|
||||
*
|
||||
* <!-- BasicDesktopIconUI -->
|
||||
*
|
||||
* @uiDefault DesktopIcon.border Border
|
||||
*
|
||||
* <!-- FlatDesktopIconUI -->
|
||||
*
|
||||
* @uiDefault DesktopIcon.background Color
|
||||
* @uiDefault DesktopIcon.foreground Color
|
||||
* @uiDefault DesktopIcon.iconSize Dimension
|
||||
* @uiDefault DesktopIcon.closeSize Dimension
|
||||
* @uiDefault DesktopIcon.closeIcon Icon
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDesktopIconUI
|
||||
extends BasicDesktopIconUI
|
||||
{
|
||||
private Dimension iconSize;
|
||||
private Dimension closeSize;
|
||||
|
||||
private JLabel dockIcon;
|
||||
private JButton closeButton;
|
||||
private JToolTip titleTip;
|
||||
private ActionListener closeListener;
|
||||
private MouseInputListener mouseInputListener;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatDesktopIconUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI( JComponent c ) {
|
||||
super.uninstallUI( c );
|
||||
|
||||
dockIcon = null;
|
||||
closeButton = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
dockIcon = new JLabel();
|
||||
dockIcon.setHorizontalAlignment( SwingConstants.CENTER );
|
||||
|
||||
closeButton = new JButton();
|
||||
closeButton.setIcon( UIManager.getIcon( "DesktopIcon.closeIcon" ) );
|
||||
closeButton.setFocusable( false );
|
||||
closeButton.setBorder( BorderFactory.createEmptyBorder() );
|
||||
closeButton.setOpaque( true );
|
||||
closeButton.setBackground( FlatUIUtils.nonUIResource( desktopIcon.getBackground() ) );
|
||||
closeButton.setForeground( FlatUIUtils.nonUIResource( desktopIcon.getForeground() ) );
|
||||
closeButton.setVisible( false );
|
||||
|
||||
desktopIcon.setLayout( new FlatDesktopIconLayout() );
|
||||
desktopIcon.add( closeButton );
|
||||
desktopIcon.add( dockIcon );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallComponents() {
|
||||
hideTitleTip();
|
||||
|
||||
desktopIcon.remove( dockIcon );
|
||||
desktopIcon.remove( closeButton );
|
||||
desktopIcon.setLayout( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
LookAndFeel.installColors( desktopIcon, "DesktopIcon.background", "DesktopIcon.foreground" );
|
||||
|
||||
iconSize = UIManager.getDimension( "DesktopIcon.iconSize" );
|
||||
closeSize = UIManager.getDimension( "DesktopIcon.closeSize" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
closeListener = e -> {
|
||||
if( frame.isClosable() )
|
||||
frame.doDefaultCloseAction();
|
||||
};
|
||||
closeButton.addActionListener( closeListener );
|
||||
closeButton.addMouseListener( mouseInputListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
|
||||
closeButton.removeActionListener( closeListener );
|
||||
closeButton.removeMouseListener( mouseInputListener );
|
||||
closeListener = null;
|
||||
mouseInputListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MouseInputListener createMouseInputListener() {
|
||||
mouseInputListener = new MouseInputAdapter() {
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
if( frame.isIcon() && desktopIcon.contains( e.getX(), e.getY() ) ) {
|
||||
hideTitleTip();
|
||||
closeButton.setVisible( false );
|
||||
|
||||
try {
|
||||
frame.setIcon( false );
|
||||
} catch( PropertyVetoException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
showTitleTip();
|
||||
if( frame.isClosable() )
|
||||
closeButton.setVisible( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ) {
|
||||
hideTitleTip();
|
||||
closeButton.setVisible( false );
|
||||
}
|
||||
};
|
||||
return mouseInputListener;
|
||||
}
|
||||
|
||||
private void showTitleTip() {
|
||||
JRootPane rootPane = SwingUtilities.getRootPane( desktopIcon );
|
||||
if( rootPane == null )
|
||||
return;
|
||||
|
||||
if( titleTip == null ) {
|
||||
titleTip = new JToolTip();
|
||||
rootPane.getLayeredPane().add( titleTip, JLayeredPane.POPUP_LAYER );
|
||||
}
|
||||
titleTip.setTipText( frame.getTitle() );
|
||||
titleTip.setSize( titleTip.getPreferredSize() );
|
||||
|
||||
int tx = (desktopIcon.getWidth() - titleTip.getWidth()) / 2;
|
||||
int ty = -(titleTip.getHeight() + UIScale.scale( 4 ));
|
||||
Point pt = SwingUtilities.convertPoint( desktopIcon, tx, ty, titleTip.getParent() );
|
||||
if( pt.x + titleTip.getWidth() > rootPane.getWidth() )
|
||||
pt.x = rootPane.getWidth() - titleTip.getWidth();
|
||||
if( pt.x < 0 )
|
||||
pt.x = 0;
|
||||
titleTip.setLocation( pt );
|
||||
titleTip.repaint();
|
||||
}
|
||||
|
||||
private void hideTitleTip() {
|
||||
if( titleTip == null )
|
||||
return;
|
||||
|
||||
titleTip.setVisible( false );
|
||||
titleTip.getParent().remove( titleTip );
|
||||
titleTip = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return UIScale.scale( iconSize );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
return getPreferredSize( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize( JComponent c ) {
|
||||
return getPreferredSize( c );
|
||||
}
|
||||
|
||||
void updateDockIcon() {
|
||||
// use invoke later to make sure that components are updated when switching LaF
|
||||
EventQueue.invokeLater( () -> {
|
||||
if( dockIcon != null )
|
||||
updateDockIconLater();
|
||||
} );
|
||||
}
|
||||
|
||||
private void updateDockIconLater() {
|
||||
// make sure that frame is not selected
|
||||
if( frame.isSelected() ) {
|
||||
try {
|
||||
frame.setSelected( false );
|
||||
} catch( PropertyVetoException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
// paint internal frame to buffered image
|
||||
int frameWidth = Math.max( frame.getWidth(), 1 );
|
||||
int frameHeight = Math.max( frame.getHeight(), 1 );
|
||||
BufferedImage frameImage = new BufferedImage( frameWidth, frameHeight, BufferedImage.TYPE_INT_ARGB );
|
||||
Graphics2D g = frameImage.createGraphics();
|
||||
try {
|
||||
//TODO fix missing internal frame header when switching LaF
|
||||
frame.paint( g );
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
// compute preview size (keep ratio; also works with non-square preview)
|
||||
Insets insets = desktopIcon.getInsets();
|
||||
int previewWidth = UIScale.scale( iconSize.width ) - insets.left - insets.right;
|
||||
int previewHeight = UIScale.scale( iconSize.height ) - insets.top - insets.bottom;
|
||||
float frameRatio = ((float) frameHeight / (float) frameWidth);
|
||||
if( ((float) previewWidth / (float) frameWidth) > ((float) previewHeight / (float) frameHeight) )
|
||||
previewWidth = Math.round( previewHeight / frameRatio );
|
||||
else
|
||||
previewHeight = Math.round( previewWidth * frameRatio );
|
||||
|
||||
// scale preview
|
||||
Image previewImage = frameImage.getScaledInstance( previewWidth, previewHeight, Image.SCALE_SMOOTH );
|
||||
dockIcon.setIcon( new ImageIcon( previewImage ) );
|
||||
}
|
||||
|
||||
//---- class DockIcon -----------------------------------------------------
|
||||
|
||||
private class FlatDesktopIconLayout
|
||||
implements LayoutManager
|
||||
{
|
||||
@Override public void addLayoutComponent( String name, Component comp ) {}
|
||||
@Override public void removeLayoutComponent( Component comp ) {}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize( Container parent ) {
|
||||
return dockIcon.getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize( Container parent ) {
|
||||
return dockIcon.getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer( Container parent ) {
|
||||
Insets insets = parent.getInsets();
|
||||
|
||||
// dock icon
|
||||
dockIcon.setBounds( insets.left, insets.top,
|
||||
parent.getWidth() - insets.left - insets.right,
|
||||
parent.getHeight() - insets.top - insets.bottom );
|
||||
|
||||
// close button in upper right corner
|
||||
Dimension cSize = UIScale.scale( closeSize );
|
||||
closeButton.setBounds( parent.getWidth() - cSize.width, 0, cSize.width, cSize.height );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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 javax.swing.DefaultDesktopManager;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicDesktopPaneUI;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JDesktopPane}.
|
||||
*
|
||||
* <!-- BasicDesktopPaneUI -->
|
||||
*
|
||||
* @uiDefault Desktop.background Color
|
||||
* @uiDefault Desktop.minOnScreenInsets Insets
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatDesktopPaneUI
|
||||
extends BasicDesktopPaneUI
|
||||
{
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatDesktopPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDesktopManager() {
|
||||
desktopManager = desktop.getDesktopManager();
|
||||
if( desktopManager == null ) {
|
||||
desktopManager = new FlatDesktopManager();
|
||||
desktop.setDesktopManager( desktopManager );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatDesktopManager -------------------------------------------
|
||||
|
||||
private class FlatDesktopManager
|
||||
extends DefaultDesktopManager
|
||||
implements UIResource
|
||||
{
|
||||
@Override
|
||||
public void iconifyFrame( JInternalFrame f ) {
|
||||
super.iconifyFrame( f );
|
||||
|
||||
((FlatDesktopIconUI)f.getDesktopIcon().getUI()).updateDockIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,9 +50,10 @@ public class FlatEmptyBorder
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
insets.left = scale( left );
|
||||
boolean leftToRight = left == right || c.getComponentOrientation().isLeftToRight();
|
||||
insets.left = scale( leftToRight ? left : right );
|
||||
insets.top = scale( top );
|
||||
insets.right = scale( right );
|
||||
insets.right = scale( leftToRight ? right : left );
|
||||
insets.bottom = scale( bottom );
|
||||
return insets;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import javax.swing.plaf.ComponentUI;
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault FormattedTextField.placeholderForeground Color
|
||||
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.LayoutManager;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF internal frame title bar.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameTitlePane
|
||||
extends BasicInternalFrameTitlePane
|
||||
{
|
||||
private JLabel titleLabel;
|
||||
private JPanel buttonPanel;
|
||||
|
||||
public FlatInternalFrameTitlePane( JInternalFrame f ) {
|
||||
super( f );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
LookAndFeel.installBorder( this, "InternalFrameTitlePane.border" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyChangeListener createPropertyChangeListener() {
|
||||
return new FlatPropertyChangeHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutManager createLayout() {
|
||||
return new BorderLayout( UIScale.scale( 4 ), 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createButtons() {
|
||||
super.createButtons();
|
||||
|
||||
iconButton.setContentAreaFilled( false );
|
||||
maxButton.setContentAreaFilled( false );
|
||||
closeButton.setContentAreaFilled( false );
|
||||
|
||||
Border emptyBorder = BorderFactory.createEmptyBorder();
|
||||
iconButton.setBorder( emptyBorder );
|
||||
maxButton.setBorder( emptyBorder );
|
||||
closeButton.setBorder( emptyBorder );
|
||||
|
||||
updateButtonsVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSubComponents() {
|
||||
titleLabel = new JLabel( frame.getTitle() );
|
||||
titleLabel.setFont( FlatUIUtils.nonUIResource( getFont() ) );
|
||||
titleLabel.setMinimumSize( new Dimension( UIScale.scale( 32 ), 1 ) );
|
||||
updateFrameIcon();
|
||||
updateColors();
|
||||
|
||||
buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) );
|
||||
buttonPanel.setOpaque( false );
|
||||
|
||||
buttonPanel.add( iconButton );
|
||||
buttonPanel.add( maxButton );
|
||||
buttonPanel.add( closeButton );
|
||||
|
||||
add( titleLabel, BorderLayout.CENTER );
|
||||
add( buttonPanel, BorderLayout.LINE_END );
|
||||
}
|
||||
|
||||
private void updateFrameIcon() {
|
||||
Icon frameIcon = frame.getFrameIcon();
|
||||
if( frameIcon == UIManager.getIcon( "InternalFrame.icon" ) )
|
||||
frameIcon = null;
|
||||
titleLabel.setIcon( frameIcon );
|
||||
}
|
||||
|
||||
private void updateColors() {
|
||||
Color background = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTitleColor : notSelectedTitleColor );
|
||||
Color foreground = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTextColor : notSelectedTextColor );
|
||||
|
||||
titleLabel.setForeground( foreground );
|
||||
iconButton.setBackground( background );
|
||||
iconButton.setForeground( foreground );
|
||||
maxButton.setBackground( background );
|
||||
maxButton.setForeground( foreground );
|
||||
closeButton.setBackground( background );
|
||||
closeButton.setForeground( foreground );
|
||||
}
|
||||
|
||||
private void updateButtonsVisibility() {
|
||||
iconButton.setVisible( frame.isIconifiable() );
|
||||
maxButton.setVisible( frame.isMaximizable() );
|
||||
closeButton.setVisible( frame.isClosable() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing because FlatLaf internal frames do not have system menus.
|
||||
*/
|
||||
@Override
|
||||
protected void assembleSystemMenu() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing because FlatLaf internal frames do not have system menus.
|
||||
*/
|
||||
@Override
|
||||
protected void showSystemMenu() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent( Graphics g ) {
|
||||
paintTitleBackground( g );
|
||||
}
|
||||
|
||||
//---- class FlatPropertyChangeHandler ------------------------------------
|
||||
|
||||
private class FlatPropertyChangeHandler
|
||||
extends PropertyChangeHandler
|
||||
{
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case JInternalFrame.TITLE_PROPERTY:
|
||||
titleLabel.setText( frame.getTitle() );
|
||||
break;
|
||||
|
||||
case JInternalFrame.FRAME_ICON_PROPERTY:
|
||||
updateFrameIcon();
|
||||
break;
|
||||
|
||||
case JInternalFrame.IS_SELECTED_PROPERTY:
|
||||
updateColors();
|
||||
break;
|
||||
|
||||
case "iconable":
|
||||
case "maximizable":
|
||||
case "closable":
|
||||
updateButtonsVisibility();
|
||||
enableActions();
|
||||
revalidate();
|
||||
repaint();
|
||||
|
||||
// do not invoke super.propertyChange() because this adds/removes the buttons
|
||||
return;
|
||||
|
||||
case "componentOrientation":
|
||||
applyComponentOrientation( frame.getComponentOrientation() );
|
||||
break;
|
||||
}
|
||||
|
||||
super.propertyChange( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame}.
|
||||
*
|
||||
* <!-- BasicInternalFrameUI -->
|
||||
*
|
||||
* @uiDefault control Color
|
||||
* @uiDefault InternalFrame.icon Icon
|
||||
* @uiDefault InternalFrame.border Border
|
||||
* @uiDefault InternalFrame.layoutTitlePaneAtOrigin boolean
|
||||
*
|
||||
* <!-- BasicInternalFrameTitlePane -->
|
||||
*
|
||||
* @uiDefault InternalFrame.titleFont Font
|
||||
* @uiDefault InternalFrame.icon Icon
|
||||
* @uiDefault InternalFrame.maximizeIcon Icon
|
||||
* @uiDefault InternalFrame.minimizeIcon Icon
|
||||
* @uiDefault InternalFrame.iconifyIcon Icon
|
||||
* @uiDefault InternalFrame.closeIcon Icon
|
||||
* @uiDefault InternalFrame.activeTitleBackground Color
|
||||
* @uiDefault InternalFrame.activeTitleForeground Color
|
||||
* @uiDefault InternalFrame.inactiveTitleBackground Color
|
||||
* @uiDefault InternalFrame.inactiveTitleForeground Color
|
||||
* @uiDefault InternalFrame.closeButtonToolTip String
|
||||
* @uiDefault InternalFrame.iconButtonToolTip String
|
||||
* @uiDefault InternalFrame.restoreButtonToolTip String
|
||||
* @uiDefault InternalFrame.maxButtonToolTip String
|
||||
* @uiDefault InternalFrameTitlePane.closeButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.minimizeButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.restoreButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.maximizeButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.moveButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.sizeButtonText String
|
||||
* @uiDefault InternalFrameTitlePane.closeButton.mnemonic Integer
|
||||
* @uiDefault InternalFrameTitlePane.minimizeButton.mnemonic Integer
|
||||
* @uiDefault InternalFrameTitlePane.restoreButton.mnemonic Integer
|
||||
* @uiDefault InternalFrameTitlePane.maximizeButton.mnemonic Integer
|
||||
* @uiDefault InternalFrameTitlePane.moveButton.mnemonic Integer
|
||||
* @uiDefault InternalFrameTitlePane.sizeButton.mnemonic Integer
|
||||
*
|
||||
* <!-- FlatInternalFrameUI -->
|
||||
*
|
||||
* @uiDefault InternalFrame.activeBorderColor Color
|
||||
* @uiDefault InternalFrame.inactiveBorderColor Color
|
||||
* @uiDefault InternalFrame.borderLineWidth int
|
||||
* @uiDefault InternalFrame.borderMargins Insets
|
||||
*
|
||||
* <!-- FlatInternalFrameTitlePane -->
|
||||
*
|
||||
* @uiDefault InternalFrameTitlePane.border Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatInternalFrameUI
|
||||
extends BasicInternalFrameUI
|
||||
{
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatInternalFrameUI( (JInternalFrame) c );
|
||||
}
|
||||
|
||||
public FlatInternalFrameUI( JInternalFrame b ) {
|
||||
super( b );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
LookAndFeel.installProperty( frame, "opaque", false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createNorthPane( JInternalFrame w ) {
|
||||
return new FlatInternalFrameTitlePane( w );
|
||||
}
|
||||
|
||||
//---- class FlatInternalFrameBorder --------------------------------------
|
||||
|
||||
public static class FlatInternalFrameBorder
|
||||
extends FlatEmptyBorder
|
||||
{
|
||||
private final Color activeBorderColor = UIManager.getColor( "InternalFrame.activeBorderColor" );
|
||||
private final Color inactiveBorderColor = UIManager.getColor( "InternalFrame.inactiveBorderColor" );
|
||||
private final int borderLineWidth = FlatUIUtils.getUIInt( "InternalFrame.borderLineWidth", 1 );
|
||||
|
||||
public FlatInternalFrameBorder() {
|
||||
super( UIManager.getInsets( "InternalFrame.borderMargins" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) {
|
||||
insets.left = scale( Math.min( borderLineWidth, left ) );
|
||||
insets.top = scale( Math.min( borderLineWidth, top ) );
|
||||
insets.right = scale( Math.min( borderLineWidth, right ) );
|
||||
insets.bottom = scale( Math.min( borderLineWidth, bottom ) );
|
||||
return insets;
|
||||
}
|
||||
|
||||
return super.getBorderInsets( c, insets );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
JInternalFrame f = (JInternalFrame) c;
|
||||
|
||||
Insets insets = getBorderInsets( c );
|
||||
float lineWidth = scale( (float) borderLineWidth );
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
g2.setColor( f.isSelected() ? activeBorderColor : inactiveBorderColor );
|
||||
g2.fill( FlatUIUtils.createRectangle(
|
||||
x + insets.left - lineWidth,
|
||||
y + insets.top - lineWidth,
|
||||
width - insets.left - insets.right + (lineWidth * 2),
|
||||
height - insets.top - insets.bottom + (lineWidth * 2),
|
||||
lineWidth ) );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.Component;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* Border for {@link javax.swing.JMenu}, {@link javax.swing.JMenuItem},
|
||||
* {@link javax.swing.JCheckBoxMenuItem} and {@link javax.swing.JRadioButtonMenuItem}.
|
||||
*
|
||||
* @uiDefault MenuBar.itemMargins Insets
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuItemBorder
|
||||
extends FlatMarginBorder
|
||||
{
|
||||
private final Insets menuBarItemMargins = UIManager.getInsets( "MenuBar.itemMargins" );
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
if( c.getParent() instanceof JMenuBar ) {
|
||||
insets.top = scale( menuBarItemMargins.top );
|
||||
insets.left = scale( menuBarItemMargins.left );
|
||||
insets.bottom = scale( menuBarItemMargins.bottom + 1 );
|
||||
insets.right = scale( menuBarItemMargins.right );
|
||||
return insets;
|
||||
} else
|
||||
return super.getBorderInsets( c, insets );
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,17 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuUI;
|
||||
|
||||
@@ -51,11 +57,17 @@ import javax.swing.plaf.basic.BasicMenuUI;
|
||||
* @uiDefault Menu.useMenuBarBackgroundForTopLevel boolean default is false
|
||||
* @uiDefault MenuBar.background Color used if Menu.useMenuBarBackgroundForTopLevel is true
|
||||
*
|
||||
* <!-- FlatMenuUI -->
|
||||
*
|
||||
* @uiDefault MenuBar.hoverBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuUI
|
||||
extends BasicMenuUI
|
||||
{
|
||||
private Color hoverBackground;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatMenuUI();
|
||||
}
|
||||
@@ -64,10 +76,21 @@ public class FlatMenuUI
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
menuItem.setRolloverEnabled( true );
|
||||
|
||||
hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" );
|
||||
|
||||
// scale
|
||||
defaultTextIconGap = scale( defaultTextIconGap );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
hoverBackground = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale defaultTextIconGap again if iconTextGap property has changed.
|
||||
*/
|
||||
@@ -81,6 +104,43 @@ public class FlatMenuUI
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MouseInputListener createMouseInputListener( JComponent c ) {
|
||||
return new BasicMenuUI.MouseInputHandler() {
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
super.mouseEntered( e );
|
||||
rollover( e, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ) {
|
||||
super.mouseExited( e );
|
||||
rollover( e, false );
|
||||
}
|
||||
|
||||
private void rollover( MouseEvent e, boolean rollover ) {
|
||||
JMenu menu = (JMenu) e.getSource();
|
||||
if( menu.isTopLevelMenu() && menu.isRolloverEnabled() ) {
|
||||
menu.getModel().setRollover( rollover );
|
||||
menu.repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground( Graphics g, JMenuItem menuItem, Color bgColor ) {
|
||||
ButtonModel model = menuItem.getModel();
|
||||
if( model.isArmed() || model.isSelected() ) {
|
||||
super.paintBackground( g, menuItem, bgColor );
|
||||
} else if( model.isRollover() && model.isEnabled() && ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||
FlatUIUtils.setColor( g, hoverBackground, menuItem.getBackground() );
|
||||
g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() );
|
||||
} else
|
||||
super.paintBackground( g, menuItem, bgColor );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) {
|
||||
FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground );
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicPasswordFieldUI;
|
||||
import javax.swing.text.Caret;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
@@ -55,6 +56,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault PasswordField.placeholderForeground Color
|
||||
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -116,6 +118,11 @@ public class FlatPasswordFieldUI
|
||||
focusListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Caret createCaret() {
|
||||
return new FlatCaret( UIManager.getString( "TextComponent.selectAllOnFocusPolicy" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Border for {@link javax.swing.JPopupMenu}.
|
||||
@@ -33,4 +38,18 @@ public class FlatPopupMenuBorder
|
||||
super( UIManager.getInsets( "PopupMenu.borderInsets" ),
|
||||
UIManager.getColor( "PopupMenu.borderColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
if( c instanceof Container &&
|
||||
((Container)c).getComponentCount() > 0 &&
|
||||
((Container)c).getComponent( 0 ) instanceof JScrollPane )
|
||||
{
|
||||
// e.g. for combobox popups
|
||||
insets.left = insets.top = insets.right = insets.bottom = UIScale.scale( 1 );
|
||||
return insets;
|
||||
}
|
||||
|
||||
return super.getBorderInsets( c, insets );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,4 +193,19 @@ public class FlatProgressBarUI
|
||||
paintString( g, x, y, width, height, amountFull, insets );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAnimationIndex( int newValue ) {
|
||||
super.setAnimationIndex( newValue );
|
||||
|
||||
// On HiDPI screens at 125%, 150% and 175% scaling, it occurs that antialiased painting
|
||||
// may paint one pixel outside of the clipping area. This results in visual artifacts
|
||||
// in indeterminate mode when the progress moves around.
|
||||
// Unfortunately it is not safe to invoke getBox() from here (may throw NPE),
|
||||
// which makes it impractical to get progress box and repaint increased box.
|
||||
// Only solution is to repaint whole progress bar.
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( progressBar.getGraphicsConfiguration() );
|
||||
if( (int) systemScaleFactor != systemScaleFactor )
|
||||
progressBar.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +118,13 @@ public class FlatRadioButtonUI
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
// fill background even if opaque if
|
||||
// - used as cell renderer (because of selection background)
|
||||
// - if background was explicitly set to a non-UIResource color
|
||||
// fill background even if not opaque if
|
||||
// - contentAreaFilled is true and
|
||||
// - used as cell renderer (because of selection background)
|
||||
// - or if background was explicitly set to a non-UIResource color
|
||||
if( !c.isOpaque() &&
|
||||
(c.getParent() instanceof CellRendererPane || !(c.getBackground() instanceof UIResource)) )
|
||||
((AbstractButton)c).isContentAreaFilled() &&
|
||||
(c.getParent() instanceof CellRendererPane || !(c.getBackground() instanceof UIResource)))
|
||||
{
|
||||
g.setColor( c.getBackground() );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
|
||||
@@ -82,6 +82,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault TabbedPane.tabSelectionHeight int
|
||||
* @uiDefault TabbedPane.contentSeparatorHeight int
|
||||
* @uiDefault TabbedPane.showTabSeparators boolean
|
||||
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
|
||||
* @uiDefault TabbedPane.hasFullBorder boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -103,6 +104,7 @@ public class FlatTabbedPaneUI
|
||||
protected int tabSelectionHeight;
|
||||
protected int contentSeparatorHeight;
|
||||
protected boolean showTabSeparators;
|
||||
protected boolean tabSeparatorsFullHeight;
|
||||
protected boolean hasFullBorder;
|
||||
protected boolean tabsOverlapBorder;
|
||||
|
||||
@@ -128,6 +130,7 @@ public class FlatTabbedPaneUI
|
||||
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
|
||||
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
|
||||
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
|
||||
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
|
||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
||||
|
||||
@@ -307,7 +310,7 @@ public class FlatTabbedPaneUI
|
||||
!isLastInRun( tabIndex ) )
|
||||
{
|
||||
float sepWidth = UIScale.scale( 1f );
|
||||
float offset = UIScale.scale( 5f );
|
||||
float offset = tabSeparatorsFullHeight ? 0 : UIScale.scale( 5f );
|
||||
|
||||
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
|
||||
if( tabPlacement == LEFT || tabPlacement == RIGHT ) {
|
||||
|
||||
@@ -22,13 +22,20 @@ import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Objects;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
@@ -49,6 +56,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault TableHeader.separatorColor Color
|
||||
* @uiDefault TableHeader.bottomSeparatorColor Color
|
||||
* @uiDefault TableHeader.height int
|
||||
* @uiDefault TableHeader.sortIconPosition String right (default), left, top or bottom
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -58,6 +66,7 @@ public class FlatTableHeaderUI
|
||||
protected Color separatorColor;
|
||||
protected Color bottomSeparatorColor;
|
||||
protected int height;
|
||||
protected int sortIconPosition;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatTableHeaderUI();
|
||||
@@ -70,12 +79,33 @@ public class FlatTableHeaderUI
|
||||
separatorColor = UIManager.getColor( "TableHeader.separatorColor" );
|
||||
bottomSeparatorColor = UIManager.getColor( "TableHeader.bottomSeparatorColor" );
|
||||
height = UIManager.getInt( "TableHeader.height" );
|
||||
switch( Objects.toString( UIManager.getString( "TableHeader.sortIconPosition" ), "right" ) ) {
|
||||
default:
|
||||
case "right": sortIconPosition = SwingConstants.RIGHT; break;
|
||||
case "left": sortIconPosition = SwingConstants.LEFT; break;
|
||||
case "top": sortIconPosition = SwingConstants.TOP; break;
|
||||
case "bottom": sortIconPosition = SwingConstants.BOTTOM; break;
|
||||
}
|
||||
|
||||
// use own renderer if necessary
|
||||
if( sortIconPosition != SwingConstants.RIGHT ) {
|
||||
TableCellRenderer defaultRenderer = header.getDefaultRenderer();
|
||||
if( defaultRenderer instanceof UIResource )
|
||||
header.setDefaultRenderer( new FlatTableCellHeaderRenderer( defaultRenderer ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
// restore default renderer
|
||||
TableCellRenderer defaultRenderer = header.getDefaultRenderer();
|
||||
if( defaultRenderer instanceof FlatTableCellHeaderRenderer ) {
|
||||
((FlatTableCellHeaderRenderer)defaultRenderer).reset();
|
||||
header.setDefaultRenderer( ((FlatTableCellHeaderRenderer)defaultRenderer).delegate );
|
||||
}
|
||||
|
||||
separatorColor = null;
|
||||
bottomSeparatorColor = null;
|
||||
}
|
||||
@@ -215,4 +245,83 @@ public class FlatTableHeaderUI
|
||||
parent = parent.getParent();
|
||||
return (parent instanceof JScrollPane) ? (JScrollPane) parent : null;
|
||||
}
|
||||
|
||||
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
||||
|
||||
/**
|
||||
* A delegating header renderer that is only used to paint sort arrows at
|
||||
* top, bottom or left position.
|
||||
*/
|
||||
private class FlatTableCellHeaderRenderer
|
||||
implements TableCellRenderer, Border, UIResource
|
||||
{
|
||||
private final TableCellRenderer delegate;
|
||||
|
||||
private int oldHorizontalTextPosition = -1;
|
||||
private Border origBorder;
|
||||
private Icon sortIcon;
|
||||
|
||||
FlatTableCellHeaderRenderer( TableCellRenderer delegate ) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column )
|
||||
{
|
||||
Component c = delegate.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
||||
if( !(c instanceof JLabel) )
|
||||
return c;
|
||||
|
||||
JLabel l = (JLabel) c;
|
||||
|
||||
if( sortIconPosition == SwingConstants.LEFT ) {
|
||||
if( oldHorizontalTextPosition < 0 )
|
||||
oldHorizontalTextPosition = l.getHorizontalTextPosition();
|
||||
l.setHorizontalTextPosition( SwingConstants.RIGHT );
|
||||
} else {
|
||||
// top or bottom
|
||||
sortIcon = l.getIcon();
|
||||
origBorder = l.getBorder();
|
||||
l.setIcon( null );
|
||||
l.setBorder( this );
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if( sortIconPosition == SwingConstants.LEFT && oldHorizontalTextPosition >= 0 ) {
|
||||
Component c = getTableCellRendererComponent( header.getTable(), "", false, false, -1, 0 );
|
||||
if( c instanceof JLabel && ((JLabel)c).getHorizontalTextPosition() == SwingConstants.RIGHT )
|
||||
((JLabel)c).setHorizontalTextPosition( oldHorizontalTextPosition );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( origBorder != null )
|
||||
origBorder.paintBorder( c, g, x, y, width, height );
|
||||
|
||||
if( sortIcon != null ) {
|
||||
int xi = x + ((width - sortIcon.getIconWidth()) / 2);
|
||||
int yi = (sortIconPosition == SwingConstants.TOP)
|
||||
? y + UIScale.scale( 1 )
|
||||
: y + height - sortIcon.getIconHeight()
|
||||
- 1 // for gap
|
||||
- (int) (1 * UIScale.getUserScaleFactor()); // for bottom border
|
||||
sortIcon.paintIcon( c, g, xi, yi );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c ) {
|
||||
return (origBorder != null) ? origBorder.getBorderInsets( c ) : new Insets( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return (origBorder != null) ? origBorder.isBorderOpaque() : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||
import javax.swing.text.Caret;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
|
||||
@@ -62,6 +63,7 @@ import com.formdev.flatlaf.FlatClientProperties;
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault TextField.placeholderForeground Color
|
||||
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -119,6 +121,11 @@ public class FlatTextFieldUI
|
||||
focusListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Caret createCaret() {
|
||||
return new FlatCaret( UIManager.getString( "TextComponent.selectAllOnFocusPolicy" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
@@ -37,7 +38,7 @@ import java.util.function.Consumer;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
@@ -109,7 +110,11 @@ public class FlatUIUtils
|
||||
}
|
||||
|
||||
public static Color nonUIResource( Color c ) {
|
||||
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
|
||||
return (c instanceof UIResource) ? new Color( c.getRGB(), true ) : c;
|
||||
}
|
||||
|
||||
public static Font nonUIResource( Font font ) {
|
||||
return (font instanceof UIResource) ? new Font( font.getName(), font.getStyle(), font.getSize() ) : font;
|
||||
}
|
||||
|
||||
public static int minimumWidth( JComponent c, int minimumWidth ) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=#777777
|
||||
@textComponentBackground=#45494A
|
||||
@menuBackground=darken(@background,5%)
|
||||
@cellFocusColor=#000000
|
||||
@icon=#adadad
|
||||
|
||||
@@ -130,6 +131,34 @@ Component.focusColor=#3d6185
|
||||
Component.linkColor=#589df6
|
||||
|
||||
|
||||
#---- Desktop ----
|
||||
|
||||
Desktop.background=#3E434C
|
||||
|
||||
|
||||
#---- DesktopIcon ----
|
||||
|
||||
DesktopIcon.background=lighten($Desktop.background,10%)
|
||||
|
||||
|
||||
#---- InternalFrame ----
|
||||
|
||||
InternalFrame.activeTitleBackground=darken(@background,10%)
|
||||
InternalFrame.activeTitleForeground=@foreground
|
||||
InternalFrame.inactiveTitleBackground=darken(@background,5%)
|
||||
InternalFrame.inactiveTitleForeground=@disabledText
|
||||
|
||||
InternalFrame.activeBorderColor=lighten($Component.borderColor,10%)
|
||||
InternalFrame.inactiveBorderColor=$Component.borderColor
|
||||
|
||||
InternalFrame.buttonHoverBackground=lighten(10%,autoInverse)
|
||||
InternalFrame.buttonPressedBackground=lighten(20%,autoInverse)
|
||||
InternalFrame.closeHoverBackground=lazy(Actions.Red)
|
||||
InternalFrame.closePressedBackground=darken(Actions.Red,10%,lazy)
|
||||
InternalFrame.closeHoverForeground=#fff
|
||||
InternalFrame.closePressedForeground=#fff
|
||||
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.background=@textComponentBackground
|
||||
@@ -144,6 +173,7 @@ Menu.icon.disabledArrowColor=#606060
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=#515151
|
||||
MenuBar.hoverBackground=lighten($MenuBar.background,10%)
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
|
||||
@@ -21,9 +21,12 @@ CheckBoxUI=com.formdev.flatlaf.ui.FlatCheckBoxUI
|
||||
CheckBoxMenuItemUI=com.formdev.flatlaf.ui.FlatCheckBoxMenuItemUI
|
||||
ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI
|
||||
ComboBoxUI=com.formdev.flatlaf.ui.FlatComboBoxUI
|
||||
DesktopIconUI=com.formdev.flatlaf.ui.FlatDesktopIconUI
|
||||
DesktopPaneUI=com.formdev.flatlaf.ui.FlatDesktopPaneUI
|
||||
EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI
|
||||
FileChooserUI=com.formdev.flatlaf.ui.FlatFileChooserUI
|
||||
FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI
|
||||
InternalFrameUI=com.formdev.flatlaf.ui.FlatInternalFrameUI
|
||||
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
|
||||
ListUI=com.formdev.flatlaf.ui.FlatListUI
|
||||
MenuUI=com.formdev.flatlaf.ui.FlatMenuUI
|
||||
@@ -59,6 +62,7 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
|
||||
#---- variables ----
|
||||
|
||||
@textComponentMargin=2,6,2,6
|
||||
@menuItemMargin=2,8,2,8
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
@@ -117,10 +121,12 @@ CheckBox.rollover=true
|
||||
|
||||
#---- CheckBoxMenuItem ----
|
||||
|
||||
CheckBoxMenuItem.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
CheckBoxMenuItem.border=com.formdev.flatlaf.ui.FlatMenuItemBorder
|
||||
CheckBoxMenuItem.checkIcon=com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon
|
||||
CheckBoxMenuItem.arrowIcon=com.formdev.flatlaf.icons.FlatMenuItemArrowIcon
|
||||
CheckBoxMenuItem.margin=2,2,2,2
|
||||
CheckBoxMenuItem.margin=@menuItemMargin
|
||||
CheckBoxMenuItem.opaque=false
|
||||
CheckBoxMenuItem.background=@menuBackground
|
||||
|
||||
|
||||
#---- ColorChooser ----
|
||||
@@ -145,6 +151,14 @@ Component.arrowType=chevron
|
||||
Component.hideMnemonics=true
|
||||
|
||||
|
||||
#---- DesktopIcon ----
|
||||
|
||||
DesktopIcon.border=4,4,4,4
|
||||
DesktopIcon.iconSize=64,64
|
||||
DesktopIcon.closeSize=20,20
|
||||
DesktopIcon.closeIcon=com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon
|
||||
|
||||
|
||||
#---- EditorPane ----
|
||||
|
||||
EditorPane.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
@@ -194,6 +208,23 @@ HelpButton.questionMarkColor=$CheckBox.icon.checkmarkColor
|
||||
HelpButton.disabledQuestionMarkColor=$CheckBox.icon.disabledCheckmarkColor
|
||||
|
||||
|
||||
#---- InternalFrame ----
|
||||
|
||||
InternalFrame.border=com.formdev.flatlaf.ui.FlatInternalFrameUI$FlatInternalFrameBorder
|
||||
InternalFrame.borderLineWidth=1
|
||||
InternalFrame.borderMargins=6,6,6,6
|
||||
InternalFrame.buttonSize=24,24
|
||||
InternalFrame.closeIcon=com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon
|
||||
InternalFrame.iconifyIcon=com.formdev.flatlaf.icons.FlatInternalFrameIconifyIcon
|
||||
InternalFrame.maximizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon
|
||||
InternalFrame.minimizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMinimizeIcon
|
||||
|
||||
|
||||
#---- InternalFrameTitlePane ----
|
||||
|
||||
InternalFrameTitlePane.border=0,8,0,0
|
||||
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.border=1,0,1,0
|
||||
@@ -212,23 +243,29 @@ List.dropLineColor=@dropLineColor
|
||||
|
||||
#---- Menu ----
|
||||
|
||||
Menu.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
Menu.border=com.formdev.flatlaf.ui.FlatMenuItemBorder
|
||||
Menu.arrowIcon=com.formdev.flatlaf.icons.FlatMenuArrowIcon
|
||||
Menu.margin=2,2,2,2
|
||||
Menu.margin=@menuItemMargin
|
||||
Menu.submenuPopupOffsetX={scaledInteger}-4
|
||||
Menu.submenuPopupOffsetY={scaledInteger}-1
|
||||
Menu.submenuPopupOffsetY={scaledInteger}-4
|
||||
Menu.opaque=false
|
||||
Menu.background=@menuBackground
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.border=com.formdev.flatlaf.ui.FlatMenuBarBorder
|
||||
MenuBar.background=@menuBackground
|
||||
MenuBar.itemMargins=3,3,3,3
|
||||
|
||||
|
||||
#---- MenuItem ----
|
||||
|
||||
MenuItem.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
MenuItem.border=com.formdev.flatlaf.ui.FlatMenuItemBorder
|
||||
MenuItem.arrowIcon=com.formdev.flatlaf.icons.FlatMenuItemArrowIcon
|
||||
MenuItem.margin=2,2,2,2
|
||||
MenuItem.margin=@menuItemMargin
|
||||
MenuItem.opaque=false
|
||||
MenuItem.background=@menuBackground
|
||||
|
||||
|
||||
#---- OptionPane ----
|
||||
@@ -265,7 +302,8 @@ PasswordField.placeholderForeground=@disabledText
|
||||
#---- PopupMenu ----
|
||||
|
||||
PopupMenu.border=com.formdev.flatlaf.ui.FlatPopupMenuBorder
|
||||
PopupMenu.borderInsets=1,1,1,1
|
||||
PopupMenu.borderInsets=4,1,4,1
|
||||
PopupMenu.background=@menuBackground
|
||||
|
||||
|
||||
#---- PopupMenuSeparator ----
|
||||
@@ -281,6 +319,8 @@ ProgressBar.border=com.formdev.flatlaf.ui.FlatEmptyBorder
|
||||
ProgressBar.arc=4
|
||||
ProgressBar.horizontalSize=146,4
|
||||
ProgressBar.verticalSize=4,146
|
||||
ProgressBar.cycleTime=4000
|
||||
ProgressBar.repaintInterval=15
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
@@ -295,10 +335,12 @@ RadioButton.rollover=true
|
||||
|
||||
#---- RadioButtonMenuItem ----
|
||||
|
||||
RadioButtonMenuItem.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
RadioButtonMenuItem.border=com.formdev.flatlaf.ui.FlatMenuItemBorder
|
||||
RadioButtonMenuItem.checkIcon=com.formdev.flatlaf.icons.FlatRadioButtonMenuItemIcon
|
||||
RadioButtonMenuItem.arrowIcon=com.formdev.flatlaf.icons.FlatMenuItemArrowIcon
|
||||
RadioButtonMenuItem.margin=2,2,2,2
|
||||
RadioButtonMenuItem.margin=@menuItemMargin
|
||||
RadioButtonMenuItem.opaque=false
|
||||
RadioButtonMenuItem.background=@menuBackground
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
@@ -407,6 +449,12 @@ TextArea.margin=@textComponentMargin
|
||||
TextArea.background=@textComponentBackground
|
||||
|
||||
|
||||
#---- TextComponent ----
|
||||
|
||||
# allowed values: "never", "once" (default) or "always"
|
||||
TextComponent.selectAllOnFocusPolicy=once
|
||||
|
||||
|
||||
#---- TextField ----
|
||||
|
||||
TextField.border=com.formdev.flatlaf.ui.FlatBorder
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=#8C8C8C
|
||||
@textComponentBackground=#ffffff
|
||||
@menuBackground=#fff
|
||||
@cellFocusColor=#000000
|
||||
@icon=#afafaf
|
||||
|
||||
@@ -132,11 +133,39 @@ Component.focusColor=#97c3f3
|
||||
Component.linkColor=#2470B3
|
||||
|
||||
|
||||
#---- Desktop ----
|
||||
|
||||
Desktop.background=#E6EBF0
|
||||
|
||||
|
||||
#---- DesktopIcon ----
|
||||
|
||||
DesktopIcon.background=darken($Desktop.background,10%)
|
||||
|
||||
|
||||
#---- HelpButton ----
|
||||
|
||||
HelpButton.questionMarkColor=#4F9EE3
|
||||
|
||||
|
||||
#---- InternalFrame ----
|
||||
|
||||
InternalFrame.activeTitleBackground=#fff
|
||||
InternalFrame.activeTitleForeground=@foreground
|
||||
InternalFrame.inactiveTitleBackground=#fafafa
|
||||
InternalFrame.inactiveTitleForeground=@disabledText
|
||||
|
||||
InternalFrame.activeBorderColor=darken($Component.borderColor,20%)
|
||||
InternalFrame.inactiveBorderColor=$Component.borderColor
|
||||
|
||||
InternalFrame.buttonHoverBackground=darken(10%,autoInverse)
|
||||
InternalFrame.buttonPressedBackground=darken(20%,autoInverse)
|
||||
InternalFrame.closeHoverBackground=lazy(Actions.Red)
|
||||
InternalFrame.closePressedBackground=darken(Actions.Red,10%,lazy)
|
||||
InternalFrame.closeHoverForeground=#fff
|
||||
InternalFrame.closePressedForeground=#fff
|
||||
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.background=@textComponentBackground
|
||||
@@ -151,6 +180,7 @@ Menu.icon.disabledArrowColor=#ABABAB
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=#cdcdcd
|
||||
MenuBar.hoverBackground=darken($MenuBar.background,10%)
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
|
||||
Reference in New Issue
Block a user