Compare commits

...

31 Commits
0.37 ... 0.38

Author SHA1 Message Date
Karl Tauber
8a6242d9ea release 0.38 2020-07-10 15:45:35 +02:00
Karl Tauber
82294b68eb CheckBox: fixed colors in light IntelliJ themes (issue #126) 2020-07-10 15:35:02 +02:00
Karl Tauber
c232de1996 Window decorations: fixed cursor of components (issue #125) 2020-07-10 11:39:17 +02:00
Karl Tauber
dc18c8178d Theme Editor: fixed typo 2020-07-10 10:54:09 +02:00
Karl Tauber
6662714277 Theme Editor: auto-completion improved:
- reference completion shows all keys defined in current and base files
- support auto-activate for value provider
- do not auto-complete single choices
2020-07-10 10:33:10 +02:00
Karl Tauber
c404a0d1a9 Theme Editor:
- auto-activate key completion on any letter
- special completion provider for references
2020-07-08 19:15:52 +02:00
Karl Tauber
990da2b412 Theme Editor:
- auto-activate completion popup when '$' is pressed
- use keys auto-complete in value if value contains '$'
- more fine grained detection what completion provider should be used
2020-07-08 18:07:37 +02:00
Karl Tauber
1b974379c8 UIDefaultsLoader: check for endless recursion in resolveValue() 2020-07-08 17:57:40 +02:00
Karl Tauber
835faf9773 Theme Editor: auto-completion depending on caret position (none for comments, keys and values); added color functions 2020-07-08 14:29:11 +02:00
Karl Tauber
80deecb73e Theme Editor: close input streams when reading base properties files 2020-07-08 10:59:40 +02:00
Karl Tauber
64328ab9cc UIDefaultsLoader: trim value in resolveValue() to ignore spaces at the end of references/variables 2020-07-08 10:47:36 +02:00
Karl Tauber
eafad942e7 Theme Editor: added basic auto-complete for keys 2020-07-08 10:43:24 +02:00
Karl Tauber
eb5a3168b9 Theme Editor: support loading/resolving base properties 2020-07-07 21:42:10 +02:00
Karl Tauber
ac8225d8fb Theme Editor: support saving file; added inspector 2020-07-07 16:17:31 +02:00
Karl Tauber
6f71e4ada0 Theme Editor: use deferred properties loading 2020-07-07 14:21:31 +02:00
Karl Tauber
7ed90cddf8 Theme Editor: support color preview for color functions
UIDefaultsLoader: made some private methods package private and return parsed valued type
2020-07-07 14:03:39 +02:00
Karl Tauber
283ba83cef Window decorations: use derived color for RootPane.inactiveBorderColor in FlatLightLaf.properties to be consistent with FlatDarkLaf.properties 2020-07-06 15:47:44 +02:00
Karl Tauber
468c66e842 Window decorations: hide window icon if InternalFrame.icon is null or its width or height is zero 2020-07-06 14:45:52 +02:00
Karl Tauber
f22862b0a4 InternalFrame: use default icon in internal frames (issue #122) 2020-07-06 14:41:17 +02:00
Karl Tauber
9e731cb67a Tree: fixed cell editor border 2020-07-06 12:01:53 +02:00
Karl Tauber
7f911b61a2 Window decorations: no longer honor minimum size of frames on resizing window, but still do for dialogs 2020-07-06 11:30:49 +02:00
Karl Tauber
cace4a9bfd Window decorations: center title if menu bar is embedded 2020-07-05 11:01:58 +02:00
Karl Tauber
0992e97a1a README.md: added Mapton, Pseudo Assembler IDE, Sound Analysis and RemoteLight to list of projects that use FlatLaf 2020-07-04 23:47:47 +02:00
Karl Tauber
eee101f279 Merge remote-tracking branch 'uwemock/patch-1' 2020-07-04 21:46:08 +02:00
Karl Tauber
4b9f204951 Tree: fixed selection colors when used as cell renderer in another component (e.g. in Rhino JavaScript debugger) (issue #120) 2020-07-04 17:51:13 +02:00
Karl Tauber
019804407b Window decorations: hide window border if window is maximized 2020-07-01 12:11:53 +02:00
Karl Tauber
65b54ced7a Window decorations: made most fields protected for extending/subclassing 2020-07-01 10:49:18 +02:00
Karl Tauber
a308114b2f Window decorations:
- use window border color from UI defaults
- support "active" and "inactive" window border colors
- better window border colors for dark themes
2020-07-01 10:37:08 +02:00
Karl Tauber
41da023bdd hide focus indicator when the containing window became inactive 2020-07-01 00:21:22 +02:00
Karl Tauber
19fcb6a82c refactored some anonymous classes into nested classes for easier extending/subclassing 2020-06-30 17:02:48 +02:00
uwemock
221a18c119 Update README.md
Added my project that uses FlatLaf
2020-05-20 07:20:42 +02:00
40 changed files with 2139 additions and 183 deletions

View File

@@ -1,6 +1,18 @@
FlatLaf Change Log
==================
## 0.38
- Hide focus indicator when window is inactive.
- Custom window decorations: Improved/fixed window border color in dark themes.
- Custom window decorations: Hide window border if window is maximized.
- Custom window decorations: Center title if menu bar is embedded.
- Custom window decorations: Cursor of components (e.g. TextField) was not
changed. (issue #125)
- CheckBox: Fixed colors in light IntelliJ themes. (issue #126)
- InternalFrame: Use default icon in internal frames. (issue #122)
## 0.37
- Custom window decorations (Windows 10 only; PR #108; issues #47 and #82)

View File

@@ -98,8 +98,15 @@ Projects using FlatLaf
[mendelson AS2](https://mendelson-e-c.com/as2/),
[AS4](https://mendelson-e-c.com/as4/) and
[OFTP2](https://mendelson-e-c.com/oftp2) (commercial)
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.1.6
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2
- [lsfusion platform](https://github.com/lsfusion/platform)
- [Jes - Die Java-EÜR](https://www.jes-eur.de)
- [Mapton](https://mapton.org/) 2.0
([source code](https://github.com/trixon/mapton)) based on NetBeans platform
- [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE)
- [Sound Analysis](https://github.com/tomasz-herman/SoundAnalysis)
- [RemoteLight](https://github.com/Drumber/RemoteLight) - Multifunctional LED
Control Software
- and more...

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
val releaseVersion = "0.37"
val developmentVersion = "0.38-SNAPSHOT"
val releaseVersion = "0.38"
val developmentVersion = "0.39-SNAPSHOT"
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion

View File

@@ -412,6 +412,10 @@ public class IntelliJTheme
String newKey = checkboxKeyMapping.get( key );
if( newKey != null ) {
String checkBoxIconPrefix = "CheckBox.icon.";
if( !dark && newKey.startsWith( checkBoxIconPrefix ) )
newKey = "CheckBox.icon[filled].".concat( newKey.substring( checkBoxIconPrefix.length() ) );
ColorUIResource color = toColor( (String) value );
if( color != null ) {
defaults.put( newKey, color );
@@ -444,12 +448,23 @@ public class IntelliJTheme
// remove hover and pressed colors
if( checkboxModified ) {
defaults.remove( "CheckBox.icon.focusWidth" );
defaults.remove( "CheckBox.icon.hoverBorderColor" );
defaults.remove( "CheckBox.icon.focusedBackground" );
defaults.remove( "CheckBox.icon.hoverBackground" );
defaults.remove( "CheckBox.icon.pressedBackground" );
defaults.remove( "CheckBox.icon.selectedFocusedBackground" );
defaults.remove( "CheckBox.icon.selectedHoverBackground" );
defaults.remove( "CheckBox.icon.selectedPressedBackground" );
defaults.remove( "CheckBox.icon[filled].focusWidth" );
defaults.remove( "CheckBox.icon[filled].hoverBorderColor" );
defaults.remove( "CheckBox.icon[filled].focusedBackground" );
defaults.remove( "CheckBox.icon[filled].hoverBackground" );
defaults.remove( "CheckBox.icon[filled].pressedBackground" );
defaults.remove( "CheckBox.icon[filled].selectedFocusedBackground" );
defaults.remove( "CheckBox.icon[filled].selectedHoverBackground" );
defaults.remove( "CheckBox.icon[filled].selectedPressedBackground" );
}
// copy values

View File

@@ -154,8 +154,11 @@ class UIDefaultsLoader
}
}
Function<String, String> propertiesGetter = key -> {
return properties.getProperty( key );
};
Function<String, String> resolver = value -> {
return resolveValue( properties, value );
return resolveValue( value, propertiesGetter );
};
// get globals, which override all other defaults that end with same suffix
@@ -165,9 +168,10 @@ class UIDefaultsLoader
if( !key.startsWith( GLOBAL_PREFIX ) )
continue;
String value = resolveValue( properties, (String) e.getValue() );
String value = resolveValue( (String) e.getValue(), propertiesGetter );
try {
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver, addonClassLoaders ) );
globals.put( key.substring( GLOBAL_PREFIX.length() ),
parseValue( key, value, null, resolver, addonClassLoaders ) );
} catch( RuntimeException ex ) {
logParseError( Level.SEVERE, key, value, ex );
}
@@ -190,9 +194,9 @@ class UIDefaultsLoader
if( key.startsWith( VARIABLE_PREFIX ) || key.startsWith( GLOBAL_PREFIX ) )
continue;
String value = resolveValue( properties, (String) e.getValue() );
String value = resolveValue( (String) e.getValue(), propertiesGetter );
try {
defaults.put( key, parseValue( key, value, resolver, addonClassLoaders ) );
defaults.put( key, parseValue( key, value, null, resolver, addonClassLoaders ) );
} catch( RuntimeException ex ) {
logParseError( Level.SEVERE, key, value, ex );
}
@@ -206,7 +210,10 @@ class UIDefaultsLoader
FlatLaf.LOG.log( level, "FlatLaf: Failed to parse: '" + key + '=' + value + '\'', ex );
}
private static String resolveValue( Properties properties, String value ) {
static String resolveValue( String value, Function<String, String> propertiesGetter ) {
value = value.trim();
String value0 = value;
if( value.startsWith( PROPERTY_PREFIX ) )
value = value.substring( PROPERTY_PREFIX.length() );
else if( !value.startsWith( VARIABLE_PREFIX ) )
@@ -218,7 +225,7 @@ class UIDefaultsLoader
optional = true;
}
String newValue = properties.getProperty( value );
String newValue = propertiesGetter.apply( value );
if( newValue == null ) {
if( optional )
return "null";
@@ -226,29 +233,40 @@ class UIDefaultsLoader
throw new IllegalArgumentException( "variable or property '" + value + "' not found" );
}
return resolveValue( properties, newValue );
if( newValue.equals( value0 ) )
throw new IllegalArgumentException( "endless recursion in variable or property '" + value + "'" );
return resolveValue( newValue, propertiesGetter );
}
private enum ValueType { UNKNOWN, STRING, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER }
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
private static ValueType[] tempResultValueType = new ValueType[1];
static Object parseValue( String key, String value ) {
return parseValue( key, value, v -> v, Collections.emptyList() );
return parseValue( key, value, null, v -> v, Collections.emptyList() );
}
private static Object parseValue( String key, String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
static Object parseValue( String key, String value, ValueType[] resultValueType,
Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
{
if( resultValueType == null )
resultValueType = tempResultValueType;
value = value.trim();
// null, false, true
switch( value ) {
case "null": return null;
case "false": return false;
case "true": return true;
case "null": resultValueType[0] = ValueType.NULL; return null;
case "false": resultValueType[0] = ValueType.BOOLEAN; return false;
case "true": resultValueType[0] = ValueType.BOOLEAN; return true;
}
// check for function "lazy"
// Syntax: lazy(uiKey)
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
resultValueType[0] = ValueType.LAZY;
String uiKey = value.substring( 5, value.length() - 1 ).trim();
return (LazyValue) t -> {
return lazyUIManagerGet( uiKey );
@@ -301,6 +319,8 @@ class UIDefaultsLoader
valueType = ValueType.GRAYFILTER;
}
resultValueType[0] = valueType;
// parse value
switch( valueType ) {
case STRING: return value;
@@ -323,20 +343,27 @@ class UIDefaultsLoader
default:
// colors
Object color = parseColorOrFunction( value, resolver, false );
if( color != null )
if( color != null ) {
resultValueType[0] = ValueType.COLOR;
return color;
}
// integer
Integer integer = parseInteger( value, false );
if( integer != null )
if( integer != null ) {
resultValueType[0] = ValueType.INTEGER;
return integer;
}
// float
Float f = parseFloat( value, false );
if( f != null )
if( f != null ) {
resultValueType[0] = ValueType.FLOAT;
return f;
}
// string
resultValueType[0] = ValueType.STRING;
return value;
}
}

View File

@@ -202,13 +202,7 @@ public class FlatButtonUI
@Override
protected BasicButtonListener createButtonListener( AbstractButton b ) {
return new BasicButtonListener( b ) {
@Override
public void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e );
FlatButtonUI.this.propertyChange( b, e );
}
};
return new FlatButtonListener( b );
}
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
@@ -475,4 +469,23 @@ public class FlatButtonUI
return prefSize;
}
//---- class FlatButtonListener -------------------------------------------
protected class FlatButtonListener
extends BasicButtonListener
{
private final AbstractButton b;
protected FlatButtonListener( AbstractButton b ) {
super( b );
this.b = b;
}
@Override
public void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e );
FlatButtonUI.this.propertyChange( b, e );
}
}
}

View File

@@ -119,7 +119,7 @@ public class FlatComboBoxUI
protected Color buttonHoverArrowColor;
private MouseListener hoverListener;
private boolean hover;
protected boolean hover;
private WeakReference<Component> lastRendererComponent;
@@ -332,14 +332,7 @@ public class FlatComboBoxUI
@Override
protected JButton createArrowButton() {
return new FlatArrowButton( SwingConstants.SOUTH, arrowType, buttonArrowColor,
buttonDisabledArrowColor, buttonHoverArrowColor, null )
{
@Override
protected boolean isHover() {
return super.isHover() || (!comboBox.isEditable() ? hover : false);
}
};
return new FlatComboBoxButton();
}
@Override
@@ -507,6 +500,27 @@ public class FlatComboBoxUI
}
}
//---- class FlatComboBoxButton -------------------------------------------
protected class FlatComboBoxButton
extends FlatArrowButton
{
protected FlatComboBoxButton() {
this( SwingConstants.SOUTH, arrowType, buttonArrowColor, buttonDisabledArrowColor, buttonHoverArrowColor, null, null );
}
protected FlatComboBoxButton( int direction, String type, Color foreground, Color disabledForeground,
Color hoverForeground, Color hoverBackground, Color pressedBackground )
{
super( direction, type, foreground, disabledForeground, hoverForeground, hoverBackground, pressedBackground );
}
@Override
protected boolean isHover() {
return super.isHover() || (!comboBox.isEditable() ? hover : false);
}
}
//---- class FlatComboPopup -----------------------------------------------
@SuppressWarnings( { "rawtypes", "unchecked" } )

View File

@@ -26,13 +26,14 @@ import java.beans.PropertyChangeListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
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.ScaledImageIcon;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -103,14 +104,16 @@ public class FlatInternalFrameTitlePane
add( buttonPanel, BorderLayout.LINE_END );
}
private void updateFrameIcon() {
protected void updateFrameIcon() {
Icon frameIcon = frame.getFrameIcon();
if( frameIcon == UIManager.getIcon( "InternalFrame.icon" ) )
if( frameIcon != null && (frameIcon.getIconWidth() == 0 || frameIcon.getIconHeight() == 0) )
frameIcon = null;
else if( frameIcon instanceof ImageIcon )
frameIcon = new ScaledImageIcon( (ImageIcon) frameIcon );
titleLabel.setIcon( frameIcon );
}
private void updateColors() {
protected void updateColors() {
Color background = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTitleColor : notSelectedTitleColor );
Color foreground = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTextColor : notSelectedTextColor );
@@ -123,7 +126,7 @@ public class FlatInternalFrameTitlePane
closeButton.setForeground( foreground );
}
private void updateButtonsVisibility() {
protected void updateButtonsVisibility() {
iconButton.setVisible( frame.isIconifiable() );
maxButton.setVisible( frame.isMaximizable() );
closeButton.setVisible( frame.isClosable() );
@@ -150,7 +153,7 @@ public class FlatInternalFrameTitlePane
//---- class FlatPropertyChangeHandler ------------------------------------
private class FlatPropertyChangeHandler
protected class FlatPropertyChangeHandler
extends PropertyChangeHandler
{
@Override

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JComponent;
@@ -106,7 +107,11 @@ public class FlatListUI
@Override
public void focusLost( FocusEvent e ) {
super.focusLost( e );
toggleSelectionColors();
// use invokeLater for the case that the window is deactivated
EventQueue.invokeLater( () -> {
toggleSelectionColors();
} );
}
};
}

View File

@@ -20,12 +20,13 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.LayoutManager2;
import java.awt.Toolkit;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.util.function.Function;
import javax.swing.JComponent;
@@ -51,12 +52,15 @@ import com.formdev.flatlaf.util.SystemInfo;
* <!-- FlatRootPaneUI -->
*
* @uiDefault RootPane.border Border
* @uiDefault RootPane.activeBorderColor Color
* @uiDefault RootPane.inactiveBorderColor Color
*
* <!-- FlatWindowResizer -->
*
* @uiDefault RootPane.borderDragThickness int
* @uiDefault RootPane.cornerDragWidth int
* @uiDefault RootPane.honorMinimumSizeOnResize boolean
* @uiDefault RootPane.honorFrameMinimumSizeOnResize boolean
* @uiDefault RootPane.honorDialogMinimumSizeOnResize boolean
*
* @author Karl Tauber
*/
@@ -67,10 +71,11 @@ public class FlatRootPaneUI
static final boolean canUseJBRCustomDecorations
= SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER && SystemInfo.IS_WINDOWS_10_OR_LATER;
private JRootPane rootPane;
private FlatTitlePane titlePane;
protected JRootPane rootPane;
protected FlatTitlePane titlePane;
protected FlatWindowResizer windowResizer;
private LayoutManager oldLayout;
private FlatWindowResizer windowResizer;
public static ComponentUI createUI( JComponent c ) {
return new FlatRootPaneUI();
@@ -323,24 +328,45 @@ public class FlatRootPaneUI
public static class FlatWindowBorder
extends BorderUIResource.EmptyBorderUIResource
{
protected final Color activeBorderColor = UIManager.getColor( "RootPane.activeBorderColor" );
protected final Color inactiveBorderColor = UIManager.getColor( "RootPane.inactiveBorderColor" );
protected final Color baseBorderColor = UIManager.getColor( "Panel.background" );
public FlatWindowBorder() {
super( 1, 1, 1, 1 );
}
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Object borderColorObj = Toolkit.getDefaultToolkit().getDesktopProperty(
"win.frame.activeBorderColor" );
Color borderColor = (borderColorObj instanceof Color)
? (Color) borderColorObj
: UIManager.getColor( "windowBorder" );
public Insets getBorderInsets( Component c, Insets insets ) {
if( isWindowMaximized( c ) ) {
// hide border if window is maximized
insets.top = insets.left = insets.bottom = insets.right = 0;
return insets;
} else
return super.getBorderInsets( c, insets );
}
g.setColor( borderColor );
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( isWindowMaximized( c ) )
return;
Container parent = c.getParent();
boolean active = parent instanceof Window ? ((Window)parent).isActive() : false;
g.setColor( FlatUIUtils.deriveColor( active ? activeBorderColor : inactiveBorderColor, baseBorderColor ) );
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
}
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
g.drawRect( x, y, width - 1, height - 1 );
}
protected boolean isWindowMaximized( Component c ) {
Container parent = c.getParent();
return parent instanceof Frame
? (((Frame)parent).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0
: false;
}
}
}

View File

@@ -198,46 +198,12 @@ public class FlatScrollBarUI
@Override
protected JButton createDecreaseButton( int orientation ) {
return createArrowButton( orientation );
return new FlatScrollBarButton( orientation );
}
@Override
protected JButton createIncreaseButton( int orientation ) {
return createArrowButton( orientation );
}
private JButton createArrowButton( int orientation ) {
FlatArrowButton button = new FlatArrowButton( orientation, arrowType, buttonArrowColor,
buttonDisabledArrowColor, null, hoverButtonBackground, pressedButtonBackground )
{
@Override
protected Color deriveBackground( Color background ) {
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
}
@Override
public Dimension getPreferredSize() {
if( isShowButtons() ) {
int w = UIScale.scale( scrollBarWidth );
return new Dimension( w, w );
} else
return new Dimension();
}
@Override
public Dimension getMinimumSize() {
return isShowButtons() ? super.getMinimumSize() : new Dimension();
}
@Override
public Dimension getMaximumSize() {
return isShowButtons() ? super.getMaximumSize() : new Dimension();
}
};
button.setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
button.setFocusable( false );
button.setRequestFocusEnabled( false );
return button;
return new FlatScrollBarButton( orientation );
}
protected boolean isShowButtons() {
@@ -377,4 +343,49 @@ public class FlatScrollBarUI
scrollbar.repaint();
}
}
//---- class FlatScrollBarButton ------------------------------------------
protected class FlatScrollBarButton
extends FlatArrowButton
{
protected FlatScrollBarButton( int direction ) {
this( direction, arrowType, buttonArrowColor, buttonDisabledArrowColor,
null, hoverButtonBackground, pressedButtonBackground );
}
protected FlatScrollBarButton( int direction, String type, Color foreground, Color disabledForeground,
Color hoverForeground, Color hoverBackground, Color pressedBackground )
{
super( direction, type, foreground, disabledForeground, hoverForeground, hoverBackground, pressedBackground );
setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
setFocusable( false );
setRequestFocusEnabled( false );
}
@Override
protected Color deriveBackground( Color background ) {
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
}
@Override
public Dimension getPreferredSize() {
if( isShowButtons() ) {
int w = UIScale.scale( scrollBarWidth );
return new Dimension( w, w );
} else
return new Dimension();
}
@Override
public Dimension getMinimumSize() {
return isShowButtons() ? super.getMinimumSize() : new Dimension();
}
@Override
public Dimension getMaximumSize() {
return isShowButtons() ? super.getMaximumSize() : new Dimension();
}
}
}

View File

@@ -87,10 +87,10 @@ public class FlatSplitPaneUI
//---- class FlatSplitPaneDivider -----------------------------------------
private class FlatSplitPaneDivider
protected class FlatSplitPaneDivider
extends BasicSplitPaneDivider
{
public FlatSplitPaneDivider( BasicSplitPaneUI ui ) {
protected FlatSplitPaneDivider( BasicSplitPaneUI ui ) {
super( ui );
}

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JCheckBox;
@@ -174,7 +175,11 @@ public class FlatTableUI
@Override
public void focusLost( FocusEvent e ) {
super.focusLost( e );
toggleSelectionColors();
// use invokeLater for the case that the window is deactivated
EventQueue.invokeLater( () -> {
toggleSelectionColors();
} );
}
};
}

View File

@@ -55,6 +55,7 @@ import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
@@ -90,30 +91,31 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatTitlePane
extends JComponent
{
private final Color activeBackground = UIManager.getColor( "TitlePane.background" );
private final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
private final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
private final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" );
private final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
protected final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" );
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
private final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" );
private final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
private final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
protected final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" );
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
private final JRootPane rootPane;
protected final JRootPane rootPane;
private JPanel leftPanel;
private JLabel iconLabel;
private JComponent menuBarPlaceholder;
private JLabel titleLabel;
private JPanel buttonPanel;
private JButton iconifyButton;
private JButton maximizeButton;
private JButton restoreButton;
private JButton closeButton;
protected JPanel leftPanel;
protected JLabel iconLabel;
protected JComponent menuBarPlaceholder;
protected JLabel titleLabel;
protected JPanel buttonPanel;
protected JButton iconifyButton;
protected JButton maximizeButton;
protected JButton restoreButton;
protected JButton closeButton;
protected Window window;
private final Handler handler;
private Window window;
public FlatTitlePane( JRootPane rootPane ) {
this.rootPane = rootPane;
@@ -146,6 +148,10 @@ public class FlatTitlePane
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
//TODO
// titleLabel.setHorizontalAlignment( JLabel.CENTER );
// titleLabel.setHorizontalAlignment( JLabel.RIGHT );
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
leftPanel.setOpaque( false );
leftPanel.add( iconLabel );
@@ -217,14 +223,17 @@ public class FlatTitlePane
}
protected void activeChanged( boolean active ) {
boolean hasEmbeddedMenuBar = rootPane.getJMenuBar() != null && isMenuBarEmbedded();
Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground );
Color foreground = FlatUIUtils.nonUIResource( active
? (rootPane.getJMenuBar() != null && isMenuBarEmbedded() ? embeddedForeground : activeForeground)
? (hasEmbeddedMenuBar ? embeddedForeground : activeForeground)
: inactiveForeground );
setBackground( background );
titleLabel.setForeground( foreground );
titleLabel.setHorizontalAlignment( hasEmbeddedMenuBar ? SwingConstants.CENTER : SwingConstants.LEADING );
// this is necessary because hover/pressed colors are derived from background color
iconifyButton.setBackground( background );
maximizeButton.setBackground( background );
@@ -275,6 +284,8 @@ public class FlatTitlePane
else {
// no icon set on window --> use default icon
Icon defaultIcon = UIManager.getIcon( "InternalFrame.icon" );
if( defaultIcon != null && (defaultIcon.getIconWidth() == 0 || defaultIcon.getIconHeight() == 0) )
defaultIcon = null;
if( defaultIcon != null ) {
if( defaultIcon instanceof ImageIcon )
defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
@@ -385,6 +396,16 @@ public class FlatTitlePane
g.fillRect( 0, 0, getWidth(), getHeight() );
}
protected void repaintWindowBorder() {
int width = rootPane.getWidth();
int height = rootPane.getHeight();
Insets insets = rootPane.getInsets();
rootPane.repaint( 0, 0, width, insets.top ); // top
rootPane.repaint( 0, 0, insets.left, height ); // left
rootPane.repaint( 0, height - insets.bottom, width, insets.bottom ); // bottom
rootPane.repaint( width - insets.right, 0, insets.right, height ); // right
}
/**
* Iconifies the window.
*/
@@ -613,6 +634,8 @@ public class FlatTitlePane
if( hasJBRCustomDecoration() )
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder();
}
@Override
@@ -622,6 +645,8 @@ public class FlatTitlePane
if( hasJBRCustomDecoration() )
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder();
}
@Override

View File

@@ -25,6 +25,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.LookAndFeel;
@@ -75,6 +76,11 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Tree.dropCellBackground Color
* @uiDefault Tree.dropCellForeground Color
*
* <!-- DefaultTreeCellEditor -->
*
* @uiDefault Tree.editorBorder Border
* @uiDefault Tree.editorBorderSelectionColor Color
*
* <!-- FlatTreeUI -->
*
* @uiDefault Tree.border Border
@@ -226,6 +232,11 @@ public class FlatTreeUI
boolean isSelected = tree.isRowSelected( row );
boolean isDropRow = isDropRow( row );
// if tree is used as cell renderer in another component (e.g. in Rhino JavaScript debugger),
// check whether that component is focused to get correct selection colors
if( !hasFocus && isSelected && tree.getParent() instanceof CellRendererPane )
hasFocus = FlatUIUtils.isPermanentFocusOwner( tree.getParent().getParent() );
// wide selection background
if( wideSelection && (isSelected || isDropRow) ) {
// fill background

View File

@@ -38,6 +38,7 @@ import java.awt.geom.RoundRectangle2D;
import java.util.function.Consumer;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
@@ -139,8 +140,14 @@ public class FlatUIUtils
return c instanceof JComponent && Boolean.TRUE.equals( ((JComponent)c).getClientProperty( "JComboBox.isTableCellEditor" ) );
}
/**
* Returns whether the given component is the permanent focus owner and
* is in the active window. Used to paint focus indicators.
*/
public static boolean isPermanentFocusOwner( Component c ) {
return (KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner() == c);
KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
return keyboardFocusManager.getPermanentFocusOwner() == c &&
keyboardFocusManager.getActiveWindow() == SwingUtilities.windowForComponent( c );
}
public static boolean isRoundRect( Component c ) {

View File

@@ -17,8 +17,6 @@
package com.formdev.flatlaf.ui;
import static java.awt.Cursor.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
@@ -48,33 +46,43 @@ import com.formdev.flatlaf.util.UIScale;
* @author Karl Tauber
*/
public class FlatWindowResizer
extends JComponent
implements PropertyChangeListener, WindowStateListener, ComponentListener
{
private final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
protected final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
private final JRootPane rootPane;
protected final JRootPane rootPane;
private final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
private final int cornerDragWidth = FlatUIUtils.getUIInt( "RootPane.cornerDragWidth", 16 );
private final boolean honorMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorMinimumSizeOnResize" );
protected final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
protected final int cornerDragWidth = FlatUIUtils.getUIInt( "RootPane.cornerDragWidth", 16 );
protected final boolean honorFrameMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorFrameMinimumSizeOnResize" );
protected final boolean honorDialogMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorDialogMinimumSizeOnResize" );
private Window window;
protected final JComponent north;
protected final JComponent south;
protected final JComponent west;
protected final JComponent east;
protected Window window;
public FlatWindowResizer( JRootPane rootPane ) {
this.rootPane = rootPane;
setLayout( new BorderLayout() );
add( createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR ), BorderLayout.NORTH );
add( createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.SOUTH );
add( createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR ), BorderLayout.WEST );
add( createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.EAST );
north = createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR );
south = createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR );
west = createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR );
east = createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR );
JLayeredPane layeredPane = rootPane.getLayeredPane();
layeredPane.add( north, WINDOW_RESIZER_LAYER );
layeredPane.add( south, WINDOW_RESIZER_LAYER );
layeredPane.add( west, WINDOW_RESIZER_LAYER );
layeredPane.add( east, WINDOW_RESIZER_LAYER );
rootPane.addComponentListener( this );
rootPane.getLayeredPane().add( this, WINDOW_RESIZER_LAYER );
rootPane.addPropertyChangeListener( "ancestor", this );
if( rootPane.isDisplayable() )
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
addNotify();
}
protected DragBorderComponent createDragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
@@ -82,14 +90,40 @@ public class FlatWindowResizer
}
public void uninstall() {
removeNotify();
rootPane.removeComponentListener( this );
rootPane.getLayeredPane().remove( this );
rootPane.removePropertyChangeListener( "ancestor", this );
JLayeredPane layeredPane = rootPane.getLayeredPane();
layeredPane.remove( north );
layeredPane.remove( south );
layeredPane.remove( west );
layeredPane.remove( east );
}
@Override
public void addNotify() {
super.addNotify();
public void doLayout() {
if( !north.isVisible() )
return;
int x = 0;
int y = 0;
int width = rootPane.getWidth();
int height = rootPane.getHeight();
if( width == 0 || height == 0 )
return;
int thickness = UIScale.scale( borderDragThickness );
int y2 = y + thickness;
int height2 = height - (thickness * 2);
north.setBounds( x, y, width, thickness );
south.setBounds( x, y + height - thickness, width, thickness );
west.setBounds( x, y2, thickness, height2 );
east.setBounds( x + width - thickness, y2, thickness, height2 );
}
protected void addNotify() {
Container parent = rootPane.getParent();
window = (parent instanceof Window) ? (Window) parent : null;
if( window instanceof Frame ) {
@@ -100,10 +134,7 @@ public class FlatWindowResizer
updateVisibility();
}
@Override
public void removeNotify() {
super.removeNotify();
protected void removeNotify() {
if( window instanceof Frame ) {
window.removePropertyChangeListener( "resizable", this );
window.removeWindowStateListener( this );
@@ -113,25 +144,26 @@ public class FlatWindowResizer
updateVisibility();
}
@Override
protected void paintChildren( Graphics g ) {
super.paintChildren( g );
// this is necessary because Dialog.setResizable() does not fire events
if( window instanceof Dialog )
updateVisibility();
}
private void updateVisibility() {
protected void updateVisibility() {
boolean visible = isWindowResizable();
if( visible == getComponent( 0 ).isVisible() )
if( visible == north.isVisible() )
return;
for( Component c : getComponents() )
c.setVisible( visible );
north.setVisible( visible );
south.setVisible( visible );
west.setVisible( visible );
// The east component is not hidden, instead its bounds are set to 0,0,1,1 and
// it is disabled. This is necessary so that DragBorderComponent.paintComponent() is invoked.
east.setEnabled( visible );
if( visible ) {
east.setVisible( true ); // necessary because it is initially invisible
doLayout();
} else
east.setBounds( 0, 0, 1, 1 );
}
private boolean isWindowResizable() {
protected boolean isWindowResizable() {
if( window instanceof Frame )
return ((Frame)window).isResizable() && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) == 0;
if( window instanceof Dialog )
@@ -141,7 +173,18 @@ public class FlatWindowResizer
@Override
public void propertyChange( PropertyChangeEvent e ) {
updateVisibility();
switch( e.getPropertyName() ) {
case "ancestor":
if( e.getNewValue() != null )
addNotify();
else
removeNotify();
break;
case "resizable":
updateVisibility();
break;
}
}
@Override
@@ -151,8 +194,7 @@ public class FlatWindowResizer
@Override
public void componentResized( ComponentEvent e ) {
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
validate();
doLayout();
}
@Override public void componentMoved( ComponentEvent e ) {}
@@ -200,13 +242,19 @@ public class FlatWindowResizer
return new Dimension( thickness, thickness );
}
/*debug
@Override
protected void paintComponent( Graphics g ) {
super.paintChildren( g );
// this is necessary because Dialog.setResizable() does not fire events
if( window instanceof Dialog )
updateVisibility();
/*debug
g.setColor( java.awt.Color.red );
g.drawRect( 0, 0, getWidth() - 1, getHeight() - 1 );
}
debug*/
}
@Override
public void mouseClicked( MouseEvent e ) {
@@ -293,6 +341,9 @@ debug*/
newBounds.height += deltaHeight;
// apply minimum window size
boolean honorMinimumSizeOnResize =
(honorFrameMinimumSizeOnResize && window instanceof Frame) ||
(honorDialogMinimumSizeOnResize && window instanceof Dialog);
Dimension minimumSize = honorMinimumSizeOnResize ? window.getMinimumSize() : null;
if( minimumSize == null )
minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
@@ -312,8 +363,7 @@ debug*/
window.setBounds( newBounds );
// immediately layout drag border components
FlatWindowResizer.this.setBounds( 0, 0, newBounds.width, newBounds.height );
FlatWindowResizer.this.validate();
FlatWindowResizer.this.doLayout();
if( Toolkit.getDefaultToolkit().isDynamicLayoutActive() ) {
window.validate();

View File

@@ -239,6 +239,12 @@ ProgressBar.selectionBackground=@foreground
RadioButton.icon[filled].centerDiameter=5
#---- RootPane ----
RootPane.activeBorderColor=darken(@background,7%,derived)
RootPane.inactiveBorderColor=darken(@background,5%,derived)
#---- ScrollBar ----
ScrollBar.track=lighten(@background,1%,derived noAutoInverse)

View File

@@ -36,7 +36,6 @@ Button.default.borderWidth=1
#---- CheckBox ----
CheckBox.icon.style=filled
CheckBox.icon[filled].focusWidth=2
#---- Component ----

View File

@@ -292,6 +292,7 @@ List.selectionInactiveForeground=@selectionInactiveForeground
List.dropCellBackground=@dropCellBackground
List.dropCellForeground=@dropCellForeground
List.dropLineColor=@dropLineColor
List.showCellFocusIndicator=false
#---- Menu ----
@@ -430,7 +431,8 @@ RadioButtonMenuItem.background=@menuBackground
RootPane.border=com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder
RootPane.borderDragThickness=5
RootPane.cornerDragWidth=16
RootPane.honorMinimumSizeOnResize=true
RootPane.honorFrameMinimumSizeOnResize=false
RootPane.honorDialogMinimumSizeOnResize=true
#---- ScrollBar ----
@@ -659,6 +661,7 @@ ToolTipManager.enableToolTipMode=activeApplication
#---- Tree ----
Tree.border=1,1,1,1
Tree.editorBorder=1,1,1,1,@cellFocusColor
Tree.selectionInactiveBackground=@selectionInactiveBackground
Tree.selectionInactiveForeground=@selectionInactiveForeground
Tree.textBackground=$Tree.background
@@ -671,6 +674,7 @@ Tree.rendererMargins=1,2,1,2
Tree.wideSelection=true
Tree.repaintWholeRow=true
Tree.paintLines=false
Tree.showCellFocusIndicator=false
Tree.leftChildIndent=7
Tree.rightChildIndent=11
Tree.rowHeight=0

View File

@@ -251,6 +251,12 @@ ProgressBar.selectionBackground=@foreground
RadioButton.icon[filled].centerDiameter=5
#---- RootPane ----
RootPane.activeBorderColor=#707070
RootPane.inactiveBorderColor=lighten($RootPane.activeBorderColor,20%,derived)
#---- ScrollBar ----
ScrollBar.track=lighten(@background,1%,derived noAutoInverse)

View File

@@ -7,6 +7,7 @@ package com.formdev.flatlaf.testing;
import java.awt.*;
import java.beans.PropertyVetoException;
import javax.swing.*;
import com.formdev.flatlaf.extras.TriStateCheckBox;
import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -50,8 +51,10 @@ public class FlatInternalFrameTest
maximizableCheckBox.isSelected(),
iconifiableCheckBox.isSelected() );
if( iconCheckBox.isSelected() )
if( iconCheckBox.getState() == TriStateCheckBox.State.SELECTED )
internalFrame.setFrameIcon( new FlatFileViewFloppyDriveIcon() );
else if( iconCheckBox.getState() == TriStateCheckBox.State.UNSELECTED )
internalFrame.setFrameIcon( null );
if( menuBarCheckBox.isSelected() ) {
JMenuBar menuBar = new JMenuBar();
@@ -100,7 +103,7 @@ public class FlatInternalFrameTest
closableCheckBox = new JCheckBox();
iconifiableCheckBox = new JCheckBox();
maximizableCheckBox = new JCheckBox();
iconCheckBox = new JCheckBox();
iconCheckBox = new TriStateCheckBox();
menuBarCheckBox = new JCheckBox();
titleLabel = new JLabel();
titleField = new JTextField();
@@ -192,7 +195,7 @@ public class FlatInternalFrameTest
private JCheckBox closableCheckBox;
private JCheckBox iconifiableCheckBox;
private JCheckBox maximizableCheckBox;
private JCheckBox iconCheckBox;
private TriStateCheckBox iconCheckBox;
private JCheckBox menuBarCheckBox;
private JLabel titleLabel;
private JTextField titleField;

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -50,7 +50,7 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
add( new FormComponent( "com.formdev.flatlaf.extras.TriStateCheckBox" ) {
name: "iconCheckBox"
"text": "Frame icon"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {

View File

@@ -120,6 +120,9 @@ public class UIDefaultsDump
// }
// dumpIntelliJThemes( dir );
// dump UI keys
UIDefaultsKeysDump.main( new String[0] );
}
@SuppressWarnings( "unused" )

View File

@@ -0,0 +1,79 @@
/*
* 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.testing.uidefaults;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import com.formdev.flatlaf.*;
/**
* Collects all FlatLaf UI defaults keys and dumps them to a file.
*
* @author Karl Tauber
*/
public class UIDefaultsKeysDump
{
public static void main( String[] args ) {
Locale.setDefault( Locale.ENGLISH );
System.setProperty( "sun.java2d.uiScale", "1x" );
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
File keysFile = new File( "../flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt" );
HashSet<String> keys = new HashSet<>();
collectKeys( FlatLightLaf.class.getName(), keys );
collectKeys( FlatDarkLaf.class.getName(), keys );
collectKeys( FlatIntelliJLaf.class.getName(), keys );
collectKeys( FlatDarculaLaf.class.getName(), keys );
try( Writer fileWriter = new BufferedWriter( new FileWriter( keysFile ) ) ) {
String[] sortedKeys = keys.toArray( new String[keys.size()] );
Arrays.sort( sortedKeys );
for( String key : sortedKeys ) {
fileWriter.write( key );
fileWriter.write( "\n" );
}
} catch( IOException ex ) {
ex.printStackTrace();
}
}
private static void collectKeys( String lookAndFeelClassName, HashSet<String> keys ) {
try {
UIManager.setLookAndFeel( lookAndFeelClassName );
} catch( Exception ex ) {
ex.printStackTrace();
return;
}
UIDefaults defaults = UIManager.getLookAndFeel().getDefaults();
for( Object key : defaults.keySet() ) {
if( key instanceof String )
keys.add( (String) key );
}
}
}

View File

@@ -348,3 +348,5 @@ ToolTip.background=#eeeeff
Tree.background=#fff0ff
Tree.paintLines=true
Tree.hash=#ff0000
Tree.editorBorder=1,1,1,1,#f00
Tree.editorBorderSelectionColor=#00f

View File

@@ -475,6 +475,7 @@ List.selectionBackground #4b6eaf javax.swing.plaf.ColorUIResource [UI]
List.selectionForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
List.selectionInactiveBackground #0d293e javax.swing.plaf.ColorUIResource [UI]
List.selectionInactiveForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
List.showCellFocusIndicator false
List.timeFactor 1000
ListUI com.formdev.flatlaf.ui.FlatListUI
@@ -752,6 +753,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #4d5154 com.formdev.flatlaf.util.DerivedColor [UI] darken(7% autoInverse)
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -764,7 +766,9 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
RootPane.honorMinimumSizeOnResize true
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #484c4e com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
@@ -1187,7 +1191,7 @@ Tree.drawsFocusBorderAroundIcon false
Tree.dropCellBackground [lazy] #3c588b javax.swing.plaf.ColorUIResource [UI]
Tree.dropCellForeground [lazy] #bbbbbb javax.swing.plaf.ColorUIResource [UI]
Tree.dropLineColor [lazy] #6d8ac0 javax.swing.plaf.ColorUIResource [UI]
Tree.editorBorder [lazy] line: #000000 java.awt.Color 1 false 1,1,1,1 true javax.swing.plaf.BorderUIResource$LineBorderUIResource [UI]
Tree.editorBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatLineBorder [UI] lineColor=#000000 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
Tree.expandedIcon [lazy] 11,11 com.formdev.flatlaf.icons.FlatTreeExpandedIcon [UI]
Tree.font [active] $defaultFont [UI]
Tree.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
@@ -1213,6 +1217,7 @@ Tree.selectionBorderColor #000000 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveBackground #0d293e javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
Tree.showCellFocusIndicator false
Tree.textBackground #45494a javax.swing.plaf.ColorUIResource [UI]
Tree.textForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
Tree.timeFactor 1000

View File

@@ -38,8 +38,6 @@
+ CheckBox.icon.style filled
+ CheckBox.icon[filled].focusWidth 2
- CheckBox.icon[filled].selectedFocusedCheckmarkColor #e3f1fa javax.swing.plaf.ColorUIResource [UI]
- ComboBox.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRoundBorder [UI]

View File

@@ -480,6 +480,7 @@ List.selectionBackground #2675bf javax.swing.plaf.ColorUIResource [UI]
List.selectionForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
List.selectionInactiveBackground #d4d4d4 javax.swing.plaf.ColorUIResource [UI]
List.selectionInactiveForeground #000000 javax.swing.plaf.ColorUIResource [UI]
List.showCellFocusIndicator false
List.timeFactor 1000
ListUI com.formdev.flatlaf.ui.FlatListUI
@@ -757,6 +758,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #707070 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -769,7 +771,9 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
RootPane.honorMinimumSizeOnResize true
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #a3a3a3 com.formdev.flatlaf.util.DerivedColor [UI] lighten(20% autoInverse)
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
@@ -1192,7 +1196,7 @@ Tree.drawsFocusBorderAroundIcon false
Tree.dropCellBackground [lazy] #3f8fd9 javax.swing.plaf.ColorUIResource [UI]
Tree.dropCellForeground [lazy] #ffffff javax.swing.plaf.ColorUIResource [UI]
Tree.dropLineColor [lazy] #6aa7e1 javax.swing.plaf.ColorUIResource [UI]
Tree.editorBorder [lazy] line: #000000 java.awt.Color 1 false 1,1,1,1 true javax.swing.plaf.BorderUIResource$LineBorderUIResource [UI]
Tree.editorBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatLineBorder [UI] lineColor=#000000 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
Tree.expandedIcon [lazy] 11,11 com.formdev.flatlaf.icons.FlatTreeExpandedIcon [UI]
Tree.font [active] $defaultFont [UI]
Tree.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
@@ -1218,6 +1222,7 @@ Tree.selectionBorderColor #000000 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveBackground #d4d4d4 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveForeground #000000 javax.swing.plaf.ColorUIResource [UI]
Tree.showCellFocusIndicator false
Tree.textBackground #ffffff javax.swing.plaf.ColorUIResource [UI]
Tree.textForeground #000000 javax.swing.plaf.ColorUIResource [UI]
Tree.timeFactor 1000

View File

@@ -20,6 +20,8 @@ plugins {
dependencies {
implementation( project( ":flatlaf-core" ) )
implementation( project( ":flatlaf-extras" ) )
implementation( "com.fifesoft:rsyntaxtextarea:3.1.0" )
implementation( "com.fifesoft:rsyntaxtextarea:3.1.1" )
implementation( "com.fifesoft:autocomplete:3.1.0" )
}

View File

@@ -16,6 +16,10 @@
package com.formdev.flatlaf;
import java.util.Collections;
import java.util.function.Function;
import com.formdev.flatlaf.UIDefaultsLoader.ValueType;
/**
* Enable accessing package private methods of {@link UIDefaultsLoader}.
*
@@ -23,6 +27,40 @@ package com.formdev.flatlaf;
*/
public class UIDefaultsLoaderAccessor
{
public static Object UNKNOWN = ValueType.UNKNOWN;
public static Object STRING = ValueType.STRING;
public static Object BOOLEAN = ValueType.BOOLEAN;
public static Object CHARACTER = ValueType.CHARACTER;
public static Object INTEGER = ValueType.INTEGER;
public static Object FLOAT = ValueType.FLOAT;
public static Object BORDER = ValueType.BORDER;
public static Object ICON = ValueType.ICON;
public static Object INSETS = ValueType.INSETS;
public static Object DIMENSION = ValueType.DIMENSION;
public static Object COLOR = ValueType.COLOR;
public static Object SCALEDINTEGER = ValueType.SCALEDINTEGER;
public static Object SCALEDFLOAT = ValueType.SCALEDFLOAT;
public static Object SCALEDINSETS = ValueType.SCALEDINSETS;
public static Object SCALEDDIMENSION = ValueType.SCALEDDIMENSION;
public static Object INSTANCE = ValueType.INSTANCE;
public static Object CLASS = ValueType.CLASS;
public static Object GRAYFILTER = ValueType.GRAYFILTER;
public static Object NULL = ValueType.NULL;
public static Object LAZY = ValueType.LAZY;
public static String resolveValue( String value, Function<String, String> propertiesGetter ) {
return UIDefaultsLoader.resolveValue( value, propertiesGetter );
}
public static Object parseValue( String key, String value, Object[] resultValueType,
Function<String, String> resolver )
{
ValueType[] resultValueType2 = new ValueType[1];
Object result = UIDefaultsLoader.parseValue( key, value, resultValueType2, resolver, Collections.emptyList() );
resultValueType[0] = resultValueType2[0];
return result;
}
public static int parseColorRGBA( String value ) {
return UIDefaultsLoader.parseColorRGBA( value );
}

View File

@@ -0,0 +1,363 @@
/*
* 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.themeeditor;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.Completion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.CompletionProviderBase;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.autocomplete.FunctionCompletion;
import org.fife.ui.autocomplete.ParameterizedCompletion;
import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
/**
* @author Karl Tauber
*/
class FlatCompletionProvider
extends CompletionProviderBase
{
private KeyCompletionProvider keyProvider;
private ReferenceCompletionProvider referenceProvider;
private ValueCompletionProvider valueProvider;
FlatCompletionProvider() {
}
@Override
public String getAlreadyEnteredText( JTextComponent comp ) {
CompletionProvider provider = getProviderFor( comp );
return (provider != null) ? provider.getAlreadyEnteredText( comp ) : null;
}
@Override
public List<Completion> getCompletionsAt( JTextComponent comp, Point p ) {
CompletionProvider provider = getProviderFor( comp );
return (provider != null) ? provider.getCompletionsAt( comp, p ) : null;
}
@Override
public List<ParameterizedCompletion> getParameterizedCompletions( JTextComponent comp ) {
CompletionProvider provider = getProviderFor( comp );
return (provider != null) ? provider.getParameterizedCompletions( comp ) : null;
}
@Override
protected List<Completion> getCompletionsImpl( JTextComponent comp ) {
CompletionProvider provider = getProviderFor( comp );
return (provider != null) ? provider.getCompletions( comp ) : null;
}
@Override
public boolean isAutoActivateOkay( JTextComponent comp ) {
CompletionProvider provider = getProviderFor( comp );
return (provider != null) ? provider.isAutoActivateOkay( comp ) : null;
}
private CompletionProvider getProviderFor( JTextComponent comp ) {
RSyntaxTextArea rsta = (RSyntaxTextArea) comp;
try {
int caretPosition = rsta.getCaretPosition();
int currentLine = rsta.getLineOfOffset( caretPosition );
int lineStart = rsta.getLineStartOffset( currentLine );
int lineEnd = rsta.getLineEndOffset( currentLine );
if( caretPosition <= lineStart ) {
// caret is at the start of the line
String line = rsta.getText( lineStart, lineEnd - lineStart );
if( line.trim().startsWith( "#" ) )
return null;
}
String lineBeforeCaret = rsta.getText( lineStart, caretPosition - lineStart );
if( lineBeforeCaret.trim().startsWith( "#" ) )
return null;
// key
if( lineBeforeCaret.indexOf( '=' ) < 0 )
return getKeyProvider();
// value
for( int i = lineBeforeCaret.length() - 1; i >= 0; i-- ) {
switch( lineBeforeCaret.charAt( i ) ) {
case '=':
case '(':
return getValueProvider();
case '$':
case '@':
return getReferenceProvider();
case ' ':
case '\t':
case '#': // colors
return null;
}
}
return null;
} catch( BadLocationException ex ) {
// ignore
return null;
}
}
private CompletionProvider getKeyProvider() {
if( keyProvider == null )
keyProvider = KeyCompletionProvider.getInstance();
return keyProvider;
}
private CompletionProvider getReferenceProvider() {
if( referenceProvider == null )
referenceProvider = new ReferenceCompletionProvider();
return referenceProvider;
}
private CompletionProvider getValueProvider() {
if( valueProvider == null )
valueProvider = new ValueCompletionProvider();
return valueProvider;
}
//---- class KeyCompletionProvider ----------------------------------------
/**
* A completion provider for keys, which always uses all known/predefined keys.
*/
private static final class KeyCompletionProvider
extends BaseCompletionProvider
{
private static KeyCompletionProvider instance;
static KeyCompletionProvider getInstance() {
if( instance == null )
instance = new KeyCompletionProvider();
return instance;
}
KeyCompletionProvider() {
setAutoActivationRules( true, "." );
// load all keys
HashSet<String> keys = new HashSet<>();
try {
try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt" ) ) {
if( in != null ) {
try( BufferedReader reader = new BufferedReader( new InputStreamReader( in, "UTF-8" ) ) ) {
String key;
while( (key = reader.readLine()) != null ) {
keys.add( key );
}
}
}
}
} catch( IOException ex ) {
ex.printStackTrace(); // TODO
}
// collect key parts
HashSet<String> keyParts = new HashSet<>();
for( String key : keys ) {
int delimIndex = key.length() + 1;
while( (delimIndex = key.lastIndexOf( '.', delimIndex - 1 )) >= 0 ) {
String part = key.substring( 0, delimIndex );
if( !keys.contains( part ) )
keyParts.add( part );
}
}
// add key parts
addWordCompletions( keyParts.toArray( new String[keyParts.size()] ) );
// add all keys
addWordCompletions( keys.toArray( new String[keys.size()] ) );
}
@Override
protected boolean isValidChar( char ch ) {
return super.isValidChar( ch ) || ch == '.';
}
}
//---- class BaseCompletionProvider ---------------------------------------
//TODO remove if https://github.com/bobbylight/AutoComplete/issues/77 is fixed
private static class BaseCompletionProvider
extends DefaultCompletionProvider
{
private boolean autoActivateAfterLetters;
private String autoActivateChars;
@Override
public boolean isAutoActivateOkay( JTextComponent comp ) {
int caretPosition = comp.getCaretPosition();
if( caretPosition <= 0 )
return false;
try {
char ch = comp.getText( caretPosition - 1, 1 ).charAt( 0 );
return (autoActivateAfterLetters && Character.isLetter( ch )) ||
(autoActivateChars != null && autoActivateChars.indexOf( ch ) >= 0);
} catch( BadLocationException | IndexOutOfBoundsException ex ) {
// ignore
return false;
}
}
@Override
public void setAutoActivationRules( boolean letters, String others ) {
autoActivateAfterLetters = letters;
autoActivateChars = others;
}
}
//---- class ReferenceCompletionProvider ----------------------------------
/**
* A completion provider for references within values. Only keys defined
* in current properties file and in base properties files are used.
*/
private static class ReferenceCompletionProvider
extends BaseCompletionProvider
{
private Set<String> lastKeys;
ReferenceCompletionProvider() {
setAutoActivationRules( true, "$@." );
}
@Override
protected boolean isValidChar( char ch ) {
return super.isValidChar( ch ) || ch == '.' || ch == '$' || ch == '@';
}
@Override
protected List<Completion> getCompletionsImpl( JTextComponent comp ) {
updateCompletions( comp );
return super.getCompletionsImpl( comp );
}
@Override
public List<Completion> getCompletionsAt( JTextComponent comp, Point pt ) {
updateCompletions( comp );
return super.getCompletionsAt( comp, pt );
}
@Override
public List<ParameterizedCompletion> getParameterizedCompletions( JTextComponent comp ) {
updateCompletions( comp );
return super.getParameterizedCompletions( comp );
}
private void updateCompletions( JTextComponent comp ) {
FlatSyntaxTextArea fsta = (FlatSyntaxTextArea) comp;
Set<String> keys = fsta.propertiesSupport.getAllKeys();
if( keys == lastKeys )
return;
completions.clear();
for( String key : keys ) {
if( key.startsWith( "*." ) )
continue;
if( !key.startsWith( "@" ) )
key = "$".concat( key );
completions.add( new BasicCompletion( this, key ) );
}
Collections.sort(completions);
}
}
//---- class ValueCompletionProvider --------------------------------------
/**
* A completion provider for values.
*/
private static class ValueCompletionProvider
extends BaseCompletionProvider
{
ValueCompletionProvider() {
setAutoActivationRules( true, null );
setParameterizedCompletionParams( '(', ",", ')' );
addFunction( "rgb",
"red", "0-255 or 0-100%",
"green", "0-255 or 0-100%",
"blue", "0-255 or 0-100%" );
addFunction( "rgba",
"red", "0-255 or 0-100%",
"green", "0-255 or 0-100%",
"blue", "0-255 or 0-100%",
"alpha", "0-255 or 0-100%" );
addFunction( "hsl",
"hue", "0-360 representing degrees",
"saturation", "0-100%",
"lightness", "0-100%" );
addFunction( "hsla",
"hue", "0-360 representing degrees",
"saturation", "0-100%",
"lightness", "0-100%",
"alpha", "0-100%" );
String[] hslIncreaseDecreaseParams = {
"color", "a color (e.g. #f00), a reference (e.g. $Other.key) or a color function",
"amount", "0-100%",
"options", "(optional) [relative] [autoInverse] [noAutoInverse] [lazy] [derived]"
};
addFunction( "lighten", hslIncreaseDecreaseParams );
addFunction( "darken", hslIncreaseDecreaseParams );
addFunction( "saturate", hslIncreaseDecreaseParams );
addFunction( "desaturate", hslIncreaseDecreaseParams );
}
private void addFunction( String name, String... paramNamesAndDescs ) {
List<Parameter> params = new ArrayList<>();
for( int i = 0; i < paramNamesAndDescs.length; i += 2 ) {
boolean endParam = i + 2 >= paramNamesAndDescs.length;
Parameter param = new Parameter( null, paramNamesAndDescs[i], endParam );
param.setDescription( paramNamesAndDescs[i + 1] );
params.add( param );
}
FunctionCompletion f = new FunctionCompletion( this, name, null ) {
@Override
public String toString() {
return getDefinitionString().replace( "(", " (" ).replace( ",", ", " );
}
};
f.setParams( params );
addCompletion( f );
}
}
}

View File

@@ -58,7 +58,7 @@ class FlatOccurrenceMarker
// make a copy of the token because it is overwritten in getTokenListForLine()
Token t2 = new TokenImpl( t );
// check whether token occurres more than once
// check whether token occurs more than once
boolean mark = false;
for( int i = 0; i < lineCount && !mark; i++ ) {
Token temp = doc.getTokenListForLine( i );

View File

@@ -34,6 +34,7 @@ class FlatSyntaxTextArea
{
private boolean useColorOfColorTokens;
final FlatThemePropertiesSupport propertiesSupport = new FlatThemePropertiesSupport( this );
private final Map<String, Color> parsedColorsMap = new HashMap<>();
FlatSyntaxTextArea() {

View File

@@ -103,11 +103,18 @@ class FlatThemeEditorOverlay
g.setColor( color );
g.fillRect( px, r.y, pw, r.height );
// if color is semi-transparent paint also none-transparent color
int alpha = color.getAlpha();
if( alpha != 255 && pw > r.height * 2 ) {
g.setColor( new Color( color.getRGB() ) );
g.fillRect( px + pw - r.height, r.y, r.height, r.height );
}
// paint text
int textX = px - maxTextWidth;
if( textX > r.x + gap) {
float[] hsl = HSLColor.fromRGB( color );
String hslStr = String.format( "HSL %d %d %d",
String hslStr = String.format( "HSL %3d %2d %2d",
Math.round( hsl[0] ), Math.round( hsl[1] ), Math.round( hsl[2] ) );
g.setColor( textArea.getForeground() );
FlatUIUtils.drawString( textArea, g, hslStr, textX,
@@ -120,6 +127,10 @@ class FlatThemeEditorOverlay
}
private Color getColorInLine( FlatSyntaxTextArea textArea, int line ) {
Object value = textArea.propertiesSupport.getParsedValueAtLine( line );
if( value instanceof Color )
return (Color) value;
Token token = textArea.getTokenListForLine( line );
for( Token t = token; t != null && t.isPaintable(); t = t.getNextToken() ) {
if( t.getType() == FlatThemeTokenMaker.TOKEN_COLOR ) {

View File

@@ -19,10 +19,15 @@ package com.formdev.flatlaf.themeeditor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.swing.JLayer;
import javax.swing.JPanel;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
import org.fife.ui.rsyntaxtextarea.FileLocation;
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
@@ -59,8 +64,8 @@ class FlatThemeEditorPane
// textArea.setUseColorOfColorTokens( true );
// theme
try {
Theme theme = Theme.load( getClass().getResourceAsStream( "light.xml" ) );
try( InputStream in = getClass().getResourceAsStream( "light.xml" ) ) {
Theme theme = Theme.load( in );
theme.apply( textArea );
} catch( IOException ex ) {
ex.printStackTrace();
@@ -72,6 +77,16 @@ class FlatThemeEditorPane
scheme.getStyle( FlatThemeTokenMaker.TOKEN_COLOR ).background = new Color( 0x0a000000, true );
scheme.getStyle( FlatThemeTokenMaker.TOKEN_VARIABLE ).background = new Color( 0x1800cc00, true );
// autocomplete
CompletionProvider provider = new FlatCompletionProvider();
AutoCompletion ac = new AutoCompletion( provider );
ac.setAutoCompleteSingleChoices( false );
ac.setAutoActivationEnabled( true );
ac.setParameterAssistanceEnabled( true );
ac.setChoicesWindowSize( UIScale.scale( 300 ), UIScale.scale( 400 ) );
ac.setDescriptionWindowSize( UIScale.scale( 300 ), UIScale.scale( 400 ) );
ac.install( textArea );
// create overlay layer
JLayer<FlatSyntaxTextArea> overlay = new JLayer<>( textArea, new FlatThemeEditorOverlay() );
@@ -94,7 +109,19 @@ class FlatThemeEditorPane
return font.deriveFont( (float) newFontSize );
}
public void load( FileLocation loc ) throws IOException {
void setBaseFiles( List<File> baseFiles ) {
textArea.propertiesSupport.setBaseFiles( baseFiles );
}
void load( FileLocation loc ) throws IOException {
textArea.load( loc, StandardCharsets.ISO_8859_1 );
}
void save() {
try {
textArea.save();
} catch( IOException ex ) {
ex.printStackTrace(); // TODO
}
}
}

View File

@@ -16,12 +16,19 @@
package com.formdev.flatlaf.themeeditor;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import org.fife.ui.rsyntaxtextarea.FileLocation;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.extras.FlatInspector;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -37,17 +44,29 @@ public class FlatThemeFileEditor
? args[0]
: "theme-editor-test.properties" ); // TODO
List<File> baseFiles = new ArrayList<>();
for( int i = 1; i < args.length; i++ )
baseFiles.add( new File( args[i] ) );
SwingUtilities.invokeLater( () -> {
FlatLightLaf.install();
FlatInspector.install( "ctrl alt shift X" );
FlatThemeFileEditor frame = new FlatThemeFileEditor();
frame.themeEditorArea.setBaseFiles( baseFiles );
try {
frame.themeEditorArea.load( FileLocation.create( file ) );
} catch( IOException ex ) {
ex.printStackTrace();
}
int menuShortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
((JComponent)frame.getContentPane()).registerKeyboardAction(
e -> frame.themeEditorArea.save(),
KeyStroke.getKeyStroke( KeyEvent.VK_S, menuShortcutKeyMask ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize( Math.min( UIScale.scale( 800 ), screenSize.width ),
screenSize.height - UIScale.scale( 100 ) );

View File

@@ -0,0 +1,233 @@
/*
* 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.themeeditor;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
/**
* Supports parsing content of text area in FlatLaf properties syntax.
*
* @author Karl Tauber
*/
class FlatThemePropertiesSupport
implements DocumentListener
{
private final FlatSyntaxTextArea textArea;
private final Function<String, String> propertiesGetter;
private final Function<String, String> resolver;
private Properties propertiesCache;
private final Map<Integer, Object> parsedValueCache = new HashMap<>();
private File[] baseFiles;
private long[] baseFilesLastModified;
private Properties[] basePropertiesCache;
private Set<String> allKeysCache;
FlatThemePropertiesSupport( FlatSyntaxTextArea textArea ) {
this.textArea = textArea;
propertiesGetter = key -> {
return getProperty( key );
};
resolver = v -> {
return resolveValue( v );
};
textArea.getDocument().addDocumentListener( this );
}
void setBaseFiles( List<File> baseFiles ) {
int size = baseFiles.size();
this.baseFiles = baseFiles.toArray( new File[size] );
baseFilesLastModified = new long[size];
basePropertiesCache = new Properties[size];
}
private String resolveValue( String value ) {
return UIDefaultsLoaderAccessor.resolveValue( value, propertiesGetter );
}
Object getParsedValueAtLine( int line ) {
Integer lineKey = line;
Object parsedValue = parsedValueCache.get( lineKey );
if( parsedValue != null )
return !(parsedValue instanceof Exception) ? parsedValue : null;
KeyValue keyValue = getKeyValueAtLine( line );
if( keyValue == null )
return null;
try {
Object[] resultValueType = new Object[1];
String value = resolveValue( keyValue.value );
parsedValue = UIDefaultsLoaderAccessor.parseValue( keyValue.key, value, resultValueType, resolver );
parsedValueCache.put( lineKey, parsedValue );
return parsedValue;
} catch( Exception ex ) {
System.out.println( ex.getMessage() ); //TODO
parsedValueCache.put( lineKey, ex );
return null;
}
}
private KeyValue getKeyValueAtLine( int line ) {
try {
int startOffset = textArea.getLineStartOffset( line );
int endOffset = textArea.getLineEndOffset( line );
String text = textArea.getText( startOffset, endOffset - startOffset );
Properties properties = new Properties();
properties.load( new StringReader( text ) );
if( properties.isEmpty() )
return null;
String key = (String) properties.keys().nextElement();
String value = properties.getProperty( key );
return new KeyValue( key, value );
} catch( BadLocationException | IOException ex ) {
// ignore
return null;
}
}
private String getProperty( String key ) {
// look in current text area
String value = getProperties().getProperty( key );
if( value != null )
return value;
if( baseFiles == null )
return null;
// look in base properties files
for( int i = 0; i < baseFiles.length; i++ ) {
value = getBaseProperties( i ).getProperty( key );
if( value != null )
return value;
}
return null;
}
private Properties getProperties() {
if( propertiesCache != null )
return propertiesCache;
propertiesCache = new Properties();
try {
propertiesCache.load( new StringReader( textArea.getText() ) );
} catch( IOException ex ) {
ex.printStackTrace(); //TODO
}
return propertiesCache;
}
private Properties getBaseProperties( int index ) {
long lastModified = baseFiles[index].lastModified();
if( baseFilesLastModified[index] != lastModified || basePropertiesCache[index] == null ) {
// (re)load base properties file
baseFilesLastModified[index] = lastModified;
basePropertiesCache[index] = new Properties();
try( InputStream in = new FileInputStream( baseFiles[index] ) ) {
basePropertiesCache[index].load( in );
} catch( IOException ex ) {
ex.printStackTrace(); //TODO
}
}
return basePropertiesCache[index];
}
Set<String> getAllKeys() {
if( allKeysCache != null )
return allKeysCache;
allKeysCache = new HashSet<>();
for( Object key : getProperties().keySet() )
allKeysCache.add( (String) key );
for( int i = 0; i < baseFiles.length; i++ ) {
for( Object key : getBaseProperties( i ).keySet() )
allKeysCache.add( (String) key );
}
return allKeysCache;
}
private void clearCache() {
propertiesCache = null;
parsedValueCache.clear();
allKeysCache = null;
}
//---- interface DocumentListener ----
@Override
public void insertUpdate( DocumentEvent e ) {
clearCache();
}
@Override
public void removeUpdate( DocumentEvent e ) {
clearCache();
}
@Override
public void changedUpdate( DocumentEvent e ) {
}
//---- class KeyValue -----------------------------------------------------
static class CacheLineInfo {
Object parsedValue;
Object valueType;
Exception parseError;
Color origColor;
}
//---- class KeyValue -----------------------------------------------------
static class KeyValue {
final String key;
final String value;
KeyValue( String key, String value ) {
this.key = key;
this.value = value;
}
}
}

View File

@@ -0,0 +1,921 @@
Actions.Blue
Actions.Green
Actions.Grey
Actions.GreyInline
Actions.Red
Actions.Yellow
AuditoryCues.allAuditoryCues
AuditoryCues.cueList
AuditoryCues.noAuditoryCues
BusyLabelUI
Button.arc
Button.background
Button.border
Button.borderColor
Button.darkShadow
Button.default.background
Button.default.boldText
Button.default.borderColor
Button.default.borderWidth
Button.default.focusColor
Button.default.focusedBackground
Button.default.focusedBorderColor
Button.default.foreground
Button.default.hoverBackground
Button.default.hoverBorderColor
Button.default.pressedBackground
Button.defaultButtonFollowsFocus
Button.disabledBackground
Button.disabledBorderColor
Button.disabledText
Button.focusInputMap
Button.focusedBackground
Button.focusedBorderColor
Button.font
Button.foreground
Button.highlight
Button.hoverBackground
Button.hoverBorderColor
Button.iconTextGap
Button.light
Button.margin
Button.minimumWidth
Button.pressedBackground
Button.rollover
Button.shadow
Button.textIconGap
Button.textShiftOffset
Button.toolbar.hoverBackground
Button.toolbar.margin
Button.toolbar.pressedBackground
Button.toolbar.spacingInsets
ButtonUI
Caret.width
CheckBox.arc
CheckBox.background
CheckBox.border
CheckBox.disabledText
CheckBox.focusInputMap
CheckBox.font
CheckBox.foreground
CheckBox.icon
CheckBox.icon.background
CheckBox.icon.borderColor
CheckBox.icon.checkmarkColor
CheckBox.icon.disabledBackground
CheckBox.icon.disabledBorderColor
CheckBox.icon.disabledCheckmarkColor
CheckBox.icon.focusedBackground
CheckBox.icon.focusedBorderColor
CheckBox.icon.hoverBackground
CheckBox.icon.hoverBorderColor
CheckBox.icon.pressedBackground
CheckBox.icon.selectedBackground
CheckBox.icon.selectedBorderColor
CheckBox.icon.selectedFocusedBorderColor
CheckBox.icon.style
CheckBox.iconTextGap
CheckBox.icon[filled].checkmarkColor
CheckBox.icon[filled].selectedBackground
CheckBox.icon[filled].selectedBorderColor
CheckBox.icon[filled].selectedFocusedBackground
CheckBox.icon[filled].selectedFocusedBorderColor
CheckBox.icon[filled].selectedFocusedCheckmarkColor
CheckBox.icon[filled].selectedHoverBackground
CheckBox.icon[filled].selectedPressedBackground
CheckBox.margin
CheckBox.rollover
CheckBox.textIconGap
CheckBox.textShiftOffset
CheckBoxMenuItem.acceleratorFont
CheckBoxMenuItem.acceleratorForeground
CheckBoxMenuItem.acceleratorSelectionForeground
CheckBoxMenuItem.arrowIcon
CheckBoxMenuItem.background
CheckBoxMenuItem.border
CheckBoxMenuItem.borderPainted
CheckBoxMenuItem.checkIcon
CheckBoxMenuItem.disabledForeground
CheckBoxMenuItem.font
CheckBoxMenuItem.foreground
CheckBoxMenuItem.margin
CheckBoxMenuItem.opaque
CheckBoxMenuItem.selectionBackground
CheckBoxMenuItem.selectionForeground
CheckBoxMenuItemUI
CheckBoxUI
ColorChooser.background
ColorChooser.font
ColorChooser.foreground
ColorChooser.swatchesDefaultRecentColor
ColorChooser.swatchesRecentSwatchSize
ColorChooser.swatchesSwatchSize
ColorChooserUI
ComboBox.ancestorInputMap
ComboBox.background
ComboBox.border
ComboBox.buttonArrowColor
ComboBox.buttonBackground
ComboBox.buttonDarkShadow
ComboBox.buttonDisabledArrowColor
ComboBox.buttonEditableBackground
ComboBox.buttonHighlight
ComboBox.buttonHoverArrowColor
ComboBox.buttonShadow
ComboBox.buttonStyle
ComboBox.disabledBackground
ComboBox.disabledForeground
ComboBox.editorColumns
ComboBox.font
ComboBox.foreground
ComboBox.isEnterSelectablePopup
ComboBox.maximumRowCount
ComboBox.minimumWidth
ComboBox.noActionOnKeyNavigation
ComboBox.padding
ComboBox.selectionBackground
ComboBox.selectionForeground
ComboBox.timeFactor
ComboBoxUI
Component.arc
Component.arrowType
Component.borderColor
Component.custom.borderColor
Component.disabledBorderColor
Component.error.borderColor
Component.error.focusedBorderColor
Component.focusColor
Component.focusWidth
Component.focusedBorderColor
Component.grayFilter
Component.hideMnemonics
Component.innerFocusWidth
Component.innerOutlineWidth
Component.linkColor
Component.minimumWidth
Component.warning.borderColor
Component.warning.focusedBorderColor
DatePickerUI
Desktop.ancestorInputMap
Desktop.background
Desktop.minOnScreenInsets
DesktopIcon.background
DesktopIcon.border
DesktopIcon.closeIcon
DesktopIcon.closeSize
DesktopIcon.foreground
DesktopIcon.iconSize
DesktopIconUI
DesktopPaneUI
EditorPane.background
EditorPane.border
EditorPane.caretBlinkRate
EditorPane.caretForeground
EditorPane.disabledBackground
EditorPane.focusInputMap
EditorPane.font
EditorPane.foreground
EditorPane.inactiveBackground
EditorPane.inactiveForeground
EditorPane.margin
EditorPane.selectionBackground
EditorPane.selectionForeground
EditorPaneUI
FileChooser.ancestorInputMap
FileChooser.detailsViewIcon
FileChooser.homeFolderIcon
FileChooser.listViewIcon
FileChooser.newFolderIcon
FileChooser.readOnly
FileChooser.upFolderIcon
FileChooser.useSystemExtensionHiding
FileChooser.usesSingleFilePane
FileChooserUI
FileView.computerIcon
FileView.directoryIcon
FileView.fileIcon
FileView.floppyDriveIcon
FileView.hardDriveIcon
FormattedTextField.background
FormattedTextField.border
FormattedTextField.caretBlinkRate
FormattedTextField.caretForeground
FormattedTextField.disabledBackground
FormattedTextField.focusInputMap
FormattedTextField.font
FormattedTextField.foreground
FormattedTextField.inactiveBackground
FormattedTextField.inactiveForeground
FormattedTextField.margin
FormattedTextField.placeholderForeground
FormattedTextField.selectionBackground
FormattedTextField.selectionForeground
FormattedTextFieldUI
HeaderUI
HelpButton.background
HelpButton.borderColor
HelpButton.disabledBackground
HelpButton.disabledBorderColor
HelpButton.disabledQuestionMarkColor
HelpButton.focusedBackground
HelpButton.focusedBorderColor
HelpButton.hoverBackground
HelpButton.hoverBorderColor
HelpButton.icon
HelpButton.pressedBackground
HelpButton.questionMarkColor
Hyperlink.disabledText
Hyperlink.linkColor
Hyperlink.visitedColor
HyperlinkUI
InternalFrame.activeBorderColor
InternalFrame.activeDropShadowInsets
InternalFrame.activeDropShadowOpacity
InternalFrame.activeTitleBackground
InternalFrame.activeTitleForeground
InternalFrame.border
InternalFrame.borderColor
InternalFrame.borderDarkShadow
InternalFrame.borderHighlight
InternalFrame.borderLight
InternalFrame.borderLineWidth
InternalFrame.borderMargins
InternalFrame.borderShadow
InternalFrame.buttonHoverBackground
InternalFrame.buttonPressedBackground
InternalFrame.buttonSize
InternalFrame.closeHoverBackground
InternalFrame.closeHoverForeground
InternalFrame.closeIcon
InternalFrame.closePressedBackground
InternalFrame.closePressedForeground
InternalFrame.dropShadowPainted
InternalFrame.icon
InternalFrame.iconifyIcon
InternalFrame.inactiveBorderColor
InternalFrame.inactiveDropShadowInsets
InternalFrame.inactiveDropShadowOpacity
InternalFrame.inactiveTitleBackground
InternalFrame.inactiveTitleForeground
InternalFrame.maximizeIcon
InternalFrame.minimizeIcon
InternalFrame.titleFont
InternalFrameTitlePane.border
InternalFrameTitlePane.closeButtonOpacity
InternalFrameTitlePane.iconifyButtonOpacity
InternalFrameTitlePane.maximizeButtonOpacity
InternalFrameUI
JXBusyLabel.baseColor
JXBusyLabel.highlightColor
JXDatePicker.border
JXHeader.background
JXHeader.startBackground
JXMonthView.arrowColor
JXMonthView.background
JXMonthView.daysOfTheWeekForeground
JXMonthView.disabledArrowColor
JXMonthView.flaggedDayForeground
JXMonthView.leadingDayForeground
JXMonthView.monthDownFileName
JXMonthView.monthStringBackground
JXMonthView.monthStringForeground
JXMonthView.monthUpFileName
JXMonthView.selectedBackground
JXMonthView.trailingDayForeground
JXMonthView.unselectableDayForeground
JXMonthView.weekOfTheYearForeground
JXTitledPanel.borderColor
JXTitledPanel.captionInsets
JXTitledPanel.titleBackground
JXTitledPanel.titleForeground
JideTabbedPane.background
JideTabbedPane.contentBorderInsets
JideTabbedPane.foreground
JideTabbedPane.shadow
JideTabbedPane.tabAreaBackground
JideTabbedPane.tabAreaInsets
JideTabbedPane.tabInsets
JideTabbedPane.tabRunOverlay
JideTabbedPaneUI
Label.background
Label.disabledForeground
Label.disabledShadow
Label.font
Label.foreground
LabelUI
List.background
List.border
List.cellFocusColor
List.cellMargins
List.cellNoFocusBorder
List.cellRenderer
List.dropCellBackground
List.dropCellForeground
List.dropLineColor
List.focusCellHighlightBorder
List.focusInputMap
List.focusInputMap.RightToLeft
List.focusSelectedCellHighlightBorder
List.font
List.foreground
List.noFocusBorder
List.selectionBackground
List.selectionForeground
List.selectionInactiveBackground
List.selectionInactiveForeground
List.showCellFocusIndicator
List.timeFactor
ListUI
Menu.acceleratorFont
Menu.acceleratorForeground
Menu.acceleratorSelectionForeground
Menu.arrowIcon
Menu.background
Menu.border
Menu.borderPainted
Menu.cancelMode
Menu.crossMenuMnemonic
Menu.disabledForeground
Menu.font
Menu.foreground
Menu.icon.arrowColor
Menu.icon.disabledArrowColor
Menu.margin
Menu.menuPopupOffsetX
Menu.menuPopupOffsetY
Menu.opaque
Menu.preserveTopLevelSelection
Menu.selectionBackground
Menu.selectionForeground
Menu.shortcutKeys
Menu.submenuPopupOffsetX
Menu.submenuPopupOffsetY
MenuBar.background
MenuBar.border
MenuBar.borderColor
MenuBar.font
MenuBar.foreground
MenuBar.highlight
MenuBar.hoverBackground
MenuBar.itemMargins
MenuBar.shadow
MenuBar.windowBindings
MenuBarUI
MenuItem.acceleratorArrowGap
MenuItem.acceleratorDelimiter
MenuItem.acceleratorFont
MenuItem.acceleratorForeground
MenuItem.acceleratorSelectionForeground
MenuItem.arrowIcon
MenuItem.background
MenuItem.border
MenuItem.borderPainted
MenuItem.checkBackground
MenuItem.checkMargins
MenuItem.disabledForeground
MenuItem.font
MenuItem.foreground
MenuItem.iconTextGap
MenuItem.margin
MenuItem.minimumIconSize
MenuItem.minimumWidth
MenuItem.opaque
MenuItem.selectionBackground
MenuItem.selectionForeground
MenuItem.textAcceleratorGap
MenuItem.textNoAcceleratorGap
MenuItem.underlineSelectionBackground
MenuItem.underlineSelectionCheckBackground
MenuItem.underlineSelectionColor
MenuItem.underlineSelectionHeight
MenuItemCheckBox.icon.checkmarkColor
MenuItemCheckBox.icon.disabledCheckmarkColor
MenuItemUI
MenuUI
MonthViewUI
Objects.BlackText
Objects.Blue
Objects.Green
Objects.GreenAndroid
Objects.Grey
Objects.Pink
Objects.Purple
Objects.Red
Objects.RedStatus
Objects.Yellow
Objects.YellowDark
OptionPane.background
OptionPane.border
OptionPane.buttonAreaBorder
OptionPane.buttonClickThreshhold
OptionPane.buttonMinimumWidth
OptionPane.buttonOrientation
OptionPane.buttonPadding
OptionPane.errorIcon
OptionPane.font
OptionPane.foreground
OptionPane.iconMessageGap
OptionPane.informationIcon
OptionPane.maxCharactersPerLine
OptionPane.messageAreaBorder
OptionPane.messagePadding
OptionPane.minimumSize
OptionPane.questionIcon
OptionPane.sameSizeButtons
OptionPane.setButtonMargin
OptionPane.warningIcon
OptionPane.windowBindings
OptionPaneUI
Panel.background
Panel.font
Panel.foreground
PanelUI
PasswordField.background
PasswordField.border
PasswordField.capsLockIcon
PasswordField.capsLockIconColor
PasswordField.caretBlinkRate
PasswordField.caretForeground
PasswordField.disabledBackground
PasswordField.echoChar
PasswordField.focusInputMap
PasswordField.font
PasswordField.foreground
PasswordField.inactiveBackground
PasswordField.inactiveForeground
PasswordField.margin
PasswordField.placeholderForeground
PasswordField.selectionBackground
PasswordField.selectionForeground
PasswordFieldUI
Popup.dropShadowColor
Popup.dropShadowInsets
Popup.dropShadowOpacity
Popup.dropShadowPainted
PopupMenu.background
PopupMenu.border
PopupMenu.borderColor
PopupMenu.borderInsets
PopupMenu.consumeEventOnClose
PopupMenu.font
PopupMenu.foreground
PopupMenu.selectedWindowInputMapBindings
PopupMenu.selectedWindowInputMapBindings.RightToLeft
PopupMenuSeparator.height
PopupMenuSeparator.stripeIndent
PopupMenuSeparator.stripeWidth
PopupMenuSeparatorUI
PopupMenuUI
ProgressBar.arc
ProgressBar.background
ProgressBar.border
ProgressBar.cellLength
ProgressBar.cellSpacing
ProgressBar.cycleTime
ProgressBar.font
ProgressBar.foreground
ProgressBar.horizontalSize
ProgressBar.repaintInterval
ProgressBar.selectionBackground
ProgressBar.selectionForeground
ProgressBar.verticalSize
ProgressBarUI
RadioButton.background
RadioButton.border
RadioButton.darkShadow
RadioButton.disabledText
RadioButton.focusInputMap
RadioButton.font
RadioButton.foreground
RadioButton.highlight
RadioButton.icon
RadioButton.icon.centerDiameter
RadioButton.iconTextGap
RadioButton.icon[filled].centerDiameter
RadioButton.light
RadioButton.margin
RadioButton.rollover
RadioButton.shadow
RadioButton.textIconGap
RadioButton.textShiftOffset
RadioButtonMenuItem.acceleratorFont
RadioButtonMenuItem.acceleratorForeground
RadioButtonMenuItem.acceleratorSelectionForeground
RadioButtonMenuItem.arrowIcon
RadioButtonMenuItem.background
RadioButtonMenuItem.border
RadioButtonMenuItem.borderPainted
RadioButtonMenuItem.checkIcon
RadioButtonMenuItem.disabledForeground
RadioButtonMenuItem.font
RadioButtonMenuItem.foreground
RadioButtonMenuItem.margin
RadioButtonMenuItem.opaque
RadioButtonMenuItem.selectionBackground
RadioButtonMenuItem.selectionForeground
RadioButtonMenuItemUI
RadioButtonUI
Resizable.resizeBorder
RootPane.activeBorderColor
RootPane.ancestorInputMap
RootPane.border
RootPane.borderDragThickness
RootPane.cornerDragWidth
RootPane.defaultButtonWindowKeyBindings
RootPane.honorDialogMinimumSizeOnResize
RootPane.honorFrameMinimumSizeOnResize
RootPane.inactiveBorderColor
RootPaneUI
ScrollBar.allowsAbsolutePositioning
ScrollBar.ancestorInputMap
ScrollBar.ancestorInputMap.RightToLeft
ScrollBar.background
ScrollBar.buttonArrowColor
ScrollBar.buttonDisabledArrowColor
ScrollBar.foreground
ScrollBar.hoverButtonBackground
ScrollBar.hoverThumbColor
ScrollBar.hoverThumbWithTrack
ScrollBar.hoverTrackColor
ScrollBar.maximumThumbSize
ScrollBar.minimumThumbSize
ScrollBar.pressedButtonBackground
ScrollBar.pressedThumbColor
ScrollBar.pressedThumbWithTrack
ScrollBar.showButtons
ScrollBar.squareButtons
ScrollBar.thumb
ScrollBar.thumbArc
ScrollBar.thumbDarkShadow
ScrollBar.thumbHighlight
ScrollBar.thumbInsets
ScrollBar.thumbShadow
ScrollBar.track
ScrollBar.trackArc
ScrollBar.trackHighlight
ScrollBar.trackInsets
ScrollBar.width
ScrollBarUI
ScrollPane.ancestorInputMap
ScrollPane.ancestorInputMap.RightToLeft
ScrollPane.background
ScrollPane.border
ScrollPane.fillUpperCorner
ScrollPane.font
ScrollPane.foreground
ScrollPane.smoothScrolling
ScrollPaneUI
Separator.background
Separator.foreground
Separator.height
Separator.highlight
Separator.shadow
Separator.stripeIndent
Separator.stripeWidth
SeparatorUI
Slider.background
Slider.disabledForeground
Slider.focus
Slider.focusInputMap
Slider.focusInputMap.RightToLeft
Slider.focusInsets
Slider.font
Slider.foreground
Slider.highlight
Slider.horizontalSize
Slider.hoverColor
Slider.minimumHorizontalSize
Slider.minimumVerticalSize
Slider.onlyLeftMouseButtonDrag
Slider.shadow
Slider.thumbColor
Slider.thumbWidth
Slider.tickColor
Slider.trackColor
Slider.trackWidth
Slider.verticalSize
SliderUI
Spinner.ancestorInputMap
Spinner.arrowButtonSize
Spinner.background
Spinner.border
Spinner.buttonArrowColor
Spinner.buttonBackground
Spinner.buttonDisabledArrowColor
Spinner.buttonHoverArrowColor
Spinner.buttonStyle
Spinner.disabledBackground
Spinner.disabledForeground
Spinner.editorAlignment
Spinner.editorBorderPainted
Spinner.font
Spinner.foreground
Spinner.padding
SpinnerUI
SplitPane.ancestorInputMap
SplitPane.background
SplitPane.centerOneTouchButtons
SplitPane.continuousLayout
SplitPane.darkShadow
SplitPane.dividerSize
SplitPane.highlight
SplitPane.oneTouchButtonOffset
SplitPane.oneTouchButtonSize
SplitPane.shadow
SplitPaneDivider.draggingColor
SplitPaneDivider.oneTouchArrowColor
SplitPaneDivider.oneTouchHoverArrowColor
SplitPaneUI
TabbedPane.ancestorInputMap
TabbedPane.background
TabbedPane.contentAreaColor
TabbedPane.contentOpaque
TabbedPane.contentSeparatorHeight
TabbedPane.darkShadow
TabbedPane.disabledForeground
TabbedPane.disabledUnderlineColor
TabbedPane.focus
TabbedPane.focusColor
TabbedPane.focusInputMap
TabbedPane.font
TabbedPane.foreground
TabbedPane.hasFullBorder
TabbedPane.highlight
TabbedPane.hoverColor
TabbedPane.labelShift
TabbedPane.light
TabbedPane.selectedLabelShift
TabbedPane.selectedTabPadInsets
TabbedPane.selectionFollowsFocus
TabbedPane.shadow
TabbedPane.tabAreaInsets
TabbedPane.tabHeight
TabbedPane.tabInsets
TabbedPane.tabRunOverlay
TabbedPane.tabSelectionHeight
TabbedPane.tabsOpaque
TabbedPane.tabsOverlapBorder
TabbedPane.textIconGap
TabbedPane.underlineColor
TabbedPaneUI
Table.ancestorInputMap
Table.ancestorInputMap.RightToLeft
Table.ascendingSortIcon
Table.background
Table.cellFocusColor
Table.cellMargins
Table.cellNoFocusBorder
Table.descendingSortIcon
Table.dropCellBackground
Table.dropCellForeground
Table.dropLineColor
Table.dropLineShortColor
Table.focusCellBackground
Table.focusCellForeground
Table.focusCellHighlightBorder
Table.focusSelectedCellHighlightBorder
Table.font
Table.foreground
Table.gridColor
Table.intercellSpacing
Table.rowHeight
Table.scrollPaneBorder
Table.selectionBackground
Table.selectionForeground
Table.selectionInactiveBackground
Table.selectionInactiveForeground
Table.showHorizontalLines
Table.showVerticalLines
Table.sortIconColor
TableHeader.ancestorInputMap
TableHeader.background
TableHeader.bottomSeparatorColor
TableHeader.cellBorder
TableHeader.focusCellBackground
TableHeader.font
TableHeader.foreground
TableHeader.height
TableHeader.separatorColor
TableHeaderUI
TableUI
TaskPane.background
TaskPane.borderColor
TaskPane.contentInsets
TaskPane.specialTitleBackground
TaskPane.specialTitleForeground
TaskPane.specialTitleOver
TaskPane.titleBackgroundGradientStart
TaskPane.titleForeground
TaskPane.titleOver
TaskPaneContainer.background
TaskPaneContainer.border
TextArea.background
TextArea.border
TextArea.caretBlinkRate
TextArea.caretForeground
TextArea.disabledBackground
TextArea.focusInputMap
TextArea.font
TextArea.foreground
TextArea.inactiveBackground
TextArea.inactiveForeground
TextArea.margin
TextArea.selectionBackground
TextArea.selectionForeground
TextAreaUI
TextComponent.arc
TextComponent.selectAllOnFocusPolicy
TextField.background
TextField.border
TextField.caretBlinkRate
TextField.caretForeground
TextField.darkShadow
TextField.disabledBackground
TextField.focusInputMap
TextField.font
TextField.foreground
TextField.highlight
TextField.inactiveBackground
TextField.inactiveForeground
TextField.light
TextField.margin
TextField.placeholderForeground
TextField.selectionBackground
TextField.selectionForeground
TextField.shadow
TextFieldUI
TextPane.background
TextPane.border
TextPane.caretBlinkRate
TextPane.caretForeground
TextPane.disabledBackground
TextPane.focusInputMap
TextPane.font
TextPane.foreground
TextPane.inactiveBackground
TextPane.inactiveForeground
TextPane.margin
TextPane.selectionBackground
TextPane.selectionForeground
TextPaneUI
TitlePane.background
TitlePane.buttonHoverBackground
TitlePane.buttonMaximizedHeight
TitlePane.buttonPressedBackground
TitlePane.buttonSize
TitlePane.closeHoverBackground
TitlePane.closeHoverForeground
TitlePane.closeIcon
TitlePane.closePressedBackground
TitlePane.closePressedForeground
TitlePane.embeddedForeground
TitlePane.foreground
TitlePane.iconMargins
TitlePane.iconSize
TitlePane.iconifyIcon
TitlePane.inactiveBackground
TitlePane.inactiveForeground
TitlePane.maximizeIcon
TitlePane.menuBarEmbedded
TitlePane.menuBarMargins
TitlePane.restoreIcon
TitlePane.titleMargins
TitledBorder.border
TitledBorder.font
TitledBorder.titleColor
TitledPanelUI
ToggleButton.background
ToggleButton.border
ToggleButton.darkShadow
ToggleButton.disabledBackground
ToggleButton.disabledSelectedBackground
ToggleButton.disabledText
ToggleButton.focusInputMap
ToggleButton.font
ToggleButton.foreground
ToggleButton.highlight
ToggleButton.iconTextGap
ToggleButton.light
ToggleButton.margin
ToggleButton.pressedBackground
ToggleButton.rollover
ToggleButton.selectedBackground
ToggleButton.selectedForeground
ToggleButton.shadow
ToggleButton.tab.disabledUnderlineColor
ToggleButton.tab.focusBackground
ToggleButton.tab.hoverBackground
ToggleButton.tab.underlineColor
ToggleButton.tab.underlineHeight
ToggleButton.textIconGap
ToggleButton.textShiftOffset
ToggleButton.toolbar.hoverBackground
ToggleButton.toolbar.pressedBackground
ToggleButton.toolbar.selectedBackground
ToggleButtonUI
ToolBar.ancestorInputMap
ToolBar.background
ToolBar.border
ToolBar.borderMargins
ToolBar.darkShadow
ToolBar.dockingBackground
ToolBar.dockingForeground
ToolBar.floatingBackground
ToolBar.floatingForeground
ToolBar.font
ToolBar.foreground
ToolBar.gripColor
ToolBar.highlight
ToolBar.isRollover
ToolBar.light
ToolBar.separatorColor
ToolBar.separatorWidth
ToolBar.shadow
ToolBar.spacingBorder
ToolBarSeparatorUI
ToolBarUI
ToolTip.background
ToolTip.border
ToolTip.font
ToolTip.foreground
ToolTipManager.enableToolTipMode
ToolTipUI
Tree.ancestorInputMap
Tree.background
Tree.border
Tree.changeSelectionWithFocus
Tree.closedIcon
Tree.collapsedIcon
Tree.drawsFocusBorderAroundIcon
Tree.dropCellBackground
Tree.dropCellForeground
Tree.dropLineColor
Tree.editorBorder
Tree.expandedIcon
Tree.focusInputMap
Tree.focusInputMap.RightToLeft
Tree.font
Tree.foreground
Tree.hash
Tree.icon.closedColor
Tree.icon.collapsedColor
Tree.icon.expandedColor
Tree.icon.leafColor
Tree.icon.openColor
Tree.leafIcon
Tree.leftChildIndent
Tree.lineTypeDashed
Tree.openIcon
Tree.paintLines
Tree.rendererFillBackground
Tree.rendererMargins
Tree.repaintWholeRow
Tree.rightChildIndent
Tree.rowHeight
Tree.scrollsOnExpand
Tree.selectionBackground
Tree.selectionBorderColor
Tree.selectionForeground
Tree.selectionInactiveBackground
Tree.selectionInactiveForeground
Tree.showCellFocusIndicator
Tree.textBackground
Tree.textForeground
Tree.timeFactor
Tree.wideSelection
TreeUI
Viewport.background
Viewport.font
Viewport.foreground
ViewportUI
activeCaption
activeCaptionBorder
activeCaptionText
control
controlDkShadow
controlHighlight
controlLtHighlight
controlShadow
controlText
defaultFont
desktop
html.missingImage
html.pendingImage
inactiveCaption
inactiveCaptionBorder
inactiveCaptionText
info
infoText
laf.scaleFactor
menu
menuText
scrollbar
swingx/TaskPaneUI
text
textHighlight
textHighlightText
textInactiveText
textText
window
windowBorder
windowText

View File

@@ -33,8 +33,8 @@ Prop.lazy=lazy(Prop.string)
Prop.colorFunc1=rgb(12,34,56)
Prop.colorFunc2=rgba(12,34,56,78)
Prop.colorFunc3=hsl(12,34,56)
Prop.colorFunc4=hsla(12,34,56,78)
Prop.colorFunc3=hsl(12,34%,56%)
Prop.colorFunc4=hsla(12,34%,56%,78%)
Prop.colorFunc5=lighten(#fe1289,20%)
Prop.colorFunc6=darken(#fe1289,20%)