mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-08 06:50:56 +03:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69851b7f3a | ||
|
|
92b53bf0df | ||
|
|
93e0496fd2 | ||
|
|
5151951f46 | ||
|
|
58dbccec2d | ||
|
|
90de14d013 | ||
|
|
5f961618bf | ||
|
|
37c375e2fa | ||
|
|
1758c175ed | ||
|
|
96f2a02cfa | ||
|
|
96d4bda6c8 | ||
|
|
02cf6050a1 | ||
|
|
38cf32a2e9 | ||
|
|
2ae7589d14 | ||
|
|
bcb2e1f0a1 | ||
|
|
14932d3f07 | ||
|
|
c3b9dc397d | ||
|
|
58b653f55d | ||
|
|
1dcdc42dde | ||
|
|
58a0a16985 | ||
|
|
a117243f14 | ||
|
|
22411060be | ||
|
|
045263ae58 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,6 +1,28 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 2.3
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
- FileChooser: Added (optional) shortcuts panel. On Windows it contains "Recent
|
||||
Items", "Desktop", "Documents", "This PC" and "Network". On macOS and Linux it
|
||||
is empty/hidden. (issue #100)
|
||||
- Button and ToggleButton: Added missing foreground colors for hover, pressed,
|
||||
focused and selected states. (issue #535)
|
||||
- Table: Optionally paint alternating rows below table if table is smaller than
|
||||
scroll pane. Set UI value `Table.paintOutsideAlternateRows` to `true`.
|
||||
Requires that `Table.alternateRowColor` is set to a color. (issue #504)
|
||||
- ToggleButton: Made the underline placement of tab-style toggle buttons
|
||||
configurable. (PR #530; issue #529)
|
||||
- Added spanish translation. (PR #525)
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- IntelliJ Themes: Fixed `TitledBorder` text color in "Monokai Pro" theme.
|
||||
(issue #524)
|
||||
|
||||
|
||||
## 2.2
|
||||
|
||||
#### New features and improvements
|
||||
@@ -141,7 +163,7 @@ FlatLaf Change Log
|
||||
- Possibility to hide window title bar icon (for single window set client
|
||||
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
|
||||
value `TitlePane.showIcon` to `false`).
|
||||
- OptionPane: Hide window title bar icon by default. Can be be made visibly by
|
||||
- OptionPane: Hide window title bar icon by default. Can be made visibly by
|
||||
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
||||
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
||||
(issue #416)
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
val releaseVersion = "2.2"
|
||||
val developmentVersion = "2.3-SNAPSHOT"
|
||||
val releaseVersion = "2.3"
|
||||
val developmentVersion = "2.4-SNAPSHOT"
|
||||
|
||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Signature file v4.1
|
||||
#Version 2.1
|
||||
#Version 2.2
|
||||
|
||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
||||
@@ -30,6 +30,9 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY = "JTextFiel
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"
|
||||
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
|
||||
fld public final static java.lang.String STYLE = "FlatLaf.style"
|
||||
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
|
||||
|
||||
@@ -992,7 +992,22 @@ public interface FlatClientProperties
|
||||
//---- JToggleButton ------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Height of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
||||
* Placement of underline if toggle button type is {@link #BUTTON_TYPE_TAB}
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||
* <strong>SupportedValues:</strong>
|
||||
* {@link SwingConstants#BOTTOM} (default)
|
||||
* {@link SwingConstants#TOP},
|
||||
* {@link SwingConstants#LEFT} or
|
||||
* {@link SwingConstants#RIGHT}
|
||||
*
|
||||
* @since 2.3
|
||||
*/
|
||||
String TAB_BUTTON_UNDERLINE_PLACEMENT = "JToggleButton.tab.underlinePlacement";
|
||||
|
||||
/**
|
||||
* Thickness of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Integer}
|
||||
|
||||
@@ -466,6 +466,10 @@ class UIDefaultsLoader
|
||||
if( knownValueTypes == null ) {
|
||||
// create lazy
|
||||
knownValueTypes = new HashMap<>();
|
||||
// system colors
|
||||
knownValueTypes.put( "activeCaptionBorder", ValueType.COLOR );
|
||||
knownValueTypes.put( "inactiveCaptionBorder", ValueType.COLOR );
|
||||
knownValueTypes.put( "windowBorder", ValueType.COLOR );
|
||||
// SplitPane
|
||||
knownValueTypes.put( "SplitPane.dividerSize", ValueType.INTEGER );
|
||||
knownValueTypes.put( "SplitPaneDivider.gripDotSize", ValueType.INTEGER );
|
||||
@@ -780,6 +784,7 @@ class UIDefaultsLoader
|
||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
||||
case "over": return parseColorOver( params, resolver, reportError );
|
||||
}
|
||||
} finally {
|
||||
parseColorDepth--;
|
||||
@@ -847,7 +852,7 @@ class UIDefaultsLoader
|
||||
int lightness = parsePercentage( params.get( 2 ) );
|
||||
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
||||
|
||||
float[] hsl = new float[] { hue, saturation, lightness };
|
||||
float[] hsl = { hue, saturation, lightness };
|
||||
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
||||
}
|
||||
|
||||
@@ -1041,6 +1046,33 @@ class UIDefaultsLoader
|
||||
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: over(foreground,background)
|
||||
* - foreground: a foreground color (e.g. #f00) or a color function;
|
||||
* the alpha of this color is used as weight to mix the two colors
|
||||
* - background: a background color (e.g. #f00) or a color function
|
||||
*/
|
||||
private static Object parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||
String foregroundStr = params.get( 0 );
|
||||
String backgroundStr = params.get( 1 );
|
||||
|
||||
// parse foreground color
|
||||
ColorUIResource foreground = (ColorUIResource) parseColorOrFunction( resolver.apply( foregroundStr ), resolver, reportError );
|
||||
if( foreground == null || foreground.getAlpha() == 255 )
|
||||
return foreground;
|
||||
|
||||
Color foreground2 = new Color( foreground.getRGB() );
|
||||
|
||||
// parse background color
|
||||
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
||||
if( background == null )
|
||||
return foreground2;
|
||||
|
||||
// create new color
|
||||
float weight = foreground.getAlpha() / 255f;
|
||||
return new ColorUIResource( ColorFunctions.mix( foreground2, background, weight ) );
|
||||
}
|
||||
|
||||
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
||||
boolean derived, Function<String, String> resolver, boolean reportError )
|
||||
{
|
||||
|
||||
@@ -78,20 +78,27 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
||||
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.focusedBackground Color optional
|
||||
* @uiDefault Button.focusedForeground Color optional
|
||||
* @uiDefault Button.hoverBackground Color optional
|
||||
* @uiDefault Button.hoverForeground Color optional
|
||||
* @uiDefault Button.pressedBackground Color optional
|
||||
* @uiDefault Button.pressedForeground Color optional
|
||||
* @uiDefault Button.selectedBackground Color
|
||||
* @uiDefault Button.selectedForeground Color
|
||||
* @uiDefault Button.disabledBackground Color optional
|
||||
* @uiDefault Button.disabledText Color
|
||||
* @uiDefault Button.disabledSelectedBackground Color
|
||||
* @uiDefault Button.disabledSelectedForeground Color optional
|
||||
* @uiDefault Button.default.background Color
|
||||
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
||||
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.default.foreground Color
|
||||
* @uiDefault Button.default.focusedBackground Color optional
|
||||
* @uiDefault Button.default.focusedForeground Color optional
|
||||
* @uiDefault Button.default.hoverBackground Color optional
|
||||
* @uiDefault Button.default.hoverForeground Color optional
|
||||
* @uiDefault Button.default.pressedBackground Color optional
|
||||
* @uiDefault Button.default.pressedForeground Color optional
|
||||
* @uiDefault Button.default.boldText boolean
|
||||
* @uiDefault Button.paintShadow boolean default is false
|
||||
* @uiDefault Button.shadowWidth int default is 2
|
||||
@@ -99,8 +106,13 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Button.default.shadowColor Color optional
|
||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||
* @uiDefault Button.toolbar.hoverBackground Color
|
||||
* @uiDefault Button.toolbar.hoverForeground Color optional
|
||||
* @uiDefault Button.toolbar.pressedBackground Color
|
||||
* @uiDefault Button.toolbar.pressedForeground Color optional
|
||||
* @uiDefault Button.toolbar.selectedBackground Color
|
||||
* @uiDefault Button.toolbar.selectedForeground Color optional
|
||||
* @uiDefault Button.toolbar.disabledSelectedBackground Color optional
|
||||
* @uiDefault Button.toolbar.disabledSelectedForeground Color optional
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -117,20 +129,27 @@ public class FlatButtonUI
|
||||
protected Color startBackground;
|
||||
protected Color endBackground;
|
||||
@Styleable protected Color focusedBackground;
|
||||
/** @since 2.3 */ @Styleable protected Color focusedForeground;
|
||||
@Styleable protected Color hoverBackground;
|
||||
/** @since 2.3 */ @Styleable protected Color hoverForeground;
|
||||
@Styleable protected Color pressedBackground;
|
||||
/** @since 2.3 */ @Styleable protected Color pressedForeground;
|
||||
@Styleable protected Color selectedBackground;
|
||||
@Styleable protected Color selectedForeground;
|
||||
@Styleable protected Color disabledBackground;
|
||||
@Styleable protected Color disabledText;
|
||||
@Styleable protected Color disabledSelectedBackground;
|
||||
/** @since 2.3 */ @Styleable protected Color disabledSelectedForeground;
|
||||
|
||||
@Styleable(dot=true) protected Color defaultBackground;
|
||||
protected Color defaultEndBackground;
|
||||
@Styleable(dot=true) protected Color defaultForeground;
|
||||
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultFocusedForeground;
|
||||
@Styleable(dot=true) protected Color defaultHoverBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultHoverForeground;
|
||||
@Styleable(dot=true) protected Color defaultPressedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultPressedForeground;
|
||||
@Styleable(dot=true) protected boolean defaultBoldText;
|
||||
|
||||
@Styleable protected boolean paintShadow;
|
||||
@@ -139,8 +158,13 @@ public class FlatButtonUI
|
||||
@Styleable(dot=true) protected Color defaultShadowColor;
|
||||
|
||||
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarHoverForeground;
|
||||
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarPressedForeground;
|
||||
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarSelectedForeground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedForeground;
|
||||
|
||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||
/** @since 2 */ @Styleable protected String buttonType;
|
||||
@@ -190,20 +214,27 @@ public class FlatButtonUI
|
||||
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||
focusedForeground = UIManager.getColor( prefix + "focusedForeground" );
|
||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||
hoverForeground = UIManager.getColor( prefix + "hoverForeground" );
|
||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||
pressedForeground = UIManager.getColor( prefix + "pressedForeground" );
|
||||
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
||||
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
||||
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
||||
disabledSelectedForeground = UIManager.getColor( prefix + "disabledSelectedForeground" );
|
||||
|
||||
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||
defaultFocusedForeground = UIManager.getColor( "Button.default.focusedForeground" );
|
||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||
defaultHoverForeground = UIManager.getColor( "Button.default.hoverForeground" );
|
||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||
defaultPressedForeground = UIManager.getColor( "Button.default.pressedForeground" );
|
||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
||||
|
||||
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
||||
@@ -212,8 +243,13 @@ public class FlatButtonUI
|
||||
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||
|
||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||
toolbarHoverForeground = UIManager.getColor( prefix + "toolbar.hoverForeground" );
|
||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||
toolbarPressedForeground = UIManager.getColor( prefix + "toolbar.pressedForeground" );
|
||||
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||
toolbarSelectedForeground = UIManager.getColor( prefix + "toolbar.selectedForeground" );
|
||||
toolbarDisabledSelectedBackground = UIManager.getColor( prefix + "toolbar.disabledSelectedBackground" );
|
||||
toolbarDisabledSelectedForeground = UIManager.getColor( prefix + "toolbar.disabledSelectedForeground" );
|
||||
|
||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
||||
@@ -532,6 +568,8 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||
if(foreground == null)
|
||||
foreground=Color.red;
|
||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||
|
||||
@@ -545,11 +583,14 @@ public class FlatButtonUI
|
||||
|
||||
// selected state
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
// in toolbar use same background colors for disabled and enabled because
|
||||
// in toolbar, if toolbarDisabledSelectedBackground is null,
|
||||
// use same background colors for disabled and enabled because
|
||||
// we assume that toolbar icon is shown disabled
|
||||
return buttonStateColor( c,
|
||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
||||
toolBarButton
|
||||
? (toolbarDisabledSelectedBackground != null ? toolbarDisabledSelectedBackground : toolbarSelectedBackground)
|
||||
: disabledSelectedBackground,
|
||||
null,
|
||||
null,
|
||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||
@@ -614,18 +655,48 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
protected Color getForeground( JComponent c ) {
|
||||
if( !c.isEnabled() )
|
||||
return disabledText;
|
||||
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||
|
||||
if( ((AbstractButton)c).isSelected() && !(isToolBarButton( c ) || isBorderlessButton( c )) )
|
||||
return selectedForeground;
|
||||
// selected state
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
return buttonStateColor( c,
|
||||
toolBarButton
|
||||
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : c.getForeground())
|
||||
: selectedForeground,
|
||||
toolBarButton
|
||||
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
||||
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
||||
null,
|
||||
null,
|
||||
toolBarButton ? toolbarPressedForeground : pressedForeground );
|
||||
}
|
||||
|
||||
// toolbar button
|
||||
if( toolBarButton ) {
|
||||
return buttonStateColor( c,
|
||||
c.getForeground(),
|
||||
disabledText,
|
||||
null,
|
||||
toolbarHoverForeground,
|
||||
toolbarPressedForeground );
|
||||
}
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return buttonStateColor( c,
|
||||
getForegroundBase( c, def ),
|
||||
disabledText,
|
||||
isCustomForeground( c.getForeground() ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
||||
def ? defaultHoverForeground : hoverForeground,
|
||||
def ? defaultPressedForeground : pressedForeground );
|
||||
}
|
||||
|
||||
/** @since 2.3 */
|
||||
protected Color getForegroundBase( JComponent c, boolean def ) {
|
||||
// use component foreground if explicitly set
|
||||
Color fg = c.getForeground();
|
||||
if( isCustomForeground( fg ) )
|
||||
return fg;
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return def ? defaultForeground : fg;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,21 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.RenderingHints;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
@@ -34,12 +44,16 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import javax.swing.filechooser.FileView;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
@@ -133,12 +147,21 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault FileChooser.listViewActionLabelText String
|
||||
* @uiDefault FileChooser.detailsViewActionLabelText String
|
||||
*
|
||||
* <!-- FlatFileChooserUI -->
|
||||
*
|
||||
* @uiDefault FileChooser.shortcuts.buttonSize Dimension optional; default is 84,64
|
||||
* @uiDefault FileChooser.shortcuts.iconSize Dimension optional; default is 32,32
|
||||
* @uiDefault FileChooser.shortcuts.filesFunction Function<File[], File[]>
|
||||
* @uiDefault FileChooser.shortcuts.displayNameFunction Function<File, String>
|
||||
* @uiDefault FileChooser.shortcuts.iconFunction Function<File, Icon>
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatFileChooserUI
|
||||
extends MetalFileChooserUI
|
||||
{
|
||||
private final FlatFileView fileView = new FlatFileView();
|
||||
private FlatShortcutsPanel shortcutsPanel;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatFileChooserUI( (JFileChooser) c );
|
||||
@@ -153,6 +176,25 @@ public class FlatFileChooserUI
|
||||
super.installComponents( fc );
|
||||
|
||||
patchUI( fc );
|
||||
|
||||
if( !UIManager.getBoolean( "FileChooser.noPlacesBar" ) ) { // same as in Windows L&F
|
||||
FlatShortcutsPanel panel = createShortcutsPanel( fc );
|
||||
if( panel.getComponentCount() > 0 ) {
|
||||
shortcutsPanel = panel;
|
||||
fc.add( shortcutsPanel, BorderLayout.LINE_START );
|
||||
fc.addPropertyChangeListener( shortcutsPanel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallComponents( JFileChooser fc ) {
|
||||
super.uninstallComponents( fc );
|
||||
|
||||
if( shortcutsPanel != null ) {
|
||||
fc.removePropertyChangeListener( shortcutsPanel );
|
||||
shortcutsPanel = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void patchUI( JFileChooser fc ) {
|
||||
@@ -192,6 +234,25 @@ public class FlatFileChooserUI
|
||||
} catch( ArrayIndexOutOfBoundsException ex ) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// put north, center and south components into a new panel so that
|
||||
// the shortcuts panel (at west) gets full height
|
||||
LayoutManager layout = fc.getLayout();
|
||||
if( layout instanceof BorderLayout ) {
|
||||
BorderLayout borderLayout = (BorderLayout) layout;
|
||||
borderLayout.setHgap( 8 );
|
||||
|
||||
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
||||
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
||||
Component south = borderLayout.getLayoutComponent( BorderLayout.SOUTH );
|
||||
if( north != null && center != null && south != null ) {
|
||||
JPanel p = new JPanel( new BorderLayout( 0, 11 ) );
|
||||
p.add( north, BorderLayout.NORTH );
|
||||
p.add( center, BorderLayout.CENTER );
|
||||
p.add( south, BorderLayout.SOUTH );
|
||||
fc.add( p, BorderLayout.CENTER );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -250,9 +311,19 @@ public class FlatFileChooserUI
|
||||
return p;
|
||||
}
|
||||
|
||||
/** @since 2.3 */
|
||||
protected FlatShortcutsPanel createShortcutsPanel( JFileChooser fc ) {
|
||||
return new FlatShortcutsPanel( fc );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return UIScale.scale( super.getPreferredSize( c ) );
|
||||
Dimension prefSize = super.getPreferredSize( c );
|
||||
Dimension minSize = getMinimumSize( c );
|
||||
int shortcutsPanelWidth = (shortcutsPanel != null) ? shortcutsPanel.getPreferredSize().width : 0;
|
||||
return new Dimension(
|
||||
Math.max( prefSize.width, minSize.width + shortcutsPanelWidth ),
|
||||
Math.max( prefSize.height, minSize.height ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -316,4 +387,234 @@ public class FlatFileChooserUI
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatShortcutsPanel -------------------------------------------
|
||||
|
||||
/** @since 2.3 */
|
||||
public static class FlatShortcutsPanel
|
||||
extends JToolBar
|
||||
implements PropertyChangeListener
|
||||
{
|
||||
private final JFileChooser fc;
|
||||
|
||||
private final Dimension buttonSize;
|
||||
private final Dimension iconSize;
|
||||
private final Function<File[], File[]> filesFunction;
|
||||
private final Function<File, String> displayNameFunction;
|
||||
private final Function<File, Icon> iconFunction;
|
||||
|
||||
protected final File[] files;
|
||||
protected final JToggleButton[] buttons;
|
||||
protected final ButtonGroup buttonGroup;
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public FlatShortcutsPanel( JFileChooser fc ) {
|
||||
super( JToolBar.VERTICAL );
|
||||
this.fc = fc;
|
||||
setFloatable( false );
|
||||
|
||||
buttonSize = UIScale.scale( getUIDimension( "FileChooser.shortcuts.buttonSize", 84, 64 ) );
|
||||
iconSize = getUIDimension( "FileChooser.shortcuts.iconSize", 32, 32 );
|
||||
|
||||
filesFunction = (Function<File[], File[]>) UIManager.get( "FileChooser.shortcuts.filesFunction" );
|
||||
displayNameFunction = (Function<File, String>) UIManager.get( "FileChooser.shortcuts.displayNameFunction" );
|
||||
iconFunction = (Function<File, Icon>) UIManager.get( "FileChooser.shortcuts.iconFunction" );
|
||||
|
||||
FileSystemView fsv = fc.getFileSystemView();
|
||||
File[] files = getChooserShortcutPanelFiles( fsv );
|
||||
if( filesFunction != null )
|
||||
files = filesFunction.apply( files );
|
||||
this.files = files;
|
||||
|
||||
// create toolbar buttons
|
||||
buttons = new JToggleButton[files.length];
|
||||
buttonGroup = new ButtonGroup();
|
||||
for( int i = 0; i < files.length; i++ ) {
|
||||
// wrap drive path
|
||||
if( fsv.isFileSystemRoot( files[i] ) )
|
||||
files[i] = fsv.createFileObject( files[i].getAbsolutePath() );
|
||||
|
||||
File file = files[i];
|
||||
String name = getDisplayName( fsv, file );
|
||||
Icon icon = getIcon( fsv, file );
|
||||
|
||||
// remove path from name
|
||||
int lastSepIndex = name.lastIndexOf( File.separatorChar );
|
||||
if( lastSepIndex >= 0 && lastSepIndex < name.length() - 1 )
|
||||
name = name.substring( lastSepIndex + 1 );
|
||||
|
||||
// scale icon (if necessary)
|
||||
if( icon instanceof ImageIcon )
|
||||
icon = new ScaledImageIcon( (ImageIcon) icon, iconSize.width, iconSize.height );
|
||||
else if( icon != null )
|
||||
icon = new ShortcutIcon( icon, iconSize.width, iconSize.height );
|
||||
|
||||
// create button
|
||||
JToggleButton button = createButton( name, icon );
|
||||
button.addActionListener( e -> {
|
||||
fc.setCurrentDirectory( file );
|
||||
} );
|
||||
|
||||
add( button );
|
||||
buttonGroup.add( button );
|
||||
buttons[i] = button;
|
||||
}
|
||||
|
||||
directoryChanged( fc.getCurrentDirectory() );
|
||||
}
|
||||
|
||||
private Dimension getUIDimension( String key, int defaultWidth, int defaultHeight ) {
|
||||
Dimension size = UIManager.getDimension( key );
|
||||
if( size == null )
|
||||
size = new Dimension( defaultWidth, defaultHeight );
|
||||
return size;
|
||||
}
|
||||
|
||||
protected JToggleButton createButton( String name, Icon icon ) {
|
||||
JToggleButton button = new JToggleButton( name, icon );
|
||||
button.setVerticalTextPosition( SwingConstants.BOTTOM );
|
||||
button.setHorizontalTextPosition( SwingConstants.CENTER );
|
||||
button.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||
button.setIconTextGap( 0 );
|
||||
button.setPreferredSize( buttonSize );
|
||||
button.setMaximumSize( buttonSize );
|
||||
return button;
|
||||
}
|
||||
|
||||
protected File[] getChooserShortcutPanelFiles( FileSystemView fsv ) {
|
||||
try {
|
||||
if( SystemInfo.isJava_12_orLater ) {
|
||||
Method m = fsv.getClass().getMethod( "getChooserShortcutPanelFiles" );
|
||||
File[] files = (File[]) m.invoke( fsv );
|
||||
|
||||
// on macOS and Linux, files consists only of the user home directory
|
||||
if( files.length == 1 && files[0].equals( new File( System.getProperty( "user.home" ) ) ) )
|
||||
files = new File[0];
|
||||
|
||||
return files;
|
||||
} else if( SystemInfo.isWindows ) {
|
||||
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||
Method m = cls.getMethod( "get", String.class );
|
||||
return (File[]) m.invoke( null, "fileChooserShortcutPanelFolders" );
|
||||
}
|
||||
} catch( IllegalAccessException ex ) {
|
||||
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
|
||||
// fallback
|
||||
return new File[0];
|
||||
}
|
||||
|
||||
protected String getDisplayName( FileSystemView fsv, File file ) {
|
||||
if( displayNameFunction != null ) {
|
||||
String name = displayNameFunction.apply( file );
|
||||
if( name != null )
|
||||
return name;
|
||||
}
|
||||
|
||||
return fsv.getSystemDisplayName( file );
|
||||
}
|
||||
|
||||
protected Icon getIcon( FileSystemView fsv, File file ) {
|
||||
if( iconFunction != null ) {
|
||||
Icon icon = iconFunction.apply( file );
|
||||
if( icon != null )
|
||||
return icon;
|
||||
}
|
||||
|
||||
// Java 17+ supports getting larger system icons
|
||||
try {
|
||||
if( SystemInfo.isJava_17_orLater ) {
|
||||
Method m = fsv.getClass().getMethod( "getSystemIcon", File.class, int.class, int.class );
|
||||
return (Icon) m.invoke( fsv, file, iconSize.width, iconSize.height );
|
||||
} else if( iconSize.width > 16 || iconSize.height > 16 ) {
|
||||
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||
if( cls.isInstance( file ) ) {
|
||||
Method m = file.getClass().getMethod( "getIcon", boolean.class );
|
||||
m.setAccessible( true );
|
||||
Image image = (Image) m.invoke( file, true );
|
||||
if( image != null )
|
||||
return new ImageIcon( image );
|
||||
}
|
||||
}
|
||||
} catch( IllegalAccessException ex ) {
|
||||
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
|
||||
// get system icon in default size 16x16
|
||||
return fsv.getSystemIcon( file );
|
||||
}
|
||||
|
||||
protected void directoryChanged( File file ) {
|
||||
if( file != null ) {
|
||||
String absolutePath = file.getAbsolutePath();
|
||||
for( int i = 0; i < files.length; i++ ) {
|
||||
// also compare path because otherwise selecting "Documents"
|
||||
// in "Look in" combobox would not select "Documents" shortcut item
|
||||
if( files[i].equals( file ) || files[i].getAbsolutePath().equals( absolutePath ) ) {
|
||||
buttons[i].setSelected( true );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buttonGroup.clearSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case JFileChooser.DIRECTORY_CHANGED_PROPERTY:
|
||||
directoryChanged( fc.getCurrentDirectory() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---- class ShortcutIcon -------------------------------------------------
|
||||
|
||||
private static class ShortcutIcon
|
||||
implements Icon
|
||||
{
|
||||
private final Icon icon;
|
||||
private final int iconWidth;
|
||||
private final int iconHeight;
|
||||
|
||||
ShortcutIcon( Icon icon, int iconWidth, int iconHeight ) {
|
||||
this.icon = icon;
|
||||
this.iconWidth = iconWidth;
|
||||
this.iconHeight = iconHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
// set rendering hint for the case that the icon is a bitmap (not used for vector icons)
|
||||
g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
|
||||
|
||||
double scale = (double) getIconWidth() / (double) icon.getIconWidth();
|
||||
g2.translate( x, y );
|
||||
g2.scale( scale, scale );
|
||||
|
||||
icon.paintIcon( c, g2, 0, 0 );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return UIScale.scale( iconWidth );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return UIScale.scale( iconHeight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2022 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.io.File;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.NativeLibrary;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Helper class to load FlatLaf native library (.dll, .so or .dylib),
|
||||
* if available for current operating system and CPU architecture.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
* @since 2.3
|
||||
*/
|
||||
class FlatNativeLibrary
|
||||
{
|
||||
private static NativeLibrary nativeLibrary;
|
||||
|
||||
/**
|
||||
* Loads native library (if available) and returns whether loaded successfully.
|
||||
* Returns {@code false} if no native library is available.
|
||||
*/
|
||||
static synchronized boolean isLoaded() {
|
||||
initialize();
|
||||
return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false;
|
||||
}
|
||||
|
||||
private static void initialize() {
|
||||
if( nativeLibrary != null )
|
||||
return;
|
||||
|
||||
String libraryName;
|
||||
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
||||
// Windows: requires Windows 10 (x86 or x86_64)
|
||||
|
||||
libraryName = "flatlaf-windows-x86";
|
||||
if( SystemInfo.isX86_64 )
|
||||
libraryName += "_64";
|
||||
|
||||
// load jawt native library
|
||||
loadJAWT();
|
||||
} else
|
||||
return; // no native library available for current OS or CPU architecture
|
||||
|
||||
// load native library
|
||||
nativeLibrary = createNativeLibrary( libraryName );
|
||||
}
|
||||
|
||||
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||
if( libraryPath != null ) {
|
||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||
if( libraryFile.exists() )
|
||||
return new NativeLibrary( libraryFile, true );
|
||||
else
|
||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||
}
|
||||
|
||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||
}
|
||||
|
||||
private static void loadJAWT() {
|
||||
if( SystemInfo.isJava_9_orLater )
|
||||
return;
|
||||
|
||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||
// is not found when running application with <jdk>/bin/java.exe.
|
||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||
// jawt.dll is located in <jdk>/jre/bin/.
|
||||
// Java 9 and later do not have this problem.
|
||||
try {
|
||||
System.loadLibrary( "jawt" );
|
||||
} catch( UnsatisfiedLinkError ex ) {
|
||||
// log error only if native library jawt.dll not already loaded
|
||||
String message = ex.getMessage();
|
||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Table.intercellSpacing Dimension
|
||||
* @uiDefault Table.selectionInactiveBackground Color
|
||||
* @uiDefault Table.selectionInactiveForeground Color
|
||||
* @uiDefault Table.paintOutsideAlternateRows boolean
|
||||
*
|
||||
* <!-- FlatTableCellBorder -->
|
||||
*
|
||||
@@ -95,7 +96,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
*/
|
||||
public class FlatTableUI
|
||||
extends BasicTableUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, FlatViewportUI.ViewportPainter
|
||||
{
|
||||
protected boolean showHorizontalLines;
|
||||
protected boolean showVerticalLines;
|
||||
@@ -421,4 +422,38 @@ public class FlatTableUI
|
||||
? (viewport != rowHeader)
|
||||
: (viewport == rowHeader || rowHeader == null);
|
||||
}
|
||||
|
||||
/** @since 2.3 */
|
||||
@Override
|
||||
public void paintViewport( Graphics g, JComponent c, JViewport viewport ) {
|
||||
int viewportWidth = viewport.getWidth();
|
||||
int viewportHeight = viewport.getHeight();
|
||||
|
||||
// fill viewport background in same color as table background
|
||||
if( viewport.isOpaque() ) {
|
||||
g.setColor( table.getBackground() );
|
||||
g.fillRect( 0, 0, viewportWidth, viewportHeight );
|
||||
}
|
||||
|
||||
// paint alternating empty rows
|
||||
boolean paintOutside = UIManager.getBoolean( "Table.paintOutsideAlternateRows" );
|
||||
Color alternateColor;
|
||||
if( paintOutside && (alternateColor = UIManager.getColor( "Table.alternateRowColor" )) != null ) {
|
||||
g.setColor( alternateColor );
|
||||
|
||||
int rowCount = table.getRowCount();
|
||||
|
||||
// paint alternating empty rows below the table
|
||||
int tableHeight = table.getHeight();
|
||||
if( tableHeight < viewportHeight ) {
|
||||
int tableWidth = table.getWidth();
|
||||
int rowHeight = table.getRowHeight();
|
||||
|
||||
for( int y = tableHeight, row = rowCount; y < viewportHeight; y += rowHeight, row++ ) {
|
||||
if( row % 2 != 0 )
|
||||
g.fillRect( 0, y, tableWidth, rowHeight );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,7 @@ import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||
@@ -51,15 +48,29 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault ToggleButton.iconTextGap int
|
||||
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
||||
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault ToggleButton.pressedBackground Color
|
||||
* @uiDefault ToggleButton.focusedBackground Color optional
|
||||
* @uiDefault ToggleButton.focusedForeground Color optional
|
||||
* @uiDefault ToggleButton.hoverBackground Color optional
|
||||
* @uiDefault ToggleButton.hoverForeground Color optional
|
||||
* @uiDefault ToggleButton.pressedBackground Color optional
|
||||
* @uiDefault ToggleButton.pressedForeground Color optional
|
||||
* @uiDefault ToggleButton.selectedBackground Color
|
||||
* @uiDefault ToggleButton.selectedForeground Color
|
||||
* @uiDefault ToggleButton.disabledBackground Color optional
|
||||
* @uiDefault ToggleButton.disabledText Color
|
||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||
* @uiDefault ToggleButton.disabledSelectedForeground Color optional
|
||||
* @uiDefault Button.paintShadow boolean default is false
|
||||
* @uiDefault Button.shadowWidth int default is 2
|
||||
* @uiDefault Button.shadowColor Color optional
|
||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.hoverForeground Color optional
|
||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.pressedForeground Color optional
|
||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.selectedForeground Color optional
|
||||
* @uiDefault ToggleButton.toolbar.disabledSelectedBackground Color optional
|
||||
* @uiDefault ToggleButton.toolbar.disabledSelectedForeground Color optional
|
||||
*
|
||||
* <!-- FlatToggleButtonUI -->
|
||||
*
|
||||
@@ -67,8 +78,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault ToggleButton.tab.underlineColor Color
|
||||
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
||||
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
||||
* @uiDefault ToggleButton.tab.selectedForeground Color optional
|
||||
* @uiDefault ToggleButton.tab.hoverBackground Color
|
||||
* @uiDefault ToggleButton.tab.hoverForeground Color optional
|
||||
* @uiDefault ToggleButton.tab.focusBackground Color
|
||||
* @uiDefault ToggleButton.tab.focusForeground Color optional
|
||||
*
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -80,8 +94,11 @@ public class FlatToggleButtonUI
|
||||
@Styleable(dot=true) protected Color tabUnderlineColor;
|
||||
@Styleable(dot=true) protected Color tabDisabledUnderlineColor;
|
||||
@Styleable(dot=true) protected Color tabSelectedBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color tabSelectedForeground;
|
||||
@Styleable(dot=true) protected Color tabHoverBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color tabHoverForeground;
|
||||
@Styleable(dot=true) protected Color tabFocusBackground;
|
||||
/** @since 2.3 */ @Styleable(dot=true) protected Color tabFocusForeground;
|
||||
|
||||
private boolean defaults_initialized = false;
|
||||
|
||||
@@ -114,8 +131,11 @@ public class FlatToggleButtonUI
|
||||
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
||||
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
||||
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
||||
tabSelectedForeground = UIManager.getColor( "ToggleButton.tab.selectedForeground" );
|
||||
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
||||
tabHoverForeground = UIManager.getColor( "ToggleButton.tab.hoverForeground" );
|
||||
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
||||
tabFocusForeground = UIManager.getColor( "ToggleButton.tab.focusForeground" );
|
||||
|
||||
defaults_initialized = true;
|
||||
}
|
||||
@@ -142,6 +162,7 @@ public class FlatToggleButtonUI
|
||||
b.repaint();
|
||||
break;
|
||||
|
||||
case TAB_BUTTON_UNDERLINE_PLACEMENT:
|
||||
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
||||
case TAB_BUTTON_UNDERLINE_COLOR:
|
||||
case TAB_BUTTON_SELECTED_BACKGROUND:
|
||||
@@ -196,13 +217,42 @@ public class FlatToggleButtonUI
|
||||
|
||||
// paint underline if selected
|
||||
if( selected ) {
|
||||
int underlineHeight = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
||||
int underlineThickness = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
||||
g.setColor( c.isEnabled()
|
||||
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
||||
: tabDisabledUnderlineColor );
|
||||
g.fillRect( 0, height - underlineHeight, width, underlineHeight );
|
||||
int placement = clientPropertyInt( c, TAB_BUTTON_UNDERLINE_PLACEMENT, SwingConstants.BOTTOM );
|
||||
switch (placement) {
|
||||
case SwingConstants.TOP:
|
||||
g.fillRect( 0, 0, width, underlineThickness );
|
||||
break;
|
||||
case SwingConstants.LEFT:
|
||||
g.fillRect( 0, 0, underlineThickness, height );
|
||||
break;
|
||||
case SwingConstants.RIGHT:
|
||||
g.fillRect( width - underlineThickness, 0, underlineThickness, height );
|
||||
break;
|
||||
case SwingConstants.BOTTOM:
|
||||
default:
|
||||
g.fillRect( 0, height - underlineThickness, width, underlineThickness );
|
||||
}
|
||||
}
|
||||
} else
|
||||
super.paintBackground( g, c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getForeground( JComponent c ) {
|
||||
if( isTabButton( c ) ) {
|
||||
if( !c.isEnabled() )
|
||||
return disabledText;
|
||||
|
||||
if( tabSelectedForeground != null && ((AbstractButton)c).isSelected() )
|
||||
return tabSelectedForeground;
|
||||
|
||||
return buttonStateColor( c, c.getForeground(), disabledText,
|
||||
tabFocusForeground, tabHoverForeground, null );
|
||||
} else
|
||||
return super.getForeground( c );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicViewportUI;
|
||||
@@ -43,15 +43,28 @@ public class FlatViewportUI
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( Graphics g, JComponent c ) {
|
||||
Component view = ((JViewport)c).getView();
|
||||
if( c.isOpaque() && view instanceof JTable ) {
|
||||
// paint viewport background in same color as table background
|
||||
g.setColor( view.getBackground() );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
super.paint( g, c );
|
||||
|
||||
paint( g, c );
|
||||
} else
|
||||
super.update( g, c );
|
||||
Component view = ((JViewport)c).getView();
|
||||
if( view instanceof JComponent ) {
|
||||
try {
|
||||
Method m = view.getClass().getMethod( "getUI" );
|
||||
Object ui = m.invoke( view );
|
||||
if( ui instanceof ViewportPainter )
|
||||
((ViewportPainter)ui).paintViewport( g, (JComponent) view, (JViewport) c );
|
||||
} catch( Exception ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---- interface ViewportPainter ------------------------------------------
|
||||
|
||||
/**
|
||||
* @since 2.3
|
||||
*/
|
||||
public interface ViewportPainter {
|
||||
void paintViewport( Graphics g, JComponent c, JViewport viewport );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.awt.Window;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
@@ -38,9 +37,7 @@ import javax.swing.Timer;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.NativeLibrary;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
//
|
||||
@@ -84,7 +81,6 @@ class FlatWindowsNativeWindowBorder
|
||||
private Color colorizationColor;
|
||||
private int colorizationColorBalance;
|
||||
|
||||
private static NativeLibrary nativeLibrary;
|
||||
private static FlatWindowsNativeWindowBorder instance;
|
||||
|
||||
static FlatNativeWindowBorder.Provider getInstance() {
|
||||
@@ -96,31 +92,8 @@ class FlatWindowsNativeWindowBorder
|
||||
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
|
||||
return null;
|
||||
|
||||
// load native library
|
||||
if( nativeLibrary == null ) {
|
||||
if( !SystemInfo.isJava_9_orLater ) {
|
||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||
// is not found when running application with <jdk>/bin/java.exe.
|
||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||
// jawt.dll is located in <jdk>/jre/bin/.
|
||||
// Java 9 and later does not have this problem.
|
||||
try {
|
||||
System.loadLibrary( "jawt" );
|
||||
} catch( UnsatisfiedLinkError ex ) {
|
||||
// log error only if native library jawt.dll not already loaded
|
||||
String message = ex.getMessage();
|
||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
nativeLibrary = createNativeLibrary();
|
||||
}
|
||||
|
||||
// check whether native library was successfully loaded
|
||||
if( !nativeLibrary.isLoaded() )
|
||||
if( !FlatNativeLibrary.isLoaded() )
|
||||
return null;
|
||||
|
||||
// create new instance
|
||||
@@ -129,23 +102,6 @@ class FlatWindowsNativeWindowBorder
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static NativeLibrary createNativeLibrary() {
|
||||
String libraryName = "flatlaf-windows-x86";
|
||||
if( SystemInfo.isX86_64 )
|
||||
libraryName += "_64";
|
||||
|
||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||
if( libraryPath != null ) {
|
||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||
if( libraryFile.exists() )
|
||||
return new NativeLibrary( libraryFile, true );
|
||||
else
|
||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||
}
|
||||
|
||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||
}
|
||||
|
||||
private FlatWindowsNativeWindowBorder() {
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public class SystemInfo
|
||||
public static final long javaVersion;
|
||||
public static final boolean isJava_9_orLater;
|
||||
public static final boolean isJava_11_orLater;
|
||||
/** @since 2.3 */ public static final boolean isJava_12_orLater;
|
||||
public static final boolean isJava_15_orLater;
|
||||
/** @since 2 */ public static final boolean isJava_17_orLater;
|
||||
/** @since 2 */ public static final boolean isJava_18_orLater;
|
||||
@@ -66,6 +67,9 @@ public class SystemInfo
|
||||
/** @since 1.1.2 */ public static final boolean isWebswing;
|
||||
/** @since 1.1.1 */ public static final boolean isWinPE;
|
||||
|
||||
// features
|
||||
/** @since 2.3 */ public static final boolean isMacFullWindowContentSupported;
|
||||
|
||||
static {
|
||||
// platforms
|
||||
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
||||
@@ -92,6 +96,7 @@ public class SystemInfo
|
||||
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||
isJava_12_orLater = (javaVersion >= toVersion( 12, 0, 0, 0 ));
|
||||
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
|
||||
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
|
||||
@@ -108,6 +113,12 @@ public class SystemInfo
|
||||
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
||||
isWebswing = (System.getProperty( "webswing.rootDir" ) != null);
|
||||
isWinPE = isWindows && "X:\\Windows\\System32".equalsIgnoreCase( System.getProperty( "user.dir" ) );
|
||||
|
||||
// features
|
||||
// available since Java 12; backported to Java 11.0.8 and 8u292
|
||||
isMacFullWindowContentSupported =
|
||||
javaVersion >= toVersion( 11, 0, 8, 0 ) ||
|
||||
(javaVersion >= toVersion( 1, 8, 0, 292 ) && !isJava_9_orLater);
|
||||
}
|
||||
|
||||
public static long scanVersion( String version ) {
|
||||
|
||||
@@ -829,6 +829,7 @@ ToggleButton.tab.underlineHeight = 2
|
||||
ToggleButton.tab.underlineColor = $TabbedPane.underlineColor
|
||||
ToggleButton.tab.disabledUnderlineColor = $TabbedPane.disabledUnderlineColor
|
||||
ToggleButton.tab.selectedBackground = $?TabbedPane.selectedBackground
|
||||
ToggleButton.tab.selectedForeground = $?TabbedPane.selectedForeground
|
||||
ToggleButton.tab.hoverBackground = $TabbedPane.hoverColor
|
||||
ToggleButton.tab.focusBackground = $TabbedPane.focusColor
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ ToggleButton.endBackground = $ToggleButton.background
|
||||
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||
|
||||
[Monokai_Pro]TitledBorder.titleColor = @foreground
|
||||
|
||||
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#---- FileChooser ----
|
||||
|
||||
#fields
|
||||
FileChooser.lookInLabel.textAndMnemonic = Buscar &en:
|
||||
FileChooser.saveInLabelText = Guardar en:
|
||||
FileChooser.fileNameLabel.textAndMnemonic = &Nombre de fichero:
|
||||
FileChooser.folderNameLabel.textAndMnemonic = &Nombre de carpeta:
|
||||
FileChooser.filesOfTypeLabel.textAndMnemonic = Ficheros de &Tipo:
|
||||
|
||||
# toolbar
|
||||
FileChooser.upFolderToolTipText = Subir un nivel
|
||||
FileChooser.upFolderAccessibleName = Subir
|
||||
FileChooser.homeFolderToolTipText = Inicio
|
||||
FileChooser.homeFolderAccessibleName = Inicio
|
||||
FileChooser.newFolderToolTipText = Crear nueva carpeta
|
||||
FileChooser.newFolderAccessibleName = Nueva carpeta
|
||||
FileChooser.listViewButtonToolTipText = Lista
|
||||
FileChooser.listViewButtonAccessibleName = Lista
|
||||
FileChooser.detailsViewButtonToolTipText = Detalles
|
||||
FileChooser.detailsViewButtonAccessibleName = Detalles
|
||||
|
||||
# details table header
|
||||
FileChooser.fileNameHeaderText = Nombre
|
||||
FileChooser.fileSizeHeaderText = Tama\u00F1o
|
||||
FileChooser.fileTypeHeaderText = Tipo
|
||||
FileChooser.fileDateHeaderText = Modificado
|
||||
FileChooser.fileAttrHeaderText = Atributos
|
||||
|
||||
# popup menu
|
||||
FileChooser.viewMenuLabelText = Ver
|
||||
FileChooser.refreshActionLabelText = Refrescar
|
||||
FileChooser.newFolderActionLabelText = Nueva carpeta
|
||||
FileChooser.listViewActionLabelText = Lista
|
||||
FileChooser.detailsViewActionLabelText = Detalles
|
||||
|
||||
|
||||
#---- SplitPaneDivider ----
|
||||
|
||||
SplitPaneDivider.collapseLeftToolTipText = Contraer Panel Izquierdo
|
||||
SplitPaneDivider.collapseRightToolTipText = Contraer panel Derecho
|
||||
SplitPaneDivider.collapseTopToolTipText = Contraer panel Superior
|
||||
SplitPaneDivider.collapseBottomToolTipText = Contraer Panel Inferior
|
||||
SplitPaneDivider.expandLeftToolTipText = Expandir Panel Izquierdo
|
||||
SplitPaneDivider.expandRightToolTipText = Expandir Panel Derecho
|
||||
SplitPaneDivider.expandTopToolTipText = Expandir Panel Superior
|
||||
SplitPaneDivider.expandBottomToolTipText = Expandir Panel Inferior
|
||||
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.moreTabsButtonToolTipText = Mostrar Pesta\u00F1as Ocultas
|
||||
@@ -96,19 +96,26 @@ public class TestFlatStyleableInfo
|
||||
"minimumWidth", int.class,
|
||||
|
||||
"focusedBackground", Color.class,
|
||||
"focusedForeground", Color.class,
|
||||
"hoverBackground", Color.class,
|
||||
"hoverForeground", Color.class,
|
||||
"pressedBackground", Color.class,
|
||||
"pressedForeground", Color.class,
|
||||
"selectedBackground", Color.class,
|
||||
"selectedForeground", Color.class,
|
||||
"disabledBackground", Color.class,
|
||||
"disabledText", Color.class,
|
||||
"disabledSelectedBackground", Color.class,
|
||||
"disabledSelectedForeground", Color.class,
|
||||
|
||||
"default.background", Color.class,
|
||||
"default.foreground", Color.class,
|
||||
"default.focusedBackground", Color.class,
|
||||
"default.focusedForeground", Color.class,
|
||||
"default.hoverBackground", Color.class,
|
||||
"default.hoverForeground", Color.class,
|
||||
"default.pressedBackground", Color.class,
|
||||
"default.pressedForeground", Color.class,
|
||||
"default.boldText", boolean.class,
|
||||
|
||||
"paintShadow", boolean.class,
|
||||
@@ -118,8 +125,13 @@ public class TestFlatStyleableInfo
|
||||
|
||||
"toolbar.spacingInsets", Insets.class,
|
||||
"toolbar.hoverBackground", Color.class,
|
||||
"toolbar.hoverForeground", Color.class,
|
||||
"toolbar.pressedBackground", Color.class,
|
||||
"toolbar.pressedForeground", Color.class,
|
||||
"toolbar.selectedBackground", Color.class,
|
||||
"toolbar.selectedForeground", Color.class,
|
||||
"toolbar.disabledSelectedBackground", Color.class,
|
||||
"toolbar.disabledSelectedForeground", Color.class,
|
||||
|
||||
"buttonType", String.class,
|
||||
"squareSize", boolean.class,
|
||||
@@ -863,8 +875,11 @@ public class TestFlatStyleableInfo
|
||||
"tab.underlineColor", Color.class,
|
||||
"tab.disabledUnderlineColor", Color.class,
|
||||
"tab.selectedBackground", Color.class,
|
||||
"tab.selectedForeground", Color.class,
|
||||
"tab.hoverBackground", Color.class,
|
||||
"tab.focusBackground", Color.class
|
||||
"tab.hoverForeground", Color.class,
|
||||
"tab.focusBackground", Color.class,
|
||||
"tab.focusForeground", Color.class
|
||||
);
|
||||
|
||||
// FlatToggleButtonUI extends FlatButtonUI
|
||||
|
||||
@@ -221,19 +221,26 @@ public class TestFlatStyling
|
||||
ui.applyStyle( b, "minimumWidth: 100" );
|
||||
|
||||
ui.applyStyle( b, "focusedBackground: #fff" );
|
||||
ui.applyStyle( b, "focusedForeground: #fff" );
|
||||
ui.applyStyle( b, "hoverBackground: #fff" );
|
||||
ui.applyStyle( b, "hoverForeground: #fff" );
|
||||
ui.applyStyle( b, "pressedBackground: #fff" );
|
||||
ui.applyStyle( b, "pressedForeground: #fff" );
|
||||
ui.applyStyle( b, "selectedBackground: #fff" );
|
||||
ui.applyStyle( b, "selectedForeground: #fff" );
|
||||
ui.applyStyle( b, "disabledBackground: #fff" );
|
||||
ui.applyStyle( b, "disabledText: #fff" );
|
||||
ui.applyStyle( b, "disabledSelectedBackground: #fff" );
|
||||
ui.applyStyle( b, "disabledSelectedForeground: #fff" );
|
||||
|
||||
ui.applyStyle( b, "default.background: #fff" );
|
||||
ui.applyStyle( b, "default.foreground: #fff" );
|
||||
ui.applyStyle( b, "default.focusedBackground: #fff" );
|
||||
ui.applyStyle( b, "default.focusedForeground: #fff" );
|
||||
ui.applyStyle( b, "default.hoverBackground: #fff" );
|
||||
ui.applyStyle( b, "default.hoverForeground: #fff" );
|
||||
ui.applyStyle( b, "default.pressedBackground: #fff" );
|
||||
ui.applyStyle( b, "default.pressedForeground: #fff" );
|
||||
ui.applyStyle( b, "default.boldText: true" );
|
||||
|
||||
ui.applyStyle( b, "paintShadow: true" );
|
||||
@@ -243,8 +250,13 @@ public class TestFlatStyling
|
||||
|
||||
ui.applyStyle( b, "toolbar.spacingInsets: 1,2,3,4" );
|
||||
ui.applyStyle( b, "toolbar.hoverBackground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.hoverForeground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.pressedBackground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.pressedForeground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.selectedBackground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.selectedForeground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.disabledSelectedBackground: #fff" );
|
||||
ui.applyStyle( b, "toolbar.disabledSelectedForeground: #fff" );
|
||||
|
||||
ui.applyStyle( b, "buttonType: help" );
|
||||
ui.applyStyle( b, "squareSize: true" );
|
||||
@@ -1073,8 +1085,11 @@ public class TestFlatStyling
|
||||
ui.applyStyle( b, "tab.underlineColor: #fff" );
|
||||
ui.applyStyle( b, "tab.disabledUnderlineColor: #fff" );
|
||||
ui.applyStyle( b, "tab.selectedBackground: #fff" );
|
||||
ui.applyStyle( b, "tab.selectedForeground: #fff" );
|
||||
ui.applyStyle( b, "tab.hoverBackground: #fff" );
|
||||
ui.applyStyle( b, "tab.hoverForeground: #fff" );
|
||||
ui.applyStyle( b, "tab.focusBackground: #fff" );
|
||||
ui.applyStyle( b, "tab.focusForeground: #fff" );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -38,8 +38,8 @@ import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.demo.HintManager.Hint;
|
||||
import com.formdev.flatlaf.demo.extras.*;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||
import com.formdev.flatlaf.extras.FlatDesktop;
|
||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||
import com.formdev.flatlaf.extras.FlatDesktop;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
||||
import com.formdev.flatlaf.extras.components.FlatButton;
|
||||
@@ -82,13 +82,33 @@ class DemoFrame
|
||||
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
||||
tabbedPane.setSelectedIndex( tabIndex );
|
||||
|
||||
// hide some menu items on macOS
|
||||
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// hide menu items that are in macOS application menu
|
||||
exitMenuItem.setVisible( false );
|
||||
aboutMenuItem.setVisible( false );
|
||||
|
||||
// do not use HTML text on macOS
|
||||
// do not use HTML text in menu items because this is not supported in macOS screen menu
|
||||
htmlMenuItem.setText( "some text" );
|
||||
|
||||
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||
// expand window content into window title bar and make title bar transparent
|
||||
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||
|
||||
// hide window title
|
||||
if( SystemInfo.isJava_17_orLater )
|
||||
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||
else
|
||||
setTitle( null );
|
||||
|
||||
// add gap to left side of toolbar
|
||||
toolBar.add( Box.createHorizontalStrut( 70 ), 0 );
|
||||
}
|
||||
|
||||
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||
if( !SystemInfo.isJava_11_orLater )
|
||||
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
||||
}
|
||||
|
||||
// integrate into macOS screen menu
|
||||
@@ -433,9 +453,9 @@ class DemoFrame
|
||||
lafClass == FlatIntelliJLaf.class ||
|
||||
lafClass == FlatDarculaLaf.class;
|
||||
|
||||
accentColorLabel.setEnabled( isAccentColorSupported );
|
||||
accentColorLabel.setVisible( isAccentColorSupported );
|
||||
for( int i = 0; i < accentColorButtons.length; i++ )
|
||||
accentColorButtons[i].setEnabled( isAccentColorSupported );
|
||||
accentColorButtons[i].setVisible( isAccentColorSupported );
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class FlatLafDemo
|
||||
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
||||
|
||||
public static void main( String[] args ) {
|
||||
// macOS
|
||||
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// enable screen menu bar
|
||||
// (moves menu bar from JFrame window to top of screen)
|
||||
@@ -51,6 +51,7 @@ public class FlatLafDemo
|
||||
// - "system": use current macOS appearance (light or dark)
|
||||
// - "NSAppearanceNameAqua": use light appearance
|
||||
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.formdev.flatlaf.extras.components;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import java.awt.Color;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
||||
|
||||
/**
|
||||
@@ -116,16 +116,37 @@ public class FlatToggleButton
|
||||
putClientProperty( OUTLINE, outline );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||
* If underline placement is not specified, returns {@link #BOTTOM} as the default
|
||||
* value.
|
||||
*
|
||||
* @since 2.3
|
||||
*/
|
||||
public int getTabUnderlinePlacement() {
|
||||
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_PLACEMENT, BOTTOM );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns height of underline if toggle button type is {@link ButtonType#tab}.
|
||||
* Specifies placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||
*
|
||||
* @param placement One of the following constants defined in SwingConstants:
|
||||
* {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, or {@link #RIGHT}.
|
||||
* @since 2.3
|
||||
*/
|
||||
public void setTabUnderlinePlacement( int placement ) {
|
||||
putClientProperty( TAB_BUTTON_UNDERLINE_PLACEMENT, (placement >= 0) ? placement : null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||
*/
|
||||
public int getTabUnderlineHeight() {
|
||||
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_HEIGHT, "ToggleButton.tab.underlineHeight" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies height of underline if toggle button type is {@link ButtonType#tab}.
|
||||
* Specifies thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||
*/
|
||||
public void setTabUnderlineHeight( int tabUnderlineHeight ) {
|
||||
putClientProperty( TAB_BUTTON_UNDERLINE_HEIGHT, (tabUnderlineHeight >= 0) ? tabUnderlineHeight : null );
|
||||
|
||||
@@ -73,43 +73,57 @@ Button.default.endBorderColor #0000ff HSL 240 100 50 javax.swing.plaf.Colo
|
||||
Button.default.focusColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.focusedBorderColor #537699 HSL 210 30 46 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.foreground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.startBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.default.startBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.defaultButtonFollowsFocus false
|
||||
Button.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.disabledBorderColor #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.disabledForeground #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.disabledSelectedBackground #112233 HSL 210 50 13 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.disabledSelectedForeground #ffcccc HSL 0 100 90 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.endBackground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.endBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.focusedBorderColor #466d94 HSL 210 36 43 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.font [active] $defaultFont [UI]
|
||||
Button.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.iconTextGap 4
|
||||
Button.innerFocusWidth 1
|
||||
Button.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
||||
Button.minimumWidth 72
|
||||
Button.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.rollover true
|
||||
Button.selectedBackground #ffbbbb HSL 0 100 87 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.selectedForeground #332211 HSL 30 50 13 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.startBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.startBorderColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.textIconGap 4
|
||||
Button.textShiftOffset 0
|
||||
Button.toolbar.disabledSelectedBackground #cccccc HSL 0 0 80 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.disabledSelectedForeground #886666 HSL 0 14 47 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.hoverForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.margin 3,3,3,3 javax.swing.plaf.InsetsUIResource [UI]
|
||||
Button.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.pressedForeground #666666 HSL 0 0 40 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.selectedForeground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
Button.toolbar.spacingInsets 1,2,1,2 javax.swing.plaf.InsetsUIResource [UI]
|
||||
ButtonUI com.formdev.flatlaf.ui.FlatButtonUI
|
||||
|
||||
@@ -1280,31 +1294,43 @@ ToggleButton.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.F
|
||||
ToggleButton.darkShadow #696969 HSL 0 0 41 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.disabledSelectedBackground #44dd44 HSL 120 69 57 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.disabledSelectedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.font [active] $defaultFont [UI]
|
||||
ToggleButton.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.iconTextGap 4
|
||||
ToggleButton.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
||||
ToggleButton.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.rollover true
|
||||
ToggleButton.selectedBackground #44ff44 HSL 120 100 63 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.selectedForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.disabledUnderlineColor #7a7a7a HSL 0 0 48 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.focusBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.focusForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.hoverBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.selectedBackground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.hoverForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.selectedBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.selectedForeground #00aaff HSL 200 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.underlineColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.tab.underlineHeight 2
|
||||
ToggleButton.textIconGap 4
|
||||
ToggleButton.textShiftOffset 0
|
||||
ToggleButton.toolbar.disabledSelectedBackground #cccccc HSL 0 0 80 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.disabledSelectedForeground #886666 HSL 0 14 47 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.hoverForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.pressedForeground #666666 HSL 0 0 40 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButton.toolbar.selectedForeground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||
ToggleButtonUI com.formdev.flatlaf.ui.FlatToggleButtonUI
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
package com.formdev.flatlaf.testing;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIcon;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -28,6 +33,24 @@ public class FlatChooserTest
|
||||
public static void main( String[] args ) {
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
|
||||
|
||||
UIManager.put( "FileChooser.shortcuts.filesFunction", (Function<File[], File[]>) files -> {
|
||||
ArrayList<File> list = new ArrayList<>( Arrays.asList( files ) );
|
||||
list.add( 0, new File( System.getProperty( "user.home" ) ) );
|
||||
return list.toArray( new File[list.size()] );
|
||||
} );
|
||||
|
||||
UIManager.put( "FileChooser.shortcuts.displayNameFunction", (Function<File, String>) file -> {
|
||||
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||
return "Home";
|
||||
return null;
|
||||
} );
|
||||
UIManager.put( "FileChooser.shortcuts.iconFunction", (Function<File, Icon>) file -> {
|
||||
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||
return new FlatFileChooserHomeFolderIcon();
|
||||
return null;
|
||||
} );
|
||||
|
||||
frame.showFrame( FlatChooserTest::new );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -336,6 +336,16 @@ public class FlatComponents2Test
|
||||
table.setSurrendersFocusOnKeystroke( focusCellEditorCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void alternatingRowsChanged() {
|
||||
UIManager.put( "Table.alternateRowColor", alternatingRowsCheckBox.isSelected() ? Color.orange : null );
|
||||
table1ScrollPane.repaint();
|
||||
}
|
||||
|
||||
private void paintOutsideAlternateRowsChanged() {
|
||||
UIManager.put( "Table.paintOutsideAlternateRows", paintOutsideAlternateRowsCheckBox.isSelected() ? true : null );
|
||||
table1ScrollPane.repaint();
|
||||
}
|
||||
|
||||
private void treeRendererChanged() {
|
||||
Object sel = treeRendererComboBox.getSelectedItem();
|
||||
if( !(sel instanceof String) )
|
||||
@@ -493,8 +503,10 @@ public class FlatComponents2Test
|
||||
focusCellEditorCheckBox = new JCheckBox();
|
||||
showVerticalLinesCheckBox = new JCheckBox();
|
||||
columnSelectionCheckBox = new JCheckBox();
|
||||
alternatingRowsCheckBox = new JCheckBox();
|
||||
intercellSpacingCheckBox = new JCheckBox();
|
||||
rowHeaderCheckBox = new JCheckBox();
|
||||
paintOutsideAlternateRowsCheckBox = new JCheckBox();
|
||||
redGridColorCheckBox = new JCheckBox();
|
||||
tableHeaderButtonCheckBox = new JCheckBox();
|
||||
|
||||
@@ -875,6 +887,11 @@ public class FlatComponents2Test
|
||||
columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged());
|
||||
tableOptionsPanel.add(columnSelectionCheckBox, "cell 1 2");
|
||||
|
||||
//---- alternatingRowsCheckBox ----
|
||||
alternatingRowsCheckBox.setText("alternating rows");
|
||||
alternatingRowsCheckBox.addActionListener(e -> alternatingRowsChanged());
|
||||
tableOptionsPanel.add(alternatingRowsCheckBox, "cell 2 2");
|
||||
|
||||
//---- intercellSpacingCheckBox ----
|
||||
intercellSpacingCheckBox.setText("intercell spacing");
|
||||
intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged());
|
||||
@@ -885,6 +902,11 @@ public class FlatComponents2Test
|
||||
rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
|
||||
tableOptionsPanel.add(rowHeaderCheckBox, "cell 1 3");
|
||||
|
||||
//---- paintOutsideAlternateRowsCheckBox ----
|
||||
paintOutsideAlternateRowsCheckBox.setText("outside alternating rows");
|
||||
paintOutsideAlternateRowsCheckBox.addActionListener(e -> paintOutsideAlternateRowsChanged());
|
||||
tableOptionsPanel.add(paintOutsideAlternateRowsCheckBox, "cell 2 3");
|
||||
|
||||
//---- redGridColorCheckBox ----
|
||||
redGridColorCheckBox.setText("red grid color");
|
||||
redGridColorCheckBox.addActionListener(e -> redGridColorChanged());
|
||||
@@ -927,8 +949,10 @@ public class FlatComponents2Test
|
||||
private JCheckBox focusCellEditorCheckBox;
|
||||
private JCheckBox showVerticalLinesCheckBox;
|
||||
private JCheckBox columnSelectionCheckBox;
|
||||
private JCheckBox alternatingRowsCheckBox;
|
||||
private JCheckBox intercellSpacingCheckBox;
|
||||
private JCheckBox rowHeaderCheckBox;
|
||||
private JCheckBox paintOutsideAlternateRowsCheckBox;
|
||||
private JCheckBox redGridColorCheckBox;
|
||||
private JCheckBox tableHeaderButtonCheckBox;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.5.0.404" Java: "17.0.2" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -485,6 +485,16 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "alternatingRowsCheckBox"
|
||||
"text": "alternating rows"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alternatingRowsChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "intercellSpacingCheckBox"
|
||||
"text": "intercell spacing"
|
||||
@@ -505,6 +515,16 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "paintOutsideAlternateRowsCheckBox"
|
||||
"text": "outside alternating rows"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "paintOutsideAlternateRowsChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "redGridColorCheckBox"
|
||||
"text": "red grid color"
|
||||
|
||||
@@ -78,9 +78,15 @@ controlDkShadow = #696969
|
||||
Button.startBackground = #fff
|
||||
Button.endBackground = #bbb
|
||||
Button.focusedBackground = #0ff
|
||||
Button.focusedForeground = #00f
|
||||
Button.hoverBackground = #ff0
|
||||
Button.hoverForeground = #00f
|
||||
Button.pressedBackground = #FFC800
|
||||
Button.pressedForeground = #0080ff
|
||||
Button.selectedBackground = #fbb
|
||||
Button.selectedForeground = #321
|
||||
Button.disabledSelectedBackground = #123
|
||||
Button.disabledSelectedForeground = #fcc
|
||||
|
||||
Button.borderColor = #0f0
|
||||
Button.startBorderColor = #00f
|
||||
@@ -95,8 +101,11 @@ Button.default.startBackground = #ddd
|
||||
Button.default.endBackground = #888
|
||||
Button.default.foreground = #800
|
||||
Button.default.focusedBackground = #0ff
|
||||
Button.default.focusedForeground = #00f
|
||||
Button.default.hoverBackground = #ff0
|
||||
Button.default.hoverForeground = #00f
|
||||
Button.default.pressedBackground = #FFC800
|
||||
Button.default.pressedForeground = #0080ff
|
||||
Button.default.startBorderColor = #f00
|
||||
Button.default.endBorderColor = #00f
|
||||
Button.default.hoverBorderColor = #f00
|
||||
@@ -104,8 +113,13 @@ Button.default.focusedBorderColor = #537699
|
||||
Button.default.focusColor = #f00
|
||||
|
||||
Button.toolbar.hoverBackground = #fff
|
||||
Button.toolbar.hoverForeground = #000
|
||||
Button.toolbar.pressedBackground = #eee
|
||||
Button.toolbar.pressedForeground = #666
|
||||
Button.toolbar.selectedBackground = #ddd
|
||||
Button.toolbar.selectedForeground = #800
|
||||
Button.toolbar.disabledSelectedBackground = #ccc
|
||||
Button.toolbar.disabledSelectedForeground = #866
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
@@ -422,12 +436,28 @@ ToggleButton.background = #ddf
|
||||
ToggleButton.selectedBackground = #4f4
|
||||
ToggleButton.selectedForeground = #000
|
||||
ToggleButton.disabledSelectedBackground = #4d4
|
||||
ToggleButton.disabledSelectedForeground = #fff
|
||||
|
||||
ToggleButton.focusedBackground = #0ff
|
||||
ToggleButton.focusedForeground = #00f
|
||||
ToggleButton.hoverBackground = #ff0
|
||||
ToggleButton.hoverForeground = #00f
|
||||
ToggleButton.pressedBackground = #FFC800
|
||||
ToggleButton.pressedForeground = #0080ff
|
||||
|
||||
ToggleButton.toolbar.hoverBackground = #fff
|
||||
ToggleButton.toolbar.hoverForeground = #000
|
||||
ToggleButton.toolbar.pressedBackground = #eee
|
||||
ToggleButton.toolbar.pressedForeground = #666
|
||||
ToggleButton.toolbar.selectedBackground = #ddd
|
||||
ToggleButton.toolbar.selectedForeground = #800
|
||||
ToggleButton.toolbar.disabledSelectedBackground = #ccc
|
||||
ToggleButton.toolbar.disabledSelectedForeground = #866
|
||||
|
||||
ToggleButton.tab.selectedBackground = #080
|
||||
ToggleButton.tab.selectedForeground = #fff
|
||||
ToggleButton.tab.hoverForeground = #00f
|
||||
ToggleButton.tab.focusForeground = #080
|
||||
|
||||
|
||||
#---- ToolBar ----
|
||||
|
||||
@@ -482,6 +482,10 @@ class FlatCompletionProvider
|
||||
"dark", colorParamDesc,
|
||||
"light", colorParamDesc,
|
||||
"threshold", "(optional) 0-100%, default is 43%" );
|
||||
|
||||
addFunction( "over",
|
||||
"foreground", colorParamDesc,
|
||||
"background", colorParamDesc );
|
||||
}
|
||||
|
||||
private void addFunction( String name, String... paramNamesAndDescs ) {
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
public class FlatLafThemeEditor
|
||||
{
|
||||
public static void main( String[] args ) {
|
||||
// macOS
|
||||
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// enable screen menu bar
|
||||
// (moves menu bar from JFrame window to top of screen)
|
||||
@@ -41,6 +41,7 @@ public class FlatLafThemeEditor
|
||||
// - "system": use current macOS appearance (light or dark)
|
||||
// - "NSAppearanceNameAqua": use light appearance
|
||||
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||
}
|
||||
|
||||
|
||||
@@ -173,10 +173,30 @@ class FlatThemeFileEditor
|
||||
|
||||
enableDisableActions();
|
||||
|
||||
// hide some menu items on macOS
|
||||
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// hide menu items that are in macOS application menu
|
||||
exitMenuItem.setVisible( false );
|
||||
aboutMenuItem.setVisible( false );
|
||||
|
||||
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||
// expand window content into window title bar and make title bar transparent
|
||||
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||
|
||||
// hide window title
|
||||
if( SystemInfo.isJava_17_orLater )
|
||||
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||
else
|
||||
setTitle( null );
|
||||
|
||||
// add gap to left side of toolbar
|
||||
controlPanel.add( Box.createHorizontalStrut( 70 ), 0 );
|
||||
}
|
||||
|
||||
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||
if( !SystemInfo.isJava_11_orLater )
|
||||
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
||||
}
|
||||
|
||||
// integrate into macOS screen menu
|
||||
@@ -365,7 +385,17 @@ class FlatThemeFileEditor
|
||||
String n2 = toSortName( f2.getName() );
|
||||
return n1.compareToIgnoreCase( n2 );
|
||||
} );
|
||||
return propertiesFiles;
|
||||
|
||||
File themesDir = new File( dir, "themes" );
|
||||
if( !themesDir.isDirectory() )
|
||||
return propertiesFiles;
|
||||
|
||||
// get files from "themes" sub-directory
|
||||
File[] themesFiles = getPropertiesFiles( themesDir );
|
||||
File[] allFiles = new File[propertiesFiles.length + themesFiles.length];
|
||||
System.arraycopy( propertiesFiles, 0, allFiles, 0, propertiesFiles.length );
|
||||
System.arraycopy( themesFiles, 0, allFiles, propertiesFiles.length, themesFiles.length );
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
private String toSortName( String name ) {
|
||||
@@ -450,12 +480,21 @@ class FlatThemeFileEditor
|
||||
FlatIntelliJLaf.NAME,
|
||||
FlatDarculaLaf.NAME,
|
||||
} );
|
||||
JCheckBox genJavaClassCheckBox = new JCheckBox( "Generate Java class" );
|
||||
genJavaClassCheckBox.setMnemonic( 'G' );
|
||||
|
||||
File themesDir = new File( dir, "themes" );
|
||||
JCheckBox useThemesDirCheckBox = themesDir.isDirectory()
|
||||
? new JCheckBox( "Create in 'themes' directory", true )
|
||||
: null;
|
||||
|
||||
JOptionPane optionPane = new JOptionPane( new Object[] {
|
||||
new JLabel( "Theme name:" ),
|
||||
themeNameField,
|
||||
new JLabel( "Base Theme:" ),
|
||||
baseThemeField,
|
||||
genJavaClassCheckBox,
|
||||
useThemesDirCheckBox,
|
||||
}, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION ) {
|
||||
@Override
|
||||
public void selectInitialValue() {
|
||||
@@ -477,7 +516,8 @@ class FlatThemeFileEditor
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File( dir, themeName + ".properties" );
|
||||
File dir2 = (useThemesDirCheckBox != null && useThemesDirCheckBox.isSelected()) ? themesDir : dir;
|
||||
File file = new File( dir2, themeName + ".properties" );
|
||||
if( file.exists() ) {
|
||||
JOptionPane.showMessageDialog( this, "Theme '" + themeName + "' already exists.", title, JOptionPane.INFORMATION_MESSAGE );
|
||||
return;
|
||||
@@ -486,7 +526,8 @@ class FlatThemeFileEditor
|
||||
try {
|
||||
String baseTheme = (String) baseThemeField.getSelectedItem();
|
||||
createTheme( file, baseTheme );
|
||||
createThemeClass( dir, themeName, baseTheme );
|
||||
if( genJavaClassCheckBox.isSelected() )
|
||||
createThemeClass( dir2, themeName, baseTheme );
|
||||
openFile( file, true );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
|
||||
@@ -76,6 +76,7 @@ public class FlatThemeTokenMaker
|
||||
tokenMap.put( "tint", TOKEN_FUNCTION );
|
||||
tokenMap.put( "shade", TOKEN_FUNCTION );
|
||||
tokenMap.put( "contrast", TOKEN_FUNCTION );
|
||||
tokenMap.put( "over", TOKEN_FUNCTION );
|
||||
|
||||
// function options
|
||||
tokenMap.put( "relative", Token.RESERVED_WORD );
|
||||
|
||||
@@ -23,10 +23,13 @@ Button.default.endBorderColor
|
||||
Button.default.focusColor
|
||||
Button.default.focusedBackground
|
||||
Button.default.focusedBorderColor
|
||||
Button.default.focusedForeground
|
||||
Button.default.foreground
|
||||
Button.default.hoverBackground
|
||||
Button.default.hoverBorderColor
|
||||
Button.default.hoverForeground
|
||||
Button.default.pressedBackground
|
||||
Button.default.pressedForeground
|
||||
Button.default.startBackground
|
||||
Button.default.startBorderColor
|
||||
Button.defaultButtonFollowsFocus
|
||||
@@ -34,23 +37,27 @@ Button.disabledBackground
|
||||
Button.disabledBorderColor
|
||||
Button.disabledForeground
|
||||
Button.disabledSelectedBackground
|
||||
Button.disabledSelectedForeground
|
||||
Button.disabledText
|
||||
Button.endBackground
|
||||
Button.endBorderColor
|
||||
Button.focusInputMap
|
||||
Button.focusedBackground
|
||||
Button.focusedBorderColor
|
||||
Button.focusedForeground
|
||||
Button.font
|
||||
Button.foreground
|
||||
Button.highlight
|
||||
Button.hoverBackground
|
||||
Button.hoverBorderColor
|
||||
Button.hoverForeground
|
||||
Button.iconTextGap
|
||||
Button.innerFocusWidth
|
||||
Button.light
|
||||
Button.margin
|
||||
Button.minimumWidth
|
||||
Button.pressedBackground
|
||||
Button.pressedForeground
|
||||
Button.rollover
|
||||
Button.selectedBackground
|
||||
Button.selectedForeground
|
||||
@@ -59,10 +66,15 @@ Button.startBackground
|
||||
Button.startBorderColor
|
||||
Button.textIconGap
|
||||
Button.textShiftOffset
|
||||
Button.toolbar.disabledSelectedBackground
|
||||
Button.toolbar.disabledSelectedForeground
|
||||
Button.toolbar.hoverBackground
|
||||
Button.toolbar.hoverForeground
|
||||
Button.toolbar.margin
|
||||
Button.toolbar.pressedBackground
|
||||
Button.toolbar.pressedForeground
|
||||
Button.toolbar.selectedBackground
|
||||
Button.toolbar.selectedForeground
|
||||
Button.toolbar.spacingInsets
|
||||
ButtonUI
|
||||
Caret.width
|
||||
@@ -185,6 +197,7 @@ ComboBox.buttonShadow
|
||||
ComboBox.buttonStyle
|
||||
ComboBox.disabledBackground
|
||||
ComboBox.disabledForeground
|
||||
ComboBox.editableBackground
|
||||
ComboBox.editorColumns
|
||||
ComboBox.focusedBackground
|
||||
ComboBox.font
|
||||
@@ -252,6 +265,8 @@ FileChooser.homeFolderIcon
|
||||
FileChooser.listViewIcon
|
||||
FileChooser.newFolderIcon
|
||||
FileChooser.readOnly
|
||||
FileChooser.shortcuts.buttonSize
|
||||
FileChooser.shortcuts.iconSize
|
||||
FileChooser.upFolderIcon
|
||||
FileChooser.useSystemExtensionHiding
|
||||
FileChooser.usesSingleFilePane
|
||||
@@ -714,6 +729,7 @@ Separator.stripeIndent
|
||||
Separator.stripeWidth
|
||||
SeparatorUI
|
||||
Slider.background
|
||||
Slider.disabledThumbBorderColor
|
||||
Slider.disabledThumbColor
|
||||
Slider.disabledTrackColor
|
||||
Slider.focus
|
||||
@@ -999,32 +1015,44 @@ ToggleButton.border
|
||||
ToggleButton.darkShadow
|
||||
ToggleButton.disabledBackground
|
||||
ToggleButton.disabledSelectedBackground
|
||||
ToggleButton.disabledSelectedForeground
|
||||
ToggleButton.disabledText
|
||||
ToggleButton.focusInputMap
|
||||
ToggleButton.focusedBackground
|
||||
ToggleButton.focusedForeground
|
||||
ToggleButton.font
|
||||
ToggleButton.foreground
|
||||
ToggleButton.highlight
|
||||
ToggleButton.hoverBackground
|
||||
ToggleButton.hoverForeground
|
||||
ToggleButton.iconTextGap
|
||||
ToggleButton.light
|
||||
ToggleButton.margin
|
||||
ToggleButton.pressedBackground
|
||||
ToggleButton.pressedForeground
|
||||
ToggleButton.rollover
|
||||
ToggleButton.selectedBackground
|
||||
ToggleButton.selectedForeground
|
||||
ToggleButton.shadow
|
||||
ToggleButton.tab.disabledUnderlineColor
|
||||
ToggleButton.tab.focusBackground
|
||||
ToggleButton.tab.focusForeground
|
||||
ToggleButton.tab.hoverBackground
|
||||
ToggleButton.tab.hoverForeground
|
||||
ToggleButton.tab.selectedBackground
|
||||
ToggleButton.tab.selectedForeground
|
||||
ToggleButton.tab.underlineColor
|
||||
ToggleButton.tab.underlineHeight
|
||||
ToggleButton.textIconGap
|
||||
ToggleButton.textShiftOffset
|
||||
ToggleButton.toolbar.disabledSelectedBackground
|
||||
ToggleButton.toolbar.disabledSelectedForeground
|
||||
ToggleButton.toolbar.hoverBackground
|
||||
ToggleButton.toolbar.hoverForeground
|
||||
ToggleButton.toolbar.pressedBackground
|
||||
ToggleButton.toolbar.pressedForeground
|
||||
ToggleButton.toolbar.selectedBackground
|
||||
ToggleButton.toolbar.selectedForeground
|
||||
ToggleButtonUI
|
||||
ToolBar.ancestorInputMap
|
||||
ToolBar.arrowKeysOnlyNavigation
|
||||
|
||||
@@ -118,6 +118,12 @@ Prop.6.selectionForeground = contrast($Prop.6.selectionBackground,#000,#fff)
|
||||
Prop.7.selectionBackground = #FF9500
|
||||
Prop.7.selectionForeground = contrast($Prop.7.selectionBackground,#000,#fff)
|
||||
|
||||
Prop.colorFunc60 = over(#fff8,#f00)
|
||||
Prop.colorFunc61 = over(#fff8,#0f0)
|
||||
Prop.colorFunc62 = over(#f000,#0f0)
|
||||
Prop.colorFunc63 = over(#f00,#0f0)
|
||||
Prop.colorFunc64 = over(#f008,null)
|
||||
|
||||
|
||||
|
||||
@varStyle1 = #f0f
|
||||
|
||||
Reference in New Issue
Block a user