Compare commits

..

2 Commits

99 changed files with 1172 additions and 8642 deletions

View File

@@ -34,7 +34,6 @@ jobs:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
if: matrix.java == '1.8'
- name: Setup Java ${{ matrix.java }}
uses: actions/setup-java@v1

View File

@@ -12,22 +12,6 @@ FlatLaf Change Log
- Style classes allow defining style rules at a single place (in UI defaults)
and use them in any component. (PR #388)\
E.g.: `mySlider.putClientProperty( "FlatLaf.styleClass", "myclass" );`
- Typography defines several font styles for headers and various text sizes,
which makes it easy to use consistent font styles across the application. (PR
#396)
- Native window decorations (Windows 10/11 only):
- Unified backgrounds for window title bar is now enabled by default (window
title bar has now same background color as window content). Bottom separator
for menu bars is no longer painted (if unified background is enabled).
- Show Windows 11 snap layouts menu when hovering the mouse over the maximize
button. (issues #397 and #407)
- 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
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)
- TextField, FormattedTextField and PasswordField: Support leading and trailing
icons (set client property `JTextField.leadingIcon` or
`JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368)
@@ -60,58 +44,25 @@ FlatLaf Change Log
incompatible changes in FlatLaf properties files.
- Slider: Support specifying width of thumb border (see UI value
`Slider.thumbBorderWidth`).
- TabbedPane: Optionally paint selected tab as card. (PR #343)
- Added more color functions to class `ColorFunctions` for easy use in
applications: `lighten()`, `darken()`, `saturate()`, `desaturate()`, `spin()`,
`tint()`, `shade()` and `luma()`.
- Support defining fonts in FlatLaf properties files. (issue #384)
- Added method `FlatLaf.registerCustomDefaultsSource(URL packageUrl)` for JPMS.
(issue #325)
- Extras:
- Added class `FlatDesktop` for easy integration into macOS screen menu
(About, Preferences and Quit) when using Java 8.
- `FlatSVGIcon`: Support loading SVG from `URL` (for JPMS), `URI`, `File` or
`InputStream`. (issues #419 and #325)
- `FlatSVGUtils`: Support loading SVG from `URL` (for JPMS). (issue #325)
## 1.6.4
#### Fixed bugs
- ComboBox: Fixed regression in FlatLaf 1.6.3 that makes selected item invisible
in popup list if `DefaultListCellRenderer` is used as renderer. If using
default renderer, it works. (issue #426)
## 1.6.3
#### Fixed bugs
- ComboBox (not editable): Fixed regression in FlatLaf 1.6.2 that may display
text in non-editable combo boxes in bold. (issue #423)
- Tree: Fixed editing cell issue with custom cell renderer and cell editor that
use same component for rendering and editing. (issue #385)
## 1.6.2
- Extras: Added class `FlatDesktop` for easy integration into macOS screen menu
(About, Preferences and Quit) when using Java 8.
#### Fixed bugs
- ComboBox (not editable): Fixed background painted outside of border if round
edges are enabled (client property `JComponent.roundRect` is `true`). (similar
to issue #382; regression since fixing #330 in FlatLaf 1.4)
- ComboBox: Fixed `NullPointerException`, which may occur under special
circumstances. (issue #408)
- Tree: Fixed editing cell issue with custom cell renderer and cell editor that
use same component for rendering and editing. (issue #385)
- Table: Do not select text in cell editor when it gets focus (when
`JTable.surrendersFocusOnKeystroke` is `true`) and
`TextComponent.selectAllOnFocusPolicy` is `once` (the default) or `always`.
(issue #395)
- Linux: Fixed NPE when using `java.awt.TrayIcon`. (issue #405)
- FileChooser: Workaround for crash on Windows with Java 17 32-bit (disabled
Windows icons). Java 17 64-bit is not affected. (issue #403)
- Native window decorations: Fixed layout loop, which may occur under special
circumstances and slows down the application. (issue #420)
## 1.6.1

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
val releaseVersion = "1.6.4"
val releaseVersion = "1.6.1"
val developmentVersion = "2.0-SNAPSHOT"
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion

View File

@@ -331,24 +331,6 @@ public interface FlatClientProperties
*/
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
/**
* Specifies whether the window icon should be shown in the window title bar
* (requires enabled window decorations).
* <p>
* Setting this shows/hides the windows icon
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
* <p>
* This client property has higher priority than UI default {@code TitlePane.showIcon}.
* <p>
* (requires Window 10)
* <p>
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
* <strong>Value type</strong> {@link java.lang.Boolean}
*
* @since 2
*/
String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
/**
* Background color of window title bar (requires enabled window decorations).
* <p>
@@ -393,35 +375,6 @@ public interface FlatClientProperties
//---- JTabbedPane --------------------------------------------------------
/**
* Specifies type of the selected tab.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong>
* {@link #TABBED_PANE_TAB_TYPE_UNDERLINED} or
* {@link #TABBED_PANE_TAB_TYPE_CARD}
*
* @since 2
*/
String TABBED_PANE_TAB_TYPE = "JTabbedPane.tabType";
/**
* Paint the selected tab underlined.
*
* @see #TABBED_PANE_TAB_TYPE
* @since 2
*/
String TABBED_PANE_TAB_TYPE_UNDERLINED = "underlined";
/**
* Paint the selected tab as card.
*
* @see #TABBED_PANE_TAB_TYPE
* @since 2
*/
String TABBED_PANE_TAB_TYPE_CARD = "card";
/**
* Specifies whether separators are shown between tabs.
* <p>

View File

@@ -31,7 +31,6 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -393,7 +392,6 @@ public abstract class FlatLaf
"EditorPane.inactiveBackground",
"FormattedTextField.disabledBackground",
"PasswordField.disabledBackground",
"RootPane.background",
"Spinner.disabledBackground",
"TextArea.disabledBackground",
"TextArea.inactiveBackground",
@@ -412,8 +410,7 @@ public abstract class FlatLaf
"Spinner.disabledForeground",
"ToggleButton.disabledText" );
putDefaults( defaults, defaults.getColor( "textText" ),
"DesktopIcon.foreground",
"RootPane.foreground" );
"DesktopIcon.foreground" );
initFonts( defaults );
initIconColors( defaults, isDark() );
@@ -423,7 +420,7 @@ public abstract class FlatLaf
// (using defaults.remove() to avoid that lazy value is resolved and icon loaded here)
Object icon = defaults.remove( "InternalFrame.icon" );
defaults.put( "InternalFrame.icon", icon );
defaults.put( "TitlePane.icon", icon ); // no longer used, but keep for compatibility
defaults.put( "TitlePane.icon", icon );
// get addons and sort them by priority
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
@@ -536,16 +533,13 @@ public abstract class FlatLaf
// use active value for all fonts to allow changing fonts in all components with:
// UIManager.put( "defaultFont", myFont );
// (this is similar as in Nimbus L&F)
Object activeFont = new ActiveFont( null, null, -1, 0, 0, 0, 0 );
Object activeFont = new ActiveFont( null, -1, 0, 0, 0, 0 );
// override fonts
for( Object key : defaults.keySet() ) {
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont );
}
// add fonts that are not set in BasicLookAndFeel
defaults.put( "RootPane.font", activeFont );
}
private void initDefaultFont( UIDefaults defaults ) {
@@ -623,7 +617,7 @@ public abstract class FlatLaf
/** @since 1.1 */
public static ActiveValue createActiveFontValue( float scaleFactor ) {
return new ActiveFont( null, null, -1, 0, 0, 0, scaleFactor );
return new ActiveFont( null, -1, 0, 0, 0, scaleFactor );
}
/**
@@ -757,9 +751,6 @@ public abstract class FlatLaf
* and can therefore override all UI defaults.
* <p>
* Invoke this method before setting the look and feel.
* <p>
* If using Java modules, the package must be opened in {@code module-info.java}.
* Otherwise use {@link #registerCustomDefaultsSource(URL)}.
*
* @param packageName a package name (e.g. "com.myapp.resources")
*/
@@ -801,32 +792,6 @@ public abstract class FlatLaf
}
}
/**
* Registers a package where FlatLaf searches for properties files with custom UI defaults.
* <p>
* See {@link #registerCustomDefaultsSource(String)} for details.
* <p>
* This method is useful if using Java modules and the package containing the properties files
* is not opened in {@code module-info.java}.
* E.g. {@code FlatLaf.registerCustomDefaultsSource( MyApp.class.getResource( "/com/myapp/themes/" ) )}.
*
* @param packageUrl a package URL
* @since 2
*/
public static void registerCustomDefaultsSource( URL packageUrl ) {
if( customDefaultsSources == null )
customDefaultsSources = new ArrayList<>();
customDefaultsSources.add( packageUrl );
}
/** @since 2 */
public static void unregisterCustomDefaultsSource( URL packageUrl ) {
if( customDefaultsSources == null )
return;
customDefaultsSources.remove( packageUrl );
}
/**
* Registers a folder where FlatLaf searches for properties files with custom UI defaults.
* <p>
@@ -1226,7 +1191,6 @@ public abstract class FlatLaf
static class ActiveFont
implements ActiveValue
{
private final String baseFontKey;
private final List<String> families;
private final int style;
private final int styleChange;
@@ -1236,9 +1200,7 @@ public abstract class FlatLaf
// cache (scaled/derived) font
private FontUIResource font;
private Font lastBaseFont;
private boolean inCreateValue;
private Font lastDefaultFont;
/**
* @param families list of font families, or {@code null}
@@ -1249,10 +1211,9 @@ public abstract class FlatLaf
* @param relativeSize added to size of base font, or {@code 0}
* @param scaleSize multiply size of base font, or {@code 0}
*/
ActiveFont( String baseFontKey, List<String> families, int style, int styleChange,
ActiveFont( List<String> families, int style, int styleChange,
int absoluteSize, int relativeSize, float scaleSize )
{
this.baseFontKey = baseFontKey;
this.families = families;
this.style = style;
this.styleChange = styleChange;
@@ -1263,30 +1224,16 @@ public abstract class FlatLaf
@Override
public Object createValue( UIDefaults table ) {
if( inCreateValue )
throw new IllegalStateException( "FlatLaf: endless recursion in font" );
Font defaultFont = UIManager.getFont( "defaultFont" );
Font baseFont = null;
// fallback (to avoid NPE in case that this is used in another Laf)
if( defaultFont == null )
defaultFont = UIManager.getFont( "Label.font" );
inCreateValue = true;
try {
if( baseFontKey != null )
baseFont = (Font) UIDefaultsLoader.lazyUIManagerGet( baseFontKey );
if( lastDefaultFont != defaultFont ) {
lastDefaultFont = defaultFont;
if( baseFont == null )
baseFont = UIManager.getFont( "defaultFont" );
// fallback (to avoid NPE in case that this is used in another Laf)
if( baseFont == null )
baseFont = UIManager.getFont( "Label.font" );
} finally {
inCreateValue = false;
}
if( lastBaseFont != baseFont ) {
lastBaseFont = baseFont;
font = derive( baseFont, fontSize -> UIScale.scale( fontSize ) );
font = derive( defaultFont, fontSize -> UIScale.scale( fontSize ) );
}
return font;

View File

@@ -22,12 +22,13 @@ import java.awt.Font;
import java.awt.Insets;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.net.URL;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -55,7 +56,6 @@ import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.HSLColor;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SoftCache;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -84,7 +84,7 @@ class UIDefaultsLoader
private static int parseColorDepth;
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
private static final Cache<String, Object> fontCache = new Cache<>();
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
Properties additionalDefaults, boolean dark, UIDefaults defaults )
@@ -158,18 +158,6 @@ class UIDefaultsLoader
properties.load( in );
}
}
} else if( source instanceof URL ) {
// load from package URL
URL packageUrl = (URL) source;
for( Class<?> lafClass : lafClasses ) {
URL propertiesUrl = new URL( packageUrl + lafClass.getSimpleName() + ".properties" );
try( InputStream in = propertiesUrl.openStream() ) {
properties.load( in );
} catch( FileNotFoundException ex ) {
// ignore
}
}
} else if( source instanceof File ) {
// load from folder
File folder = (File) source;
@@ -441,7 +429,10 @@ class UIDefaultsLoader
// check whether value type is specified in the value
if( value.startsWith( "#" ) )
valueType = ValueType.COLOR;
else if( value.startsWith( TYPE_PREFIX ) ) {
else if( value.startsWith( "\"" ) && value.indexOf( '"', 1 ) == value.length() - 1 ) {
valueType = ValueType.STRING;
value = value.substring( 1, value.length() - 1 );
} else if( value.startsWith( TYPE_PREFIX ) ) {
int end = value.indexOf( TYPE_PREFIX_END );
if( end != -1 ) {
try {
@@ -533,12 +524,6 @@ class UIDefaultsLoader
case GRAYFILTER: return parseGrayFilter( value );
case UNKNOWN:
default:
// string
if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
resultValueType[0] = ValueType.STRING;
return value.substring( 1, value.length() - 1 );
}
// colors
Object color = parseColorOrFunction( value, resolver, false );
if( color != null ) {
@@ -1054,7 +1039,7 @@ class UIDefaultsLoader
}
/**
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]] [$baseFontKey]
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]]
*/
private static Object parseFont( String value ) {
Object font = fontCache.get( value );
@@ -1067,7 +1052,6 @@ class UIDefaultsLoader
int relativeSize = 0;
float scaleSize = 0;
List<String> families = null;
String baseFontKey = null;
// use StreamTokenizer to split string because it supports quoted strings
StreamTokenizer st = new StreamTokenizer( new StringReader( value ) );
@@ -1117,12 +1101,6 @@ class UIDefaultsLoader
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ), true ) / 100f;
else
absoluteSize = parseInteger( param, true );
} else if( firstChar == '$' ) {
// reference to base font
if( baseFontKey != null )
throw new IllegalArgumentException( "baseFontKey specified more than once in '" + value + "'" );
baseFontKey = param.substring( 1 );
} else {
// font family
if( families == null )
@@ -1149,7 +1127,7 @@ class UIDefaultsLoader
throw new IllegalArgumentException( "can not use '+italic' and '-italic' in '" + value + "'" );
}
font = new FlatLaf.ActiveFont( baseFontKey, families, style, styleChange, absoluteSize, relativeSize, scaleSize );
font = new FlatLaf.ActiveFont( families, style, styleChange, absoluteSize, relativeSize, scaleSize );
fontCache.put( value, font );
return font;
}
@@ -1302,7 +1280,7 @@ class UIDefaultsLoader
* For use in LazyValue to get value for given key from UIManager and report error
* if not found. If key is prefixed by '?', then no error is reported.
*/
static Object lazyUIManagerGet( String uiKey ) {
private static Object lazyUIManagerGet( String uiKey ) {
boolean optional = false;
if( uiKey.startsWith( OPTIONAL_PREFIX ) ) {
uiKey = uiKey.substring( OPTIONAL_PREFIX.length() );
@@ -1318,4 +1296,43 @@ class UIDefaultsLoader
private static void throwMissingParametersException( String value ) {
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
}
//---- class Cache --------------------------------------------------------
private static class Cache<K,V>
{
private final Map<K, CacheReference<K,V>> map = new HashMap<>();
private final ReferenceQueue<V> queue = new ReferenceQueue<>();
V get( K key ) {
expungeStaleEntries();
CacheReference<K,V> ref = map.get( key );
return (ref != null) ? ref.get() : null;
}
void put( K key, V value ) {
expungeStaleEntries();
map.put( key, new CacheReference<>( key, value, queue ) );
}
@SuppressWarnings( "unchecked" )
void expungeStaleEntries() {
Reference<? extends V> reference;
while( (reference = queue.poll()) != null )
map.remove( ((CacheReference<K,V>)reference).key );
}
//---- class CacheReference ----
private static class CacheReference<K,V>
extends SoftReference<V>
{
final K key;
public CacheReference( K key, V value, ReferenceQueue<? super V> queue ) {
super( value, queue );
this.key = key;
}
}
}
}

View File

@@ -69,13 +69,7 @@ public abstract class FlatAbstractIcon
}
}
/**
* Paint the icon at {@code [0,0]} location.
* <p>
* The given graphics context is scaled.
* Use unscaled coordinates, width and height for painting.
*/
protected abstract void paintIcon( Component c, Graphics2D g );
protected abstract void paintIcon( Component c, Graphics2D g2 );
@Override
public int getIconWidth() {

View File

@@ -21,7 +21,6 @@ import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import com.formdev.flatlaf.util.AnimatedIcon;
import com.formdev.flatlaf.util.AnimatedPainter;
/**
* Base class for animated icons that scales width and height, creates and initializes
@@ -31,7 +30,7 @@ import com.formdev.flatlaf.util.AnimatedPainter;
* <p>
* This class does not store any state information (needed for animation) in its instance.
* Instead a client property is set on the painted component.
* This makes it possible to use a shared icon instance for multiple components.
* This makes it possible to use a share icon instance for multiple components.
*
* @author Karl Tauber
*/
@@ -46,34 +45,11 @@ public abstract class FlatAnimatedIcon
@Override
public void paintIcon( Component c, Graphics g, int x, int y ) {
super.paintIcon( c, g, x, y );
AnimatedPainter.saveRepaintLocation( this, c, x, y );
AnimatedIcon.AnimationSupport.saveIconLocation( this, c, x, y );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
paintWithAnimation( c, g, 0, 0, getIconWidth(), getIconHeight() );
AnimatedIcon.AnimationSupport.paintIcon( this, c, g, 0, 0 );
}
/**
* Delegates painting to {@link #paintIconAnimated(Component, Graphics2D, float[])}.
* Ignores the given bounds because {@code [x,y]} are always {@code [0,0]} and
* {@code [width,height]} are scaled, but painting code should use unscaled width
* and height because given graphics context is scaled.
*
* @since 2
*/
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
paintIconAnimated( c, g, animatedValues );
}
/**
* Paint the icon at {@code 0,0} location.
* <p>
* The given graphics context is scaled.
* Use unscaled coordinates, width and height for painting.
*
* @since 2
*/
protected abstract void paintIconAnimated( Component c, Graphics2D g, float[] animatedValues );
}

View File

@@ -575,6 +575,22 @@ public class FlatComboBoxUI
@Override
@SuppressWarnings( "unchecked" )
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
// apply clipping using rounded rectangle to avoid that renderer paints
// outside of border if combobox uses larger arc for edges
// (e.g. FlatClientProperties.COMPONENT_ROUND_RECT is true)
FlatBorder border = FlatUIUtils.getOutsideFlatBorder( comboBox );
if( border != null ) {
int clipArc = border.getArc( comboBox ) - (border.getLineWidth( comboBox ) * 2);
if( clipArc > 0 ) {
int x = bounds.x;
int width = bounds.width + bounds.height;
if( !comboBox.getComponentOrientation().isLeftToRight() )
x -= bounds.height;
((Graphics2D)g).clip( FlatUIUtils.createComponentRectangle(
x, bounds.y, width, bounds.height, scale( (float) clipArc ) ) );
}
}
paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer();
@@ -588,20 +604,11 @@ public class FlatComboBoxUI
c.setBackground( getBackground( enabled ) );
c.setForeground( getForeground( enabled ) );
// make renderer component temporary non-opaque to avoid that renderer paints
// background outside of border if combobox uses larger arc for edges
// (e.g. FlatClientProperties.COMPONENT_ROUND_RECT is true)
if( c instanceof JComponent )
((JComponent)c).setOpaque( false );
boolean shouldValidate = (c instanceof JPanel);
paddingBorder.install( c );
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
paddingBorder.uninstall();
if( c instanceof JComponent )
((JComponent)c).setOpaque( true );
}
@Override

View File

@@ -262,20 +262,12 @@ public class FlatFileChooserUI
@Override
public FileView getFileView( JFileChooser fc ) {
return doNotUseSystemIcons() ? super.getFileView( fc ) : fileView;
return fileView;
}
@Override
public void clearIconCache() {
if( doNotUseSystemIcons() )
super.clearIconCache();
else
fileView.clearIconCache();
}
private boolean doNotUseSystemIcons() {
// Java 17 32bit craches on Windows when using system icons
return SystemInfo.isWindows && SystemInfo.isJava_17_orLater && !SystemInfo.isX86_64;
fileView.clearIconCache();
}
//---- class FlatFileView -------------------------------------------------

View File

@@ -53,9 +53,6 @@ public class FlatMenuBarBorder
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( !showBottomSeparator( c ) )
return;
float lineHeight = scale( (float) 1 );
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
}
@@ -71,9 +68,4 @@ public class FlatMenuBarBorder
insets.right = scale( margin.right );
return insets;
}
/** @since 2 */
protected boolean showBottomSeparator( Component c ) {
return !FlatMenuBarUI.useUnifiedBackground( c );
}
}

View File

@@ -17,7 +17,6 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Window;
@@ -190,8 +189,10 @@ public class FlatMenuBarUI
return background;
// use parent background for unified title pane
if( useUnifiedBackground( c ) )
background = FlatUIUtils.getParentBackground( c );
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
if( UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() ) )
background = FlatUIUtils.getParentBackground( c );
// paint background in full screen mode
if( FlatUIUtils.isFullScreen( rootPane ) )
@@ -201,22 +202,6 @@ public class FlatMenuBarUI
return FlatRootPaneUI.isMenuBarEmbedded( rootPane ) ? null : background;
}
/**@since 2 */
static boolean useUnifiedBackground( Component c ) {
// check whether:
// - TitlePane.unifiedBackground is true and
// - menu bar is the "main" menu bar and
// - window has custom decorations enabled
JRootPane rootPane;
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
return UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
(rootPane = SwingUtilities.getRootPane( c )) != null &&
rootPane.getParent() instanceof Window &&
rootPane.getJMenuBar() == c &&
FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() );
}
//---- class TakeFocus ----------------------------------------------------
/**

View File

@@ -235,8 +235,7 @@ public class FlatNativeWindowBorder
}
static void setTitleBarHeightAndHitTestSpots( Window window, int titleBarHeight,
List<Rectangle> hitTestSpots, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
List<Rectangle> hitTestSpots, Rectangle appIconBounds )
{
if( canUseJBRCustomDecorations ) {
JBRCustomDecorations.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots );
@@ -246,8 +245,9 @@ public class FlatNativeWindowBorder
if( !isSupported() )
return;
nativeProvider.updateTitleBarInfo( window, titleBarHeight, hitTestSpots,
appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
nativeProvider.setTitleBarHeight( window, titleBarHeight );
nativeProvider.setTitleBarHitTestSpots( window, hitTestSpots );
nativeProvider.setTitleBarAppIconBounds( window, appIconBounds );
}
static boolean showWindow( Window window, int cmd ) {
@@ -268,7 +268,7 @@ public class FlatNativeWindowBorder
try {
/*
Class<?> cls = Class.forName( "com.formdev.flatlaf.natives.jna.windows.FlatWindowsNativeWindowBorder" );
java.lang.reflect.Method m = cls.getMethod( "getInstance" );
Method m = cls.getMethod( "getInstance" );
setNativeProvider( (Provider) m.invoke( null ) );
*/
setNativeProvider( FlatWindowsNativeWindowBorder.getInstance() );
@@ -292,9 +292,9 @@ public class FlatNativeWindowBorder
{
boolean hasCustomDecoration( Window window );
void setHasCustomDecoration( Window window, boolean hasCustomDecoration );
void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
Rectangle closeButtonBounds );
void setTitleBarHeight( Window window, int titleBarHeight );
void setTitleBarHitTestSpots( Window window, List<Rectangle> hitTestSpots );
void setTitleBarAppIconBounds( Window window, Rectangle appIconBounds );
// commands for showWindow(); values must match Win32 API
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow

View File

@@ -22,22 +22,18 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.beans.PropertyChangeListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicOptionPaneUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -83,7 +79,6 @@ import com.formdev.flatlaf.util.UIScale;
*
* <!-- FlatOptionPaneUI -->
*
* @uiDefault OptionPane.showIcon boolean
* @uiDefault OptionPane.iconMessageGap int
* @uiDefault OptionPane.messagePadding int
* @uiDefault OptionPane.maxCharactersPerLine int
@@ -93,7 +88,6 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatOptionPaneUI
extends BasicOptionPaneUI
{
/** @since 2 */ protected boolean showIcon;
protected int iconMessageGap;
protected int messagePadding;
protected int maxCharactersPerLine;
@@ -108,7 +102,6 @@ public class FlatOptionPaneUI
protected void installDefaults() {
super.installDefaults();
showIcon = UIManager.getBoolean( "OptionPane.showIcon" );
iconMessageGap = UIManager.getInt( "OptionPane.iconMessageGap" );
messagePadding = UIManager.getInt( "OptionPane.messagePadding" );
maxCharactersPerLine = UIManager.getInt( "OptionPane.maxCharactersPerLine" );
@@ -123,24 +116,6 @@ public class FlatOptionPaneUI
updateChildPanels( optionPane );
}
@Override
protected PropertyChangeListener createPropertyChangeListener() {
PropertyChangeListener superListener = super.createPropertyChangeListener();
return e -> {
superListener.propertyChange( e );
// hide window title bar icon
// (only if showIcon is false, otherwise the default behavior is used)
if( !showIcon && "ancestor".equals( e.getPropertyName() ) && e.getNewValue() != null ) {
JRootPane rootPane = SwingUtilities.getRootPane( optionPane );
if( rootPane != null &&
rootPane.getContentPane().getComponentCount() > 0 &&
rootPane.getContentPane().getComponent( 0 ) == optionPane )
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, false );
}
};
}
@Override
public Dimension getMinimumOptionPaneSize() {
return UIScale.scale( super.getMinimumOptionPaneSize() );

View File

@@ -66,9 +66,6 @@ import com.formdev.flatlaf.util.UIScale;
*
* <!-- FlatWindowResizer -->
*
* @uiDefault RootPane.font Font unused
* @uiDefault RootPane.background Color
* @uiDefault RootPane.foreground Color unused
* @uiDefault RootPane.borderDragThickness int
* @uiDefault RootPane.cornerDragWidth int
* @uiDefault RootPane.honorFrameMinimumSizeOnResize boolean
@@ -129,23 +126,8 @@ public class FlatRootPaneUI
protected void installDefaults( JRootPane c ) {
super.installDefaults( c );
// Give the root pane useful background, foreground and font.
// Background is used for title bar and menu bar if native window decorations
// and unified background are enabled.
// Foreground and font are usually not used, but set for completeness.
// Not using LookAndFeel.installColorsAndFont() here because it will not work
// because the properties are null by default but inherit non-null values from parent.
if( !c.isBackgroundSet() || c.getBackground() instanceof UIResource )
c.setBackground( UIManager.getColor( "RootPane.background" ) );
if( !c.isForegroundSet() || c.getForeground() instanceof UIResource )
c.setForeground( UIManager.getColor( "RootPane.foreground" ) );
if( !c.isFontSet() || c.getFont() instanceof UIResource )
c.setFont( UIManager.getFont( "RootPane.font" ) );
// Update background color of JFrame or JDialog parent to avoid bad border
// on HiDPI screens when switching from light to dark Laf.
// Window background color is also used in native window decorations
// to fill background when window is initially shown or when resizing window.
// The background of JFrame is initialized in JFrame.frameInit() and
// the background of JDialog in JDialog.dialogInit(),
// but it was not updated when switching Laf.
@@ -331,11 +313,6 @@ public class FlatRootPaneUI
}
break;
case FlatClientProperties.TITLE_BAR_SHOW_ICON:
if( titlePane != null )
titlePane.updateIcon();
break;
case FlatClientProperties.TITLE_BAR_BACKGROUND:
case FlatClientProperties.TITLE_BAR_FOREGROUND:
if( titlePane != null )

View File

@@ -97,7 +97,8 @@ public class FlatStylingSupport
Object style = getStyle( c );
Object styleClass = getStyleClass( c );
Object styleForClasses = getStyleForClasses( styleClass, type );
return joinStyles( styleForClasses, style );
Object styleForType = getStyleForType( type );
return joinStyles( joinStyles( styleForType, styleForClasses ), style );
}
/**
@@ -162,6 +163,28 @@ public class FlatStylingSupport
UIManager.get( "[style]" + type + '.' + styleClass ) );
}
/**
* Returns the styles for the given type.
* <p>
* The style rules must be defined in UI defaults either as strings (in CSS syntax)
* or as {@link java.util.Map}&lt;String, Object&gt; (with binary values).
* The key must be in syntax: {@code [style]type}.
* E.g. in FlatLaf properties file:
* <pre>{@code
* [style]Button = borderColor: #08f; background: #08f; foreground: #fff
* }</pre>
* or in Java code:
* <pre>{@code
* UIManager.put( "[style]Button", "borderColor: #08f; background: #08f; foreground: #fff" );
* }</pre>
*
* @param type the type of the component
* @return the styles
*/
public static Object getStyleForType( String type ) {
return UIManager.get( "[style]" + type );
}
/**
* Joins two styles. They can be either strings (in CSS syntax)
* or {@link java.util.Map}&lt;String, Object&gt; (with binary values).
@@ -462,22 +485,34 @@ public class FlatStylingSupport
String getterName = buildMethodName( "get", name );
String setterName = buildMethodName( "set", name );
try {
Method getter;
for(;;) {
try {
getter = cls.getMethod( getterName );
Method getter;
try {
getter = cls.getMethod( getterName );
} catch( NoSuchMethodException ex ) {
getter = cls.getMethod( buildMethodName( "is", name ) );
}
Method setter = cls.getMethod( setterName, getter.getReturnType() );
Object oldValue = getter.invoke( obj );
setter.invoke( obj, convertToEnum( value, getter.getReturnType() ) );
return oldValue;
} catch( NoSuchMethodException ex ) {
getter = cls.getMethod( buildMethodName( "is", name ) );
throw new UnknownStyleException( name );
} catch( Exception ex ) {
if( ex instanceof IllegalAccessException ) {
// this may happen for private subclasses of public Swing classes
// that override public property getter/setter
// e.g. class JSlider.SmartHashtable.LabelUIResource.getForeground()
// --> try again with superclass
cls = cls.getSuperclass();
if( cls != null && cls != Object.class )
continue;
}
throw new IllegalArgumentException( "failed to invoke property methods '" + cls.getName() + "."
+ getterName + "()' or '" + setterName + "(...)'", ex );
}
Method setter = cls.getMethod( setterName, getter.getReturnType() );
Object oldValue = getter.invoke( obj );
setter.invoke( obj, convertToEnum( value, getter.getReturnType() ) );
return oldValue;
} catch( NoSuchMethodException ex ) {
throw new UnknownStyleException( name );
} catch( Exception ex ) {
throw new IllegalArgumentException( "failed to invoke property methods '" + cls.getName() + "."
+ getterName + "()' or '" + setterName + "(...)'", ex );
}
}

View File

@@ -40,8 +40,6 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@@ -136,15 +134,12 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.maximumTabWidth int optional
* @uiDefault TabbedPane.tabHeight int
* @uiDefault TabbedPane.tabSelectionHeight int
* @uiDefault TabbedPane.cardTabSelectionHeight int
* @uiDefault TabbedPane.contentSeparatorHeight int
* @uiDefault TabbedPane.showTabSeparators boolean
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
* @uiDefault TabbedPane.hasFullBorder boolean
* @uiDefault TabbedPane.activeTabBorder boolean
*
* @uiDefault TabbedPane.tabLayoutPolicy String wrap (default) or scroll
* @uiDefault TabbedPane.tabType String underlined (default) or card
* @uiDefault TabbedPane.tabsPopupPolicy String never or asNeeded (default)
* @uiDefault TabbedPane.scrollButtonsPolicy String never, asNeeded or asNeededSingle (default)
* @uiDefault TabbedPane.scrollButtonsPlacement String both (default) or trailing
@@ -170,10 +165,6 @@ public class FlatTabbedPaneUI
extends BasicTabbedPaneUI
implements StyleableUI
{
// tab type
/** @since 2 */ protected static final int TAB_TYPE_UNDERLINED = 0;
/** @since 2 */ protected static final int TAB_TYPE_CARD = 1;
// tabs popup policy / scroll arrows policy
protected static final int NEVER = 0;
// protected static final int ALWAYS = 1;
@@ -209,14 +200,12 @@ public class FlatTabbedPaneUI
@Styleable protected int maximumTabWidth;
@Styleable protected int tabHeight;
@Styleable protected int tabSelectionHeight;
/** @since 2 */ @Styleable protected int cardTabSelectionHeight;
@Styleable protected int contentSeparatorHeight;
@Styleable protected boolean showTabSeparators;
@Styleable protected boolean tabSeparatorsFullHeight;
@Styleable protected boolean hasFullBorder;
@Styleable protected boolean tabsOpaque = true;
@Styleable(type=String.class) private int tabType;
@Styleable(type=String.class) private int tabsPopupPolicy;
@Styleable(type=String.class) private int scrollButtonsPolicy;
@Styleable(type=String.class) private int scrollButtonsPlacement;
@@ -329,14 +318,12 @@ public class FlatTabbedPaneUI
maximumTabWidth = UIManager.getInt( "TabbedPane.maximumTabWidth" );
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
cardTabSelectionHeight = UIManager.getInt( "TabbedPane.cardTabSelectionHeight" );
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
tabType = parseTabType( UIManager.getString( "TabbedPane.tabType" ) );
tabsPopupPolicy = parseTabsPopupPolicy( UIManager.getString( "TabbedPane.tabsPopupPolicy" ) );
scrollButtonsPolicy = parseScrollButtonsPolicy( UIManager.getString( "TabbedPane.scrollButtonsPolicy" ) );
scrollButtonsPlacement = parseScrollButtonsPlacement( UIManager.getString( "TabbedPane.scrollButtonsPlacement" ) );
@@ -573,13 +560,6 @@ public class FlatTabbedPaneUI
return handler;
}
@Override
protected FocusListener createFocusListener() {
Handler handler = getHandler();
handler.focusDelegate = super.createFocusListener();
return handler;
}
@Override
protected LayoutManager createLayoutManager() {
if( tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT )
@@ -638,7 +618,6 @@ public class FlatTabbedPaneUI
if( value instanceof String ) {
switch( key ) {
case "tabType": value = parseTabType( (String) value ); break;
case "tabsPopupPolicy": value = parseTabsPopupPolicy( (String) value ); break;
case "scrollButtonsPolicy": value = parseScrollButtonsPolicy( (String) value ); break;
case "scrollButtonsPlacement": value = parseScrollButtonsPlacement( (String) value ); break;
@@ -728,25 +707,8 @@ public class FlatTabbedPaneUI
return;
Rectangle r = getTabBounds( tabPane, tabIndex );
if( r == null )
return;
// increase size of repaint region to include part of content border
if( contentSeparatorHeight > 0 &&
getTabType() == TAB_TYPE_CARD &&
clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
{
int sh = scale( contentSeparatorHeight );
switch( tabPane.getTabPlacement() ) {
default:
case TOP: r.height += sh; break;
case BOTTOM: r.height += sh; r.y -= sh; break;
case LEFT: r.width += sh; break;
case RIGHT: r.width += sh; r.x -= sh; break;
}
}
tabPane.repaint( r );
if( r != null )
tabPane.repaint( r );
}
private boolean inCalculateEqual;
@@ -1083,21 +1045,16 @@ public class FlatTabbedPaneUI
int x, int y, int w, int h, boolean isSelected )
{
// paint tab background
Color background = getTabBackground( tabPlacement, tabIndex, isSelected );
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
g.fillRect( x, y, w, h );
}
/** @since 2 */
protected Color getTabBackground( int tabPlacement, int tabIndex, boolean isSelected ) {
boolean enabled = tabPane.isEnabled();
return enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex
Color background = enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex
? hoverColor
: (enabled && isSelected && FlatUIUtils.isPermanentFocusOwner( tabPane )
? focusColor
: (selectedBackground != null && enabled && isSelected
? selectedBackground
: tabPane.getBackgroundAt( tabIndex )));
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
g.fillRect( x, y, w, h );
}
@Override
@@ -1107,62 +1064,7 @@ public class FlatTabbedPaneUI
// paint tab separators
if( clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) &&
!isLastInRun( tabIndex ) )
{
if( getTabType() == TAB_TYPE_CARD ) {
// some separators need to be omitted if selected tab is painted as card
int selectedIndex = tabPane.getSelectedIndex();
if( tabIndex != selectedIndex - 1 && tabIndex != selectedIndex )
paintTabSeparator( g, tabPlacement, x, y, w, h );
} else
paintTabSeparator( g, tabPlacement, x, y, w, h );
}
// paint active tab border
if( isSelected && getTabType() == TAB_TYPE_CARD )
paintCardTabBorder( g, tabPlacement, tabIndex, x, y, w, h );
}
/** @since 2 */
protected void paintCardTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h ) {
Graphics2D g2 = (Graphics2D) g;
float borderWidth = scale( (float) contentSeparatorHeight );
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
switch( tabPlacement ) {
default:
case TOP:
case BOTTOM:
// paint left and right tab border
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) );
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) );
break;
case LEFT:
case RIGHT:
// paint top and bottom tab border
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) );
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
}
if( cardTabSelectionHeight <= 0 ) {
// if there is no tab selection indicator, paint a top border as well
switch( tabPlacement ) {
default:
case TOP:
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) );
break;
case BOTTOM:
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
case LEFT:
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) );
break;
case RIGHT:
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) );
break;
}
}
paintTabSeparator( g, tabPlacement, x, y, w, h );
}
protected void paintTabCloseButton( Graphics g, int tabIndex, int x, int y, int w, int h ) {
@@ -1208,30 +1110,26 @@ public class FlatTabbedPaneUI
g.setColor( tabPane.isEnabled() ? underlineColor : disabledUnderlineColor );
// paint underline selection
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
Insets contentInsets = getContentBorderInsets( tabPlacement );
int tabSelectionHeight = scale( atBottom ? this.tabSelectionHeight : cardTabSelectionHeight );
int sx, sy;
int tabSelectionHeight = scale( this.tabSelectionHeight );
switch( tabPlacement ) {
case TOP:
default:
sy = atBottom ? (y + h + contentInsets.top - tabSelectionHeight) : y;
int sy = y + h + contentInsets.top - tabSelectionHeight;
g.fillRect( x, sy, w, tabSelectionHeight );
break;
case BOTTOM:
sy = atBottom ? (y - contentInsets.bottom) : (y + h - tabSelectionHeight);
g.fillRect( x, sy, w, tabSelectionHeight );
g.fillRect( x, y - contentInsets.bottom, w, tabSelectionHeight );
break;
case LEFT:
sx = atBottom ? (x + w + contentInsets.left - tabSelectionHeight) : x;
int sx = x + w + contentInsets.left - tabSelectionHeight;
g.fillRect( sx, y, tabSelectionHeight, h );
break;
case RIGHT:
sx = atBottom ? (x - contentInsets.right) : (x + w - tabSelectionHeight);
g.fillRect( sx, y, tabSelectionHeight, h );
g.fillRect( x - contentInsets.right, y, tabSelectionHeight, h );
break;
}
}
@@ -1243,7 +1141,6 @@ public class FlatTabbedPaneUI
* - paint full border (if enabled)
* - not invoking paintContentBorder*Edge() methods
* - repaint selection
* - painting active tab border style
*/
@Override
protected void paintContentBorder( Graphics g, int tabPlacement, int selectedIndex ) {
@@ -1292,49 +1189,12 @@ public class FlatTabbedPaneUI
Insets ci = new Insets( 0, 0, 0, 0 );
rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement );
// create path for content separator or full border
// paint content separator or full border
g.setColor( contentAreaColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Rectangle2D.Float( x, y, w, h ), false );
path.append( new Rectangle2D.Float( x + (ci.left / 100f), y + (ci.top / 100f),
w - (ci.left / 100f) - (ci.right / 100f), h - (ci.top / 100f) - (ci.bottom / 100f) ), false );
// add gap for selected tab to path
if( getTabType() == TAB_TYPE_CARD ) {
float csh = scale( (float) contentSeparatorHeight );
Rectangle tabRect = getTabBounds( tabPane, selectedIndex );
Rectangle2D.Float innerTabRect = new Rectangle2D.Float( tabRect.x + csh, tabRect.y + csh,
tabRect.width - (csh * 2), tabRect.height - (csh * 2) );
// Ensure that the separator outside the tabViewport is present (doesn't get cutoff by the active tab)
// If left unsolved the active tab is "visible" in the separator (the gap) even when outside the viewport
if( tabViewport != null )
Rectangle2D.intersect( tabViewport.getBounds(), innerTabRect, innerTabRect );
Rectangle2D.Float gap = null;
if( isHorizontalTabPlacement() ) {
if( innerTabRect.width > 0 ) {
float y2 = (tabPlacement == TOP) ? y : y + h - csh;
gap = new Rectangle2D.Float( innerTabRect.x, y2, innerTabRect.width, csh );
}
} else {
if( innerTabRect.height > 0 ) {
float x2 = (tabPlacement == LEFT) ? x : x + w - csh;
gap = new Rectangle2D.Float( x2, innerTabRect.y, csh, innerTabRect.height );
}
}
if( gap != null ) {
path.append( gap, false );
// fill gap in case that the tab is colored (e.g. focused or hover)
g.setColor( getTabBackground( tabPlacement, selectedIndex, true ) );
((Graphics2D)g).fill( gap );
}
}
// paint content separator or full border
g.setColor( contentAreaColor );
((Graphics2D)g).fill( path );
// repaint selection in scroll-tab-layout because it may be painted before
@@ -1539,15 +1399,6 @@ public class FlatTabbedPaneUI
clientPropertyBoolean( tabPane, TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, hideTabAreaWithOneTab );
}
/** @since 2 */
protected int getTabType() {
Object value = tabPane.getClientProperty( TABBED_PANE_TAB_TYPE );
return (value instanceof String)
? parseTabType( (String) value )
: tabType;
}
protected int getTabsPopupPolicy() {
Object value = tabPane.getClientProperty( TABBED_PANE_TABS_POPUP_POLICY );
@@ -1600,18 +1451,6 @@ public class FlatTabbedPaneUI
: tabWidthMode;
}
/** @since 2 */
protected static int parseTabType( String str ) {
if( str == null )
return TAB_TYPE_UNDERLINED;
switch( str ) {
default:
case TABBED_PANE_TAB_TYPE_UNDERLINED: return TAB_TYPE_UNDERLINED;
case TABBED_PANE_TAB_TYPE_CARD: return TAB_TYPE_CARD;
}
}
protected static int parseTabsPopupPolicy( String str ) {
if( str == null )
return AS_NEEDED;
@@ -2425,12 +2264,11 @@ public class FlatTabbedPaneUI
private class Handler
implements MouseListener, MouseMotionListener, PropertyChangeListener,
ChangeListener, ComponentListener, ContainerListener, FocusListener
ChangeListener, ComponentListener, ContainerListener
{
MouseListener mouseDelegate;
PropertyChangeListener propertyChangeDelegate;
ChangeListener changeDelegate;
FocusListener focusDelegate;
private final PropertyChangeListener contentListener = this::contentPropertyChange;
@@ -2600,10 +2438,6 @@ public class FlatTabbedPaneUI
break;
case TABBED_PANE_SHOW_TAB_SEPARATORS:
case TABBED_PANE_TAB_TYPE:
tabPane.repaint();
break;
case TABBED_PANE_SHOW_CONTENT_SEPARATOR:
case TABBED_PANE_HAS_FULL_BORDER:
case TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB:
@@ -2702,20 +2536,6 @@ public class FlatTabbedPaneUI
if( !(c instanceof UIResource) )
c.removePropertyChangeListener( contentListener );
}
//---- interface FocusListener ----
@Override
public void focusGained( FocusEvent e ) {
focusDelegate.focusGained( e );
repaintTab( tabPane.getSelectedIndex() );
}
@Override
public void focusLost( FocusEvent e ) {
focusDelegate.focusLost( e );
repaintTab( tabPane.getSelectedIndex() );
}
}
//---- class FlatTabbedPaneLayout -----------------------------------------

View File

@@ -50,6 +50,8 @@ import javax.accessibility.AccessibleContext;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
@@ -64,6 +66,7 @@ import javax.swing.border.Border;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.ui.FlatNativeWindowBorder.WindowTopBorder;
import com.formdev.flatlaf.util.ScaledImageIcon;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -77,8 +80,6 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.embeddedForeground Color
* @uiDefault TitlePane.borderColor Color optional
* @uiDefault TitlePane.unifiedBackground boolean
* @uiDefault TitlePane.showIcon boolean
* @uiDefault TitlePane.noIconLeftGap int
* @uiDefault TitlePane.iconSize Dimension
* @uiDefault TitlePane.iconMargins Insets
* @uiDefault TitlePane.titleMargins Insets
@@ -87,6 +88,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.centerTitle boolean
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.menuBarTitleGap int
* @uiDefault TitlePane.icon Icon
* @uiDefault TitlePane.closeIcon Icon
* @uiDefault TitlePane.iconifyIcon Icon
* @uiDefault TitlePane.maximizeIcon Icon
@@ -104,8 +106,6 @@ public class FlatTitlePane
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" );
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
@@ -224,11 +224,6 @@ public class FlatTitlePane
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() );
// initially hide buttons that are only supported in frames
iconifyButton.setVisible( false );
maximizeButton.setVisible( false );
restoreButton.setVisible( false );
buttonPanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
@@ -248,9 +243,11 @@ public class FlatTitlePane
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
// JRootPane.FRAME works only for frames (and not for dialogs)
// but at this time the owner window type is unknown (not yet added)
// so we add the iconify/maximize/restore buttons and they are shown
// so we add the iconify/maximize/restore buttons and they are hidden
// later in frameStateChanged(), which is invoked from addNotify()
restoreButton.setVisible( false );
buttonPanel.add( iconifyButton );
buttonPanel.add( maximizeButton );
buttonPanel.add( restoreButton );
@@ -340,27 +337,36 @@ public class FlatTitlePane
protected void updateIcon() {
// get window images
List<Image> images = null;
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, showIcon ) ) {
images = window.getIconImages();
if( images.isEmpty() ) {
// search in owners
for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
images = owner.getIconImages();
if( !images.isEmpty() )
break;
}
List<Image> images = window.getIconImages();
if( images.isEmpty() ) {
// search in owners
for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
images = owner.getIconImages();
if( !images.isEmpty() )
break;
}
}
boolean hasIcon = (images != null && !images.isEmpty());
boolean hasIcon = true;
// set icon
iconLabel.setIcon( hasIcon ? new FlatTitlePaneIcon( images, iconSize ) : null );
if( !images.isEmpty() )
iconLabel.setIcon( new FlatTitlePaneIcon( images, iconSize ) );
else {
// no icon set on window --> use default icon
Icon defaultIcon = UIManager.getIcon( "TitlePane.icon" );
if( defaultIcon != null && (defaultIcon.getIconWidth() == 0 || defaultIcon.getIconHeight() == 0) )
defaultIcon = null;
if( defaultIcon != null ) {
if( defaultIcon instanceof ImageIcon )
defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
iconLabel.setIcon( defaultIcon );
} else
hasIcon = false;
}
// show/hide icon
iconLabel.setVisible( hasIcon );
leftPanel.setBorder( hasIcon ? null : new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) );
updateNativeTitleBarHeightAndHitTestSpotsLater();
}
@@ -502,7 +508,7 @@ public class FlatTitlePane
protected void menuBarLayouted() {
updateNativeTitleBarHeightAndHitTestSpotsLater();
doLayout();
revalidate();
}
/*debug
@@ -515,23 +521,17 @@ public class FlatTitlePane
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
}
if( debugHitTestSpots != null ) {
g.setColor( Color.red );
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
for( Rectangle r : debugHitTestSpots )
paintRect( g, Color.red, r );
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
if( debugAppIconBounds != null ) {
g.setColor( Color.blue);
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
Rectangle r = debugAppIconBounds;
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
paintRect( g, Color.cyan, debugCloseButtonBounds );
paintRect( g, Color.blue, debugAppIconBounds );
paintRect( g, Color.blue, debugMinimizeButtonBounds );
paintRect( g, Color.magenta, debugMaximizeButtonBounds );
paintRect( g, Color.cyan, debugCloseButtonBounds );
}
private void paintRect( Graphics g, Color color, Rectangle r ) {
if( r == null )
return;
g.setColor( color );
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
debug*/
@@ -702,15 +702,9 @@ debug*/
return window != null && FlatNativeWindowBorder.hasCustomDecoration( window );
}
// used to invoke updateNativeTitleBarHeightAndHitTestSpots() only once from latest invokeLater()
private int laterCounter;
protected void updateNativeTitleBarHeightAndHitTestSpotsLater() {
laterCounter++;
EventQueue.invokeLater( () -> {
laterCounter--;
if( laterCounter == 0 )
updateNativeTitleBarHeightAndHitTestSpots();
updateNativeTitleBarHeightAndHitTestSpots();
} );
}
@@ -728,9 +722,8 @@ debug*/
List<Rectangle> hitTestSpots = new ArrayList<>();
Rectangle appIconBounds = null;
if( iconLabel.isVisible() ) {
// compute real icon size (without insets; 1px larger for easier hitting)
// compute real icon size (without insets; 1px wider for easier hitting)
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
Insets iconInsets = iconLabel.getInsets();
Rectangle iconBounds = new Rectangle(
@@ -766,7 +759,7 @@ debug*/
JMenuBar menuBar = rootPane.getJMenuBar();
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
r = getNativeHitTestSpot( menuBar );
r = getNativeHitTestSpot( menuBarPlaceholder );
if( r != null ) {
Component horizontalGlue = findHorizontalGlue( menuBar );
if( horizontalGlue != null ) {
@@ -775,18 +768,18 @@ debug*/
// the glue component area can used to move the window.
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
int x2 = glueLocation.x + horizontalGlue.getWidth();
Rectangle r2;
if( getComponentOrientation().isLeftToRight() ) {
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
r.width = glueLocation.x - r.x;
int trailingWidth = (r.x + r.width - HIT_TEST_SPOT_GROW) - glueLocation.x;
r.width -= trailingWidth;
r2 = new Rectangle( glueLocation.x + horizontalGlue.getWidth(), r.y, trailingWidth, r.height );
} else {
r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
r.width = (r.x + r.width) - x2;
r.x = x2;
int leadingWidth = (glueLocation.x + horizontalGlue.getWidth()) - (r.x + HIT_TEST_SPOT_GROW);
r.x += leadingWidth;
r.width -= leadingWidth;
r2 = new Rectangle( glueLocation.x -leadingWidth, r.y, leadingWidth, r.height );
}
r2.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
hitTestSpots.add( r2 );
}
@@ -794,30 +787,16 @@ debug*/
}
}
Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
Rectangle closeButtonBounds = boundsInWindow( closeButton );
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots, appIconBounds );
/*debug
debugTitleBarHeight = titleBarHeight;
debugHitTestSpots = hitTestSpots;
debugAppIconBounds = appIconBounds;
debugMinimizeButtonBounds = minimizeButtonBounds;
debugMaximizeButtonBounds = maximizeButtonBounds;
debugCloseButtonBounds = closeButtonBounds;
repaint();
debug*/
}
private Rectangle boundsInWindow( JComponent c ) {
return c.isShowing()
? SwingUtilities.convertRectangle( c.getParent(), c.getBounds(), window )
: null;
}
protected Rectangle getNativeHitTestSpot( JComponent c ) {
Dimension size = c.getSize();
if( size.width <= 0 || size.height <= 0 )
@@ -825,16 +804,17 @@ debug*/
Point location = SwingUtilities.convertPoint( c, 0, 0, window );
Rectangle r = new Rectangle( location, size );
// slightly increase rectangle so that component receives mouseExit events
r.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
return r;
}
private static final int HIT_TEST_SPOT_GROW = 2;
/*debug
private int debugTitleBarHeight;
private List<Rectangle> debugHitTestSpots;
private Rectangle debugAppIconBounds;
private Rectangle debugMinimizeButtonBounds;
private Rectangle debugMaximizeButtonBounds;
private Rectangle debugCloseButtonBounds;
debug*/
//---- class FlatTitlePaneBorder ------------------------------------------
@@ -866,7 +846,7 @@ debug*/
Border menuBarBorder = getMenuBarBorder();
if( menuBarBorder != null ) {
// if menu bar is embedded, paint menu bar border
menuBarBorder.paintBorder( rootPane.getJMenuBar(), g, x, y, width, height );
menuBarBorder.paintBorder( c, g, x, y, width, height );
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) ) {
// paint border between title pane and content if border color is specified
float lineHeight = UIScale.scale( (float) 1 );

View File

@@ -54,10 +54,6 @@ import com.formdev.flatlaf.util.SystemInfo;
// https://github.com/oberth/custom-chrome
// https://github.com/rossy/borderless-window
//
// Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
// https://github.com/dotnet/wpf/issues/4825#issuecomment-930442736
//
/**
* Native window border support for Windows 10 when using custom decorations.
@@ -181,24 +177,30 @@ class FlatWindowsNativeWindowBorder
}
@Override
public void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
Rectangle closeButtonBounds )
{
public void setTitleBarHeight( Window window, int titleBarHeight ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.titleBarHeight = titleBarHeight;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
wndProc.appIconBounds = cloneRectange( appIconBounds );
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
wndProc.closeButtonBounds = cloneRectange( closeButtonBounds );
}
private static Rectangle cloneRectange( Rectangle rect ) {
return (rect != null) ? new Rectangle( rect ) : null;
@Override
public void setTitleBarHitTestSpots( Window window, List<Rectangle> hitTestSpots ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
}
@Override
public void setTitleBarAppIconBounds( Window window, Rectangle appIconBounds ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.appIconBounds = (appIconBounds != null) ? new Rectangle( appIconBounds ) : null;
}
@Override
@@ -301,21 +303,14 @@ class FlatWindowsNativeWindowBorder
HTCLIENT = 1,
HTCAPTION = 2,
HTSYSMENU = 3,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTTOP = 12,
HTCLOSE = 20;
HTTOP = 12;
private Window window;
private final long hwnd;
// Swing coordinates/values may be scaled on a HiDPI screen
private int titleBarHeight;
private Rectangle[] hitTestSpots;
private Rectangle appIconBounds;
private Rectangle minimizeButtonBounds;
private Rectangle maximizeButtonBounds;
private Rectangle closeButtonBounds;
WndProc( Window window ) {
this.window = window;
@@ -360,7 +355,7 @@ class FlatWindowsNativeWindowBorder
// invoked from native code
private int onNcHitTest( int x, int y, boolean isOnResizeBorder ) {
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
// scale-down mouse x/y
Point pt = scaleDown( x, y );
int sx = pt.x;
int sy = pt.y;
@@ -368,26 +363,9 @@ class FlatWindowsNativeWindowBorder
// return HTSYSMENU if mouse is over application icon
// - left-click on HTSYSMENU area shows system menu
// - double-left-click sends WM_CLOSE
if( contains( appIconBounds, sx, sy ) )
if( appIconBounds != null && appIconBounds.contains( sx, sy ) )
return HTSYSMENU;
// return HTMINBUTTON if mouse is over minimize button
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
if( contains( minimizeButtonBounds, sx, sy ) )
return HTMINBUTTON;
// return HTMAXBUTTON if mouse is over maximize/restore button
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
if( contains( maximizeButtonBounds, sx, sy ) )
return HTMAXBUTTON;
// return HTCLOSE if mouse is over close button
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
if( contains( closeButtonBounds, sx, sy ) )
return HTCLOSE;
boolean isOnTitleBar = (sy < titleBarHeight);
if( isOnTitleBar ) {
@@ -404,10 +382,6 @@ class FlatWindowsNativeWindowBorder
return isOnResizeBorder ? HTTOP : HTCLIENT;
}
private boolean contains( Rectangle rect, int x, int y ) {
return (rect != null && rect.contains( x, y ) );
}
/**
* Scales down in the same way as AWT.
* See AwtWin32GraphicsDevice::ScaleDownX() and ::ScaleDownY()

View File

@@ -1,83 +0,0 @@
/*
* Copyright 2021 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.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.border.Border;
/**
* Border that automatically animates painting on component value changes.
* <p>
* {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* <p>
* Example for an animated border:
* <pre>
* private class MyAnimatedBorder
* implements AnimatedBorder
* {
* &#64;Override
* public float[] getAnimatableValues( Component c ) {
* return new float[] { c.isFocusOwner() ? 1 : 0 };
* }
*
* &#64;Override
* public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
* int lh = UIScale.scale( 2 );
*
* g.setColor( Color.blue );
* g.fillRect( x, y + height - lh, Math.round( width * animatedValues[0] ), lh );
* }
*
* &#64;Override
* public Insets getBorderInsets( Component c ) {
* return UIScale.scale( new Insets( 4, 4, 4, 4 ) );
* }
*
* &#64;Override public boolean isBorderOpaque() { return false; }
* }
*
* // sample usage
* JTextField textField = new JTextField();
* textField.setBorder( new MyAnimatedBorder() );
* </pre>
*
* Animation works only if the component passed to {@link #paintBorder(Component, Graphics, int, int, int, int)}
* is a instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
* @since 2
*/
public interface AnimatedBorder
extends Border, AnimatedPainter
{
/**
* Invokes {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*/
@Override
default void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
paintWithAnimation( c, g, x, y, width, height );
}
}

View File

@@ -18,87 +18,62 @@ package com.formdev.flatlaf.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.Icon;
import javax.swing.JComponent;
import com.formdev.flatlaf.util.Animator.Interpolator;
/**
* Icon that automatically animates painting on component value changes.
* <p>
* {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* {@link #getValue(Component)} returns the value of the component.
* If the value changes, then {@link #paintIconAnimated(Component, Graphics, int, int, float)}
* is invoked multiple times with animated value (from old value to new value).
* <p>
* Example for an animated icon:
* <pre>
* private class MyAnimatedIcon
* private class AnimatedMinimalTestIcon
* implements AnimatedIcon
* {
* &#64;Override
* public float[] getAnimatableValues( Component c ) {
* return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
* }
*
* &#64;Override public int getIconWidth() { return 100; }
* &#64;Override public int getIconHeight() { return 20; }
*
* &#64;Override
* public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
* public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
* int w = getIconWidth();
* int h = getIconHeight();
*
* g.setColor( Color.red );
* g.drawRect( x, y, width - 1, height - 1 );
* g.fillRect( x, y, Math.round( width * animatedValues[0] ), height );
* g.drawRect( x, y, w - 1, h - 1 );
* g.fillRect( x, y, Math.round( w * animatedValue ), h );
* }
*
* &#64;Override
* public float getValue( Component c ) {
* return ((AbstractButton)c).isSelected() ? 1 : 0;
* }
* }
*
* // sample usage
* JCheckBox checkBox = new JCheckBox( "test" );
* checkBox.setIcon( new MyAnimatedIcon() );
* checkBox.setIcon( new AnimatedMinimalTestIcon() );
* </pre>
*
* Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)}
* is an instance of {@link JComponent}.
* is a instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
*/
public interface AnimatedIcon
extends Icon, AnimatedPainter
extends Icon
{
/**
* {@inheritDoc}
*
* @since 2
*/
@Override
default float[] getAnimatableValues( Component c ) {
// for compatibility
return new float[] { getValue( c ) };
public default void paintIcon( Component c, Graphics g, int x, int y ) {
AnimationSupport.paintIcon( this, c, g, x, y );
}
/**
* Invokes {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*/
@Override
default void paintIcon( Component c, Graphics g, int x, int y ) {
paintWithAnimation( c, g, x, y, getIconWidth(), getIconHeight() );
}
/**
* {@inheritDoc}
*
* @since 2
*/
@Override
default void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
// for compatibility
paintIconAnimated( c, g, x, y, animatedValues[0] );
}
/**
* Paints the icon for the given (animated) value.
* Paints the icon for the given animated value.
*
* @param c the component that this icon belongs to
* @param g the graphics context
@@ -107,45 +82,52 @@ public interface AnimatedIcon
* @param animatedValue the animated value, which is either equal to what {@link #getValue(Component)}
* returned, or somewhere between the previous value and the latest value
* that {@link #getValue(Component)} returned
*
* @deprecated override {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])} instead
*/
@Deprecated
default void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
}
void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue );
/**
* Gets the animatable value of the component.
* Gets the value of the component.
* <p>
* This can be any value and depends on the component.
* If the value changes, then this class animates from the old value to the new one.
* <p>
* For a toggle button this could be {@code 0} for off and {@code 1} for on.
*
* @deprecated override {@link #getAnimatableValues(Component)} instead
*/
@Deprecated
default float getValue( Component c ) {
return 0;
float getValue( Component c );
/**
* Returns whether animation is enabled for this icon (default is {@code true}).
*/
default boolean isAnimationEnabled() {
return true;
}
/**
* {@inheritDoc}
*
* @since TODO
* Returns the duration of the animation in milliseconds (default is 150).
*/
@Override
default Object getAnimationClientPropertyKey() {
// for compatibility
return getClientPropertyKey();
default int getAnimationDuration() {
return 150;
}
/**
* Returns the resolution of the animation in milliseconds (default is 10).
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution() {
return 10;
}
/**
* Returns the interpolator for the animation.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator() {
return CubicBezierEasing.STANDARD_EASING;
}
/**
* Returns the client property key used to store the animation support.
*
* @deprecated override {@link #getAnimationClientPropertyKey()} instead
*/
@Deprecated
default Object getClientPropertyKey() {
return getClass();
}
@@ -153,25 +135,115 @@ public interface AnimatedIcon
//---- class AnimationSupport ---------------------------------------------
/**
* Animation support.
* Animation support class that stores the animation state and implements the animation.
*/
@Deprecated
class AnimationSupport
{
/**
* @deprecated use {@link AnimatedPainter#paintWithAnimation(Component, Graphics, int, int, int, int)} instead
*/
@Deprecated
private float startValue;
private float targetValue;
private float animatedValue;
private float fraction;
private Animator animator;
// last x,y coordinates of the icon needed to repaint while animating
private int x;
private int y;
public static void paintIcon( AnimatedIcon icon, Component c, Graphics g, int x, int y ) {
AnimatedPainterSupport.paint( icon, c, (Graphics2D) g, x, y, icon.getIconWidth(), icon.getIconHeight() );
if( !isAnimationEnabled( icon, c ) ) {
// paint without animation if animation is disabled or
// component is not a JComponent and therefore does not support
// client properties, which are required to keep animation state
paintIconImpl( icon, c, g, x, y, null );
return;
}
JComponent jc = (JComponent) c;
Object key = icon.getClientPropertyKey();
AnimationSupport as = (AnimationSupport) jc.getClientProperty( key );
if( as == null ) {
// painted first time --> do not animate, but remember current component value
as = new AnimationSupport();
as.startValue = as.targetValue = as.animatedValue = icon.getValue( c );
as.x = x;
as.y = y;
jc.putClientProperty( key, as );
} else {
// get component value
float value = icon.getValue( c );
if( value != as.targetValue ) {
// value changed --> (re)start animation
if( as.animator == null ) {
// create animator
AnimationSupport as2 = as;
as.animator = new Animator( icon.getAnimationDuration(), fraction -> {
// check whether component was removed while animation is running
if( !c.isDisplayable() ) {
as2.animator.stop();
return;
}
// compute animated value
as2.animatedValue = as2.startValue + ((as2.targetValue - as2.startValue) * fraction);
as2.fraction = fraction;
// repaint icon
c.repaint( as2.x, as2.y, icon.getIconWidth(), icon.getIconHeight() );
}, () -> {
as2.startValue = as2.animatedValue = as2.targetValue;
as2.animator = null;
} );
}
if( as.animator.isRunning() ) {
// if animation is still running, restart it from the current
// animated value to the new target value with reduced duration
as.animator.cancel();
int duration2 = (int) (icon.getAnimationDuration() * as.fraction);
if( duration2 > 0 )
as.animator.setDuration( duration2 );
as.startValue = as.animatedValue;
} else {
// new animation
as.animator.setDuration( icon.getAnimationDuration() );
as.animator.setResolution( icon.getAnimationResolution() );
as.animator.setInterpolator( icon.getAnimationInterpolator() );
as.animatedValue = as.startValue;
}
as.targetValue = value;
as.animator.start();
}
as.x = x;
as.y = y;
}
paintIconImpl( icon, c, g, x, y, as );
}
private static void paintIconImpl( AnimatedIcon icon, Component c, Graphics g, int x, int y, AnimationSupport as ) {
float value = (as != null) ? as.animatedValue : icon.getValue( c );
icon.paintIconAnimated( c, g, x, y, value );
}
private static boolean isAnimationEnabled( AnimatedIcon icon, Component c ) {
return Animator.useAnimation() && icon.isAnimationEnabled() && c instanceof JComponent;
}
/**
* @deprecated use {@link AnimatedPainter#saveRepaintLocation(AnimatedPainter, Component, int, int)} instead
*/
@Deprecated
public static void saveIconLocation( AnimatedIcon icon, Component c, int x, int y ) {
AnimatedPainterSupport.saveRepaintLocation( icon, c, x, y );
if( !isAnimationEnabled( icon, c ) )
return;
AnimationSupport as = (AnimationSupport) ((JComponent)c).getClientProperty( icon.getClientPropertyKey() );
if( as != null ) {
as.x = x;
as.y = y;
}
}
}
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright 2021 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.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import com.formdev.flatlaf.util.Animator.Interpolator;
/**
* Painter that automatically animates painting on component value(s) changes.
* <p>
* {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* <p>
* See {@link AnimatedBorder} or {@link AnimatedIcon} for examples.
* <p>
* Animation works only if the component passed to {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}
* is an instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
* @since 2
*/
public interface AnimatedPainter
{
/**
* Gets the animatable value(s) of the component.
* <p>
* This can be any value(s) and depends on the component.
* If the value(s) changes, then this class animates from the old value(s) to the new ones.
* If multiple values are returned, then each value gets its own independent animation.
* <p>
* For a toggle button this could be {@code 0} for off and {@code 1} for on.
* A complex check box could return values for selected, hover, pressed and focused states.
* The painter then can show independent animations for those states.
*/
float[] getAnimatableValues( Component c );
/**
* Starts painting.
* Either invokes {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* once to paint current value(s) (see {@link #getAnimatableValues(Component)}. Or if value(s) has
* changed, compared to last painting, then it starts an animation and invokes
* {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* multiple times with animated value(s) (from old value(s) to new value(s)).
*
* @param c the component that this painter belongs to
* @param g the graphics context
* @param x the x coordinate of the paint area
* @param y the y coordinate of the paint area
* @param width the width of the paint area
* @param height the height of the paint area
*/
default void paintWithAnimation( Component c, Graphics g, int x, int y, int width, int height ) {
AnimatedPainterSupport.paint( this, c, (Graphics2D) g, x, y, width, height );
}
/**
* Paints the given (animated) value(s).
* <p>
* Invoked from {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*
* @param c the component that this painter belongs to
* @param g the graphics context
* @param x the x coordinate of the paint area
* @param y the y coordinate of the paint area
* @param width the width of the paint area
* @param height the height of the paint area
* @param animatedValues the animated values, which are either equal to what {@link #getAnimatableValues(Component)}
* returned, or somewhere between the previous values and the latest values
* that {@link #getAnimatableValues(Component)} returned
*/
void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues );
/**
* Invoked from animator to repaint an area.
* <p>
* Useful to limit the repaint region. E.g. if only the bottom border is animated.
* If more than one border side is animated (e.g. bottom and right side), then it
* makes no sense to do separate repaints because the Swing repaint manager unions
* the regions and the whole component is repainted.
* <p>
* The default implementation repaints the whole given area.
*/
default void repaintDuringAnimation( Component c, int x, int y, int width, int height ) {
c.repaint( x, y, width, height );
}
/**
* Returns whether animation is enabled for this painter (default is {@code true}).
*/
default boolean isAnimationEnabled() {
return true;
}
/**
* Returns the duration of the animation in milliseconds (default is 150).
*/
default int getAnimationDuration() {
return 150;
}
/**
* Returns the resolution of the animation in milliseconds (default is 10).
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution() {
return 10;
}
/**
* Returns the interpolator for the animation.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator() {
return CubicBezierEasing.STANDARD_EASING;
}
/**
* Returns the duration of the animation in milliseconds (default is 150)
* for the given value index and value.
*/
default int getAnimationDuration( int valueIndex, float value ) {
return getAnimationDuration();
}
/**
* Returns the resolution of the animation in milliseconds (default is 10)
* for the given value index and value.
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution( int valueIndex, float value ) {
return getAnimationResolution();
}
/**
* Returns the interpolator for the animation
* for the given value index and value.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator( int valueIndex, float value ) {
return getAnimationInterpolator();
}
/**
* Returns the client property key used to store the animation support.
*/
default Object getAnimationClientPropertyKey() {
return getClass();
}
/**
* Saves location for repainting animated area with
* {@link AnimatedPainter#repaintDuringAnimation(Component, int, int, int, int)}.
* Only needed when graphics context passed to {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}
* uses transformed location.
*/
static void saveRepaintLocation( AnimatedPainter painter, Component c, int x, int y ) {
AnimatedPainterSupport.saveRepaintLocation( painter, c, x, y );
}
}

View File

@@ -1,185 +0,0 @@
/*
* Copyright 2021 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.util;
import java.awt.Component;
import java.awt.Graphics2D;
import javax.swing.JComponent;
/**
* Animation support class that stores the animation state and implements the animation.
*
* @author Karl Tauber
* @since 2
*/
class AnimatedPainterSupport
{
private final int valueIndex;
private float startValue;
private float targetValue;
private float animatedValue;
private float fraction;
private Animator animator;
// last bounds of the paint area needed to repaint while animating
private int x;
private int y;
private int width;
private int height;
private AnimatedPainterSupport( int valueIndex ) {
this.valueIndex = valueIndex;
}
static void paint( AnimatedPainter painter, Component c, Graphics2D g,
int x, int y, int width, int height )
{
// get animatable component values
float[] values = painter.getAnimatableValues( c );
if( !isAnimationEnabled( painter, c ) ) {
// paint without animation if animation is disabled or
// component is not a JComponent and therefore does not support
// client properties, which are required to keep animation state
painter.paintAnimated( c, g, x, y, width, height, values );
return;
}
JComponent jc = (JComponent) c;
Object key = painter.getAnimationClientPropertyKey();
AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) jc.getClientProperty( key );
// check whether length of values array has changed
if( ass != null && ass.length != values.length ) {
// cancel all running animations
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
if( as.animator != null )
as.animator.cancel();
}
ass = null;
}
if( ass == null ) {
ass = new AnimatedPainterSupport[values.length];
jc.putClientProperty( key, ass );
}
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
float value = values[i];
if( as == null ) {
// painted first time --> do not animate, but remember current component value
as = new AnimatedPainterSupport( i );
as.startValue = as.targetValue = as.animatedValue = value;
ass[i] = as;
} else if( value != as.targetValue ) {
// value changed --> (re)start animation
int animationDuration = painter.getAnimationDuration( as.valueIndex, value );
// do not animate if animation duration (for current value) is zero
if( animationDuration <= 0 ) {
if( as.animator != null ) {
as.animator.cancel();
as.animator = null;
}
as.startValue = as.targetValue = as.animatedValue = value;
as.fraction = 0;
continue;
}
if( as.animator == null ) {
// create animator
AnimatedPainterSupport as2 = as;
as.animator = new Animator( 1, fraction -> {
// check whether component was removed while animation is running
if( !c.isDisplayable() ) {
as2.animator.stop();
return;
}
// compute animated value
as2.animatedValue = as2.startValue + ((as2.targetValue - as2.startValue) * fraction);
as2.fraction = fraction;
// repaint
painter.repaintDuringAnimation( c, as2.x, as2.y, as2.width, as2.height );
}, () -> {
as2.startValue = as2.animatedValue = as2.targetValue;
as2.animator = null;
} );
}
if( as.animator.isRunning() ) {
// if animation is still running, restart it from the current
// animated value to the new target value with reduced duration
as.animator.cancel();
int duration2 = (int) (animationDuration * as.fraction);
if( duration2 > 0 )
as.animator.setDuration( duration2 );
as.startValue = as.animatedValue;
} else {
// new animation
as.animator.setDuration( animationDuration );
as.animatedValue = as.startValue;
}
// update animator for new value
as.animator.setResolution( painter.getAnimationResolution( as.valueIndex, value ) );
as.animator.setInterpolator( painter.getAnimationInterpolator( as.valueIndex, value ) );
// start animation
as.targetValue = value;
as.animator.start();
}
as.x = x;
as.y = y;
as.width = width;
as.height = height;
}
float[] animatedValues = new float[ass.length];
for( int i = 0; i < ass.length; i++ )
animatedValues[i] = ass[i].animatedValue;
painter.paintAnimated( c, g, x, y, width, height, animatedValues );
}
private static boolean isAnimationEnabled( AnimatedPainter painter, Component c ) {
return Animator.useAnimation() && painter.isAnimationEnabled() && c instanceof JComponent;
}
static void saveRepaintLocation( AnimatedPainter painter, Component c, int x, int y ) {
if( !isAnimationEnabled( painter, c ) )
return;
AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) ((JComponent)c).getClientProperty( painter.getAnimationClientPropertyKey() );
if( ass != null ) {
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
as.x = x;
as.y = y;
}
}
}
}

View File

@@ -1,168 +0,0 @@
/*
* Copyright 2021 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.util;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
/**
* A simple cache (map) that uses soft references for the values.
*
* @author Karl Tauber
* @since 2
*/
public class SoftCache<K,V>
implements Map<K, V>
{
private final Map<K, CacheReference<K,V>> map;
private final ReferenceQueue<V> queue = new ReferenceQueue<>();
public SoftCache() {
map = new HashMap<>();
}
public SoftCache( int initialCapacity ) {
map = new HashMap<>( initialCapacity );
}
@Override
public int size() {
expungeStaleEntries();
return map.size();
}
@Override
public boolean isEmpty() {
expungeStaleEntries();
return map.isEmpty();
}
@Override
public boolean containsKey( Object key ) {
expungeStaleEntries();
return map.containsKey( key );
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public boolean containsValue( Object value ) {
throw new UnsupportedOperationException();
}
@Override
public V get( Object key ) {
expungeStaleEntries();
return getRef( map.get( key ) );
}
@Override
public V put( K key, V value ) {
expungeStaleEntries();
return getRef( map.put( key, new CacheReference<>( key, value, queue ) ) );
}
@Override
public V remove( Object key ) {
expungeStaleEntries();
return getRef( map.remove( key ) );
}
private V getRef( CacheReference<K,V> ref ) {
return (ref != null) ? ref.get() : null;
}
@Override
public void putAll( Map<? extends K, ? extends V> m ) {
expungeStaleEntries();
for( Entry<? extends K, ? extends V> e : m.entrySet() )
put( e.getKey(), e.getValue() );
}
@Override
public void clear() {
map.clear();
expungeStaleEntries();
}
@Override
public Set<K> keySet() {
expungeStaleEntries();
return map.keySet();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public Collection<V> values() {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public Set<Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public void forEach( BiConsumer<? super K, ? super V> action ) {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public void replaceAll( BiFunction<? super K, ? super V, ? extends V> function ) {
throw new UnsupportedOperationException();
}
@SuppressWarnings( "unchecked" )
private void expungeStaleEntries() {
Reference<? extends V> reference;
while( (reference = queue.poll()) != null )
map.remove( ((CacheReference<K,V>)reference).key );
}
//---- class CacheReference ----
private static class CacheReference<K,V>
extends SoftReference<V>
{
// needed to remove reference from map in expungeStaleEntries()
final K key;
CacheReference( K key, V value, ReferenceQueue<? super V> queue ) {
super( value, queue );
this.key = key;
}
}
}

View File

@@ -46,7 +46,6 @@ public class SystemInfo
public static final boolean isJava_9_orLater;
public static final boolean isJava_11_orLater;
public static final boolean isJava_15_orLater;
/** @since 2 */ public static final boolean isJava_17_orLater;
// Java VMs
public static final boolean isJetBrainsJVM;
@@ -83,7 +82,6 @@ public class SystemInfo
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
// Java VMs
isJetBrainsJVM = System.getProperty( "java.vm.vendor", "Unknown" )

View File

@@ -26,68 +26,6 @@
# Instead copy and modify only those properties that you need to alter.
#
#---- typography / fonts ----
# headings
h00.font = +24
h0.font = +18
h1.font = +12 $semibold.font
h2.font = +6 $semibold.font
h3.font = +3 $semibold.font
h4.font = bold
h1.regular.font = +12
h2.regular.font = +6
h3.regular.font = +3
# text
large.font = +2
medium.font = -1
small.font = -2
mini.font = -3
# default font
#defaultFont = ...
# font weights
# Windows
[win]light.font = "Segoe UI Light"
[win]semibold.font = "Segoe UI Semibold"
# macOS
[mac]light.font = "HelveticaNeue-Thin"
[mac]semibold.font = "HelveticaNeue-Medium"
# Linux
[linux]light.font = "Lato Light", "Ubuntu Light", "Cantarell Light"
[linux]semibold.font = "Lato Semibold", "Ubuntu Medium"
# fallback for unknown platform
light.font = +0
semibold.font = +0
# monospaced
[win]monospaced.font = Consolas, "Courier New", Monospaced
[mac]monospaced.font = Menlo, Monospaced
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
monospaced.font = Monospaced
# styles
[style].h00 = font: $h00.font
[style].h0 = font: $h0.font
[style].h1 = font: $h1.font
[style].h2 = font: $h2.font
[style].h3 = font: $h3.font
[style].h4 = font: $h4.font
[style].h1.regular = font: $h1.regular.font
[style].h2.regular = font: $h2.regular.font
[style].h3.regular = font: $h3.regular.font
[style].large = font: $large.font
[style].medium = font: $medium.font
[style].small = font: $small.font
[style].mini = font: $mini.font
[style].light = font: $light.font
[style].semibold = font: $semibold.font
[style].monospaced = font: $monospaced.font
#---- UI delegates ----
ButtonUI = com.formdev.flatlaf.ui.FlatButtonUI
@@ -456,7 +394,6 @@ OptionPane.messageAreaBorder = 0,0,0,0
OptionPane.buttonAreaBorder = 12,0,0,0
OptionPane.messageForeground = null
OptionPane.showIcon = false
OptionPane.maxCharactersPerLine = 80
OptionPane.iconMessageGap = 16
OptionPane.messagePadding = 3
@@ -650,7 +587,6 @@ SplitPaneDivider.gripGap = 2
TabbedPane.tabHeight = 32
TabbedPane.tabSelectionHeight = 3
TabbedPane.cardTabSelectionHeight = 2
TabbedPane.contentSeparatorHeight = 1
TabbedPane.showTabSeparators = false
TabbedPane.tabSeparatorsFullHeight = false
@@ -672,9 +608,6 @@ TabbedPane.tabAlignment = center
# allowed values: preferred, equal or compact
TabbedPane.tabWidthMode = preferred
# allowed values: underlined or card
TabbedPane.tabType = underlined
# allowed values: chevron or triangle
TabbedPane.arrowType = chevron
TabbedPane.buttonInsets = 2,1,2,1
@@ -776,9 +709,7 @@ TitledBorder.border = 1,1,1,1,$Separator.foreground
TitlePane.useWindowDecorations = true
TitlePane.menuBarEmbedded = true
TitlePane.unifiedBackground = true
TitlePane.showIcon = true
TitlePane.noIconLeftGap = 8
TitlePane.unifiedBackground = false
TitlePane.iconSize = 16,16
TitlePane.iconMargins = 3,8,3,8
TitlePane.titleMargins = 3,0,3,0

View File

@@ -0,0 +1,306 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.FlatSystemProperties;
/**
* @author Karl Tauber
*/
public class TestFlatStyleType
{
@BeforeAll
static void setup() {
System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" );
TestUtils.setup( false );
UIManager.put( "[style]Button", "foreground: #000001" );
UIManager.put( "[style]CheckBox", "foreground: #000002" );
UIManager.put( "[style]ComboBox", "foreground: #000003" );
UIManager.put( "[style]EditorPane", "foreground: #000004" );
UIManager.put( "[style]FormattedTextField", "foreground: #000005" );
UIManager.put( "[style]InternalFrame", "foreground: #000006" );
UIManager.put( "[style]Label", "foreground: #000007" );
UIManager.put( "[style]List", "foreground: #000008" );
UIManager.put( "[style]MenuBar", "foreground: #000009" );
UIManager.put( "[style]Menu", "foreground: #000010" );
UIManager.put( "[style]MenuItem", "foreground: #000011" );
UIManager.put( "[style]CheckBoxMenuItem", "foreground: #000012" );
UIManager.put( "[style]RadioButtonMenuItem", "foreground: #000013" );
UIManager.put( "[style]PasswordField", "foreground: #000014" );
UIManager.put( "[style]PopupMenu", "foreground: #000015" );
UIManager.put( "[style]PopupMenuSeparator", "foreground: #000016" );
UIManager.put( "[style]ProgressBar", "foreground: #000017" );
UIManager.put( "[style]RadioButton", "foreground: #000018" );
UIManager.put( "[style]ScrollBar", "foreground: #000019" );
UIManager.put( "[style]ScrollPane", "foreground: #000020" );
UIManager.put( "[style]Separator", "foreground: #000021" );
UIManager.put( "[style]Slider", "foreground: #000022" );
UIManager.put( "[style]Spinner", "foreground: #000023" );
UIManager.put( "[style]SplitPane", "foreground: #000024" );
UIManager.put( "[style]TabbedPane", "foreground: #000025" );
UIManager.put( "[style]Table", "foreground: #000026" );
UIManager.put( "[style]TableHeader", "foreground: #000027" );
UIManager.put( "[style]TextArea", "foreground: #000028" );
UIManager.put( "[style]TextField", "foreground: #000029" );
UIManager.put( "[style]TextPane", "foreground: #000030" );
UIManager.put( "[style]ToggleButton", "foreground: #000031" );
UIManager.put( "[style]ToolBar", "foreground: #000032" );
UIManager.put( "[style]Tree", "foreground: #000033" );
// JToolBar.Separator
UIManager.put( "[style]ToolBarSeparator", "separatorWidth: 21" );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED );
}
@Test
void styleForType() {
assertEquals( "foreground: #000001", FlatStylingSupport.getStyleForType( "Button" ) );
}
//---- components ---------------------------------------------------------
@Test
void button() {
JButton c = new JButton();
assertEquals( new Color( 0x000001 ), c.getForeground() );
}
@Test
void checkBox() {
JCheckBox c = new JCheckBox();
assertEquals( new Color( 0x000002 ), c.getForeground() );
}
@Test
void comboBox() {
JComboBox<Object> c = new JComboBox<>();
assertEquals( new Color( 0x000003 ), c.getForeground() );
}
@Test
void editorPane() {
JEditorPane c = new JEditorPane();
assertEquals( new Color( 0x000004 ), c.getForeground() );
}
@Test
void formattedTextField() {
JFormattedTextField c = new JFormattedTextField();
assertEquals( new Color( 0x000005 ), c.getForeground() );
}
@Test
void internalFrame() {
JInternalFrame c = new JInternalFrame();
assertEquals( new Color( 0x000006 ), c.getForeground() );
}
@Test
void label() {
JLabel c = new JLabel();
assertEquals( new Color( 0x000007 ), c.getForeground() );
}
@Test
void list() {
JList<Object> c = new JList<>();
assertEquals( new Color( 0x000008 ), c.getForeground() );
}
@Test
void menuBar() {
JMenuBar c = new JMenuBar();
assertEquals( new Color( 0x000009 ), c.getForeground() );
}
@Test
void menu() {
JMenu c = new JMenu();
assertEquals( new Color( 0x000010 ), c.getForeground() );
}
@Test
void menuItem() {
JMenuItem c = new JMenuItem();
assertEquals( new Color( 0x000011 ), c.getForeground() );
}
@Test
void checkBoxMenuItem() {
JCheckBoxMenuItem c = new JCheckBoxMenuItem();
assertEquals( new Color( 0x000012 ), c.getForeground() );
}
@Test
void radioButtonMenuItem() {
JRadioButtonMenuItem c = new JRadioButtonMenuItem();
assertEquals( new Color( 0x000013 ), c.getForeground() );
}
@Test
void passwordField() {
JPasswordField c = new JPasswordField();
assertEquals( new Color( 0x000014 ), c.getForeground() );
}
@Test
void popupMenu() {
JPopupMenu c = new JPopupMenu();
assertEquals( new Color( 0x000015 ), c.getForeground() );
}
@Test
void popupMenuSeparator() {
JPopupMenu.Separator c = new JPopupMenu.Separator();
assertEquals( new Color( 0x000016 ), c.getForeground() );
}
@Test
void progressBar() {
JProgressBar c = new JProgressBar();
assertEquals( new Color( 0x000017 ), c.getForeground() );
}
@Test
void radioButton() {
JRadioButton c = new JRadioButton();
assertEquals( new Color( 0x000018 ), c.getForeground() );
}
@Test
void scrollBar() {
JScrollBar c = new JScrollBar();
assertEquals( new Color( 0x000019 ), c.getForeground() );
}
@Test
void scrollPane() {
JScrollPane c = new JScrollPane();
assertEquals( new Color( 0x000020 ), c.getForeground() );
}
@Test
void separator() {
JSeparator c = new JSeparator();
assertEquals( new Color( 0x000021 ), c.getForeground() );
}
@Test
void slider() {
JSlider c = new JSlider();
assertEquals( new Color( 0x000022 ), c.getForeground() );
}
@Test
void slider2() {
JSlider c = new JSlider();
// when slider labels are painted, then a Java private subclass of JLabel
// is used that overrides getForeground(), which is not accessible via reflection
// see class JSlider.SmartHashtable.LabelUIResource
c.setPaintLabels( true );
c.setMajorTickSpacing( 50 );
assertEquals( new Color( 0x000022 ), c.getForeground() );
}
@Test
void spinner() {
JSpinner c = new JSpinner();
assertEquals( new Color( 0x000023 ), c.getForeground() );
}
@Test
void splitPane() {
JSplitPane c = new JSplitPane();
assertEquals( new Color( 0x000024 ), c.getForeground() );
}
@Test
void tabbedPane() {
JTabbedPane c = new JTabbedPane();
assertEquals( new Color( 0x000025 ), c.getForeground() );
}
@Test
void table() {
JTable c = new JTable();
assertEquals( new Color( 0x000026 ), c.getForeground() );
}
@Test
void tableHeader() {
JTableHeader c = new JTableHeader();
assertEquals( new Color( 0x000027 ), c.getForeground() );
}
@Test
void textArea() {
JTextArea c = new JTextArea();
assertEquals( new Color( 0x000028 ), c.getForeground() );
}
@Test
void textField() {
JTextField c = new JTextField();
assertEquals( new Color( 0x000029 ), c.getForeground() );
}
@Test
void textPane() {
JTextPane c = new JTextPane();
assertEquals( new Color( 0x000030 ), c.getForeground() );
}
@Test
void toggleButton() {
JToggleButton c = new JToggleButton();
assertEquals( new Color( 0x000031 ), c.getForeground() );
}
@Test
void toolBar() {
JToolBar c = new JToolBar();
assertEquals( new Color( 0x000032 ), c.getForeground() );
}
@Test
void toolBarSeparator() {
JToolBar.Separator c = new JToolBar.Separator();
assertEquals( new Dimension( 0, 21 ), c.getPreferredSize() );
}
@Test
void tree() {
JTree c = new JTree();
assertEquals( new Color( 0x000033 ), c.getForeground() );
}
}

View File

@@ -685,14 +685,12 @@ public class TestFlatStyleableInfo
"maximumTabWidth", int.class,
"tabHeight", int.class,
"tabSelectionHeight", int.class,
"cardTabSelectionHeight", int.class,
"contentSeparatorHeight", int.class,
"showTabSeparators", boolean.class,
"tabSeparatorsFullHeight", boolean.class,
"hasFullBorder", boolean.class,
"tabsOpaque", boolean.class,
"tabType", String.class,
"tabsPopupPolicy", String.class,
"scrollButtonsPolicy", String.class,
"scrollButtonsPlacement", String.class,

View File

@@ -849,14 +849,12 @@ public class TestFlatStyling
ui.applyStyle( "maximumTabWidth: 100" );
ui.applyStyle( "tabHeight: 30" );
ui.applyStyle( "tabSelectionHeight: 3" );
ui.applyStyle( "cardTabSelectionHeight: 2" );
ui.applyStyle( "contentSeparatorHeight: 1" );
ui.applyStyle( "showTabSeparators: false" );
ui.applyStyle( "tabSeparatorsFullHeight: false" );
ui.applyStyle( "hasFullBorder: false" );
ui.applyStyle( "tabsOpaque: false" );
ui.applyStyle( "tabType: card" );
ui.applyStyle( "tabsPopupPolicy: asNeeded" );
ui.applyStyle( "scrollButtonsPolicy: asNeeded" );
ui.applyStyle( "scrollButtonsPlacement: both" );

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import java.awt.Font;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import javax.swing.UIManager;
@@ -42,7 +43,12 @@ public class TestUtils
}
public static void cleanup() {
UIManager.put( "defaultFont", null );
// remove all properties added by UIManager.put()
Iterator<Object> it = UIManager.getDefaults().keySet().iterator();
while( it.hasNext() ) {
it.next();
it.remove();
}
}
public static void scaleFont( float factor ) {

View File

@@ -22,10 +22,6 @@ import javax.swing.text.DefaultEditorKit;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.icons.FlatSearchIcon;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.BoundSize;
import net.miginfocom.layout.ConstraintParser;
import net.miginfocom.layout.DimConstraint;
import net.miginfocom.swing.*;
/**
@@ -134,22 +130,6 @@ class BasicComponentsPanel
JTextField leadingIconTextField = new JTextField();
JTextField trailingIconTextField = new JTextField();
JTextField iconsTextField = new JTextField();
JLabel fontsLabel = new JLabel();
JLabel h00Label = new JLabel();
JLabel h0Label = new JLabel();
JLabel h1Label = new JLabel();
JLabel h2Label = new JLabel();
JLabel h3Label = new JLabel();
JLabel h4Label = new JLabel();
JLabel lightLabel = new JLabel();
JLabel semiboldLabel = new JLabel();
JLabel fontZoomLabel = new JLabel();
JLabel largeLabel = new JLabel();
JLabel defaultLabel = new JLabel();
JLabel mediumLabel = new JLabel();
JLabel smallLabel = new JLabel();
JLabel miniLabel = new JLabel();
JLabel monospacedLabel = new JLabel();
JPopupMenu popupMenu1 = new JPopupMenu();
JMenuItem cutMenuItem = new JMenuItem();
JMenuItem copyMenuItem = new JMenuItem();
@@ -180,8 +160,6 @@ class BasicComponentsPanel
"[]para" +
"[]" +
"[]" +
"[]" +
"[]0" +
"[]"));
//---- labelLabel ----
@@ -689,85 +667,6 @@ class BasicComponentsPanel
iconsTextField.setText("text");
add(iconsTextField, "cell 3 14,growx");
//---- fontsLabel ----
fontsLabel.setText("Typography / Fonts:");
add(fontsLabel, "cell 0 15");
//---- h00Label ----
h00Label.setText("H00");
h00Label.putClientProperty("FlatLaf.styleClass", "h00");
add(h00Label, "cell 1 15 5 1");
//---- h0Label ----
h0Label.setText("H0");
h0Label.putClientProperty("FlatLaf.styleClass", "h0");
add(h0Label, "cell 1 15 5 1");
//---- h1Label ----
h1Label.setText("H1");
h1Label.putClientProperty("FlatLaf.styleClass", "h1");
add(h1Label, "cell 1 15 5 1");
//---- h2Label ----
h2Label.setText("H2");
h2Label.putClientProperty("FlatLaf.styleClass", "h2");
add(h2Label, "cell 1 15 5 1");
//---- h3Label ----
h3Label.setText("H3");
h3Label.putClientProperty("FlatLaf.styleClass", "h3");
add(h3Label, "cell 1 15 5 1");
//---- h4Label ----
h4Label.setText("H4");
h4Label.putClientProperty("FlatLaf.styleClass", "h4");
add(h4Label, "cell 1 15 5 1");
//---- lightLabel ----
lightLabel.setText("light");
lightLabel.putClientProperty("FlatLaf.style", "font: 200% $light.font");
add(lightLabel, "cell 1 15 5 1,gapx 30");
//---- semiboldLabel ----
semiboldLabel.setText("semibold");
semiboldLabel.putClientProperty("FlatLaf.style", "font: 200% $semibold.font");
add(semiboldLabel, "cell 1 15 5 1");
//---- fontZoomLabel ----
fontZoomLabel.setText("(200%)");
fontZoomLabel.putClientProperty("FlatLaf.styleClass", "small");
fontZoomLabel.setEnabled(false);
add(fontZoomLabel, "cell 1 15 5 1");
//---- largeLabel ----
largeLabel.setText("large");
largeLabel.putClientProperty("FlatLaf.styleClass", "large");
add(largeLabel, "cell 1 16 5 1");
//---- defaultLabel ----
defaultLabel.setText("default");
add(defaultLabel, "cell 1 16 5 1");
//---- mediumLabel ----
mediumLabel.setText("medium");
mediumLabel.putClientProperty("FlatLaf.styleClass", "medium");
add(mediumLabel, "cell 1 16 5 1");
//---- smallLabel ----
smallLabel.setText("small");
smallLabel.putClientProperty("FlatLaf.styleClass", "small");
add(smallLabel, "cell 1 16 5 1");
//---- miniLabel ----
miniLabel.setText("mini");
miniLabel.putClientProperty("FlatLaf.styleClass", "mini");
add(miniLabel, "cell 1 16 5 1");
//---- monospacedLabel ----
monospacedLabel.setText("monospaced");
monospacedLabel.putClientProperty("FlatLaf.styleClass", "monospaced");
add(monospacedLabel, "cell 1 16 5 1,gapx 30");
//======== popupMenu1 ========
{
@@ -806,55 +705,37 @@ class BasicComponentsPanel
if( FlatLafDemo.screenshotsMode ) {
// hide some components
Component[] hiddenComponents = {
labelLabel, label1, label2,
button13, button14, button15, button16, comboBox5, comboBox6,
textField6, passwordField5,
textFieldLabel, textField2, textField4, textField6,
formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4, formattedTextField5,
passwordFieldLabel, passwordField1, passwordField2, passwordField3, passwordField4, passwordField5,
textAreaLabel, scrollPane1, scrollPane2, scrollPane3, scrollPane4, textArea5,
editorPaneLabel, scrollPane5, scrollPane6, scrollPane7, scrollPane8, editorPane5,
textPaneLabel, scrollPane9, scrollPane10, scrollPane11, scrollPane12, textPane5,
errorHintsLabel, errorHintsTextField, errorHintsComboBox, errorHintsSpinner,
warningHintsLabel, warningHintsTextField, warningHintsComboBox, warningHintsSpinner,
fontZoomLabel,
};
for( Component c : hiddenComponents )
c.setVisible( false );
// update layout (change row gaps to zero)
// move leading/trailing icon fields and password fields some rows up
Component[] formattedTextFields = { formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4 };
Component[] passwordFields = { passwordFieldLabel, passwordField1, passwordField2, passwordField3, passwordField4 };
Component[] iconsFields = { iconsLabel, leadingIconTextField, trailingIconTextField, iconsTextField };
MigLayout layout = (MigLayout) getLayout();
Object rowCons = layout.getRowConstraints();
AC ac = (rowCons instanceof String)
? ConstraintParser.parseColumnConstraints( (String) rowCons )
: (AC) rowCons;
BoundSize zeroGap = ConstraintParser.parseBoundSize( "0", true, true );
DimConstraint[] rows = ac.getConstaints();
rows[6].setGapBefore( zeroGap );
rows[7].setGapBefore( zeroGap );
rows[8].setGapBefore( zeroGap );
rows[9].setGapBefore( zeroGap );
rows[10].setGapBefore( zeroGap );
rows[11].setGapBefore( zeroGap );
rows[11].setGapAfter( zeroGap );
rows[12].setGapBefore( zeroGap );
rows[13].setGapBefore( zeroGap );
rows[15].setGapBefore( zeroGap );
layout.setRowConstraints( ac );
// move two text field into same row as spinners
spinnerLabel.setText( "JSpinner / JTextField:" );
layout.setComponentConstraints( textField1, "cell 3 5,growx" );
layout.setComponentConstraints( textField3, "cell 4 5,growx" );
for( int i = 0; i < iconsFields.length; i++ ) {
Object cons = layout.getComponentConstraints( passwordFields[i] );
layout.setComponentConstraints( iconsFields[i], cons );
}
for( int i = 0; i < passwordFields.length; i++ ) {
Object cons = layout.getComponentConstraints( formattedTextFields[i] );
layout.setComponentConstraints( passwordFields[i], cons );
}
// make "Not editable disabled" combobox smaller
Object cons = layout.getComponentConstraints( comboBox4 );
layout.setComponentConstraints( comboBox4, cons + ",width 50:50" );
revalidate();
repaint();
}
}

View File

@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[][sizegroup 1][sizegroup 1][sizegroup 1][][]"
"$rowConstraints": "[][][][][][][][][][][][]para[][][][]0[]"
"$rowConstraints": "[][][][][][][][][][][][]para[][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -671,120 +671,9 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 14,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontsLabel"
"text": "Typography / Fonts:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 15"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h00Label"
"text": "H00"
"$client.FlatLaf.styleClass": "h00"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h0Label"
"text": "H0"
"$client.FlatLaf.styleClass": "h0"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h1Label"
"text": "H1"
"$client.FlatLaf.styleClass": "h1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h2Label"
"text": "H2"
"$client.FlatLaf.styleClass": "h2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h3Label"
"text": "H3"
"$client.FlatLaf.styleClass": "h3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h4Label"
"text": "H4"
"$client.FlatLaf.styleClass": "h4"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "lightLabel"
"text": "light"
"$client.FlatLaf.style": "font: 200% $light.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1,gapx 30"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "semiboldLabel"
"text": "semibold"
"$client.FlatLaf.style": "font: 200% $semibold.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontZoomLabel"
"text": "(200%)"
"$client.FlatLaf.styleClass": "small"
"enabled": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "largeLabel"
"text": "large"
"$client.FlatLaf.styleClass": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "defaultLabel"
"text": "default"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "mediumLabel"
"text": "medium"
"$client.FlatLaf.styleClass": "medium"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "smallLabel"
"text": "small"
"$client.FlatLaf.styleClass": "small"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "miniLabel"
"text": "mini"
"$client.FlatLaf.styleClass": "mini"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "monospacedLabel"
"text": "monospaced"
"$client.FlatLaf.styleClass": "monospaced"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1,gapx 30"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 920, 550 )
"size": new java.awt.Dimension( 920, 480 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1"
@@ -804,7 +693,7 @@ new FormModel {
"mnemonic": 80
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 570 )
"location": new java.awt.Point( 0, 500 )
"size": new java.awt.Dimension( 91, 87 )
} )
}

View File

@@ -29,7 +29,6 @@ import java.util.prefs.Preferences;
import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.StyleContext;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
@@ -51,6 +50,7 @@ import com.formdev.flatlaf.ui.JBRCustomDecorations;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.layout.ConstraintParser;
import net.miginfocom.layout.LC;
import net.miginfocom.layout.UnitValue;
@@ -160,7 +160,8 @@ class DemoFrame
private void aboutActionPerformed() {
JLabel titleLabel = new JLabel( "FlatLaf Demo" );
titleLabel.putClientProperty( FlatClientProperties.STYLE_CLASS, "h1" );
Font titleFont = titleLabel.getFont();
titleLabel.setFont( titleFont.deriveFont( (float) titleFont.getSize() + UIScale.scale( 6 ) ) );
String link = "https://www.formdev.com/flatlaf/";
JLabel linkLabel = new JLabel( "<html><a href=\"#\">" + link + "</a></html>" );
@@ -215,7 +216,6 @@ class DemoFrame
menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
unifiedTitleBarMenuItem.setEnabled( windowDecorations );
showTitleBarIconMenuItem.setEnabled( windowDecorations );
}
private void menuBarEmbeddedChanged() {
@@ -228,16 +228,6 @@ class DemoFrame
FlatLaf.repaintAllFramesAndDialogs();
}
private void showTitleBarIcon() {
boolean showIcon = showTitleBarIconMenuItem.isSelected();
// for main frame (because already created)
getRootPane().putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIcon );
// for other not yet created frames/dialogs
UIManager.put( "TitlePane.showIcon", showIcon );
}
private void underlineMenuSelection() {
UIManager.put( "MenuItem.selectionType", underlineMenuSelectionMenuItem.isSelected() ? "underline" : null );
}
@@ -477,7 +467,6 @@ class DemoFrame
windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem();
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
unifiedTitleBarMenuItem = new JCheckBoxMenuItem();
showTitleBarIconMenuItem = new JCheckBoxMenuItem();
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
animatedLafChangeMenuItem = new JCheckBoxMenuItem();
@@ -729,11 +718,13 @@ class DemoFrame
//---- windowDecorationsCheckBoxMenuItem ----
windowDecorationsCheckBoxMenuItem.setText("Window decorations");
windowDecorationsCheckBoxMenuItem.setSelected(true);
windowDecorationsCheckBoxMenuItem.addActionListener(e -> windowDecorationsChanged());
optionsMenu.add(windowDecorationsCheckBoxMenuItem);
//---- menuBarEmbeddedCheckBoxMenuItem ----
menuBarEmbeddedCheckBoxMenuItem.setText("Embedded menu bar");
menuBarEmbeddedCheckBoxMenuItem.setSelected(true);
menuBarEmbeddedCheckBoxMenuItem.addActionListener(e -> menuBarEmbeddedChanged());
optionsMenu.add(menuBarEmbeddedCheckBoxMenuItem);
@@ -742,11 +733,6 @@ class DemoFrame
unifiedTitleBarMenuItem.addActionListener(e -> unifiedTitleBar());
optionsMenu.add(unifiedTitleBarMenuItem);
//---- showTitleBarIconMenuItem ----
showTitleBarIconMenuItem.setText("Show window title bar icon");
showTitleBarIconMenuItem.addActionListener(e -> showTitleBarIcon());
optionsMenu.add(showTitleBarIconMenuItem);
//---- underlineMenuSelectionMenuItem ----
underlineMenuSelectionMenuItem.setText("Use underline menu selection");
underlineMenuSelectionMenuItem.addActionListener(e -> underlineMenuSelection());
@@ -890,11 +876,6 @@ class DemoFrame
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
if( FlatLaf.supportsNativeWindowDecorations() ) {
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
if( JBRCustomDecorations.isSupported() ) {
// If the JetBrains Runtime is used, it forces the use of it's own custom
// window decoration, which can not disabled.
@@ -904,7 +885,6 @@ class DemoFrame
unsupported( windowDecorationsCheckBoxMenuItem );
unsupported( menuBarEmbeddedCheckBoxMenuItem );
unsupported( unifiedTitleBarMenuItem );
unsupported( showTitleBarIconMenuItem );
}
if( SystemInfo.isMacOS )
@@ -937,7 +917,6 @@ class DemoFrame
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
private JCheckBoxMenuItem unifiedTitleBarMenuItem;
private JCheckBoxMenuItem showTitleBarIconMenuItem;
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
private JCheckBoxMenuItem animatedLafChangeMenuItem;

View File

@@ -354,6 +354,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "windowDecorationsCheckBoxMenuItem"
"text": "Window decorations"
"selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -362,6 +363,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "menuBarEmbeddedCheckBoxMenuItem"
"text": "Embedded menu bar"
"selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -375,14 +377,6 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "unifiedTitleBar", false ) )
} )
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "showTitleBarIconMenuItem"
"text": "Show window title bar icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
} )
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "underlineMenuSelectionMenuItem"
"text": "Use underline menu selection"

View File

@@ -18,15 +18,11 @@ package com.formdev.flatlaf.demo;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatDropShadowBorder;
import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatPopupMenuBorder;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -91,9 +87,6 @@ class HintManager
initComponents();
setOpaque( false );
updateBalloonBorder();
hintLabel.setText( "<html>" + hint.message + "</html>" );
// grab all mouse events to avoid that components overlapped
@@ -105,28 +98,8 @@ class HintManager
public void updateUI() {
super.updateUI();
if( UIManager.getLookAndFeel() instanceof FlatLaf )
setBackground( UIManager.getColor( "HintPanel.backgroundColor" ) );
else {
// using nonUIResource() because otherwise Nimbus does not fill the background
setBackground( FlatUIUtils.nonUIResource( UIManager.getColor( "info" ) ) );
}
if( hint != null )
updateBalloonBorder();
}
private void updateBalloonBorder() {
int direction;
switch( hint.position ) {
case SwingConstants.LEFT: direction = SwingConstants.RIGHT; break;
case SwingConstants.TOP: direction = SwingConstants.BOTTOM; break;
case SwingConstants.RIGHT: direction = SwingConstants.LEFT; break;
case SwingConstants.BOTTOM: direction = SwingConstants.TOP; break;
default: throw new IllegalArgumentException();
}
setBorder( new BalloonBorder( direction, FlatUIUtils.getUIColor( "PopupMenu.borderColor", Color.gray ) ) );
setBackground( UIManager.getColor( "HintPanel.backgroundColor" ) );
setBorder( new FlatPopupMenuBorder() );
}
void showHint() {
@@ -142,6 +115,11 @@ class HintManager
public void updateUI() {
super.updateUI();
setBorder( new FlatDropShadowBorder(
UIManager.getColor( "Popup.dropShadowColor" ),
UIManager.getInsets( "Popup.dropShadowInsets" ),
FlatUIUtils.getUIFloat( "Popup.dropShadowOpacity", 0.5f ) ) );
// use invokeLater because at this time the UI delegates
// of child components are not yet updated
EventQueue.invokeLater( () -> {
@@ -238,127 +216,4 @@ class HintManager
private JButton gotItButton;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
//---- class BalloonBorder ------------------------------------------------
private static class BalloonBorder
extends FlatEmptyBorder
{
private static int ARC = 8;
private static int ARROW_XY = 16;
private static int ARROW_SIZE = 8;
private static int SHADOW_SIZE = 6;
private static int SHADOW_TOP_SIZE = 3;
private static int SHADOW_SIZE2 = SHADOW_SIZE + 2;
private final int direction;
private final Color borderColor;
private final Border shadowBorder;
public BalloonBorder( int direction, Color borderColor ) {
super( 1 + SHADOW_TOP_SIZE, 1 + SHADOW_SIZE, 1 + SHADOW_SIZE, 1 + SHADOW_SIZE );
this.direction = direction;
this.borderColor = borderColor;
switch( direction ) {
case SwingConstants.LEFT: left += ARROW_SIZE; break;
case SwingConstants.TOP: top += ARROW_SIZE; break;
case SwingConstants.RIGHT: right += ARROW_SIZE; break;
case SwingConstants.BOTTOM: bottom += ARROW_SIZE; break;
}
shadowBorder = UIManager.getLookAndFeel() instanceof FlatLaf
? new FlatDropShadowBorder(
UIManager.getColor( "Popup.dropShadowColor" ),
new Insets( SHADOW_SIZE2, SHADOW_SIZE2, SHADOW_SIZE2, SHADOW_SIZE2 ),
FlatUIUtils.getUIFloat( "Popup.dropShadowOpacity", 0.5f ) )
: null;
}
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
g2.translate( x, y );
// shadow coordinates
int sx = 0;
int sy = 0;
int sw = width;
int sh = height;
int arrowSize = UIScale.scale( ARROW_SIZE );
switch( direction ) {
case SwingConstants.LEFT: sx += arrowSize; sw -= arrowSize; break;
case SwingConstants.TOP: sy += arrowSize; sh -= arrowSize; break;
case SwingConstants.RIGHT: sw -= arrowSize; break;
case SwingConstants.BOTTOM: sh -= arrowSize; break;
}
// paint shadow
if( shadowBorder != null )
shadowBorder.paintBorder( c, g2, sx, sy, sw, sh );
// create balloon shape
int bx = UIScale.scale( SHADOW_SIZE );
int by = UIScale.scale( SHADOW_TOP_SIZE );
int bw = width - UIScale.scale( SHADOW_SIZE + SHADOW_SIZE );
int bh = height - UIScale.scale( SHADOW_TOP_SIZE + SHADOW_SIZE );
g2.translate( bx, by );
Shape shape = createBalloonShape( bw, bh );
// fill balloon background
g2.setColor( c.getBackground() );
g2.fill( shape );
// paint balloon border
g2.setColor( borderColor );
g2.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
g2.draw( shape );
} finally {
g2.dispose();
}
}
private Shape createBalloonShape( int width, int height ) {
int arc = UIScale.scale( ARC );
int xy = UIScale.scale( ARROW_XY );
int awh = UIScale.scale( ARROW_SIZE );
Shape rect;
Shape arrow;
switch( direction ) {
case SwingConstants.LEFT:
rect = new RoundRectangle2D.Float( awh, 0, width - 1 - awh, height - 1, arc, arc );
arrow = FlatUIUtils.createPath( awh,xy, 0,xy+awh, awh,xy+awh+awh );
break;
case SwingConstants.TOP:
rect = new RoundRectangle2D.Float( 0, awh, width - 1, height - 1 - awh, arc, arc );
arrow = FlatUIUtils.createPath( xy,awh, xy+awh,0, xy+awh+awh,awh );
break;
case SwingConstants.RIGHT:
rect = new RoundRectangle2D.Float( 0, 0, width - 1 - awh, height - 1, arc, arc );
int x = width - 1 - awh;
arrow = FlatUIUtils.createPath( x,xy, x+awh,xy+awh, x,xy+awh+awh );
break;
case SwingConstants.BOTTOM:
rect = new RoundRectangle2D.Float( 0, 0, width - 1, height - 1 - awh, arc, arc );
int y = height - 1 - awh;
arrow = FlatUIUtils.createPath( xy,y, xy+awh,y+awh, xy+awh+awh,y );
break;
default:
throw new RuntimeException();
}
Area area = new Area( rect );
area.add( new Area( arrow ) );
return area;
}
}
}

View File

@@ -21,7 +21,6 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.border.*;
import com.formdev.flatlaf.FlatLaf;
import net.miginfocom.swing.*;
/**
@@ -45,29 +44,6 @@ class OptionPanePanel
"OK",
"Cancel",
} );
if( FlatLaf.supportsNativeWindowDecorations() ) {
updateShowTitleBarIcon();
UIManager.getDefaults().addPropertyChangeListener( e -> {
switch( e.getPropertyName() ) {
case "TitlePane.showIcon":
case "TitlePane.useWindowDecorations":
updateShowTitleBarIcon();
break;
}
} );
} else
showTitleBarIconCheckBox.setEnabled( false );
}
private void updateShowTitleBarIcon() {
showTitleBarIconCheckBox.setEnabled( UIManager.getBoolean( "TitlePane.showIcon" ) &&
FlatLaf.isUseNativeWindowDecorations() );
}
private void showTitleBarIcon() {
UIManager.put( "OptionPane.showIcon", showTitleBarIconCheckBox.isSelected() );
}
private void initComponents() {
@@ -78,7 +54,6 @@ class OptionPanePanel
JPanel panel1 = new JPanel();
JOptionPane plainOptionPane = new JOptionPane();
plainShowDialogLabel = new OptionPanePanel.ShowDialogLinkLabel();
showTitleBarIconCheckBox = new JCheckBox();
JLabel errorLabel = new JLabel();
JPanel panel2 = new JPanel();
JOptionPane errorOptionPane = new JOptionPane();
@@ -118,7 +93,7 @@ class OptionPanePanel
//======== panel9 ========
{
panel9.setLayout(new MigLayout(
"insets dialog,hidemode 3",
"flowy,insets dialog,hidemode 3",
// columns
"[]" +
"[]" +
@@ -151,12 +126,7 @@ class OptionPanePanel
//---- plainShowDialogLabel ----
plainShowDialogLabel.setOptionPane(plainOptionPane);
plainShowDialogLabel.setTitleLabel(plainLabel);
panel9.add(plainShowDialogLabel, "cell 1 0");
//---- showTitleBarIconCheckBox ----
showTitleBarIconCheckBox.setText("Show window title bar icon");
showTitleBarIconCheckBox.addActionListener(e -> showTitleBarIcon());
panel9.add(showTitleBarIconCheckBox, "cell 2 0");
panel9.add(plainShowDialogLabel, "cell 2 0");
//---- errorLabel ----
errorLabel.setText("Error");
@@ -178,7 +148,7 @@ class OptionPanePanel
//---- errorShowDialogLabel ----
errorShowDialogLabel.setTitleLabel(errorLabel);
errorShowDialogLabel.setOptionPane(errorOptionPane);
panel9.add(errorShowDialogLabel, "cell 1 1");
panel9.add(errorShowDialogLabel, "cell 2 1");
//---- informationLabel ----
informationLabel.setText("Information");
@@ -200,7 +170,7 @@ class OptionPanePanel
//---- informationShowDialogLabel ----
informationShowDialogLabel.setOptionPane(informationOptionPane);
informationShowDialogLabel.setTitleLabel(informationLabel);
panel9.add(informationShowDialogLabel, "cell 1 2");
panel9.add(informationShowDialogLabel, "cell 2 2");
//---- questionLabel ----
questionLabel.setText("Question");
@@ -244,7 +214,7 @@ class OptionPanePanel
//---- warningShowDialogLabel ----
warningShowDialogLabel.setOptionPane(warningOptionPane);
warningShowDialogLabel.setTitleLabel(warningLabel);
panel9.add(warningShowDialogLabel, "cell 1 4");
panel9.add(warningShowDialogLabel, "cell 2 4");
//---- inputLabel ----
inputLabel.setText("Input");
@@ -266,7 +236,7 @@ class OptionPanePanel
//---- inputShowDialogLabel ----
inputShowDialogLabel.setOptionPane(inputOptionPane);
inputShowDialogLabel.setTitleLabel(inputLabel);
panel9.add(inputShowDialogLabel, "cell 1 5");
panel9.add(inputShowDialogLabel, "cell 2 5");
//---- inputIconLabel ----
inputIconLabel.setText("Input + icon");
@@ -289,7 +259,7 @@ class OptionPanePanel
//---- inputIconShowDialogLabel ----
inputIconShowDialogLabel.setTitleLabel(inputIconLabel);
inputIconShowDialogLabel.setOptionPane(inputIconOptionPane);
panel9.add(inputIconShowDialogLabel, "cell 1 6");
panel9.add(inputIconShowDialogLabel, "cell 2 6");
//---- customLabel ----
customLabel.setText("Custom");
@@ -309,7 +279,7 @@ class OptionPanePanel
//---- customShowDialogLabel ----
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
panel9.add(customShowDialogLabel, "cell 1 7");
panel9.add(customShowDialogLabel, "cell 2 7");
}
scrollPane1.setViewportView(panel9);
}
@@ -319,7 +289,6 @@ class OptionPanePanel
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private OptionPanePanel.ShowDialogLinkLabel plainShowDialogLabel;
private JCheckBox showTitleBarIconCheckBox;
private OptionPanePanel.ShowDialogLinkLabel errorShowDialogLabel;
private OptionPanePanel.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
@@ -335,7 +304,6 @@ class OptionPanePanel
ShowDialogLinkLabel() {
setText( "<html><a href=\"#\">Show dialog</a></html>" );
setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
addMouseListener( new MouseAdapter() {
@Override

View File

@@ -12,7 +12,7 @@ new FormModel {
name: "scrollPane1"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$layoutConstraints": "flowy,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top]"
} ) {
@@ -42,16 +42,6 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTitleBarIconCheckBox"
"text": "Show window title bar icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
@@ -83,7 +73,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
"value": "cell 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "informationLabel"
@@ -113,7 +103,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
"value": "cell 2 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "questionLabel"
@@ -167,7 +157,7 @@ new FormModel {
"optionPane": new FormReference( "warningOptionPane" )
"titleLabel": new FormReference( "warningLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
"value": "cell 2 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputLabel"
@@ -194,7 +184,7 @@ new FormModel {
"optionPane": new FormReference( "inputOptionPane" )
"titleLabel": new FormReference( "inputLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5"
"value": "cell 2 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputIconLabel"
@@ -222,7 +212,7 @@ new FormModel {
"titleLabel": new FormReference( "inputIconLabel" )
"optionPane": new FormReference( "inputIconOptionPane" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6"
"value": "cell 2 6"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "customLabel"
@@ -250,7 +240,7 @@ new FormModel {
"optionPane": new FormReference( "customOptionPane" )
"titleLabel": new FormReference( "customLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7"
"value": "cell 2 7"
} )
} )
}, new FormLayoutConstraints( class java.lang.String ) {
@@ -258,7 +248,7 @@ new FormModel {
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 955, 900 )
"size": new java.awt.Dimension( 840, 900 )
} )
}
}

View File

@@ -303,11 +303,6 @@ class TabsPanel
putTabbedPanesClientProperty( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT, scrollButtonsPlacement );
}
private void tabTypeChanged() {
String tabType = cardTabTypeButton.isSelected() ? TABBED_PANE_TAB_TYPE_CARD : null;
putTabbedPanesClientProperty( TABBED_PANE_TAB_TYPE, tabType );
}
private void showTabSeparatorsChanged() {
Boolean showTabSeparators = showTabSeparatorsCheckBox.isSelected() ? true : null;
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
@@ -401,15 +396,11 @@ class TabsPanel
scrollButtonsPlacementToolBar = new JToolBar();
scrollBothButton = new JToggleButton();
scrollTrailingButton = new JToggleButton();
showTabSeparatorsCheckBox = new JCheckBox();
tabsPopupPolicyLabel = new JLabel();
tabsPopupPolicyToolBar = new JToolBar();
popupAsNeededButton = new JToggleButton();
popupNeverButton = new JToggleButton();
tabTypeLabel = new JLabel();
tabTypeToolBar = new JToolBar();
underlinedTabTypeButton = new JToggleButton();
cardTabTypeButton = new JToggleButton();
showTabSeparatorsCheckBox = new JCheckBox();
//======== this ========
setName("this");
@@ -444,7 +435,7 @@ class TabsPanel
//---- tabPlacementLabel ----
tabPlacementLabel.setText("Tab placement");
tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabPlacementLabel.setFont(tabPlacementLabel.getFont().deriveFont(tabPlacementLabel.getFont().getSize() + 4f));
tabPlacementLabel.setName("tabPlacementLabel");
panel1.add(tabPlacementLabel, "cell 0 0");
@@ -457,28 +448,28 @@ class TabsPanel
//---- topPlacementButton ----
topPlacementButton.setText("top");
topPlacementButton.setSelected(true);
topPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
topPlacementButton.setFont(topPlacementButton.getFont().deriveFont(topPlacementButton.getFont().getSize() - 2f));
topPlacementButton.setName("topPlacementButton");
topPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(topPlacementButton);
//---- bottomPlacementButton ----
bottomPlacementButton.setText("bottom");
bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
bottomPlacementButton.setFont(bottomPlacementButton.getFont().deriveFont(bottomPlacementButton.getFont().getSize() - 2f));
bottomPlacementButton.setName("bottomPlacementButton");
bottomPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(bottomPlacementButton);
//---- leftPlacementButton ----
leftPlacementButton.setText("left");
leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
leftPlacementButton.setFont(leftPlacementButton.getFont().deriveFont(leftPlacementButton.getFont().getSize() - 2f));
leftPlacementButton.setName("leftPlacementButton");
leftPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(leftPlacementButton);
//---- rightPlacementButton ----
rightPlacementButton.setText("right");
rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
rightPlacementButton.setFont(rightPlacementButton.getFont().deriveFont(rightPlacementButton.getFont().getSize() - 2f));
rightPlacementButton.setName("rightPlacementButton");
rightPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(rightPlacementButton);
@@ -486,14 +477,14 @@ class TabsPanel
//---- scrollButton ----
scrollButton.setText("scroll");
scrollButton.putClientProperty("FlatLaf.styleClass", "small");
scrollButton.setFont(scrollButton.getFont().deriveFont(scrollButton.getFont().getSize() - 2f));
scrollButton.setName("scrollButton");
scrollButton.addActionListener(e -> scrollChanged());
tabPlacementToolBar.add(scrollButton);
//---- borderButton ----
borderButton.setText("border");
borderButton.putClientProperty("FlatLaf.styleClass", "small");
borderButton.setFont(borderButton.getFont().deriveFont(borderButton.getFont().getSize() - 2f));
borderButton.setName("borderButton");
borderButton.addActionListener(e -> borderChanged());
tabPlacementToolBar.add(borderButton);
@@ -508,7 +499,7 @@ class TabsPanel
//---- tabLayoutLabel ----
tabLayoutLabel.setText("Tab layout");
tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabLayoutLabel.setFont(tabLayoutLabel.getFont().deriveFont(tabLayoutLabel.getFont().getSize() + 4f));
tabLayoutLabel.setName("tabLayoutLabel");
panel1.add(tabLayoutLabel, "cell 0 2");
@@ -520,15 +511,15 @@ class TabsPanel
//---- scrollTabLayoutButton ----
scrollTabLayoutButton.setText("scroll");
scrollTabLayoutButton.setFont(scrollTabLayoutButton.getFont().deriveFont(scrollTabLayoutButton.getFont().getSize() - 2f));
scrollTabLayoutButton.setSelected(true);
scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTabLayoutButton.setName("scrollTabLayoutButton");
scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(scrollTabLayoutButton);
//---- wrapTabLayoutButton ----
wrapTabLayoutButton.setText("wrap");
wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
wrapTabLayoutButton.setFont(wrapTabLayoutButton.getFont().deriveFont(wrapTabLayoutButton.getFont().getSize() - 2f));
wrapTabLayoutButton.setName("wrapTabLayoutButton");
wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(wrapTabLayoutButton);
@@ -538,14 +529,14 @@ class TabsPanel
//---- scrollLayoutNoteLabel ----
scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)");
scrollLayoutNoteLabel.setEnabled(false);
scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
scrollLayoutNoteLabel.setFont(scrollLayoutNoteLabel.getFont().deriveFont(scrollLayoutNoteLabel.getFont().getSize() - 2f));
scrollLayoutNoteLabel.setName("scrollLayoutNoteLabel");
panel1.add(scrollLayoutNoteLabel, "cell 0 3");
//---- wrapLayoutNoteLabel ----
wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)");
wrapLayoutNoteLabel.setEnabled(false);
wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
wrapLayoutNoteLabel.setFont(wrapLayoutNoteLabel.getFont().deriveFont(wrapLayoutNoteLabel.getFont().getSize() - 2f));
wrapLayoutNoteLabel.setName("wrapLayoutNoteLabel");
panel1.add(wrapLayoutNoteLabel, "cell 0 3");
@@ -563,7 +554,7 @@ class TabsPanel
//---- closableTabsLabel ----
closableTabsLabel.setText("Closable tabs");
closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3");
closableTabsLabel.setFont(closableTabsLabel.getFont().deriveFont(closableTabsLabel.getFont().getSize() + 4f));
closableTabsLabel.setName("closableTabsLabel");
panel1.add(closableTabsLabel, "cell 0 5");
@@ -575,22 +566,22 @@ class TabsPanel
//---- squareCloseButton ----
squareCloseButton.setText("square");
squareCloseButton.setFont(squareCloseButton.getFont().deriveFont(squareCloseButton.getFont().getSize() - 2f));
squareCloseButton.setSelected(true);
squareCloseButton.putClientProperty("FlatLaf.styleClass", "small");
squareCloseButton.setName("squareCloseButton");
squareCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(squareCloseButton);
//---- circleCloseButton ----
circleCloseButton.setText("circle");
circleCloseButton.putClientProperty("FlatLaf.styleClass", "small");
circleCloseButton.setFont(circleCloseButton.getFont().deriveFont(circleCloseButton.getFont().getSize() - 2f));
circleCloseButton.setName("circleCloseButton");
circleCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(circleCloseButton);
//---- redCrossCloseButton ----
redCrossCloseButton.setText("red cross");
redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small");
redCrossCloseButton.setFont(redCrossCloseButton.getFont().deriveFont(redCrossCloseButton.getFont().getSize() - 2f));
redCrossCloseButton.setName("redCrossCloseButton");
redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(redCrossCloseButton);
@@ -605,7 +596,7 @@ class TabsPanel
//---- tabAreaComponentsLabel ----
tabAreaComponentsLabel.setText("Custom tab area components");
tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaComponentsLabel.setFont(tabAreaComponentsLabel.getFont().deriveFont(tabAreaComponentsLabel.getFont().getSize() + 4f));
tabAreaComponentsLabel.setName("tabAreaComponentsLabel");
panel1.add(tabAreaComponentsLabel, "cell 0 7");
@@ -617,16 +608,16 @@ class TabsPanel
//---- leadingComponentButton ----
leadingComponentButton.setText("leading");
leadingComponentButton.setFont(leadingComponentButton.getFont().deriveFont(leadingComponentButton.getFont().getSize() - 2f));
leadingComponentButton.setSelected(true);
leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
leadingComponentButton.setName("leadingComponentButton");
leadingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(leadingComponentButton);
//---- trailingComponentButton ----
trailingComponentButton.setText("trailing");
trailingComponentButton.setFont(trailingComponentButton.getFont().deriveFont(trailingComponentButton.getFont().getSize() - 2f));
trailingComponentButton.setSelected(true);
trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
trailingComponentButton.setName("trailingComponentButton");
trailingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(trailingComponentButton);
@@ -664,14 +655,14 @@ class TabsPanel
//---- tabIconPlacementLabel ----
tabIconPlacementLabel.setText("Tab icon placement");
tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabIconPlacementLabel.setFont(tabIconPlacementLabel.getFont().deriveFont(tabIconPlacementLabel.getFont().getSize() + 4f));
tabIconPlacementLabel.setName("tabIconPlacementLabel");
panel2.add(tabIconPlacementLabel, "cell 0 0");
//---- tabIconPlacementNodeLabel ----
tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)");
tabIconPlacementNodeLabel.setEnabled(false);
tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small");
tabIconPlacementNodeLabel.setFont(tabIconPlacementNodeLabel.getFont().deriveFont(tabIconPlacementNodeLabel.getFont().getSize() - 2f));
tabIconPlacementNodeLabel.setName("tabIconPlacementNodeLabel");
panel2.add(tabIconPlacementNodeLabel, "cell 0 1");
@@ -701,14 +692,14 @@ class TabsPanel
//---- tabAreaAlignmentLabel ----
tabAreaAlignmentLabel.setText("Tab area alignment");
tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaAlignmentLabel.setFont(tabAreaAlignmentLabel.getFont().deriveFont(tabAreaAlignmentLabel.getFont().getSize() + 4f));
tabAreaAlignmentLabel.setName("tabAreaAlignmentLabel");
panel2.add(tabAreaAlignmentLabel, "cell 0 6");
//---- tabAreaAlignmentNoteLabel ----
tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)");
tabAreaAlignmentNoteLabel.setEnabled(false);
tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAreaAlignmentNoteLabel.setFont(tabAreaAlignmentNoteLabel.getFont().deriveFont(tabAreaAlignmentNoteLabel.getFont().getSize() - 2f));
tabAreaAlignmentNoteLabel.setName("tabAreaAlignmentNoteLabel");
panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7");
@@ -759,14 +750,14 @@ class TabsPanel
//---- tabWidthModeLabel ----
tabWidthModeLabel.setText("Tab width mode");
tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabWidthModeLabel.setFont(tabWidthModeLabel.getFont().deriveFont(tabWidthModeLabel.getFont().getSize() + 4f));
tabWidthModeLabel.setName("tabWidthModeLabel");
panel3.add(tabWidthModeLabel, "cell 0 0");
//---- tabWidthModeNoteLabel ----
tabWidthModeNoteLabel.setText("(preferred/equal/compact)");
tabWidthModeNoteLabel.setFont(tabWidthModeNoteLabel.getFont().deriveFont(tabWidthModeNoteLabel.getFont().getSize() - 2f));
tabWidthModeNoteLabel.setEnabled(false);
tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabWidthModeNoteLabel.setName("tabWidthModeNoteLabel");
panel3.add(tabWidthModeNoteLabel, "cell 0 1");
@@ -790,7 +781,7 @@ class TabsPanel
//---- minMaxTabWidthLabel ----
minMaxTabWidthLabel.setText("Minimum/maximum tab width");
minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3");
minMaxTabWidthLabel.setFont(minMaxTabWidthLabel.getFont().deriveFont(minMaxTabWidthLabel.getFont().getSize() + 4f));
minMaxTabWidthLabel.setName("minMaxTabWidthLabel");
panel3.add(minMaxTabWidthLabel, "cell 0 5");
@@ -808,7 +799,7 @@ class TabsPanel
//---- tabAlignmentLabel ----
tabAlignmentLabel.setText("Tab title alignment");
tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAlignmentLabel.setFont(tabAlignmentLabel.getFont().deriveFont(tabAlignmentLabel.getFont().getSize() + 4f));
tabAlignmentLabel.setName("tabAlignmentLabel");
panel3.add(tabAlignmentLabel, "cell 0 8");
@@ -829,14 +820,14 @@ class TabsPanel
//---- tabAlignmentNoteLabel ----
tabAlignmentNoteLabel.setText("(leading/center/trailing)");
tabAlignmentNoteLabel.setEnabled(false);
tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel.setFont(tabAlignmentNoteLabel.getFont().deriveFont(tabAlignmentNoteLabel.getFont().getSize() - 2f));
tabAlignmentNoteLabel.setName("tabAlignmentNoteLabel");
panel5.add(tabAlignmentNoteLabel, "cell 0 0");
//---- tabAlignmentNoteLabel2 ----
tabAlignmentNoteLabel2.setText("(trailing)");
tabAlignmentNoteLabel2.setEnabled(false);
tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel2.setFont(tabAlignmentNoteLabel2.getFont().deriveFont(tabAlignmentNoteLabel2.getFont().getSize() - 2f));
tabAlignmentNoteLabel2.setName("tabAlignmentNoteLabel2");
panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0");
@@ -882,8 +873,7 @@ class TabsPanel
"[]" +
"[fill]para" +
"[fill]" +
"[fill]para" +
"[fill]",
"[fill]para",
// rows
"[]" +
"[center]"));
@@ -901,22 +891,22 @@ class TabsPanel
//---- scrollAsNeededSingleButton ----
scrollAsNeededSingleButton.setText("asNeededSingle");
scrollAsNeededSingleButton.setFont(scrollAsNeededSingleButton.getFont().deriveFont(scrollAsNeededSingleButton.getFont().getSize() - 2f));
scrollAsNeededSingleButton.setSelected(true);
scrollAsNeededSingleButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededSingleButton.setName("scrollAsNeededSingleButton");
scrollAsNeededSingleButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededSingleButton);
//---- scrollAsNeededButton ----
scrollAsNeededButton.setText("asNeeded");
scrollAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededButton.setFont(scrollAsNeededButton.getFont().deriveFont(scrollAsNeededButton.getFont().getSize() - 2f));
scrollAsNeededButton.setName("scrollAsNeededButton");
scrollAsNeededButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededButton);
//---- scrollNeverButton ----
scrollNeverButton.setText("never");
scrollNeverButton.putClientProperty("FlatLaf.styleClass", "small");
scrollNeverButton.setFont(scrollNeverButton.getFont().deriveFont(scrollNeverButton.getFont().getSize() - 2f));
scrollNeverButton.setName("scrollNeverButton");
scrollNeverButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollNeverButton);
@@ -936,27 +926,21 @@ class TabsPanel
//---- scrollBothButton ----
scrollBothButton.setText("both");
scrollBothButton.setFont(scrollBothButton.getFont().deriveFont(scrollBothButton.getFont().getSize() - 2f));
scrollBothButton.setSelected(true);
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
scrollBothButton.setName("scrollBothButton");
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollBothButton);
//---- scrollTrailingButton ----
scrollTrailingButton.setText("trailing");
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTrailingButton.setFont(scrollTrailingButton.getFont().deriveFont(scrollTrailingButton.getFont().getSize() - 2f));
scrollTrailingButton.setName("scrollTrailingButton");
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollTrailingButton);
}
panel4.add(scrollButtonsPlacementToolBar, "cell 3 0");
//---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.setName("showTabSeparatorsCheckBox");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
panel4.add(showTabSeparatorsCheckBox, "cell 4 0");
//---- tabsPopupPolicyLabel ----
tabsPopupPolicyLabel.setText("Tabs popup policy:");
tabsPopupPolicyLabel.setName("tabsPopupPolicyLabel");
@@ -970,47 +954,26 @@ class TabsPanel
//---- popupAsNeededButton ----
popupAsNeededButton.setText("asNeeded");
popupAsNeededButton.setFont(popupAsNeededButton.getFont().deriveFont(popupAsNeededButton.getFont().getSize() - 2f));
popupAsNeededButton.setSelected(true);
popupAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
popupAsNeededButton.setName("popupAsNeededButton");
popupAsNeededButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupAsNeededButton);
//---- popupNeverButton ----
popupNeverButton.setText("never");
popupNeverButton.putClientProperty("FlatLaf.styleClass", "small");
popupNeverButton.setFont(popupNeverButton.getFont().deriveFont(popupNeverButton.getFont().getSize() - 2f));
popupNeverButton.setName("popupNeverButton");
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupNeverButton);
}
panel4.add(tabsPopupPolicyToolBar, "cell 1 1");
//---- tabTypeLabel ----
tabTypeLabel.setText("Tab type:");
tabTypeLabel.setName("tabTypeLabel");
panel4.add(tabTypeLabel, "cell 2 1");
//======== tabTypeToolBar ========
{
tabTypeToolBar.setFloatable(false);
tabTypeToolBar.setName("tabTypeToolBar");
//---- underlinedTabTypeButton ----
underlinedTabTypeButton.setText("underlined");
underlinedTabTypeButton.setSelected(true);
underlinedTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
underlinedTabTypeButton.setName("underlinedTabTypeButton");
underlinedTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(underlinedTabTypeButton);
//---- cardTabTypeButton ----
cardTabTypeButton.setText("card");
cardTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
cardTabTypeButton.setName("cardTabTypeButton");
cardTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(cardTabTypeButton);
}
panel4.add(tabTypeToolBar, "cell 3 1");
//---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.setName("showTabSeparatorsCheckBox");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
panel4.add(showTabSeparatorsCheckBox, "cell 2 1 2 1");
}
add(panel4, "cell 0 2 3 1");
@@ -1047,11 +1010,6 @@ class TabsPanel
ButtonGroup tabsPopupPolicyButtonGroup = new ButtonGroup();
tabsPopupPolicyButtonGroup.add(popupAsNeededButton);
tabsPopupPolicyButtonGroup.add(popupNeverButton);
//---- tabTypeButtonGroup ----
ButtonGroup tabTypeButtonGroup = new ButtonGroup();
tabTypeButtonGroup.add(underlinedTabTypeButton);
tabTypeButtonGroup.add(cardTabTypeButton);
// JFormDesigner - End of component initialization //GEN-END:initComponents
if( FlatLafDemo.screenshotsMode ) {
@@ -1131,14 +1089,10 @@ class TabsPanel
private JToolBar scrollButtonsPlacementToolBar;
private JToggleButton scrollBothButton;
private JToggleButton scrollTrailingButton;
private JCheckBox showTabSeparatorsCheckBox;
private JLabel tabsPopupPolicyLabel;
private JToolBar tabsPopupPolicyToolBar;
private JToggleButton popupAsNeededButton;
private JToggleButton popupNeverButton;
private JLabel tabTypeLabel;
private JToolBar tabTypeToolBar;
private JToggleButton underlinedTabTypeButton;
private JToggleButton cardTabTypeButton;
private JCheckBox showTabSeparatorsCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -22,7 +22,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabPlacementLabel"
"text": "Tab placement"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -38,28 +38,28 @@ new FormModel {
"text": "top"
"selected": true
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont0 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "bottomPlacementButton"
"text": "bottom"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "leftPlacementButton"
"text": "left"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "rightPlacementButton"
"text": "right"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
@@ -68,13 +68,13 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollButton"
"text": "scroll"
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "borderButton"
"text": "border"
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "borderChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -88,7 +88,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabLayoutLabel"
"text": "Tab layout"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont1 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -103,15 +103,15 @@ new FormModel {
name: "scrollTabLayoutButton"
"text": "scroll"
"$buttonGroup": new FormReference( "tabLayoutButtonGroup" )
"font": &SwingDerivedFont2 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "wrapTabLayoutButton"
"text": "wrap"
"$buttonGroup": new FormReference( "tabLayoutButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -121,7 +121,7 @@ new FormModel {
name: "scrollLayoutNoteLabel"
"text": "(use mouse wheel to scroll; arrow button shows hidden tabs)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont3 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
@@ -129,7 +129,7 @@ new FormModel {
name: "wrapLayoutNoteLabel"
"text": "(probably better to use scroll layout?)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont3
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
@@ -146,7 +146,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "closableTabsLabel"
"text": "Closable tabs"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -160,23 +160,23 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "squareCloseButton"
"text": "square"
"font": &SwingDerivedFont4 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "circleCloseButton"
"text": "circle"
"font": #SwingDerivedFont4
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "redCrossCloseButton"
"text": "red cross"
"font": #SwingDerivedFont4
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -190,7 +190,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAreaComponentsLabel"
"text": "Custom tab area components"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -204,15 +204,15 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "leadingComponentButton"
"text": "leading"
"font": &SwingDerivedFont5 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "trailingComponentButton"
"text": "trailing"
"font": #SwingDerivedFont5
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -238,7 +238,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabIconPlacementLabel"
"text": "Tab icon placement"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -249,7 +249,7 @@ new FormModel {
name: "tabIconPlacementNodeLabel"
"text": "(top/bottom/leading/trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -279,7 +279,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAreaAlignmentLabel"
"text": "Tab area alignment"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont6 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -290,7 +290,7 @@ new FormModel {
name: "tabAreaAlignmentNoteLabel"
"text": "(leading/center/trailing/fill)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont7 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -332,7 +332,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabWidthModeLabel"
"text": "Tab width mode"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont6
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -342,8 +342,8 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabWidthModeNoteLabel"
"text": "(preferred/equal/compact)"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"enabled": false
"$client.FlatLaf.styleClass": "small"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -368,7 +368,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "minMaxTabWidthLabel"
"text": "Minimum/maximum tab width"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -388,7 +388,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAlignmentLabel"
"text": "Tab title alignment"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont6
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -405,7 +405,7 @@ new FormModel {
name: "tabAlignmentNoteLabel"
"text": "(leading/center/trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont7
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -416,7 +416,7 @@ new FormModel {
name: "tabAlignmentNoteLabel2"
"text": "(trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont7
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -457,7 +457,7 @@ new FormModel {
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[][fill]para[fill][fill]para[fill]"
"$columnConstraints": "[][fill]para[fill][fill]para"
"$rowConstraints": "[][center]"
} ) {
name: "panel4"
@@ -477,23 +477,23 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollAsNeededSingleButton"
"text": "asNeededSingle"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollAsNeededButton"
"text": "asNeeded"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollNeverButton"
"text": "never"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -512,31 +512,21 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollBothButton"
"text": "both"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollTrailingButton"
"text": "trailing"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox"
"text": "Show tab separators"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabsPopupPolicyLabel"
"text": "Tabs popup policy:"
@@ -550,54 +540,37 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "popupAsNeededButton"
"text": "asNeeded"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "popupNeverButton"
"text": "never"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabTypeLabel"
"text": "Tab type:"
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox"
"text": "Show tab separators"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1"
} )
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
name: "tabTypeToolBar"
"floatable": false
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "underlinedTabTypeButton"
"text": "underlined"
"selected": true
"$buttonGroup": new FormReference( "tabTypeButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabTypeChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "cardTabTypeButton"
"text": "card"
"$buttonGroup": new FormReference( "tabTypeButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabTypeChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 1"
"value": "cell 2 1 2 1"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 1145, 895 )
"size": new java.awt.Dimension( 1075, 895 )
} )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "tabPlacementButtonGroup"
@@ -629,10 +602,5 @@ new FormModel {
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 200, 1020 )
} )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "tabTypeButtonGroup"
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 1072 )
} )
}
}

View File

@@ -474,9 +474,9 @@ public class FlatInspector
if( c instanceof JComponent )
appendRow( buf, "Border", toString( ((JComponent)c).getBorder(), classHierarchy ) );
appendRow( buf, "Background", toString( c.getBackground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
appendRow( buf, "Foreground", toString( c.getForeground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
appendRow( buf, "Font", toString( c.getFont() ) + (c.isFontSet() ? "" : " NOT SET") );
appendRow( buf, "Background", toString( c.getBackground() ) );
appendRow( buf, "Foreground", toString( c.getForeground() ) );
appendRow( buf, "Font", toString( c.getFont() ) );
if( c instanceof JComponent ) {
try {

View File

@@ -27,10 +27,6 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
@@ -48,7 +44,6 @@ import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.SoftCache;
import com.formdev.flatlaf.util.UIScale;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
@@ -63,12 +58,8 @@ public class FlatSVGIcon
extends ImageIcon
implements DisabledIconProvider
{
// cache that uses soft references for values, which allows freeing SVG diagrams if no longer used
private static final SoftCache<URI, SVGDiagram> svgCache = new SoftCache<>();
// use own SVG universe so that it can not be cleared from anywhere
private static final SVGUniverse svgUniverse = new SVGUniverse();
private static int streamNumber;
private final String name;
private final int width;
@@ -76,30 +67,23 @@ public class FlatSVGIcon
private final float scale;
private final boolean disabled;
private final ClassLoader classLoader;
private final URI uri;
private ColorFilter colorFilter;
private SVGDiagram diagram;
private boolean dark;
private boolean loadFailed;
/**
* Creates an SVG icon from the given resource name.
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name ) {
this( name, -1, -1, 1, false, null, null );
this( name, -1, -1, 1, false, null );
}
/**
@@ -108,37 +92,27 @@ public class FlatSVGIcon
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @param classLoader the class loader used to load the SVG resource
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, ClassLoader classLoader ) {
this( name, -1, -1, 1, false, classLoader, null );
this( name, -1, -1, 1, false, classLoader );
}
/**
* Creates an SVG icon from the given resource name with the given width and height.
* <p>
* The icon is scaled if the given size is different to the size specified in the SVG file.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @param width the width of the icon
* @param height the height of the icon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, int width, int height ) {
this( name, width, height, 1, false, null, null );
this( name, width, height, 1, false, null );
}
/**
@@ -146,20 +120,15 @@ public class FlatSVGIcon
* The SVG file is loaded from the given class loader.
* <p>
* The icon is scaled if the given size is different to the size specified in the SVG file.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @param width the width of the icon
* @param height the height of the icon
* @param classLoader the class loader used to load the SVG resource
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, int width, int height, ClassLoader classLoader ) {
this( name, width, height, 1, false, classLoader, null );
this( name, width, height, 1, false, classLoader );
}
/**
@@ -168,18 +137,13 @@ public class FlatSVGIcon
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as base icon size, which is multiplied
* by the given scale factor.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @param scale the amount by which the icon size is scaled
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, float scale ) {
this( name, -1, -1, scale, false, null, null );
this( name, -1, -1, scale, false, null );
}
/**
@@ -189,107 +153,23 @@ public class FlatSVGIcon
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as base icon size, which is multiplied
* by the given scale factor.
* <p>
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
* Otherwise use {@link #FlatSVGIcon(URL)}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param name the name of the SVG resource (a '/'-separated path; e.g. {@code "com/myapp/myicon.svg"})
* @param name the name of the SVG resource (a '/'-separated path)
* @param scale the amount by which the icon size is scaled
* @param classLoader the class loader used to load the SVG resource
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, float scale, ClassLoader classLoader ) {
this( name, -1, -1, scale, false, classLoader, null );
this( name, -1, -1, scale, false, classLoader );
}
/**
* Creates an SVG icon from the given URL.
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* This method is useful if using Java modules and the package containing the icon
* is not opened in {@code module-info.java}.
* E.g. {@code new FlatSVGIcon( getClass().getResource( "/com/myapp/myicon.svg" ) )}.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param url the URL of the SVG resource
* @see ClassLoader#getResource(String)
* @since 2
*/
public FlatSVGIcon( URL url ) {
this( null, -1, -1, 1, false, null, url2uri( url ) );
}
/**
* Creates an SVG icon from the given URI.
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param uri the URI of the SVG resource
* @see ClassLoader#getResource(String)
* @since 2
*/
public FlatSVGIcon( URI uri ) {
this( null, -1, -1, 1, false, null, uri );
}
/**
* Creates an SVG icon from the given file.
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* This is cheap operation because the icon is only loaded when used.
*
* @param file the SVG file
* @since 2
*/
public FlatSVGIcon( File file ) {
this( null, -1, -1, 1, false, null, file.toURI() );
}
/**
* Creates an SVG icon from the given input stream.
* <p>
* The SVG attributes {@code width} and {@code height} (or {@code viewBox})
* in the tag {@code <svg>} are used as icon size.
* <p>
* The input stream is loaded, parsed and closed immediately.
*
* @param in the input stream for reading a SVG resource
* @throws IOException if an I/O exception occurs
* @since 2
*/
public FlatSVGIcon( InputStream in ) throws IOException {
this( null, -1, -1, 1, false, null, loadFromStream( in ) );
// since the input stream is already loaded and parsed,
// get diagram here and remove it from cache
update();
svgCache.remove( uri );
}
private static URI loadFromStream( InputStream in ) throws IOException {
try( InputStream in2 = in ) {
return svgUniverse.loadSVG( in2, "/flatlaf-stream-" + (streamNumber++) );
}
}
protected FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader, URI uri ) {
protected FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader ) {
this.name = name;
this.width = width;
this.height = height;
this.scale = scale;
this.disabled = disabled;
this.classLoader = classLoader;
this.uri = uri;
}
/**
@@ -368,7 +248,7 @@ public class FlatSVGIcon
if( width == this.width && height == this.height )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri );
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader );
icon.colorFilter = colorFilter;
icon.diagram = diagram;
icon.dark = dark;
@@ -387,7 +267,7 @@ public class FlatSVGIcon
if( scale == this.scale )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri );
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader );
icon.colorFilter = colorFilter;
icon.diagram = diagram;
icon.dark = dark;
@@ -406,7 +286,7 @@ public class FlatSVGIcon
if( disabled )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader, uri );
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader );
icon.colorFilter = colorFilter;
icon.diagram = diagram;
icon.dark = dark;
@@ -444,56 +324,20 @@ public class FlatSVGIcon
}
private void update() {
if( loadFailed )
return;
if( dark == isDarkLaf() && diagram != null )
return;
dark = isDarkLaf();
URL url = getIconURL( name, dark );
if( url == null & dark )
url = getIconURL( name, false );
// SVGs already loaded via url or input stream can not have light/dark variants
if( uri != null && diagram != null )
return;
URI uri = this.uri;
if( uri == null ) {
URL url = getIconURL( name, dark );
if( url == null & dark )
url = getIconURL( name, false );
if( url == null ) {
loadFailed = true;
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null );
return;
}
uri = url2uri( url );
// load/get image
try {
diagram = svgUniverse.getDiagram( url.toURI() );
} catch( URISyntaxException ex ) {
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load SVG icon '" + url + "'.", ex );
}
diagram = loadSVG( uri );
loadFailed = (diagram == null);
}
static SVGDiagram loadSVG( URI uri ) {
// get from our cache
SVGDiagram diagram = svgCache.get( uri );
if( diagram != null )
return diagram;
// load/get SVG diagram
diagram = svgUniverse.getDiagram( uri );
if( diagram == null ) {
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + uri + "'", null );
return null;
}
// add to our (soft) cache and remove from SVGUniverse (hard) cache
svgCache.put( uri, diagram );
svgUniverse.removeDocument( uri );
return diagram;
}
private URL getIconURL( String name, boolean dark ) {
@@ -643,14 +487,6 @@ public class FlatSVGIcon
return MultiResolutionImageSupport.create( 0, dimensions, producer );
}
static URI url2uri( URL url ) {
try {
return url.toURI();
} catch( URISyntaxException ex ) {
throw new IllegalArgumentException( ex );
}
}
private static Boolean darkLaf;
/**

View File

@@ -21,6 +21,7 @@ import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
@@ -28,6 +29,7 @@ import java.util.List;
import javax.swing.JWindow;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.SystemInfo;
import com.kitfox.svg.SVGCache;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
@@ -48,9 +50,6 @@ public class FlatSVGUtils
* for requested sizes from SVG.
* This has the advantage that only images for used sizes are created.
* Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
* <p>
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
* Otherwise use {@link #createWindowIconImages(URL)}.
*
* @param svgName the name of the SVG resource (a '/'-separated path)
* @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64)
@@ -58,32 +57,7 @@ public class FlatSVGUtils
* @see JWindow#setIconImages(List)
*/
public static List<Image> createWindowIconImages( String svgName ) {
return createWindowIconImages( getResource( svgName ) );
}
/**
* Creates from the given SVG a list of icon images with different sizes that
* can be used for windows headers. The SVG should have a size of 16x16,
* otherwise it is scaled.
* <p>
* If running on Windows in Java 9 or later and multi-resolution image support is available,
* then a single multi-resolution image is returned that creates images on demand
* for requested sizes from SVG.
* This has the advantage that only images for used sizes are created.
* Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
* <p>
* This method is useful if using Java modules and the package containing the SVG
* is not opened in {@code module-info.java}.
* E.g. {@code createWindowIconImages( getClass().getResource( "/com/myapp/myicon.svg" ) )}.
*
* @param svgUrl the URL of the SVG resource
* @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64)
* @throws RuntimeException if failed to load or render SVG file
* @see JWindow#setIconImages(List)
* @since 2
*/
public static List<Image> createWindowIconImages( URL svgUrl ) {
SVGDiagram diagram = loadSVG( svgUrl );
SVGDiagram diagram = loadSVG( svgName );
if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) {
// use a multi-resolution image that creates images on demand for requested sizes
@@ -119,9 +93,6 @@ public class FlatSVGUtils
/**
* Creates a buffered image and renders the given SVG into it.
* <p>
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
* Otherwise use {@link #svg2image(URL, int, int)}.
*
* @param svgName the name of the SVG resource (a '/'-separated path)
* @param width the width of the image
@@ -130,32 +101,11 @@ public class FlatSVGUtils
* @throws RuntimeException if failed to load or render SVG file
*/
public static BufferedImage svg2image( String svgName, int width, int height ) {
return svg2image( getResource( svgName ), width, height );
return svg2image( loadSVG( svgName ), width, height );
}
/**
* Creates a buffered image and renders the given SVG into it.
* <p>
* This method is useful if using Java modules and the package containing the SVG
* is not opened in {@code module-info.java}.
* E.g. {@code svg2image( getClass().getResource( "/com/myapp/myicon.svg" ), 24, 24 )}.
*
* @param svgUrl the URL of the SVG resource
* @param width the width of the image
* @param height the height of the image
* @return the image
* @throws RuntimeException if failed to load or render SVG file
* @since 2
*/
public static BufferedImage svg2image( URL svgUrl, int width, int height ) {
return svg2image( loadSVG( svgUrl ), width, height );
}
/**
* Creates a buffered image and renders the given SVG into it.
* <p>
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
* Otherwise use {@link #svg2image(URL, float)}.
*
* @param svgName the name of the SVG resource (a '/'-separated path)
* @param scaleFactor the amount by which the SVG size is scaled
@@ -163,24 +113,7 @@ public class FlatSVGUtils
* @throws RuntimeException if failed to load or render SVG file
*/
public static BufferedImage svg2image( String svgName, float scaleFactor ) {
return svg2image( getResource( svgName ), scaleFactor );
}
/**
* Creates a buffered image and renders the given SVG into it.
* <p>
* This method is useful if using Java modules and the package containing the SVG
* is not opened in {@code module-info.java}.
* E.g. {@code svg2image( getClass().getResource( "/com/myapp/myicon.svg" ), 1.5f )}.
*
* @param svgUrl the URL of the SVG resource
* @param scaleFactor the amount by which the SVG size is scaled
* @return the image
* @throws RuntimeException if failed to load or render SVG file
* @since 2
*/
public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) {
SVGDiagram diagram = loadSVG( svgUrl );
SVGDiagram diagram = loadSVG( svgName );
int width = (int) (diagram.getWidth() * scaleFactor);
int height = (int) (diagram.getHeight() * scaleFactor);
return svg2image( diagram, width, height );
@@ -222,11 +155,19 @@ public class FlatSVGUtils
}
}
private static URL getResource( String svgName ) {
return FlatSVGUtils.class.getResource( svgName );
}
private static SVGDiagram loadSVG( URL url ) {
return FlatSVGIcon.loadSVG( FlatSVGIcon.url2uri( url ) );
/**
* Loads a SVG file.
*
* @param svgName the name of the SVG resource (a '/'-separated path)
* @return the SVG diagram
* @throws RuntimeException if failed to load SVG file
*/
private static SVGDiagram loadSVG( String svgName ) {
try {
URL url = FlatSVGUtils.class.getResource( svgName );
return SVGCache.getSVGUniverse().getDiagram( url.toURI() );
} catch( URISyntaxException ex ) {
throw new RuntimeException( ex );
}
}
}

View File

@@ -1000,9 +1000,6 @@ public class FlatUIDefaultsInspector
{
private Item item;
// used instead of getBackground() because this did not work in some 3rd party Lafs
private Color valueColor;
@Override
public Component getTableCellRendererComponent( JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column )
@@ -1026,7 +1023,7 @@ public class FlatUIDefaultsInspector
if( item.value instanceof Color ) {
Color color = (item.info instanceof Color[]) ? ((Color[])item.info)[0] : (Color) item.value;
boolean isDark = new HSLColor( color ).getLuminance() < 70 && color.getAlpha() >= 128;
valueColor = color;
setBackground( color );
setForeground( isDark ? Color.white : Color.black );
} else if( item.value instanceof Icon ) {
Icon icon = (Icon) item.value;
@@ -1051,7 +1048,7 @@ public class FlatUIDefaultsInspector
if( item.value instanceof Color ) {
int width = getWidth();
int height = getHeight();
Color background = valueColor;
Color background = getBackground();
// paint color
fillRect( g, background, 0, 0, width, height );

View File

@@ -16,7 +16,6 @@
package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.STYLE_CLASS;
import javax.swing.JLabel;
/**
@@ -27,24 +26,6 @@ import javax.swing.JLabel;
*/
public class FlatLabel
extends JLabel
implements FlatComponentExtension, FlatStyleableComponent
implements FlatStyleableComponent
{
// NOTE: enum names must be equal to typography/font styles
public enum LabelType { h00, h0, h1, h2, h3, h4, large, regular, medium, small, mini, monospaced }
/**
* Returns type of the label.
*/
public LabelType getLabelType() {
return getClientPropertyEnumString( STYLE_CLASS, LabelType.class, null, LabelType.regular );
}
/**
* Specifies type of the label.
*/
public void setLabelType( LabelType labelType ) {
if( labelType == LabelType.regular )
labelType = null;
putClientPropertyEnumString( STYLE_CLASS, labelType );
}
}

View File

@@ -363,29 +363,6 @@ public class FlatTabbedPane
}
// NOTE: enum names must be equal to allowed strings
/** @since 2 */ public enum TabType { underlined, card };
/**
* Returns type of selected tab.
*
* @since 2
*/
public TabType getTabType() {
return getClientPropertyEnumString( TABBED_PANE_TAB_TYPE, TabType.class,
"TabbedPane.tabType", TabType.underlined );
}
/**
* Specifies type of selected tab.
*
* @since 2
*/
public void setTabType( TabType tabType ) {
putClientPropertyEnumString( TABBED_PANE_TAB_TYPE, tabType );
}
// NOTE: enum names must be equal to allowed strings
public enum TabsPopupPolicy { never, asNeeded };

View File

@@ -20,6 +20,6 @@ plugins {
dependencies {
implementation( project( ":flatlaf-core" ) )
implementation( "net.java.dev.jna:jna:5.10.0" )
implementation( "net.java.dev.jna:jna-platform:5.10.0" )
implementation( "net.java.dev.jna:jna:5.7.0" )
implementation( "net.java.dev.jna:jna-platform:5.7.0" )
}

View File

@@ -47,7 +47,7 @@ import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.Shell32;
@@ -77,10 +77,6 @@ import com.sun.jna.win32.W32APIOptions;
// https://github.com/oberth/custom-chrome
// https://github.com/rossy/borderless-window
//
// Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
// https://github.com/dotnet/wpf/issues/4825#issuecomment-930442736
//
/**
* Native window border support for Windows 10 when using custom decorations.
@@ -164,24 +160,30 @@ public class FlatWindowsNativeWindowBorder
}
@Override
public void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
Rectangle closeButtonBounds )
{
public void setTitleBarHeight( Window window, int titleBarHeight ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.titleBarHeight = titleBarHeight;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
wndProc.appIconBounds = cloneRectange( appIconBounds );
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
wndProc.closeButtonBounds = cloneRectange( closeButtonBounds );
}
private static Rectangle cloneRectange( Rectangle rect ) {
return (rect != null) ? new Rectangle( rect ) : null;
@Override
public void setTitleBarHitTestSpots( Window window, List<Rectangle> hitTestSpots ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
}
@Override
public void setTitleBarAppIconBounds( Window window, Rectangle appIconBounds ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.appIconBounds = (appIconBounds != null) ? new Rectangle( appIconBounds ) : null;
}
@Override
@@ -291,16 +293,7 @@ public class FlatWindowsNativeWindowBorder
WM_ERASEBKGND = 0x0014,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x0084,
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCRBUTTONUP = 0x00A5,
WM_MOUSEMOVE= 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320;
// WM_SIZE wParam
@@ -313,10 +306,7 @@ public class FlatWindowsNativeWindowBorder
HTCLIENT = 1,
HTCAPTION = 2,
HTSYSMENU = 3,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTTOP = 12,
HTCLOSE = 20;
HTTOP = 12;
private static final int ABS_AUTOHIDE = 0x0000001;
private static final int ABM_GETAUTOHIDEBAREX = 0x0000000b;
@@ -338,17 +328,13 @@ public class FlatWindowsNativeWindowBorder
private Window window;
private final HWND hwnd;
private final LONG_PTR defaultWndProc;
private final BaseTSD.LONG_PTR defaultWndProc;
private int wmSizeWParam = -1;
private HBRUSH background;
// Swing coordinates/values may be scaled on a HiDPI screen
private int titleBarHeight;
private Rectangle[] hitTestSpots;
private Rectangle appIconBounds;
private Rectangle minimizeButtonBounds;
private Rectangle maximizeButtonBounds;
private Rectangle closeButtonBounds;
WndProc( Window window ) {
this.window = window;
@@ -434,7 +420,6 @@ public class FlatWindowsNativeWindowBorder
*/
@Override
public LRESULT callback( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ) {
long wparam = wParam.longValue();
switch( uMsg ) {
case WM_NCCALCSIZE:
return WmNcCalcSize( hwnd, uMsg, wParam, lParam );
@@ -442,29 +427,8 @@ public class FlatWindowsNativeWindowBorder
case WM_NCHITTEST:
return WmNcHitTest( hwnd, uMsg, wParam, lParam );
case WM_NCMOUSEMOVE:
// if mouse is moved over some non-client areas,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wparam == HTMINBUTTON || wparam == HTMAXBUTTON || wparam == HTCLOSE ||
wparam == HTCAPTION || wparam == HTSYSMENU )
sendMessageToClientArea( hwnd, WM_MOUSEMOVE, lParam );
break;
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
// if left mouse was pressed/released over minimize/maximize/close button,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wparam == HTMINBUTTON || wparam == HTMAXBUTTON || wparam == HTCLOSE ) {
int uClientMsg = (uMsg == WM_NCLBUTTONDOWN) ? WM_LBUTTONDOWN : WM_LBUTTONUP;
sendMessageToClientArea( hwnd, uClientMsg, lParam );
return new LRESULT( 0 );
}
break;
case WM_NCRBUTTONUP:
if( wparam == HTCAPTION || wparam == HTSYSMENU )
if( wParam.longValue() == HTCAPTION || wParam.longValue() == HTSYSMENU )
openSystemMenu( hwnd, GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) );
break;
@@ -558,7 +522,7 @@ public class FlatWindowsNativeWindowBorder
boolean isMaximized = User32Ex.INSTANCE.IsZoomed( hwnd );
if( isMaximized && !isFullscreen() ) {
// When a window is maximized, its size is actually a little bit larger
// When a window is maximized, its size is actually a little bit more
// than the monitor's work area. The window is positioned and sized in
// such a way that the resize handles are outside of the monitor and
// then the window is clipped to the monitor so that the resize handle
@@ -610,12 +574,15 @@ public class FlatWindowsNativeWindowBorder
if( lResult.longValue() != HTCLIENT )
return lResult;
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
int x = GET_X_LPARAM( xy );
int y = GET_Y_LPARAM( xy );
// get window rectangle needed to convert mouse x/y from screen to window coordinates
RECT rcWindow = new RECT();
User32.INSTANCE.GetWindowRect( hwnd, rcWindow );
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
// get mouse x/y in window coordinates
int x = GET_X_LPARAM( lParam ) - rcWindow.left;
int y = GET_Y_LPARAM( lParam ) - rcWindow.top;
// scale-down mouse x/y
Point pt = scaleDown( x, y );
int sx = pt.x;
int sy = pt.y;
@@ -623,26 +590,9 @@ public class FlatWindowsNativeWindowBorder
// return HTSYSMENU if mouse is over application icon
// - left-click on HTSYSMENU area shows system menu
// - double-left-click sends WM_CLOSE
if( contains( appIconBounds, sx, sy ) )
if( appIconBounds != null && appIconBounds.contains( sx, sy ) )
return new LRESULT( HTSYSMENU );
// return HTMINBUTTON if mouse is over minimize button
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
if( contains( minimizeButtonBounds, sx, sy ) )
return new LRESULT( HTMINBUTTON );
// return HTMAXBUTTON if mouse is over maximize/restore button
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
if( contains( maximizeButtonBounds, sx, sy ) )
return new LRESULT( HTMAXBUTTON );
// return HTCLOSE if mouse is over close button
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
if( contains( closeButtonBounds, sx, sy ) )
return new LRESULT( HTCLOSE );
int resizeBorderHeight = getResizeHandleHeight();
boolean isOnResizeBorder = (y < resizeBorderHeight) &&
(User32.INSTANCE.GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
@@ -662,25 +612,6 @@ public class FlatWindowsNativeWindowBorder
return new LRESULT( isOnResizeBorder ? HTTOP : HTCLIENT );
}
private boolean contains( Rectangle rect, int x, int y ) {
return (rect != null && rect.contains( x, y ) );
}
/**
* Converts screen coordinates to window coordinates.
*/
private LRESULT screen2windowCoordinates( HWND hwnd, LPARAM lParam ) {
// get window rectangle needed to convert mouse x/y from screen to window coordinates
RECT rcWindow = new RECT();
User32.INSTANCE.GetWindowRect( hwnd, rcWindow );
// get mouse x/y in window coordinates
int x = GET_X_LPARAM( lParam ) - rcWindow.left;
int y = GET_Y_LPARAM( lParam ) - rcWindow.top;
return new LRESULT( MAKELONG( x, y ) );
}
/**
* Returns the height of the little space at the top of the window used to
* resize the window.
@@ -747,7 +678,7 @@ public class FlatWindowsNativeWindowBorder
*
* https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-nchittest#remarks
*/
private int GET_X_LPARAM( LONG_PTR lParam ) {
private int GET_X_LPARAM( LPARAM lParam ) {
return (short) (lParam.longValue() & 0xffff);
}
@@ -757,17 +688,10 @@ public class FlatWindowsNativeWindowBorder
*
* https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-nchittest#remarks
*/
private int GET_Y_LPARAM( LONG_PTR lParam ) {
private int GET_Y_LPARAM( LPARAM lParam ) {
return (short) ((lParam.longValue() >> 16) & 0xffff);
}
/**
* Same implementation as MAKELONG(wLow, wHigh) macro in windef.h.
*/
private long MAKELONG( int low, int high ) {
return (low & 0xffff) | ((high & 0xffff) << 16);
}
/**
* Same implementation as RGB(r,g,b) macro in wingdi.h.
*/
@@ -775,14 +699,6 @@ public class FlatWindowsNativeWindowBorder
return new DWORD( (r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16) );
}
private void sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam ) {
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
// send message
User32.INSTANCE.SendMessage( hwnd, uMsg, new WPARAM(), new LPARAM( xy.longValue() ) );
}
/**
* Opens the window's system menu.
* The system menu is the menu that opens when the user presses Alt+Space or

View File

@@ -215,27 +215,6 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
case WM_NCHITTEST:
return WmNcHitTest( hwnd, uMsg, wParam, lParam );
case WM_NCMOUSEMOVE:
// if mouse is moved over some non-client areas,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wParam == HTMINBUTTON || wParam == HTMAXBUTTON || wParam == HTCLOSE ||
wParam == HTCAPTION || wParam == HTSYSMENU )
sendMessageToClientArea( hwnd, WM_MOUSEMOVE, lParam );
break;
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
// if left mouse was pressed/released over minimize/maximize/close button,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wParam == HTMINBUTTON || wParam == HTMAXBUTTON || wParam == HTCLOSE ) {
int uClientMsg = (uMsg == WM_NCLBUTTONDOWN) ? WM_LBUTTONDOWN : WM_LBUTTONUP;
sendMessageToClientArea( hwnd, uClientMsg, lParam );
return 0;
}
break;
case WM_NCRBUTTONUP:
if( wParam == HTCAPTION || wParam == HTSYSMENU )
openSystemMenu( hwnd, GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) );
@@ -326,7 +305,7 @@ LRESULT FlatWndProc::WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lP
bool isMaximized = ::IsZoomed( hwnd );
if( isMaximized && !isFullscreen() ) {
// When a window is maximized, its size is actually a little bit larger
// When a window is maximized, its size is actually a little bit more
// than the monitor's work area. The window is positioned and sized in
// such a way that the resize handles are outside of the monitor and
// then the window is clipped to the monitor so that the resize handle
@@ -375,22 +354,6 @@ LRESULT FlatWndProc::WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPa
if( lResult != HTCLIENT )
return lResult;
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
int x = GET_X_LPARAM( xy );
int y = GET_Y_LPARAM( xy );
int resizeBorderHeight = getResizeHandleHeight();
bool isOnResizeBorder = (y < resizeBorderHeight) &&
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
return onNcHitTest( x, y, isOnResizeBorder );
}
/**
* Converts screen coordinates to window coordinates.
*/
LRESULT FlatWndProc::screen2windowCoordinates( HWND hwnd, LPARAM lParam ) {
// get window rectangle needed to convert mouse x/y from screen to window coordinates
RECT rcWindow;
::GetWindowRect( hwnd, &rcWindow );
@@ -399,7 +362,11 @@ LRESULT FlatWndProc::screen2windowCoordinates( HWND hwnd, LPARAM lParam ) {
int x = GET_X_LPARAM( lParam ) - rcWindow.left;
int y = GET_Y_LPARAM( lParam ) - rcWindow.top;
return MAKELONG( x, y );
int resizeBorderHeight = getResizeHandleHeight();
bool isOnResizeBorder = (y < resizeBorderHeight) &&
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
return onNcHitTest( x, y, isOnResizeBorder );
}
/**
@@ -462,14 +429,6 @@ JNIEnv* FlatWndProc::getEnv() {
return env;
}
void FlatWndProc::sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam ) {
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
// send message
::SendMessage( hwnd, uMsg, 0, xy );
}
/**
* Opens the window's system menu.
* The system menu is the menu that opens when the user presses Alt+Space or

View File

@@ -54,7 +54,6 @@ private:
LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT screen2windowCoordinates( HWND hwnd, LPARAM lParam );
int getResizeHandleHeight();
bool hasAutohideTaskbar( UINT edge, RECT rcMonitor );
BOOL isFullscreen();
@@ -62,7 +61,6 @@ private:
void fireStateChangedLaterOnce();
JNIEnv* getEnv();
void sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam );
void openSystemMenu( HWND hwnd, int x, int y );
void setMenuItemState( HMENU systemMenu, int item, bool enabled );

View File

@@ -13,14 +13,8 @@ extern "C" {
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTCAPTION 2L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU 3L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMINBUTTON
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMINBUTTON 8L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON 9L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP 12L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTCLOSE
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTCLOSE 20L
/*
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
* Method: installImpl

View File

@@ -1,46 +1,20 @@
- Java 1.8.0_202
+ Java 1.8.0_292
- OS Windows 10
+ OS Mac OS X
#---- ComboBox ----
+ ComboBox.showPopupOnNavigation true
#---- FileChooser ----
- FileChooser.useSystemExtensionHiding true
+ FileChooser.useSystemExtensionHiding false
#---- Menu ----
- Menu.shortcutKeys length=1 [I
[0] 8
+ Menu.shortcutKeys length=1 [I
[0] 10
#---- MenuItem ----
- MenuItem.acceleratorDelimiter -
+ MenuItem.acceleratorDelimiter
#---- OptionPane ----
+ OptionPane.isYesLast true
#---- ProgressBar ----
- ProgressBar.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
+ ProgressBar.font [active] Helvetica Neue plain 11 javax.swing.plaf.FontUIResource [UI]
#---- ScrollBar ----
+ ProgressBar.font [active] .SF NS Text plain 11 javax.swing.plaf.FontUIResource [UI]
- ScrollBar.hoverThumbWithTrack false
+ ScrollBar.hoverThumbWithTrack true
@@ -53,93 +27,7 @@
- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI]
+ defaultFont Helvetica Neue plain 13 javax.swing.plaf.FontUIResource [UI]
+ defaultFont .SF NS Text plain 13 javax.swing.plaf.FontUIResource [UI]
#---- h0 ----
- h0.font [active] Segoe UI plain 30 javax.swing.plaf.FontUIResource [UI]
+ h0.font [active] Helvetica Neue plain 31 javax.swing.plaf.FontUIResource [UI]
#---- h00 ----
- h00.font [active] Segoe UI plain 36 javax.swing.plaf.FontUIResource [UI]
+ h00.font [active] Helvetica Neue plain 37 javax.swing.plaf.FontUIResource [UI]
#---- h1 ----
- h1.font [active] Segoe UI Semibold plain 24 javax.swing.plaf.FontUIResource [UI]
+ h1.font [active] HelveticaNeue-Medium plain 25 javax.swing.plaf.FontUIResource [UI]
- h1.regular.font [active] Segoe UI plain 24 javax.swing.plaf.FontUIResource [UI]
+ h1.regular.font [active] Helvetica Neue plain 25 javax.swing.plaf.FontUIResource [UI]
#---- h2 ----
- h2.font [active] Segoe UI Semibold plain 18 javax.swing.plaf.FontUIResource [UI]
+ h2.font [active] HelveticaNeue-Medium plain 19 javax.swing.plaf.FontUIResource [UI]
- h2.regular.font [active] Segoe UI plain 18 javax.swing.plaf.FontUIResource [UI]
+ h2.regular.font [active] Helvetica Neue plain 19 javax.swing.plaf.FontUIResource [UI]
#---- h3 ----
- h3.font [active] Segoe UI Semibold plain 15 javax.swing.plaf.FontUIResource [UI]
+ h3.font [active] HelveticaNeue-Medium plain 16 javax.swing.plaf.FontUIResource [UI]
- h3.regular.font [active] Segoe UI plain 15 javax.swing.plaf.FontUIResource [UI]
+ h3.regular.font [active] Helvetica Neue plain 16 javax.swing.plaf.FontUIResource [UI]
#---- h4 ----
- h4.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
+ h4.font [active] Helvetica Neue bold 13 javax.swing.plaf.FontUIResource [UI]
#---- large ----
- large.font [active] Segoe UI plain 14 javax.swing.plaf.FontUIResource [UI]
+ large.font [active] Helvetica Neue plain 15 javax.swing.plaf.FontUIResource [UI]
#---- light ----
- light.font [active] Segoe UI Light plain 12 javax.swing.plaf.FontUIResource [UI]
+ light.font [active] HelveticaNeue-Thin plain 13 javax.swing.plaf.FontUIResource [UI]
#---- medium ----
- medium.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
+ medium.font [active] Helvetica Neue plain 12 javax.swing.plaf.FontUIResource [UI]
#---- mini ----
- mini.font [active] Segoe UI plain 9 javax.swing.plaf.FontUIResource [UI]
+ mini.font [active] Helvetica Neue plain 10 javax.swing.plaf.FontUIResource [UI]
#---- monospaced ----
- monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
#---- semibold ----
- semibold.font [active] Segoe UI Semibold plain 12 javax.swing.plaf.FontUIResource [UI]
+ semibold.font [active] HelveticaNeue-Medium plain 13 javax.swing.plaf.FontUIResource [UI]
#---- small ----
- small.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
+ small.font [active] Helvetica Neue plain 11 javax.swing.plaf.FontUIResource [UI]

View File

@@ -671,7 +671,6 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -819,7 +818,6 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #4d5154 HSL 206 4 32 com.formdev.flatlaf.util.DerivedColor [UI] lighten(7% autoInverse)
RootPane.background #3c3f41 HSL 204 4 25 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -832,8 +830,6 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
RootPane.font [active] $defaultFont [UI]
RootPane.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #484c4e HSL 200 4 29 com.formdev.flatlaf.util.DerivedColor [UI] lighten(5% autoInverse)
@@ -1005,7 +1001,6 @@ TabbedPane.buttonArc 6
TabbedPane.buttonHoverBackground #303234 HSL 210 4 20 com.formdev.flatlaf.util.DerivedColor [UI] darken(5%)
TabbedPane.buttonInsets 2,1,2,1 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.buttonPressedBackground #282a2c HSL 210 5 16 com.formdev.flatlaf.util.DerivedColor [UI] darken(8%)
TabbedPane.cardTabSelectionHeight 2
TabbedPane.closeArc 4
TabbedPane.closeCrossFilledSize 7.5
TabbedPane.closeCrossLineWidth 1
@@ -1048,7 +1043,6 @@ TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [U
TabbedPane.tabRunOverlay 0
TabbedPane.tabSelectionHeight 3
TabbedPane.tabSeparatorsFullHeight false
TabbedPane.tabType underlined
TabbedPane.tabWidthMode preferred
TabbedPane.tabsOpaque true
TabbedPane.tabsOverlapBorder false
@@ -1219,11 +1213,9 @@ TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.unifiedBackground true
TitlePane.unifiedBackground false
TitlePane.useWindowDecorations true
@@ -1392,26 +1384,6 @@ Viewport.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.Colo
ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style] ----
[style].h00 font: $h00.font
[style].h0 font: $h0.font
[style].h1.regular font: $h1.regular.font
[style].h1 font: $h1.font
[style].h2.regular font: $h2.regular.font
[style].h2 font: $h2.font
[style].h3.regular font: $h3.regular.font
[style].h3 font: $h3.font
[style].h4 font: $h4.font
[style].large font: $large.font
[style].light font: $light.font
[style].medium font: $medium.font
[style].mini font: $mini.font
[style].monospaced font: $monospaced.font
[style].semibold font: $semibold.font
[style].small font: $small.font
#---- ----
activeCaption #434e60 HSL 217 18 32 javax.swing.plaf.ColorUIResource [UI]
@@ -1427,39 +1399,6 @@ defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResou
desktop #46494b HSL 204 3 28 javax.swing.plaf.ColorUIResource [UI]
#---- h0 ----
h0.font [active] Segoe UI plain 30 javax.swing.plaf.FontUIResource [UI]
#---- h00 ----
h00.font [active] Segoe UI plain 36 javax.swing.plaf.FontUIResource [UI]
#---- h1 ----
h1.font [active] Segoe UI Semibold plain 24 javax.swing.plaf.FontUIResource [UI]
h1.regular.font [active] Segoe UI plain 24 javax.swing.plaf.FontUIResource [UI]
#---- h2 ----
h2.font [active] Segoe UI Semibold plain 18 javax.swing.plaf.FontUIResource [UI]
h2.regular.font [active] Segoe UI plain 18 javax.swing.plaf.FontUIResource [UI]
#---- h3 ----
h3.font [active] Segoe UI Semibold plain 15 javax.swing.plaf.FontUIResource [UI]
h3.regular.font [active] Segoe UI plain 15 javax.swing.plaf.FontUIResource [UI]
#---- h4 ----
h4.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
#---- html ----
html.missingImage [lazy] 38,38 sun.swing.ImageIconUIResource [UI] (sun.awt.image.ToolkitImage)
@@ -1481,52 +1420,13 @@ laf.dark true
laf.scaleFactor [active] 1.0
#---- large ----
large.font [active] Segoe UI plain 14 javax.swing.plaf.FontUIResource [UI]
#---- light ----
light.font [active] Segoe UI Light plain 12 javax.swing.plaf.FontUIResource [UI]
#---- medium ----
medium.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
#---- ----
menu #3c3f41 HSL 204 4 25 javax.swing.plaf.ColorUIResource [UI]
menuText #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
#---- mini ----
mini.font [active] Segoe UI plain 9 javax.swing.plaf.FontUIResource [UI]
#---- monospaced ----
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
#---- ----
scrollbar #3e4244 HSL 200 5 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
#---- semibold ----
semibold.font [active] Segoe UI Semibold plain 12 javax.swing.plaf.FontUIResource [UI]
#---- small ----
small.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
#---- swingx/TaskPane ----
swingx/TaskPaneUI com.formdev.flatlaf.swingx.ui.FlatTaskPaneUI

View File

@@ -1,46 +1,20 @@
- Java 1.8.0_202
+ Java 1.8.0_292
- OS Windows 10
+ OS Mac OS X
#---- ComboBox ----
+ ComboBox.showPopupOnNavigation true
#---- FileChooser ----
- FileChooser.useSystemExtensionHiding true
+ FileChooser.useSystemExtensionHiding false
#---- Menu ----
- Menu.shortcutKeys length=1 [I
[0] 8
+ Menu.shortcutKeys length=1 [I
[0] 10
#---- MenuItem ----
- MenuItem.acceleratorDelimiter -
+ MenuItem.acceleratorDelimiter
#---- OptionPane ----
+ OptionPane.isYesLast true
#---- ProgressBar ----
- ProgressBar.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
+ ProgressBar.font [active] Helvetica Neue plain 11 javax.swing.plaf.FontUIResource [UI]
#---- ScrollBar ----
+ ProgressBar.font [active] .SF NS Text plain 11 javax.swing.plaf.FontUIResource [UI]
- ScrollBar.hoverThumbWithTrack false
+ ScrollBar.hoverThumbWithTrack true
@@ -53,93 +27,7 @@
- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI]
+ defaultFont Helvetica Neue plain 13 javax.swing.plaf.FontUIResource [UI]
+ defaultFont .SF NS Text plain 13 javax.swing.plaf.FontUIResource [UI]
#---- h0 ----
- h0.font [active] Segoe UI plain 30 javax.swing.plaf.FontUIResource [UI]
+ h0.font [active] Helvetica Neue plain 31 javax.swing.plaf.FontUIResource [UI]
#---- h00 ----
- h00.font [active] Segoe UI plain 36 javax.swing.plaf.FontUIResource [UI]
+ h00.font [active] Helvetica Neue plain 37 javax.swing.plaf.FontUIResource [UI]
#---- h1 ----
- h1.font [active] Segoe UI Semibold plain 24 javax.swing.plaf.FontUIResource [UI]
+ h1.font [active] HelveticaNeue-Medium plain 25 javax.swing.plaf.FontUIResource [UI]
- h1.regular.font [active] Segoe UI plain 24 javax.swing.plaf.FontUIResource [UI]
+ h1.regular.font [active] Helvetica Neue plain 25 javax.swing.plaf.FontUIResource [UI]
#---- h2 ----
- h2.font [active] Segoe UI Semibold plain 18 javax.swing.plaf.FontUIResource [UI]
+ h2.font [active] HelveticaNeue-Medium plain 19 javax.swing.plaf.FontUIResource [UI]
- h2.regular.font [active] Segoe UI plain 18 javax.swing.plaf.FontUIResource [UI]
+ h2.regular.font [active] Helvetica Neue plain 19 javax.swing.plaf.FontUIResource [UI]
#---- h3 ----
- h3.font [active] Segoe UI Semibold plain 15 javax.swing.plaf.FontUIResource [UI]
+ h3.font [active] HelveticaNeue-Medium plain 16 javax.swing.plaf.FontUIResource [UI]
- h3.regular.font [active] Segoe UI plain 15 javax.swing.plaf.FontUIResource [UI]
+ h3.regular.font [active] Helvetica Neue plain 16 javax.swing.plaf.FontUIResource [UI]
#---- h4 ----
- h4.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
+ h4.font [active] Helvetica Neue bold 13 javax.swing.plaf.FontUIResource [UI]
#---- large ----
- large.font [active] Segoe UI plain 14 javax.swing.plaf.FontUIResource [UI]
+ large.font [active] Helvetica Neue plain 15 javax.swing.plaf.FontUIResource [UI]
#---- light ----
- light.font [active] Segoe UI Light plain 12 javax.swing.plaf.FontUIResource [UI]
+ light.font [active] HelveticaNeue-Thin plain 13 javax.swing.plaf.FontUIResource [UI]
#---- medium ----
- medium.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
+ medium.font [active] Helvetica Neue plain 12 javax.swing.plaf.FontUIResource [UI]
#---- mini ----
- mini.font [active] Segoe UI plain 9 javax.swing.plaf.FontUIResource [UI]
+ mini.font [active] Helvetica Neue plain 10 javax.swing.plaf.FontUIResource [UI]
#---- monospaced ----
- monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
#---- semibold ----
- semibold.font [active] Segoe UI Semibold plain 12 javax.swing.plaf.FontUIResource [UI]
+ semibold.font [active] HelveticaNeue-Medium plain 13 javax.swing.plaf.FontUIResource [UI]
#---- small ----
- small.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
+ small.font [active] Helvetica Neue plain 11 javax.swing.plaf.FontUIResource [UI]

View File

@@ -676,7 +676,6 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -824,7 +823,6 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #737373 HSL 0 0 45 com.formdev.flatlaf.util.DerivedColor [UI] darken(50% autoInverse)
RootPane.background #f2f2f2 HSL 0 0 95 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -837,8 +835,6 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
RootPane.font [active] $defaultFont [UI]
RootPane.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #a6a6a6 HSL 0 0 65 com.formdev.flatlaf.util.DerivedColor [UI] darken(30% autoInverse)
@@ -1010,7 +1006,6 @@ TabbedPane.buttonArc 6
TabbedPane.buttonHoverBackground #e0e0e0 HSL 0 0 88 com.formdev.flatlaf.util.DerivedColor [UI] darken(7% autoInverse)
TabbedPane.buttonInsets 2,1,2,1 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.buttonPressedBackground #d9d9d9 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
TabbedPane.cardTabSelectionHeight 2
TabbedPane.closeArc 4
TabbedPane.closeCrossFilledSize 7.5
TabbedPane.closeCrossLineWidth 1
@@ -1053,7 +1048,6 @@ TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [U
TabbedPane.tabRunOverlay 0
TabbedPane.tabSelectionHeight 3
TabbedPane.tabSeparatorsFullHeight false
TabbedPane.tabType underlined
TabbedPane.tabWidthMode preferred
TabbedPane.tabsOpaque true
TabbedPane.tabsOverlapBorder false
@@ -1224,11 +1218,9 @@ TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.unifiedBackground true
TitlePane.unifiedBackground false
TitlePane.useWindowDecorations true
@@ -1397,26 +1389,6 @@ Viewport.foreground #000000 HSL 0 0 0 javax.swing.plaf.Colo
ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style] ----
[style].h00 font: $h00.font
[style].h0 font: $h0.font
[style].h1.regular font: $h1.regular.font
[style].h1 font: $h1.font
[style].h2.regular font: $h2.regular.font
[style].h2 font: $h2.font
[style].h3.regular font: $h3.regular.font
[style].h3 font: $h3.font
[style].h4 font: $h4.font
[style].large font: $large.font
[style].light font: $light.font
[style].medium font: $medium.font
[style].mini font: $mini.font
[style].monospaced font: $monospaced.font
[style].semibold font: $semibold.font
[style].small font: $small.font
#---- ----
activeCaption #99b4d1 HSL 211 38 71 javax.swing.plaf.ColorUIResource [UI]
@@ -1432,39 +1404,6 @@ defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResou
desktop #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
#---- h0 ----
h0.font [active] Segoe UI plain 30 javax.swing.plaf.FontUIResource [UI]
#---- h00 ----
h00.font [active] Segoe UI plain 36 javax.swing.plaf.FontUIResource [UI]
#---- h1 ----
h1.font [active] Segoe UI Semibold plain 24 javax.swing.plaf.FontUIResource [UI]
h1.regular.font [active] Segoe UI plain 24 javax.swing.plaf.FontUIResource [UI]
#---- h2 ----
h2.font [active] Segoe UI Semibold plain 18 javax.swing.plaf.FontUIResource [UI]
h2.regular.font [active] Segoe UI plain 18 javax.swing.plaf.FontUIResource [UI]
#---- h3 ----
h3.font [active] Segoe UI Semibold plain 15 javax.swing.plaf.FontUIResource [UI]
h3.regular.font [active] Segoe UI plain 15 javax.swing.plaf.FontUIResource [UI]
#---- h4 ----
h4.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
#---- html ----
html.missingImage [lazy] 38,38 sun.swing.ImageIconUIResource [UI] (sun.awt.image.ToolkitImage)
@@ -1486,52 +1425,13 @@ laf.dark false
laf.scaleFactor [active] 1.0
#---- large ----
large.font [active] Segoe UI plain 14 javax.swing.plaf.FontUIResource [UI]
#---- light ----
light.font [active] Segoe UI Light plain 12 javax.swing.plaf.FontUIResource [UI]
#---- medium ----
medium.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
#---- ----
menu #f2f2f2 HSL 0 0 95 javax.swing.plaf.ColorUIResource [UI]
menuText #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
#---- mini ----
mini.font [active] Segoe UI plain 9 javax.swing.plaf.FontUIResource [UI]
#---- monospaced ----
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
#---- ----
scrollbar #f5f5f5 HSL 0 0 96 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
#---- semibold ----
semibold.font [active] Segoe UI Semibold plain 12 javax.swing.plaf.FontUIResource [UI]
#---- small ----
small.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
#---- swingx/TaskPane ----
swingx/TaskPaneUI com.formdev.flatlaf.swingx.ui.FlatTaskPaneUI

View File

@@ -687,7 +687,6 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -834,7 +833,6 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.background #ccffcc HSL 120 100 90 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -847,8 +845,6 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
RootPane.font [active] $defaultFont [UI]
RootPane.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
@@ -1021,7 +1017,6 @@ TabbedPane.buttonArc 6
TabbedPane.buttonHoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.buttonInsets 2,1,2,1 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.buttonPressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.cardTabSelectionHeight 2
TabbedPane.closeArc 999
TabbedPane.closeCrossFilledSize 6.5
TabbedPane.closeCrossLineWidth 2
@@ -1067,7 +1062,6 @@ TabbedPane.tabRunOverlay 0
TabbedPane.tabSelectionHeight 3
TabbedPane.tabSeparatorColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.tabSeparatorsFullHeight false
TabbedPane.tabType underlined
TabbedPane.tabWidthMode preferred
TabbedPane.tabsOpaque true
TabbedPane.tabsOverlapBorder false
@@ -1239,11 +1233,9 @@ TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.unifiedBackground true
TitlePane.unifiedBackground false
TitlePane.useWindowDecorations true
@@ -1411,26 +1403,6 @@ Viewport.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style] ----
[style].h00 font: $h00.font
[style].h0 font: $h0.font
[style].h1.regular font: $h1.regular.font
[style].h1 font: $h1.font
[style].h2.regular font: $h2.regular.font
[style].h2 font: $h2.font
[style].h3.regular font: $h3.regular.font
[style].h3 font: $h3.font
[style].h4 font: $h4.font
[style].large font: $large.font
[style].light font: $light.font
[style].medium font: $medium.font
[style].mini font: $mini.font
[style].monospaced font: $monospaced.font
[style].semibold font: $semibold.font
[style].small font: $small.font
#---- ----
activeCaption #99b4d1 HSL 211 38 71 javax.swing.plaf.ColorUIResource [UI]
@@ -1446,39 +1418,6 @@ defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResou
desktop #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
#---- h0 ----
h0.font [active] Segoe UI plain 30 javax.swing.plaf.FontUIResource [UI]
#---- h00 ----
h00.font [active] Segoe UI plain 36 javax.swing.plaf.FontUIResource [UI]
#---- h1 ----
h1.font [active] Segoe UI Semibold plain 24 javax.swing.plaf.FontUIResource [UI]
h1.regular.font [active] Segoe UI plain 24 javax.swing.plaf.FontUIResource [UI]
#---- h2 ----
h2.font [active] Segoe UI Semibold plain 18 javax.swing.plaf.FontUIResource [UI]
h2.regular.font [active] Segoe UI plain 18 javax.swing.plaf.FontUIResource [UI]
#---- h3 ----
h3.font [active] Segoe UI Semibold plain 15 javax.swing.plaf.FontUIResource [UI]
h3.regular.font [active] Segoe UI plain 15 javax.swing.plaf.FontUIResource [UI]
#---- h4 ----
h4.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
#---- html ----
html.missingImage [lazy] 38,38 sun.swing.ImageIconUIResource [UI] (sun.awt.image.ToolkitImage)
@@ -1500,52 +1439,13 @@ laf.dark false
laf.scaleFactor [active] 1.0
#---- large ----
large.font [active] Segoe UI plain 14 javax.swing.plaf.FontUIResource [UI]
#---- light ----
light.font [active] Segoe UI Light plain 12 javax.swing.plaf.FontUIResource [UI]
#---- medium ----
medium.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
#---- ----
menu #ccffcc HSL 120 100 90 javax.swing.plaf.ColorUIResource [UI]
menuText #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
#---- mini ----
mini.font [active] Segoe UI plain 9 javax.swing.plaf.FontUIResource [UI]
#---- monospaced ----
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
#---- ----
scrollbar #88ff88 HSL 120 100 77 javax.swing.plaf.ColorUIResource [UI]
#---- semibold ----
semibold.font [active] Segoe UI Semibold plain 12 javax.swing.plaf.FontUIResource [UI]
#---- small ----
small.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI]
#---- swingx/TaskPane ----
swingx/TaskPaneUI com.formdev.flatlaf.swingx.ui.FlatTaskPaneUI

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/flatlaf-testing-modular-app"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="-Ddummy=dummy"/>
<listAttribute key="org.eclipse.jdt.launching.MODULEPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/&quot; path=&quot;4&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/flatlaf-testing-modular-app/build/libs/flatlaf-testing-modular-app-2.0-SNAPSHOT.jar&quot; path=&quot;4&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/flatlaf-core/build/libs/flatlaf-2.0-SNAPSHOT.jar&quot; path=&quot;4&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/flatlaf-extras/build/libs/flatlaf-extras-2.0-SNAPSHOT.jar&quot; path=&quot;4&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;C:/Users/charly/.gradle/caches/modules-2/files-2.1/com.formdev/svgSalamander/1.1.2.4/828c2ce815bf62031764f5219597948bd2587aa5/svgSalamander-1.1.2.4.jar&quot; path=&quot;4&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="flatlaf-testing-modular-app"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-m com.formdev.flatlaf.testing.modular.app/com.formdev.flatlaf.testing.modular.app.FlatModularAppTest"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="flatlaf-testing-modular-app"/>
</launchConfiguration>

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2021 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.
*/
plugins {
`java-library`
`flatlaf-module-info`
}
dependencies {
implementation( project( ":flatlaf-core" ) )
implementation( project( ":flatlaf-extras" ) )
}
flatlafModuleInfo {
dependsOn( ":flatlaf-core:jar" )
dependsOn( ":flatlaf-extras:jar" )
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing.modular.app;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.extras.FlatSVGUtils;
/**
* @author Karl Tauber
*/
public class FlatModularAppTest
{
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatLaf.registerCustomDefaultsSource(
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/themes/" ) );
FlatLightLaf.setup();
JButton button1 = new JButton( "Hello" );
JButton button2 = new JButton( "World" );
button1.setIcon( new FlatSVGIcon(
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/icons/copy.svg" ) ) );
JPanel panel = new JPanel();
panel.add( new JLabel( "Hello World" ) );
panel.add( button1 );
panel.add( button2 );
JFrame frame = new JFrame( "FlatModularAppTest" );
frame.setIconImages( FlatSVGUtils.createWindowIconImages(
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/icons/copy.svg" ) ) );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( panel );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
} );
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing.modular.app.plaf;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import com.formdev.flatlaf.ui.FlatButtonUI;
/**
* @author Karl Tauber
*/
public class MyButtonUI
extends FlatButtonUI
{
public static ComponentUI createUI( JComponent c ) {
return new MyButtonUI();
}
protected MyButtonUI() {
super( false );
System.out.println( "MyButtonUI" );
}
}

View File

@@ -1,27 +0,0 @@
/*
* Copyright 2021 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.
*/
/**
* @author Karl Tauber
*/
module com.formdev.flatlaf.testing.modular.app {
requires java.desktop;
requires com.formdev.flatlaf;
requires com.formdev.flatlaf.extras;
requires com.kitfox.svg;
exports com.formdev.flatlaf.testing.modular.app.plaf;
}

View File

@@ -1,7 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<path fill="#6E6E6E" d="M11,3 L4,3 L4,11 L2,11 L2,1 L11,1 L11,3 Z"/>
<path fill="#6E6E6E" d="M5,4 L14,4 L14,14 L5,14 L5,4 Z M7,6 L7,7 L12,7 L12,6 L7,6 Z M7,10 L7,11 L12,11 L12,10 L7,10 Z M7,8 L7,9 L12,9 L12,8 L7,8 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 510 B

View File

@@ -1,20 +0,0 @@
#
# Copyright 2020 FormDev Software GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
@background = #fff
@foreground = #f00
ButtonUI = com.formdev.flatlaf.testing.modular.app.plaf.MyButtonUI

View File

@@ -1,438 +0,0 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.AnimatedBorder;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatAnimatedBorderTest
extends FlatTestPanel
{
private static final Color CHART_FADE_1 = Color.blue;
private static final Color CHART_FADE_2 = Color.red;
private static final Color CHART_MATERIAL_1 = Color.green;
private static final Color CHART_MATERIAL_2 = Color.magenta;
private static final Color CHART_MATERIAL_3 = Color.pink;
private static final Color CHART_MATERIAL_4 = Color.cyan;
private static final Color CHART_MINIMAL = Color.orange;
private static final String CHART_COLOR_KEY = "chartColor";
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatAnimatedBorderTest" );
frame.showFrame( FlatAnimatedBorderTest::new );
} );
}
FlatAnimatedBorderTest() {
initComponents();
fade1TextField.setBorder( new AnimatedFocusFadeBorder() );
fade2TextField.setBorder( new AnimatedFocusFadeBorder() );
material1TextField.setBorder( new AnimatedMaterialBorder() );
material2TextField.setBorder( new AnimatedMaterialBorder() );
material3TextField.setBorder( new AnimatedMaterialLabeledBorder() );
material4TextField.setBorder( new AnimatedMaterialLabeledBorder() );
minimalTextField.setBorder( new AnimatedMinimalTestBorder() );
fade1TextField.putClientProperty( CHART_COLOR_KEY, CHART_FADE_1 );
fade2TextField.putClientProperty( CHART_COLOR_KEY, CHART_FADE_2 );
material1TextField.putClientProperty( CHART_COLOR_KEY, CHART_MATERIAL_1 );
material2TextField.putClientProperty( CHART_COLOR_KEY, CHART_MATERIAL_2 );
material3TextField.putClientProperty( CHART_COLOR_KEY, CHART_MATERIAL_3 );
material4TextField.putClientProperty( CHART_COLOR_KEY, CHART_MATERIAL_4 );
minimalTextField.putClientProperty( CHART_COLOR_KEY, CHART_MINIMAL );
fade1ChartColor.setForeground( CHART_FADE_1 );
fade2ChartColor.setForeground( CHART_FADE_2 );
material1ChartColor.setForeground( CHART_MATERIAL_1 );
material2ChartColor.setForeground( CHART_MATERIAL_2 );
material3ChartColor.setForeground( CHART_MATERIAL_3 );
material4ChartColor.setForeground( CHART_MATERIAL_4 );
minimalChartColor.setForeground( CHART_MINIMAL );
material3TextField.putClientProperty( AnimatedMaterialLabeledBorder.LABEL_TEXT_KEY, "Label" );
material4TextField.putClientProperty( AnimatedMaterialLabeledBorder.LABEL_TEXT_KEY, "Label" );
material4TextField.setText( "Text" );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label3 = new JLabel();
lineChartPanel = new LineChartPanel();
fade1TextField = new JTextField();
fade1ChartColor = new FlatAnimatorTest.JChartColor();
fade2TextField = new JTextField();
fade2ChartColor = new FlatAnimatorTest.JChartColor();
label2 = new JLabel();
material1TextField = new JTextField();
material1ChartColor = new FlatAnimatorTest.JChartColor();
material2TextField = new JTextField();
material2ChartColor = new FlatAnimatorTest.JChartColor();
material3TextField = new JTextField();
material3ChartColor = new FlatAnimatorTest.JChartColor();
material4TextField = new JTextField();
material4ChartColor = new FlatAnimatorTest.JChartColor();
label1 = new JLabel();
minimalTextField = new JTextField();
minimalChartColor = new FlatAnimatorTest.JChartColor();
durationLabel = new JLabel();
durationField = new JSpinner();
//======== this ========
setLayout(new MigLayout(
"insets dialog,hidemode 3",
// columns
"[fill]" +
"[fill]para" +
"[grow,fill]",
// rows
"[]" +
"[]" +
"[]para" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]para" +
"[]" +
"[]" +
"[grow]" +
"[]"));
//---- label3 ----
label3.setText("Fade:");
add(label3, "cell 0 0");
add(lineChartPanel, "cell 2 0 1 12,growy");
add(fade1TextField, "cell 0 1");
add(fade1ChartColor, "cell 1 1");
add(fade2TextField, "cell 0 2");
add(fade2ChartColor, "cell 1 2");
//---- label2 ----
label2.setText("Material:");
add(label2, "cell 0 3");
add(material1TextField, "cell 0 4");
add(material1ChartColor, "cell 1 4");
add(material2TextField, "cell 0 5");
add(material2ChartColor, "cell 1 5");
//---- material3TextField ----
material3TextField.putClientProperty(FlatClientProperties.STYLE_CLASS, "large");
add(material3TextField, "cell 0 6");
add(material3ChartColor, "cell 1 6");
//---- material4TextField ----
material4TextField.putClientProperty(FlatClientProperties.STYLE_CLASS, "large");
add(material4TextField, "cell 0 7");
add(material4ChartColor, "cell 1 7");
//---- label1 ----
label1.setText("Minimal:");
add(label1, "cell 0 8");
add(minimalTextField, "cell 0 9");
add(minimalChartColor, "cell 1 9");
//---- durationLabel ----
durationLabel.setText("Duration:");
add(durationLabel, "cell 0 11");
//---- durationField ----
durationField.setModel(new SpinnerNumberModel(200, 0, null, 50));
add(durationField, "cell 0 11");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel label3;
private LineChartPanel lineChartPanel;
private JTextField fade1TextField;
private FlatAnimatorTest.JChartColor fade1ChartColor;
private JTextField fade2TextField;
private FlatAnimatorTest.JChartColor fade2ChartColor;
private JLabel label2;
private JTextField material1TextField;
private FlatAnimatorTest.JChartColor material1ChartColor;
private JTextField material2TextField;
private FlatAnimatorTest.JChartColor material2ChartColor;
private JTextField material3TextField;
private FlatAnimatorTest.JChartColor material3ChartColor;
private JTextField material4TextField;
private FlatAnimatorTest.JChartColor material4ChartColor;
private JLabel label1;
private JTextField minimalTextField;
private FlatAnimatorTest.JChartColor minimalChartColor;
private JLabel durationLabel;
private JSpinner durationField;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class AnimatedMaterialBorder ---------------------------------------
/**
* Experimental text field border that:
* - animates focus indicator color and border width
*/
private class AnimatedFocusFadeBorder
extends AbstractBorder
implements AnimatedBorder
{
// needed because otherwise the empty paint method in superclass
// javax.swing.border.AbstractBorder would be used
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
paintWithAnimation( c, g, x, y, width, height );
}
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
float animatedValue = animatedValues[0];
FlatUIUtils.setRenderingHints( g );
// border width is 1 if not focused and 2 if focused
float lw = UIScale.scale( 1 + animatedValue );
// paint border
Color color = ColorFunctions.mix( Color.red, Color.lightGray, animatedValue );
FlatUIUtils.paintOutlinedComponent( g, x, y, width, height, 0, 0, 0, lw, 0,
null, color, null );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "fade" );
}
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
insets.top = insets.bottom = UIScale.scale( 3 );
insets.left = insets.right = UIScale.scale( 7 );
return insets;
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
@Override
public int getAnimationDuration() {
return (Integer) durationField.getValue();
}
}
//---- class AnimatedMaterialBorder ---------------------------------------
/**
* Experimental text field border that:
* - paint border only at bottom
* - animates focus indicator at bottom
*/
private class AnimatedMaterialBorder
extends AbstractBorder
implements AnimatedBorder
{
// needed because otherwise the empty paint method in superclass
// javax.swing.border.AbstractBorder would be used
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
paintWithAnimation( c, g, x, y, width, height );
}
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
float animatedValue = animatedValues[0];
FlatUIUtils.setRenderingHints( g );
// use paintAtScale1x() for consistent line thickness when scaled
HiDPIUtils.paintAtScale1x( g, x, y, width, height,
(g2d, x2, y2, width2, height2, scaleFactor) -> {
float lh = (float) (UIScale.scale( 1f ) * scaleFactor);
g2d.setColor( Color.gray );
g2d.fill( new Rectangle2D.Float( x2, y2 + height2 - lh, width2, lh ) );
if( animatedValue > 0 ) {
lh = (float) (UIScale.scale( 2f ) * scaleFactor);
int lw = Math.round( width2 * animatedValue );
g2d.setColor( Color.red );
g2d.fill( new Rectangle2D.Float( x2 + (width2 - lw) / 2, y2 + height2 - lh, lw, lh ) );
}
} );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "material" );
}
}
@Override
public void repaintDuringAnimation( Component c, int x, int y, int width, int height ) {
// limit repaint to bottom border
int lh = UIScale.scale( 2 );
c.repaint( x, y + height - lh, width, lh );
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
insets.top = insets.bottom = UIScale.scale( 3 );
insets.left = insets.right = UIScale.scale( 7 );
return insets;
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
@Override
public int getAnimationDuration() {
return (Integer) durationField.getValue();
}
}
//---- class AnimatedMaterialLabeledBorder --------------------------------
/**
* Experimental text field border that:
* - paints a label above the text, or in center if text field is empty
* - paint border only at bottom
* - animates focus indicator at bottom
*/
private class AnimatedMaterialLabeledBorder
extends AnimatedMaterialBorder
{
static final String LABEL_TEXT_KEY = "JTextField.labelText";
private static final float LABEL_FONT_SCALE = 0.75f;
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
super.paintAnimated( c, g, x, y, width, height, animatedValues );
float animatedValue = animatedValues[0];
JComponent jc = (JComponent) c;
String label = (String) jc.getClientProperty( LABEL_TEXT_KEY );
if( label == null )
return;
FontMetrics fm = c.getFontMetrics( c.getFont() );
int labelFontHeight = Math.round( fm.getHeight() * LABEL_FONT_SCALE );
int tx = UIScale.scale( 7 );
int ty = y + labelFontHeight - UIScale.scale( 2 );
float sf = LABEL_FONT_SCALE;
if( ((JTextField)c).getDocument().getLength() == 0 ) {
// paint label in center of text field if it is empty
int ty2 = ((height - fm.getHeight()) / 2) + labelFontHeight;
ty += (ty2 - ty) * (1 - animatedValue);
sf += (1 - LABEL_FONT_SCALE) * (1 - animatedValue);
}
Graphics2D g2 = (Graphics2D) g.create();
try {
g2.translate( tx, ty );
g2.scale( sf, sf );
g2.setColor( ColorFunctions.mix( Color.red, Color.gray, animatedValue ) );
FlatUIUtils.drawString( jc, g2, label, 0, 0 );
} finally {
g2.dispose();
}
}
@Override
public void repaintDuringAnimation( Component c, int x, int y, int width, int height ) {
c.repaint( x, y, width, height );
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
super.getBorderInsets( c, insets );
FontMetrics fm = c.getFontMetrics( c.getFont() );
int labelFontHeight = Math.round( fm.getHeight() * LABEL_FONT_SCALE );
insets.top = labelFontHeight;
insets.bottom = UIScale.scale( 5 );
return insets;
}
}
//---- class AnimatedMinimalTestBorder ------------------------------------
/**
* Minimal example for an animated border.
*/
private class AnimatedMinimalTestBorder
implements AnimatedBorder
{
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
float animatedValue = animatedValues[0];
int lh = UIScale.scale( 2 );
g.setColor( Color.blue );
g.fillRect( x, y + height - lh, Math.round( width * animatedValue ), lh );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "minimal" );
}
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { FlatUIUtils.isPermanentFocusOwner( c ) ? 1 : 0 };
}
@Override
public int getAnimationDuration() {
return (Integer) durationField.getValue();
}
@Override
public Insets getBorderInsets( Component c ) {
return UIScale.scale( new Insets( 3, 7, 3, 7 ) );
}
@Override
public boolean isBorderOpaque() {
return false;
}
}
}

View File

@@ -1,128 +0,0 @@
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill]para[grow,fill]"
"$rowConstraints": "[][][]para[][][][][]para[][][grow][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "Fade:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.LineChartPanel" ) {
name: "lineChartPanel"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0 1 12,growy"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "fade1TextField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "fade1ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "fade2TextField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "fade2ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
"text": "Material:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "material1TextField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "material1ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "material2TextField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "material2ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "material3TextField"
"$client.FlatLaf.styleClass": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "material3ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "material4TextField"
"$client.FlatLaf.styleClass": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "material4ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Minimal:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "minimalTextField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "minimalChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "durationLabel"
"text": "Duration:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 11"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "durationField"
"model": new javax.swing.SpinnerNumberModel {
minimum: 0
stepSize: 50
value: 200
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 11"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 725, 465 )
} )
}
}

View File

@@ -18,14 +18,13 @@ package com.formdev.flatlaf.testing;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import javax.swing.*;
import com.formdev.flatlaf.icons.FlatAnimatedIcon;
import com.formdev.flatlaf.util.AnimatedIcon;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
/**
@@ -34,15 +33,6 @@ import net.miginfocom.swing.*;
public class FlatAnimatedIconTest
extends FlatTestPanel
{
private static final Color CHART_RADIO_BUTTON_1 = Color.blue;
private static final Color CHART_RADIO_BUTTON_2 = Color.red;
private static final Color CHART_RADIO_BUTTON_3 = Color.green;
private static final Color CHART_CHECK_BOX_1 = Color.magenta;
private static final Color CHART_CHECK_BOX_2 = Color.orange;
private static final Color[] CHART_SWITCH_EX = { Color.red, Color.green, Color.blue };
private static final String CHART_COLOR_KEY = "chartColor";
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatAnimatedIconTest" );
@@ -59,36 +49,16 @@ public class FlatAnimatedIconTest
radioButton3.setIcon( radioIcon );
checkBox1.setIcon( new AnimatedSwitchIcon() );
checkBox3.setIcon( new AnimatedSwitchIconEx() );
checkBox2.setIcon( new AnimatedMinimalTestIcon() );
radioButton1.putClientProperty( CHART_COLOR_KEY, CHART_RADIO_BUTTON_1 );
radioButton2.putClientProperty( CHART_COLOR_KEY, CHART_RADIO_BUTTON_2 );
radioButton3.putClientProperty( CHART_COLOR_KEY, CHART_RADIO_BUTTON_3 );
checkBox1.putClientProperty( CHART_COLOR_KEY, CHART_CHECK_BOX_1 );
checkBox2.putClientProperty( CHART_COLOR_KEY, CHART_CHECK_BOX_2 );
radioButton1ChartColor.setForeground( CHART_RADIO_BUTTON_1 );
radioButton2ChartColor.setForeground( CHART_RADIO_BUTTON_2 );
radioButton3ChartColor.setForeground( CHART_RADIO_BUTTON_3 );
checkBox1ChartColor.setForeground( CHART_CHECK_BOX_1 );
checkBox2ChartColor.setForeground( CHART_CHECK_BOX_2 );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
radioButton1 = new JRadioButton();
radioButton1ChartColor = new FlatAnimatorTest.JChartColor();
lineChartPanel = new LineChartPanel();
radioButton2 = new JRadioButton();
radioButton2ChartColor = new FlatAnimatorTest.JChartColor();
radioButton3 = new JRadioButton();
radioButton3ChartColor = new FlatAnimatorTest.JChartColor();
checkBox1 = new JCheckBox();
checkBox1ChartColor = new FlatAnimatorTest.JChartColor();
checkBox3 = new JCheckBox();
checkBox2 = new JCheckBox();
checkBox2ChartColor = new FlatAnimatorTest.JChartColor();
durationLabel = new JLabel();
durationField = new JSpinner();
@@ -96,16 +66,14 @@ public class FlatAnimatedIconTest
setLayout(new MigLayout(
"insets dialog,hidemode 3",
// columns
"[]" +
"[fill]para" +
"[grow,fill]",
"[]para" +
"[fill]",
// rows
"[]" +
"[]" +
"[]para" +
"[]" +
"[]" +
"[]" +
"[grow]" +
"[]"));
@@ -113,40 +81,30 @@ public class FlatAnimatedIconTest
radioButton1.setText("radio 1");
radioButton1.setSelected(true);
add(radioButton1, "cell 0 0");
add(radioButton1ChartColor, "cell 1 0");
add(lineChartPanel, "cell 2 0 1 8,growy");
//---- radioButton2 ----
radioButton2.setText("radio 2");
add(radioButton2, "cell 0 1");
add(radioButton2ChartColor, "cell 1 1");
//---- radioButton3 ----
radioButton3.setText("radio 3");
add(radioButton3, "cell 0 2");
add(radioButton3ChartColor, "cell 1 2");
//---- checkBox1 ----
checkBox1.setText("switch");
add(checkBox1, "cell 0 3");
add(checkBox1ChartColor, "cell 1 3");
//---- checkBox3 ----
checkBox3.setText("switch ex");
add(checkBox3, "cell 0 4");
//---- checkBox2 ----
checkBox2.setText("minimal");
add(checkBox2, "cell 0 5");
add(checkBox2ChartColor, "cell 1 5");
add(checkBox2, "cell 0 4");
//---- durationLabel ----
durationLabel.setText("Duration:");
add(durationLabel, "cell 0 7 2 1");
add(durationLabel, "cell 0 6 2 1");
//---- durationField ----
durationField.setModel(new SpinnerNumberModel(200, 0, null, 50));
add(durationField, "cell 0 7 2 1");
durationField.setModel(new SpinnerNumberModel(200, 100, null, 50));
add(durationField, "cell 0 6 2 1");
//---- buttonGroup1 ----
ButtonGroup buttonGroup1 = new ButtonGroup();
@@ -158,17 +116,10 @@ public class FlatAnimatedIconTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JRadioButton radioButton1;
private FlatAnimatorTest.JChartColor radioButton1ChartColor;
private LineChartPanel lineChartPanel;
private JRadioButton radioButton2;
private FlatAnimatorTest.JChartColor radioButton2ChartColor;
private JRadioButton radioButton3;
private FlatAnimatorTest.JChartColor radioButton3ChartColor;
private JCheckBox checkBox1;
private FlatAnimatorTest.JChartColor checkBox1ChartColor;
private JCheckBox checkBox3;
private JCheckBox checkBox2;
private FlatAnimatorTest.JChartColor checkBox2ChartColor;
private JLabel durationLabel;
private JSpinner durationField;
// JFormDesigner - End of variables declaration //GEN-END:variables
@@ -195,8 +146,7 @@ public class FlatAnimatedIconTest
}
@Override
public void paintIconAnimated( Component c, Graphics2D g, float[] animatedValues ) {
float animatedValue = animatedValues[0];
public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
Color color = ColorFunctions.mix( onColor, offColor, animatedValue );
// border
@@ -212,17 +162,12 @@ public class FlatAnimatedIconTest
float dotDiameter = DOT_SIZE * animatedValue;
float xy = (SIZE - dotDiameter) / 2f;
g.setColor( color );
g.fill( new Ellipse2D.Float( xy, xy, dotDiameter, dotDiameter ) );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "radio" );
}
((Graphics2D)g).fill( new Ellipse2D.Float( xy, xy, dotDiameter, dotDiameter ) );
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { ((JRadioButton)c).isSelected() ? 1 : 0 };
public float getValue( Component c ) {
return ((JRadioButton)c).isSelected() ? 1 : 0;
}
@Override
@@ -233,7 +178,7 @@ public class FlatAnimatedIconTest
//---- class AnimatedSwitchIcon -------------------------------------------
private class AnimatedSwitchIcon
public class AnimatedSwitchIcon
extends FlatAnimatedIcon
{
private final Color offColor = Color.lightGray;
@@ -244,113 +189,22 @@ public class FlatAnimatedIconTest
}
@Override
public void paintIconAnimated( Component c, Graphics2D g, float[] animatedValues ) {
float animatedValue = animatedValues[0];
public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
Color color = ColorFunctions.mix( onColor, offColor, animatedValue );
// paint track
g.setColor( color );
g.fillRoundRect( 0, 0, width, height, height, height );
// paint thumb
int thumbSize = height - 4;
float thumbX = 2 + ((width - 4 - thumbSize) * animatedValue);
int thumbY = 2;
g.setColor( Color.white );
g.fill( new Ellipse2D.Float( thumbX, thumbY, thumbSize, thumbSize ) );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "switch" );
}
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
}
@Override
public int getAnimationDuration() {
return (Integer) durationField.getValue();
}
}
//---- class AnimatedSwitchIconEx -----------------------------------------
private static final int HW = 8;
private class AnimatedSwitchIconEx
extends FlatAnimatedIcon
{
private final Color offColor = Color.lightGray;
private final Color onColor = Color.red;
private final Color hoverColor = new Color( 0x4400cc00, true );
private final Color pressedColor = new Color( 0x440000cc, true );
public AnimatedSwitchIconEx() {
super( 28 + HW, 16 + HW, null );
}
@Override
public void paintIconAnimated( Component c, Graphics2D g, float[] animatedValues ) {
Color color = ColorFunctions.mix( onColor, offColor, animatedValues[0] );
int hw2 = HW / 2;
int x = hw2;
int y = hw2;
int width = this.width - HW;
int height = this.height - HW;
// paint track
g.setColor( color );
g.fillRoundRect( x, y, width, height, height, height );
// paint thumb
int thumbSize = height - 4;
float thumbX = x + 2 + ((width - 4 - thumbSize) * animatedValues[0]);
float thumbX = x + 2 + ((width - 4 - thumbSize) * animatedValue);
int thumbY = y + 2;
g.setColor( Color.white );
g.fill( new Ellipse2D.Float( thumbX, thumbY, thumbSize, thumbSize ) );
// paint hover
if( animatedValues[1] > 0 ) {
g.setColor( hoverColor );
paintHoverOrPressed( g, thumbX, thumbY, thumbSize, animatedValues[1] );
}
// paint pressed
if( animatedValues[2] > 0 ) {
g.setColor( pressedColor );
paintHoverOrPressed( g, thumbX, thumbY, thumbSize, animatedValues[2] );
}
for( int i = 0; i < animatedValues.length; i++ ) {
float animatedValue = animatedValues[i];
if( animatedValue != 0 && animatedValue != 1 )
lineChartPanel.addValue( CHART_SWITCH_EX[i], animatedValue, Integer.MIN_VALUE, "switch ex" );
}
}
private void paintHoverOrPressed( Graphics2D g, float thumbX, int thumbY, int thumbSize, float animatedValue ) {
float hw = (HW + 4) * animatedValue;
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Ellipse2D.Float( thumbX - (hw / 2), thumbY - (hw / 2),
thumbSize + hw, thumbSize + hw ), false );
path.append( new Ellipse2D.Float( thumbX, thumbY, thumbSize, thumbSize ), false );
g.fill( path );
((Graphics2D)g).fill( new Ellipse2D.Float( thumbX, thumbY, thumbSize, thumbSize ) );
}
@Override
public float[] getAnimatableValues( Component c ) {
AbstractButton b = (AbstractButton) c;
ButtonModel bm = b.getModel();
return new float[] {
b.isSelected() ? 1 : 0,
bm.isRollover() ? 1 : 0,
bm.isPressed() ? 1 : 0,
};
public float getValue( Component c ) {
return ((AbstractButton)c).isSelected() ? 1 : 0;
}
@Override
@@ -369,31 +223,27 @@ public class FlatAnimatedIconTest
{
@Override
public int getIconWidth() {
return UIScale.scale( 50 );
return 100;
}
@Override
public int getIconHeight() {
return UIScale.scale( 16 );
return 20;
}
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
float animatedValue = animatedValues[0];
public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
int w = getIconWidth();
int h = getIconHeight();
g.setColor( Color.red );
g.drawRect( x, y, width - 1, height - 1 );
g.fillRect( x, y, Math.round( width * animatedValue ), height );
if( animatedValue != 0 && animatedValue != 1 ) {
Color chartColor = (Color) ((JComponent)c).getClientProperty( CHART_COLOR_KEY );
lineChartPanel.addValue( chartColor, animatedValue, Integer.MIN_VALUE, "minimal" );
}
g.drawRect( x, y, w - 1, h - 1 );
g.fillRect( x, y, Math.round( w * animatedValue ), h );
}
@Override
public float[] getAnimatableValues( Component c ) {
return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
public float getValue( Component c ) {
return ((AbstractButton)c).isSelected() ? 1 : 0;
}
@Override

View File

@@ -1,12 +1,12 @@
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[][fill]para[grow,fill]"
"$rowConstraints": "[][][]para[][][][grow][]"
"$columnConstraints": "[]para[fill]"
"$rowConstraints": "[][][]para[][][grow][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JRadioButton" ) {
@@ -17,16 +17,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "radioButton1ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.LineChartPanel" ) {
name: "lineChartPanel"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0 1 8,growy"
} )
add( new FormComponent( "javax.swing.JRadioButton" ) {
name: "radioButton2"
"text": "radio 2"
@@ -34,11 +24,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "radioButton2ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JRadioButton" ) {
name: "radioButton3"
"text": "radio 3"
@@ -46,58 +31,37 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "radioButton3ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "checkBox1"
"text": "switch"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "checkBox1ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "checkBox3"
"text": "switch ex"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "checkBox2"
"text": "minimal"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "checkBox2ChartColor"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5"
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "durationLabel"
"text": "Duration:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7 2 1"
"value": "cell 0 6 2 1"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "durationField"
"model": new javax.swing.SpinnerNumberModel {
minimum: 0
minimum: 100
stepSize: 50
value: 200
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7 2 1"
"value": "cell 0 6 2 1"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 810, 350 )
"size": new java.awt.Dimension( 415, 350 )
} )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "buttonGroup1"

View File

@@ -20,8 +20,6 @@ import java.awt.*;
import javax.swing.*;
import com.formdev.flatlaf.util.Animator;
import com.formdev.flatlaf.util.CubicBezierEasing;
import com.formdev.flatlaf.util.UIScale;
import com.formdev.flatlaf.util.Animator.Interpolator;
import net.miginfocom.swing.*;
/**
@@ -30,13 +28,8 @@ import net.miginfocom.swing.*;
public class FlatAnimatorTest
extends FlatTestPanel
{
private static final Color CHART_LINEAR = Color.blue;
private static final Color CHART_EASE_IN_OUT = Color.magenta;
private static final Color CHART_STANDARD_EASING = Color.red;
private Animator linearAnimator;
private Animator easeInOutAnimator;
private Animator standardEasingAnimator;
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
@@ -47,132 +40,85 @@ public class FlatAnimatorTest
FlatAnimatorTest() {
initComponents();
linearChartColor.setForeground( CHART_LINEAR );
easeInOutChartColor.setForeground( CHART_EASE_IN_OUT );
standardEasingChartColor.setForeground( CHART_STANDARD_EASING );
}
private void start() {
linearAnimator = start( linearAnimator, null, linearScrollBar, CHART_LINEAR );
easeInOutAnimator = start( easeInOutAnimator, CubicBezierEasing.EASE_IN_OUT, easeInOutScrollBar, CHART_EASE_IN_OUT );
standardEasingAnimator = start( standardEasingAnimator, CubicBezierEasing.STANDARD_EASING, standardEasingScrollBar, CHART_STANDARD_EASING );
startLinear();
startEaseInOut();
}
private Animator start( Animator animator, Interpolator interpolator, JScrollBar scrollBar, Color chartColor ) {
if( animator != null ) {
animator.stop();
animator.start();
private void startLinear() {
if( linearAnimator != null ) {
linearAnimator.stop();
linearAnimator.start();
} else {
animator = new Animator( 1000, fraction -> {
scrollBar.setValue( Math.round( fraction * scrollBar.getMaximum() ) );
lineChartPanel.addValue( chartColor, fraction, Integer.MIN_VALUE, "animator" );
linearAnimator = new Animator( 1000, fraction -> {
linearScrollBar.setValue( Math.round( fraction * linearScrollBar.getMaximum() ) );
} );
animator.setInterpolator( interpolator );
animator.start();
linearAnimator.start();
}
}
private void startEaseInOut() {
if( easeInOutAnimator != null ) {
easeInOutAnimator.stop();
easeInOutAnimator.start();
} else {
easeInOutAnimator = new Animator( 1000, fraction -> {
easeInOutScrollBar.setValue( Math.round( fraction * easeInOutScrollBar.getMaximum() ) );
} );
easeInOutAnimator.setInterpolator( CubicBezierEasing.EASE_IN_OUT );
easeInOutAnimator.start();
}
return animator;
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
linearLabel = new JLabel();
linearChartColor = new FlatAnimatorTest.JChartColor();
JLabel label1 = new JLabel();
linearScrollBar = new JScrollBar();
easeInOutLabel = new JLabel();
easeInOutChartColor = new FlatAnimatorTest.JChartColor();
JLabel label2 = new JLabel();
easeInOutScrollBar = new JScrollBar();
standardEasingLabel = new JLabel();
standardEasingChartColor = new FlatAnimatorTest.JChartColor();
standardEasingScrollBar = new JScrollBar();
startButton = new JButton();
lineChartPanel = new LineChartPanel();
//======== this ========
setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
// columns
"[fill]" +
"[fill]" +
"[grow,fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]para" +
"[400,grow,fill]"));
"[]"));
//---- linearLabel ----
linearLabel.setText("Linear:");
add(linearLabel, "cell 0 0");
add(linearChartColor, "cell 1 0");
//---- label1 ----
label1.setText("Linear:");
add(label1, "cell 0 0");
//---- linearScrollBar ----
linearScrollBar.setOrientation(Adjustable.HORIZONTAL);
linearScrollBar.setBlockIncrement(1);
add(linearScrollBar, "cell 2 0");
add(linearScrollBar, "cell 1 0");
//---- easeInOutLabel ----
easeInOutLabel.setText("Ease in out:");
add(easeInOutLabel, "cell 0 1");
add(easeInOutChartColor, "cell 1 1");
//---- label2 ----
label2.setText("Ease in out:");
add(label2, "cell 0 1");
//---- easeInOutScrollBar ----
easeInOutScrollBar.setOrientation(Adjustable.HORIZONTAL);
easeInOutScrollBar.setBlockIncrement(1);
add(easeInOutScrollBar, "cell 2 1");
//---- standardEasingLabel ----
standardEasingLabel.setText("Standard easing:");
add(standardEasingLabel, "cell 0 2");
add(standardEasingChartColor, "cell 1 2");
//---- standardEasingScrollBar ----
standardEasingScrollBar.setOrientation(Adjustable.HORIZONTAL);
standardEasingScrollBar.setBlockIncrement(1);
add(standardEasingScrollBar, "cell 2 2");
add(easeInOutScrollBar, "cell 1 1");
//---- startButton ----
startButton.setText("Start");
startButton.addActionListener(e -> start());
add(startButton, "cell 0 3");
add(lineChartPanel, "cell 0 4 3 1");
add(startButton, "cell 0 2");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel linearLabel;
private FlatAnimatorTest.JChartColor linearChartColor;
private JScrollBar linearScrollBar;
private JLabel easeInOutLabel;
private FlatAnimatorTest.JChartColor easeInOutChartColor;
private JScrollBar easeInOutScrollBar;
private JLabel standardEasingLabel;
private FlatAnimatorTest.JChartColor standardEasingChartColor;
private JScrollBar standardEasingScrollBar;
private JButton startButton;
private LineChartPanel lineChartPanel;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class JChartColor --------------------------------------------------
static class JChartColor
extends JComponent
{
@Override
public Dimension getPreferredSize() {
return new Dimension( UIScale.scale( 24 ), UIScale.scale( 12 ) );
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
protected void paintComponent( Graphics g ) {
g.setColor( getForeground() );
g.fillRect( 0, 0, UIScale.scale( 24 ), UIScale.scale( 12 ) );
}
}
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "14.0.2" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -8,27 +8,16 @@ new FormModel {
}
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][grow,fill]"
"$rowConstraints": "[][][][]para[400,grow,fill]"
"$columnConstraints": "[fill][grow,fill]"
"$rowConstraints": "[][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "linearLabel"
name: "label1"
"text": "Linear:"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "linearChartColor"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JScrollBar" ) {
name: "linearScrollBar"
"orientation": 0
@@ -37,25 +26,14 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "easeInOutLabel"
name: "label2"
"text": "Ease in out:"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "easeInOutChartColor"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JScrollBar" ) {
name: "easeInOutScrollBar"
"orientation": 0
@@ -64,34 +42,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "standardEasingLabel"
"text": "Standard easing:"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$JChartColor" ) {
name: "standardEasingChartColor"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JScrollBar" ) {
name: "standardEasingScrollBar"
"orientation": 0
"blockIncrement": 1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2"
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "startButton"
@@ -101,19 +52,11 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "start", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.LineChartPanel" ) {
name: "lineChartPanel"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4 3 1"
"value": "cell 0 2"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 625, 625 )
"size": new java.awt.Dimension( 415, 350 )
} )
}
}

View File

@@ -198,17 +198,17 @@ public class FlatComponentStateTest
//---- label11 ----
label11.setText("JButton");
label11.putClientProperty("FlatLaf.styleClass", "h3");
label11.setFont(label11.getFont().deriveFont(label11.getFont().getSize() + 4f));
add(label11, "cell 1 0 2 1");
//---- label12 ----
label12.setText("JToggleButton");
label12.putClientProperty("FlatLaf.styleClass", "h3");
label12.setFont(label12.getFont().deriveFont(label12.getFont().getSize() + 4f));
add(label12, "cell 5 0 3 1");
//---- label32 ----
label32.setText("Help Button");
label32.putClientProperty("FlatLaf.styleClass", "h3");
label32.setFont(label32.getFont().deriveFont(label32.getFont().getSize() + 4f));
add(label32, "cell 9 0 2 1");
//---- label5 ----
@@ -513,12 +513,12 @@ public class FlatComponentStateTest
//---- label22 ----
label22.setText("JCheckBox");
label22.putClientProperty("FlatLaf.styleClass", "h3");
label22.setFont(label22.getFont().deriveFont(label22.getFont().getSize() + 4f));
add(label22, "cell 1 8 2 1");
//---- label27 ----
label27.setText("JRadioButton");
label27.putClientProperty("FlatLaf.styleClass", "h3");
label27.setFont(label27.getFont().deriveFont(label27.getFont().getSize() + 4f));
add(label27, "cell 5 8 2 1");
//---- label23 ----

View File

@@ -12,21 +12,21 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JButton"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont0 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label12"
"text": "JToggleButton"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 0 3 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label32"
"text": "Help Button"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 9 0 2 1"
} )
@@ -447,14 +447,14 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label22"
"text": "JCheckBox"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label27"
"text": "JRadioButton"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 8 2 1"
} )

View File

@@ -1621,7 +1621,6 @@ public class FlatComponentsTest
// customRenderer.setBorder( new LineBorder( Color.red ) );
// comboBox1.setRenderer( customRenderer );
// comboBox3.setRenderer( customRenderer );
// comboBox5.setRenderer( new DefaultListCellRenderer() );
// for testing issue #382
// spinner1.setModel( new SpinnerNumberModel( 0, null, 100, 1 ) );

View File

@@ -50,8 +50,6 @@ public class FlatContainerTest
public FlatContainerTest() {
initComponents();
tabTypeComboBox.init( TabType.class, true );
tabPlacementField.init( TabPlacement.class, true );
iconPlacementField.init( TabIconPlacement.class, true );
tabsPopupPolicyField.init( TabsPopupPolicy.class, true );
@@ -312,12 +310,6 @@ public class FlatContainerTest
tabbedPane.setTabWidthMode( value );
}
private void tabTypeChanged() {
TabType value = tabTypeComboBox.getSelectedValue();
for( FlatTabbedPane tabbedPane : allTabbedPanes )
tabbedPane.setTabType( value );
}
private void tabBackForegroundChanged() {
for( JTabbedPane tabbedPane : allTabbedPanes )
tabBackForegroundChanged( tabbedPane );
@@ -499,8 +491,6 @@ public class FlatContainerTest
tabAlignmentField = new FlatTestEnumComboBox<>();
JLabel tabWidthModeLabel = new JLabel();
tabWidthModeField = new FlatTestEnumComboBox<>();
JLabel tabTypeLabel = new JLabel();
tabTypeComboBox = new FlatTestEnumComboBox<>();
leadingComponentCheckBox = new JCheckBox();
customBorderCheckBox = new JCheckBox();
tabAreaInsetsCheckBox = new JCheckBox();
@@ -629,7 +619,6 @@ public class FlatContainerTest
"[]" +
"[]" +
"[]" +
"[]" +
"[]para" +
"[]" +
"[]para" +
@@ -750,83 +739,75 @@ public class FlatContainerTest
tabWidthModeField.addActionListener(e -> tabWidthModeChanged());
tabbedPaneControlPanel.add(tabWidthModeField, "cell 2 5");
//---- tabTypeLabel ----
tabTypeLabel.setText("Tab type:");
tabbedPaneControlPanel.add(tabTypeLabel, "cell 0 6");
//---- tabTypeComboBox ----
tabTypeComboBox.addActionListener(e -> tabTypeChanged());
tabbedPaneControlPanel.add(tabTypeComboBox, "cell 1 6");
//---- leadingComponentCheckBox ----
leadingComponentCheckBox.setText("Leading component");
leadingComponentCheckBox.addActionListener(e -> leadingComponentChanged());
tabbedPaneControlPanel.add(leadingComponentCheckBox, "cell 0 7");
tabbedPaneControlPanel.add(leadingComponentCheckBox, "cell 0 6");
//---- customBorderCheckBox ----
customBorderCheckBox.setText("Custom border");
customBorderCheckBox.addActionListener(e -> customBorderChanged());
tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 7");
tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 6");
//---- tabAreaInsetsCheckBox ----
tabAreaInsetsCheckBox.setText("Tab area insets (5,5,10,10)");
tabAreaInsetsCheckBox.addActionListener(e -> tabAreaInsetsChanged());
tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 7");
tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 6");
//---- trailingComponentCheckBox ----
trailingComponentCheckBox.setText("Trailing component");
trailingComponentCheckBox.addActionListener(e -> trailingComponentChanged());
tabbedPaneControlPanel.add(trailingComponentCheckBox, "cell 0 8");
tabbedPaneControlPanel.add(trailingComponentCheckBox, "cell 0 7");
//---- hasFullBorderCheckBox ----
hasFullBorderCheckBox.setText("Show content border");
hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 8,alignx left,growx 0");
tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 7,alignx left,growx 0");
//---- smallerTabHeightCheckBox ----
smallerTabHeightCheckBox.setText("Smaller tab height (26)");
smallerTabHeightCheckBox.addActionListener(e -> smallerTabHeightChanged());
tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 8");
tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 7");
//---- minimumTabWidthCheckBox ----
minimumTabWidthCheckBox.setText("Minimum tab width (100)");
minimumTabWidthCheckBox.addActionListener(e -> minimumTabWidthChanged());
tabbedPaneControlPanel.add(minimumTabWidthCheckBox, "cell 0 9");
tabbedPaneControlPanel.add(minimumTabWidthCheckBox, "cell 0 8");
//---- hideContentSeparatorCheckBox ----
hideContentSeparatorCheckBox.setText("Hide content separator");
hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 9");
tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 8");
//---- smallerInsetsCheckBox ----
smallerInsetsCheckBox.setText("Smaller tab insets (2,2,2,2)");
smallerInsetsCheckBox.addActionListener(e -> smallerInsetsChanged());
tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 9");
tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 8");
//---- maximumTabWidthCheckBox ----
maximumTabWidthCheckBox.setText("Maximum tab width (60)");
maximumTabWidthCheckBox.addActionListener(e -> maximumTabWidthChanged());
tabbedPaneControlPanel.add(maximumTabWidthCheckBox, "cell 0 10");
tabbedPaneControlPanel.add(maximumTabWidthCheckBox, "cell 0 9");
//---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 10");
tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 9");
//---- secondTabWiderCheckBox ----
secondTabWiderCheckBox.setText("Second Tab insets wider (4,20,4,20)");
secondTabWiderCheckBox.addActionListener(e -> secondTabWiderChanged());
tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 10");
tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 9");
//---- hideTabAreaWithOneTabCheckBox ----
hideTabAreaWithOneTabCheckBox.setText("Hide tab area with one tab");
hideTabAreaWithOneTabCheckBox.addActionListener(e -> hideTabAreaWithOneTabChanged());
tabbedPaneControlPanel.add(hideTabAreaWithOneTabCheckBox, "cell 1 11");
tabbedPaneControlPanel.add(hideTabAreaWithOneTabCheckBox, "cell 1 10");
//---- customWheelScrollingCheckBox ----
customWheelScrollingCheckBox.setText("Custom wheel scrolling");
customWheelScrollingCheckBox.addActionListener(e -> customWheelScrollingChanged());
tabbedPaneControlPanel.add(customWheelScrollingCheckBox, "cell 2 11");
tabbedPaneControlPanel.add(customWheelScrollingCheckBox, "cell 2 10");
}
panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1));
}
@@ -859,7 +840,6 @@ public class FlatContainerTest
private FlatTestEnumComboBox<TabAreaAlignment> tabAreaAlignmentField;
private FlatTestEnumComboBox<TabAlignment> tabAlignmentField;
private FlatTestEnumComboBox<TabWidthMode> tabWidthModeField;
private FlatTestEnumComboBox<TabType> tabTypeComboBox;
private JCheckBox leadingComponentCheckBox;
private JCheckBox customBorderCheckBox;
private JCheckBox tabAreaInsetsCheckBox;

View File

@@ -132,7 +132,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestFrame$NoRightToLeftPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[][fill][]"
"$rowConstraints": "[center][][][][][][]para[][]para[][][]"
"$rowConstraints": "[center][][][][][]para[][]para[][][]"
} ) {
name: "tabbedPaneControlPanel"
"opaque": false
@@ -372,22 +372,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabTypeLabel"
"text": "Tab type:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumComboBox" ) {
name: "tabTypeComboBox"
auxiliary() {
"JavaCodeGenerator.typeParameters": "TabType"
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabTypeChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingComponentCheckBox"
"text": "Leading component"
@@ -396,7 +380,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingComponentChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7"
"value": "cell 0 6"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "customBorderCheckBox"
@@ -406,7 +390,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customBorderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7"
"value": "cell 1 6"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "tabAreaInsetsCheckBox"
@@ -416,7 +400,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabAreaInsetsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 7"
"value": "cell 2 6"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingComponentCheckBox"
@@ -426,7 +410,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingComponentChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8"
"value": "cell 0 7"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hasFullBorderCheckBox"
@@ -436,7 +420,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8,alignx left,growx 0"
"value": "cell 1 7,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "smallerTabHeightCheckBox"
@@ -446,7 +430,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerTabHeightChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 8"
"value": "cell 2 7"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "minimumTabWidthCheckBox"
@@ -456,7 +440,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "minimumTabWidthChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9"
"value": "cell 0 8"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hideContentSeparatorCheckBox"
@@ -466,7 +450,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideContentSeparatorChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9"
"value": "cell 1 8"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "smallerInsetsCheckBox"
@@ -476,7 +460,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerInsetsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 9"
"value": "cell 2 8"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "maximumTabWidthCheckBox"
@@ -486,7 +470,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "maximumTabWidthChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10"
"value": "cell 0 9"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox"
@@ -496,7 +480,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10"
"value": "cell 1 9"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "secondTabWiderCheckBox"
@@ -506,7 +490,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "secondTabWiderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 10"
"value": "cell 2 9"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hideTabAreaWithOneTabCheckBox"
@@ -516,7 +500,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideTabAreaWithOneTabChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11"
"value": "cell 1 10"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "customWheelScrollingCheckBox"
@@ -526,7 +510,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customWheelScrollingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 11"
"value": "cell 2 10"
} )
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
"gridY": 11

View File

@@ -34,7 +34,7 @@ public class FlatCustomBordersTest
private static final Color RED = new Color( 0x60ff0000, true );
private static final Color GREEN = new Color( 0x6000ff00, true );
private static final Color MAGENTA = new Color( 0x60ff00ff, true );
private static final Color BLUE = new Color( 0x300000ff, true );
private static final Color ORANGE = new Color( 0x60ffc800, true );
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
@@ -127,7 +127,7 @@ public class FlatCustomBordersTest
@SuppressWarnings( "unchecked" )
private void applySpecialComboBoxRenderers() {
BasicComboBoxRenderer sharedRenderer = new BasicComboBoxRenderer();
sharedRenderer.setBorder( new LineBorder( BLUE, UIScale.scale( 2 ) ) );
sharedRenderer.setBorder( new LineBorder( ORANGE, UIScale.scale( 2 ) ) );
comboBox29.setRenderer( sharedRenderer );
comboBox30.setRenderer( sharedRenderer );
@@ -160,7 +160,7 @@ public class FlatCustomBordersTest
}
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( BLUE, UIScale.scale( 6 ) ) );
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
}
private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) {
@@ -180,7 +180,7 @@ public class FlatCustomBordersTest
}
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( BLUE, UIScale.scale( 6 ) ) );
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
}
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {

View File

@@ -1,242 +0,0 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.*;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatFontsTest
extends JPanel
{
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatFontsTest" );
frame.showFrame( FlatFontsTest::new );
} );
}
FlatFontsTest() {
initComponents();
Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
TreeMap<String, TreeMap<String, Font>> familiesMap = new TreeMap<>();
for( Font font : allFonts ) {
TreeMap<String, Font> familyFontsMap = familiesMap.computeIfAbsent( font.getFamily(), key -> new TreeMap<>() );
Font old = familyFontsMap.put( font.getName(), font );
if( old != null ) {
System.err.println( "Duplicate font name '" + font.getName() + "'" );
System.err.println( " " + old );
System.err.println( " " + font );
}
}
DefaultListModel<FontFamilyInfo> model = new DefaultListModel<>();
for( Map.Entry<String, TreeMap<String, Font>> e : familiesMap.entrySet() ) {
FontFamilyInfo info = new FontFamilyInfo();
info.name = e.getKey();
info.fonts = e.getValue();
model.addElement( info );
}
familiesList.setModel( model );
familiesList.setCellRenderer( new FontFamilyRenderer() );
familiesList.setSelectedIndex( 0 );
SwingUtilities.invokeLater( () -> {
SwingUtilities.invokeLater( () -> {
familiesList.requestFocusInWindow();
} );
} );
}
private void familyChanged() {
previewFamilyNameLabel.setText( "" );
previewPanel.removeAll();
FontFamilyInfo info = familiesList.getSelectedValue();
if( info == null )
return;
previewFamilyNameLabel.setText( info.name );
for( Map.Entry<String, Font> e : info.fonts.entrySet() ) {
JLabel label = new JLabel( e.getKey() );
label.setFont( e.getValue().deriveFont( (float) UIScale.scale( 36 ) ) );
previewPanel.add( label, "wrap" );
}
previewPanel.revalidate();
previewPanel.repaint();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JLabel familiesLabel = new JLabel();
previewFamilyNameLabel = new JLabel();
JScrollPane familiesScrollPane = new JScrollPane();
familiesList = new JList<>();
JSeparator separator1 = new JSeparator();
JScrollPane scrollPane1 = new JScrollPane();
previewPanel = new JPanel();
//======== this ========
setBorder(null);
setLayout(new MigLayout(
"insets dialog,hidemode 3",
// columns
"[230:230,fill]para" +
"[grow,fill]",
// rows
"[top]" +
"[]" +
"[]" +
"[800,grow,fill]"));
//---- familiesLabel ----
familiesLabel.setText("Families:");
add(familiesLabel, "cell 0 0");
//---- previewFamilyNameLabel ----
previewFamilyNameLabel.setText("name");
previewFamilyNameLabel.putClientProperty("FlatLaf.styleClass", "h1");
add(previewFamilyNameLabel, "cell 1 1");
//======== familiesScrollPane ========
{
//---- familiesList ----
familiesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
familiesList.addListSelectionListener(e -> familyChanged());
familiesScrollPane.setViewportView(familiesList);
}
add(familiesScrollPane, "cell 0 1 1 3,growy");
add(separator1, "cell 1 2");
//======== scrollPane1 ========
{
scrollPane1.setBorder(BorderFactory.createEmptyBorder());
//======== previewPanel ========
{
previewPanel.setLayout(new MigLayout(
"insets dialog,hidemode 3",
// columns
"[fill]",
// rows
"[]"));
}
scrollPane1.setViewportView(previewPanel);
}
add(scrollPane1, "cell 1 3");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel previewFamilyNameLabel;
private JList<FontFamilyInfo> familiesList;
private JPanel previewPanel;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class FontFamilyInfo -----------------------------------------------
private static class FontFamilyInfo
{
String name;
TreeMap<String, Font> fonts;
}
//---- class FontFamilyRenderer -------------------------------------------
private static class FontFamilyRenderer
extends JPanel
implements ListCellRenderer<FontFamilyInfo>
{
private FontFamilyRenderer() {
initComponents();
}
@Override
public Component getListCellRendererComponent( JList<? extends FontFamilyInfo> list,
FontFamilyInfo value, int index, boolean isSelected, boolean cellHasFocus )
{
String family = value.name;
StringBuilder buf = new StringBuilder();
for( String key : value.fonts.keySet() ) {
if( key.startsWith( family ) ) {
key = key.substring( family.length() ).trim();
if( key.isEmpty() )
key = "Regular";
}
if( buf.length() > 0 )
buf.append( ", " );
buf.append( key );
}
familyNameLabel.setText( family );
familyDescriptionLabel.setText( buf.toString() );
familyNameLabel.setFont( UIManager.getFont( "large.font" ) );
familyDescriptionLabel.setFont( UIManager.getFont( "small.font" ) );
familyDescriptionLabel.setEnabled( isSelected );
setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() );
Color fg = isSelected ? list.getSelectionForeground() : list.getForeground();
familyNameLabel.setForeground( fg );
familyDescriptionLabel.setForeground( fg );
return this;
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
familyNameLabel = new JLabel();
familyDescriptionLabel = new JLabel();
//======== this ========
setLayout(new MigLayout(
"insets 2 6 2 6,hidemode 3",
// columns
"[fill]",
// rows
"[]0" +
"[]"));
//---- familyNameLabel ----
familyNameLabel.setText("text");
add(familyNameLabel, "cell 0 0");
//---- familyDescriptionLabel ----
familyDescriptionLabel.setText("text");
add(familyDescriptionLabel, "cell 0 1");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel familyNameLabel;
private JLabel familyDescriptionLabel;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
}

View File

@@ -1,103 +0,0 @@
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
auxiliary() {
"JavaCodeGenerator.defaultVariableLocal": true
}
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[230:230,fill]para[grow,fill]"
"$rowConstraints": "[top][][][800,grow,fill]"
} ) {
name: "this"
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE
add( new FormComponent( "javax.swing.JLabel" ) {
name: "familiesLabel"
"text": "Families:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "previewFamilyNameLabel"
"text": "name"
"$client.FlatLaf.styleClass": "h1"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "familiesScrollPane"
add( new FormComponent( "javax.swing.JList" ) {
name: "familiesList"
"selectionMode": 0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
"JavaCodeGenerator.typeParameters": "FontFamilyInfo"
}
addEvent( new FormEvent( "javax.swing.event.ListSelectionListener", "valueChanged", "familyChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1 1 3,growy"
} )
add( new FormComponent( "javax.swing.JSeparator" ) {
name: "separator1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane1"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[fill]"
"$rowConstraints": "[]"
} ) {
name: "previewPanel"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 450, 300 )
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 2 6 2 6,hidemode 3"
"$columnConstraints": "[fill]"
"$rowConstraints": "[]0[]"
} ) {
name: "panel1"
auxiliary() {
"JavaCodeGenerator.className": "FontFamilyRenderer"
}
add( new FormComponent( "javax.swing.JLabel" ) {
name: "familyNameLabel"
"text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "familyDescriptionLabel"
"text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 330 )
"size": new java.awt.Dimension( 255, 105 )
} )
}
}

View File

@@ -33,7 +33,6 @@ public class FlatOptionPaneTest
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatOptionPaneTest" );
frame.setIconImage( new ImageIcon( FlatOptionPaneTest.class.getResource( "/com/formdev/flatlaf/testing/test16.png" ) ).getImage() );
frame.showFrame( FlatOptionPaneTest::new );
} );
}
@@ -55,10 +54,6 @@ public class FlatOptionPaneTest
} );
}
private void showTitleBarIcon() {
UIManager.put( "OptionPane.showIcon", showTitleBarIconCheckBox.isSelected() );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
ScrollablePanel panel9 = new ScrollablePanel();
@@ -66,7 +61,6 @@ public class FlatOptionPaneTest
JPanel panel1 = new JPanel();
JOptionPane plainOptionPane = new JOptionPane();
plainShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
showTitleBarIconCheckBox = new JCheckBox();
JLabel errorLabel = new JLabel();
JPanel panel2 = new JPanel();
JOptionPane errorOptionPane = new JOptionPane();
@@ -106,7 +100,7 @@ public class FlatOptionPaneTest
//======== panel9 ========
{
panel9.setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
"flowy,ltr,insets dialog,hidemode 3",
// columns
"[]" +
"[]" +
@@ -140,12 +134,7 @@ public class FlatOptionPaneTest
//---- plainShowDialogLabel ----
plainShowDialogLabel.setOptionPane(plainOptionPane);
plainShowDialogLabel.setTitleLabel(plainLabel);
panel9.add(plainShowDialogLabel, "cell 1 0");
//---- showTitleBarIconCheckBox ----
showTitleBarIconCheckBox.setText("Show window title bar icon");
showTitleBarIconCheckBox.addActionListener(e -> showTitleBarIcon());
panel9.add(showTitleBarIconCheckBox, "cell 2 0");
panel9.add(plainShowDialogLabel, "cell 2 0");
//---- errorLabel ----
errorLabel.setText("Error");
@@ -167,7 +156,7 @@ public class FlatOptionPaneTest
//---- errorShowDialogLabel ----
errorShowDialogLabel.setTitleLabel(errorLabel);
errorShowDialogLabel.setOptionPane(errorOptionPane);
panel9.add(errorShowDialogLabel, "cell 1 1");
panel9.add(errorShowDialogLabel, "cell 2 1");
//---- informationLabel ----
informationLabel.setText("Information");
@@ -189,7 +178,7 @@ public class FlatOptionPaneTest
//---- informationShowDialogLabel ----
informationShowDialogLabel.setOptionPane(informationOptionPane);
informationShowDialogLabel.setTitleLabel(informationLabel);
panel9.add(informationShowDialogLabel, "cell 1 2");
panel9.add(informationShowDialogLabel, "cell 2 2");
//---- questionLabel ----
questionLabel.setText("Question");
@@ -233,7 +222,7 @@ public class FlatOptionPaneTest
//---- warningShowDialogLabel ----
warningShowDialogLabel.setOptionPane(warningOptionPane);
warningShowDialogLabel.setTitleLabel(warningLabel);
panel9.add(warningShowDialogLabel, "cell 1 4");
panel9.add(warningShowDialogLabel, "cell 2 4");
//---- inputLabel ----
inputLabel.setText("Input");
@@ -255,7 +244,7 @@ public class FlatOptionPaneTest
//---- inputShowDialogLabel ----
inputShowDialogLabel.setOptionPane(inputOptionPane);
inputShowDialogLabel.setTitleLabel(inputLabel);
panel9.add(inputShowDialogLabel, "cell 1 5");
panel9.add(inputShowDialogLabel, "cell 2 5");
//---- inputIconLabel ----
inputIconLabel.setText("Input + icon");
@@ -278,7 +267,7 @@ public class FlatOptionPaneTest
//---- inputIconShowDialogLabel ----
inputIconShowDialogLabel.setTitleLabel(inputIconLabel);
inputIconShowDialogLabel.setOptionPane(inputIconOptionPane);
panel9.add(inputIconShowDialogLabel, "cell 1 6");
panel9.add(inputIconShowDialogLabel, "cell 2 6");
//---- customLabel ----
customLabel.setText("Custom");
@@ -298,7 +287,7 @@ public class FlatOptionPaneTest
//---- customShowDialogLabel ----
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
panel9.add(customShowDialogLabel, "cell 1 7");
panel9.add(customShowDialogLabel, "cell 2 7");
//---- rightToLeftLabel ----
rightToLeftLabel.setText("Right-to-left:");
@@ -328,7 +317,6 @@ public class FlatOptionPaneTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private FlatOptionPaneTest.ShowDialogLinkLabel plainShowDialogLabel;
private JCheckBox showTitleBarIconCheckBox;
private FlatOptionPaneTest.ShowDialogLinkLabel errorShowDialogLabel;
private FlatOptionPaneTest.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
@@ -345,7 +333,6 @@ public class FlatOptionPaneTest
ShowDialogLinkLabel() {
setText( "<html><a href=\"#\">Show dialog</a></html>" );
setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
addMouseListener( new MouseAdapter() {
@Override

View File

@@ -10,7 +10,7 @@ new FormModel {
name: "this"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$layoutConstraints": "flowy,ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top][top]"
} ) {
@@ -40,16 +40,6 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTitleBarIconCheckBox"
"text": "Show window title bar icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
@@ -81,7 +71,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
"value": "cell 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "informationLabel"
@@ -111,7 +101,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
"value": "cell 2 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "questionLabel"
@@ -165,7 +155,7 @@ new FormModel {
"optionPane": new FormReference( "warningOptionPane" )
"titleLabel": new FormReference( "warningLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
"value": "cell 2 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputLabel"
@@ -192,7 +182,7 @@ new FormModel {
"optionPane": new FormReference( "inputOptionPane" )
"titleLabel": new FormReference( "inputLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5"
"value": "cell 2 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputIconLabel"
@@ -220,7 +210,7 @@ new FormModel {
"titleLabel": new FormReference( "inputIconLabel" )
"optionPane": new FormReference( "inputIconOptionPane" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6"
"value": "cell 2 6"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "customLabel"
@@ -248,7 +238,7 @@ new FormModel {
"optionPane": new FormReference( "customOptionPane" )
"titleLabel": new FormReference( "customLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7"
"value": "cell 2 7"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightToLeftLabel"
@@ -283,7 +273,7 @@ new FormModel {
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 995, 1080 )
"size": new java.awt.Dimension( 895, 1080 )
} )
}
}

View File

@@ -27,7 +27,6 @@ import java.util.List;
import java.util.Random;
import javax.swing.*;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import net.miginfocom.swing.*;
@@ -74,9 +73,6 @@ public class FlatWindowDecorationsTest
menuBarCheckBox.setSelected( window instanceof JFrame );
maximizedBoundsCheckBox.setEnabled( window instanceof Frame );
menuBarEmbeddedCheckBox.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
unifiedBackgroundCheckBox.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
addMenuButton.setEnabled( menuBarCheckBox.isEnabled() );
addGlueButton.setEnabled( menuBarCheckBox.isEnabled() );
removeMenuButton.setEnabled( menuBarCheckBox.isEnabled() );
@@ -95,35 +91,20 @@ public class FlatWindowDecorationsTest
JRootPane rootPane = getWindowRootPane();
if( rootPane != null ) {
updateDecorationStyleRadioButtons( rootPane );
rootPane.addPropertyChangeListener( "windowDecorationStyle", e -> {
updateDecorationStyleRadioButtons( rootPane );
} );
int style = rootPane.getWindowDecorationStyle();
if( style == JRootPane.NONE )
styleNoneRadioButton.setSelected( true );
else if( style == JRootPane.FRAME )
styleFrameRadioButton.setSelected( true );
else if( style == JRootPane.PLAIN_DIALOG )
stylePlainRadioButton.setSelected( true );
else if( style == JRootPane.INFORMATION_DIALOG )
styleInfoRadioButton.setSelected( true );
else
throw new RuntimeException(); // not used
}
}
private void updateDecorationStyleRadioButtons( JRootPane rootPane ) {
int style = rootPane.getWindowDecorationStyle();
if( style == JRootPane.NONE )
styleNoneRadioButton.setSelected( true );
else if( style == JRootPane.FRAME )
styleFrameRadioButton.setSelected( true );
else if( style == JRootPane.PLAIN_DIALOG )
stylePlainRadioButton.setSelected( true );
else if( style == JRootPane.INFORMATION_DIALOG )
styleInfoRadioButton.setSelected( true );
else if( style == JRootPane.ERROR_DIALOG )
styleErrorRadioButton.setSelected( true );
else if( style == JRootPane.QUESTION_DIALOG )
styleQuestionRadioButton.setSelected( true );
else if( style == JRootPane.WARNING_DIALOG )
styleWarningRadioButton.setSelected( true );
else if( style == JRootPane.COLOR_CHOOSER_DIALOG )
styleColorChooserRadioButton.setSelected( true );
else if( style == JRootPane.FILE_CHOOSER_DIALOG )
styleFileChooserRadioButton.setSelected( true );
}
private void unifiedBackgroundChanged() {
UIManager.put( "TitlePane.unifiedBackground", unifiedBackgroundCheckBox.isSelected() );
Window window = SwingUtilities.windowForComponent( this );
@@ -406,12 +387,6 @@ public class FlatWindowDecorationsTest
}
}
private void showIconChanged() {
JRootPane rootPane = getWindowRootPane();
if( rootPane != null )
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIconCheckBox.getChecked() );
}
private JRootPane getWindowRootPane() {
Window window = SwingUtilities.windowForComponent( this );
if( window instanceof JFrame )
@@ -460,7 +435,6 @@ public class FlatWindowDecorationsTest
iconTestRandomRadioButton = new JRadioButton();
iconTestMRIRadioButton = new JRadioButton();
iconTestDynMRIRadioButton = new JRadioButton();
showIconCheckBox = new FlatTriStateCheckBox();
JButton openDialogButton = new JButton();
JButton openFrameButton = new JButton();
menuBar = new JMenuBar();
@@ -696,13 +670,12 @@ public class FlatWindowDecorationsTest
panel2.setLayout(new MigLayout(
"ltr,insets 0,hidemode 3,gap 0 0",
// columns
"[left]",
"[fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
"[]rel" +
"[]"));
//---- iconNoneRadioButton ----
@@ -730,11 +703,6 @@ public class FlatWindowDecorationsTest
iconTestDynMRIRadioButton.setText("test dynamic multi-resolution (Java 9+)");
iconTestDynMRIRadioButton.addActionListener(e -> iconChanged());
panel2.add(iconTestDynMRIRadioButton, "cell 0 4");
//---- showIconCheckBox ----
showIconCheckBox.setText("show icon");
showIconCheckBox.addActionListener(e -> showIconChanged());
panel2.add(showIconCheckBox, "cell 0 5");
}
add(panel2, "cell 1 8");
@@ -972,7 +940,6 @@ public class FlatWindowDecorationsTest
private JRadioButton iconTestRandomRadioButton;
private JRadioButton iconTestMRIRadioButton;
private JRadioButton iconTestDynMRIRadioButton;
private FlatTriStateCheckBox showIconCheckBox;
private JMenuBar menuBar;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -327,8 +327,8 @@ new FormModel {
"value": "cell 0 8"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[left]"
"$rowConstraints": "[][][][][]rel[]"
"$columnConstraints": "[fill]"
"$rowConstraints": "[][][][][]"
"$layoutConstraints": "ltr,insets 0,hidemode 3,gap 0 0"
} ) {
name: "panel2"
@@ -388,16 +388,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
name: "showIconCheckBox"
"text": "show icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showIconChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8"
} )

View File

@@ -1,883 +0,0 @@
/*
/*
* Copyright 2023 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.HierarchyEvent;
import java.awt.event.MouseEvent;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.swing.*;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.HSLColor;
import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
class LineChartPanel
extends JPanel
{
LineChartPanel() {
initComponents();
lineChartScrollPane.putClientProperty( FlatClientProperties.SCROLL_PANE_SMOOTH_SCROLLING, false );
oneSecondWidthChanged();
updateChartDelayedChanged();
// clear chart on startup
addHierarchyListener( e -> {
if( (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && isShowing() )
EventQueue.invokeLater( this::clearChart );
} );
// show chart tooltips immediately and forever
ToolTipManager.sharedInstance().setInitialDelay( 0 );
ToolTipManager.sharedInstance().setDismissDelay( Integer.MAX_VALUE );
}
@Override
public void addNotify() {
super.addNotify();
// allow clearing chart with Alt+C without moving focus to button
getRootPane().registerKeyboardAction(
e -> clearChart(),
KeyStroke.getKeyStroke( "alt " + (char) clearChartButton.getMnemonic() ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
}
public boolean isYZeroAtTop() {
return lineChart.yZeroAtTop;
}
public void setYZeroAtTop( boolean yZeroAtTop ) {
lineChart.yZeroAtTop = yZeroAtTop;
lineChart.repaint();
}
public boolean isAsynchron() {
return lineChart.asynchron;
}
public void setAsynchron( boolean asynchron ) {
lineChart.asynchron = asynchron;
lineChart.repaint();
}
public boolean isTemporaryValueDetection() {
return lineChart.temporaryValueDetection;
}
public void setTemporaryValueDetection( boolean temporaryValueDetection ) {
lineChart.temporaryValueDetection = temporaryValueDetection;
lineChart.repaint();
}
public String getLegendYValueText() {
return yValueLabel.getText();
}
public void setLegendYValueText( String s ) {
yValueLabel.setText( s );
}
public String getLegend1Text() {
return legend1Label.getText();
}
public void setLegend1Text( String s ) {
legend1Label.setText( s );
}
public String getLegend2Text() {
return legend2Label.getText();
}
public void setLegend2Text( String s ) {
legend2Label.setText( s );
}
public int getOneSecondWidth() {
return oneSecondWidthSlider.getValue();
}
public void setOneSecondWidth( int oneSecondWidth ) {
oneSecondWidthSlider.setValue( oneSecondWidth );
}
public boolean isUpdateChartDelayed() {
return updateChartDelayedCheckBox.isSelected();
}
public void setUpdateChartDelayed( boolean updateChartDelayed ) {
updateChartDelayedCheckBox.setSelected( updateChartDelayed );
updateChartDelayedChanged();
}
void addValue( Color chartColor, double value, int ivalue, String name ) {
lineChart.addValue( chartColor, value, ivalue, null, false, name );
}
void addValueWithDot( Color chartColor, double value, int ivalue, Color dotColor, String name ) {
if( dotColor == null )
dotColor = chartColor;
lineChart.addValue( chartColor, value, ivalue, dotColor, false, name );
}
void addDot( Color chartColor, double value, int ivalue, Color dotColor, String name ) {
if( dotColor == null )
dotColor = chartColor;
lineChart.addValue( chartColor, value, ivalue, dotColor, true, name );
}
void addMethodHighlight( String classAndMethod, String highlightColor ) {
lineChart.methodHighlightMap.put( classAndMethod, highlightColor );
}
private void oneSecondWidthChanged() {
int oneSecondWidth = oneSecondWidthSlider.getValue();
int msPerLineX =
oneSecondWidth <= 2000 ? 100 :
oneSecondWidth <= 4000 ? 50 :
oneSecondWidth <= 8000 ? 25 :
10;
lineChart.oneSecondWidth = oneSecondWidth;
lineChart.msPerLineX = msPerLineX;
lineChart.revalidate();
lineChart.repaint();
if( xLabelText == null )
xLabelText = xLabel.getText();
xLabel.setText( MessageFormat.format( xLabelText, msPerLineX ) );
}
private String xLabelText;
private void updateChartDelayedChanged() {
lineChart.updateDelayed = updateChartDelayedCheckBox.isSelected();
}
private void clearChart() {
lineChart.clear();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
lineChartScrollPane = new JScrollPane();
lineChart = new LineChartPanel.LineChart();
JPanel legendPanel = new JPanel();
xLabel = new JLabel();
legend1Label = new JLabel();
JLabel yLabel = new JLabel();
yValueLabel = new JLabel();
JLabel yLabel2 = new JLabel();
JPanel hSpacer1 = new JPanel(null);
legend2Label = new JLabel();
JLabel oneSecondWidthLabel = new JLabel();
oneSecondWidthSlider = new JSlider();
updateChartDelayedCheckBox = new JCheckBox();
clearChartButton = new JButton();
//======== this ========
setLayout(new MigLayout(
"hidemode 3",
// columns
"[grow,fill]",
// rows
"[100:300,grow,fill]" +
"[]"));
//======== lineChartScrollPane ========
{
lineChartScrollPane.setViewportView(lineChart);
}
add(lineChartScrollPane, "cell 0 0");
//======== legendPanel ========
{
legendPanel.setLayout(new MigLayout(
"insets 0,hidemode 3,gapy 0",
// columns
"[fill]para" +
"[fill]",
// rows
"[]" +
"[]"));
//---- xLabel ----
xLabel.setText("X: time ({0}ms per line)");
legendPanel.add(xLabel, "cell 0 0");
legendPanel.add(legend1Label, "cell 1 0");
//---- yLabel ----
yLabel.setText("Y: ");
legendPanel.add(yLabel, "cell 0 1,gapx 0 0");
//---- yValueLabel ----
yValueLabel.setText("value");
legendPanel.add(yValueLabel, "cell 0 1,gapx 0 0");
//---- yLabel2 ----
yLabel2.setText(" (10% per line)");
legendPanel.add(yLabel2, "cell 0 1,gapx 0 0");
legendPanel.add(hSpacer1, "cell 0 1,growx");
legendPanel.add(legend2Label, "cell 1 1");
}
add(legendPanel, "cell 0 1");
//---- oneSecondWidthLabel ----
oneSecondWidthLabel.setText("Scale X:");
oneSecondWidthLabel.setDisplayedMnemonic('A');
oneSecondWidthLabel.setLabelFor(oneSecondWidthSlider);
add(oneSecondWidthLabel, "cell 0 1,alignx right,growx 0");
//---- oneSecondWidthSlider ----
oneSecondWidthSlider.setMinimum(100);
oneSecondWidthSlider.setMaximum(10000);
oneSecondWidthSlider.setSnapToTicks(true);
oneSecondWidthSlider.setMajorTickSpacing(100);
oneSecondWidthSlider.setValue(500);
oneSecondWidthSlider.addChangeListener(e -> oneSecondWidthChanged());
add(oneSecondWidthSlider, "cell 0 1,alignx right,growx 0");
//---- updateChartDelayedCheckBox ----
updateChartDelayedCheckBox.setText("Update chart delayed");
updateChartDelayedCheckBox.setMnemonic('P');
updateChartDelayedCheckBox.addActionListener(e -> updateChartDelayedChanged());
add(updateChartDelayedCheckBox, "cell 0 1,alignx right,growx 0");
//---- clearChartButton ----
clearChartButton.setText("Clear Chart");
clearChartButton.setMnemonic('C');
clearChartButton.addActionListener(e -> clearChart());
add(clearChartButton, "cell 0 1,alignx right,growx 0");
// JFormDesigner - End of component initialization //GEN-END:initComponents @formatter:on
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables @formatter:off
private JScrollPane lineChartScrollPane;
private LineChartPanel.LineChart lineChart;
private JLabel xLabel;
private JLabel legend1Label;
private JLabel yValueLabel;
private JLabel legend2Label;
private JSlider oneSecondWidthSlider;
private JCheckBox updateChartDelayedCheckBox;
private JButton clearChartButton;
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
//---- class LineChart ----------------------------------------------------
private static class LineChart
extends JComponent
implements Scrollable
{
private static final int UPDATE_DELAY_MS = 20;
private static final int NEW_SEQUENCE_TIME_LAG_MS = 500;
private static final int NEW_SEQUENCE_GAP_MS = 100;
private static final int HIT_OFFSET = 4;
private static final boolean TEST = false;
// asynchron means that chart for each color starts at x=0
private boolean asynchron;
private boolean temporaryValueDetection;
private boolean yZeroAtTop;
private int oneSecondWidth = 500;
private int msPerLineX = 100;
private final HashMap<String, String> methodHighlightMap = new HashMap<>();
private static class Data {
final double value;
final int ivalue;
final Color chartColor;
final Color dotColor;
final boolean dotOnly;
final long time; // in milliseconds
final String name;
final Exception stack;
Data( double value, int ivalue, Color chartColor, Color dotColor,
boolean dotOnly, long time, String name, Exception stack )
{
this.value = value;
this.ivalue = ivalue;
this.chartColor = chartColor;
this.dotColor = dotColor;
this.dotOnly = dotOnly;
this.time = time;
this.name = name;
this.stack = stack;
}
@Override
public String toString() {
// for debugging
return "value=" + value + ", ivalue=" + ivalue + ", dotColor=" + dotColor
+ ", dotOnly=" + dotOnly + ", time=" + time + ", name=" + name;
}
}
private final List<Data> syncChartData = new ArrayList<>();
private final Map<Color, List<Data>> asyncColor2dataMap = new HashMap<>();
private final Timer repaintTime;
private Color lastUsedChartColor;
private boolean updateDelayed;
private final List<Point> lastPoints = new ArrayList<>();
private final List<Data> lastDatas = new ArrayList<>();
private double lastSystemScaleFactor = 1;
private String lastToolTipPrinted;
LineChart() {
repaintTime = new Timer( UPDATE_DELAY_MS, e -> repaintAndRevalidate() );
repaintTime.setRepeats( false );
ToolTipManager.sharedInstance().registerComponent( this );
if( TEST )
initTestData();
}
void addValue( Color chartColor, double value, int ivalue, Color dotColor, boolean dotOnly, String name ) {
if( TEST )
return;
List<Data> chartData = asyncColor2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
Data data = new Data( value, ivalue, chartColor, dotColor, dotOnly, System.nanoTime() / 1_000_000, name, new Exception() );
if( asynchron )
chartData.add( data );
else
syncChartData.add( data );
lastUsedChartColor = chartColor;
if( updateDelayed ) {
repaintTime.stop();
repaintTime.start();
} else
repaintAndRevalidate();
}
void clear() {
if( TEST ) {
repaint();
return;
}
syncChartData.clear();
asyncColor2dataMap.clear();
lastUsedChartColor = null;
repaint();
revalidate();
}
private void repaintAndRevalidate() {
repaint();
revalidate();
// scroll horizontally
if( lastUsedChartColor != null ) {
// compute chart width of last used color and start of last sequence
int[] lastSeqX = new int[1];
int cw = chartWidth( asynchron ? asyncColor2dataMap.get( lastUsedChartColor ) : syncChartData, lastSeqX );
// scroll to end of last sequence (of last used color)
int lastSeqWidth = cw - lastSeqX[0];
int width = Math.min( lastSeqWidth, getParent().getWidth() );
int x = cw - width;
scrollRectToVisible( new Rectangle( x, 0, width, getHeight() ) );
}
}
@Override
protected void paintComponent( Graphics g ) {
Graphics g2 = g.create();
try {
HiDPIUtils.paintAtScale1x( (Graphics2D) g2, this, this::paintAt1x );
} finally {
g2.dispose();
}
}
private void paintAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
FlatUIUtils.setRenderingHints( g );
int oneSecondWidth = (int) (UIScale.scale( this.oneSecondWidth ) * scaleFactor);
int seqGapWidth = (oneSecondWidth * NEW_SEQUENCE_GAP_MS) / 1000;
int hitOffset = (int) Math.round( UIScale.scale( HIT_OFFSET ) * scaleFactor );
Color lineColor = FlatUIUtils.getUIColor( "Component.borderColor", Color.lightGray );
Color lineColor2 = FlatLaf.isLafDark()
? new HSLColor( lineColor ).adjustTone( 30 )
: new HSLColor( lineColor ).adjustShade( 30 );
g.translate( x, y );
// fill background
g.setColor( UIManager.getColor( "Table.background" ) );
g.fillRect( x, y, width, height );
// paint horizontal lines
for( int i = 1; i < 10; i++ ) {
int hy = (height * i) / 10;
g.setColor( (i != 5) ? lineColor : lineColor2 );
g.drawLine( 0, hy, width, hy );
}
// paint vertical lines
int perLineXWidth = Math.round( (oneSecondWidth / 1000f) * msPerLineX );
for( int i = 1, xv = perLineXWidth; xv < width; xv += perLineXWidth, i++ ) {
g.setColor( (i % 5 != 0) ? lineColor : lineColor2 );
g.drawLine( xv, 0, xv, height );
}
lastPoints.clear();
lastDatas.clear();
lastSystemScaleFactor = scaleFactor;
// paint lines
for( Map.Entry<Color, List<Data>> e : asyncColor2dataMap.entrySet() ) {
List<Data> chartData = asynchron ? e.getValue() : syncChartData;
Color chartColor = e.getKey();
if( FlatLaf.isLafDark() )
chartColor = new HSLColor( chartColor ).adjustTone( 50 );
Color temporaryValueColor = fade( chartColor, FlatLaf.isLafDark() ? 0.7f : 0.3f );
Color dataPointColor = fade( chartColor, FlatLaf.isLafDark() ? 0.6f : 0.2f );
// sequence start time and x coordinate
long seqStartTime = 0;
int seqStartX = 0;
// "previous" data point time and x coordinate (used for "new sequence" detection)
long ptime = Long.MIN_VALUE;
int px = 0;
// "line" data point x/y coordinates
int lx = -1;
int ly = -1;
boolean isTemporaryValue = false;
int lastTemporaryValueIndex = -1;
int size = chartData.size();
for( int i = 0; i < size; i++ ) {
Data data = chartData.get( i );
boolean useData = (data.chartColor == chartColor);
// start new sequence if there is a larger time gap to previous data point
boolean newSeq = (data.time > ptime + NEW_SEQUENCE_TIME_LAG_MS);
ptime = data.time;
if( newSeq ) {
// start new sequence
seqStartTime = data.time;
seqStartX = (i > 0) ? px + seqGapWidth : 0;
px = seqStartX;
lx = -1;
ly = -1;
isTemporaryValue = false;
}
// x/y coordinates of current data point
int dx = (int) (seqStartX + (((data.time - seqStartTime) / 1000.) * oneSecondWidth));
int dy = (int) ((height - 1) * data.value);
if( !yZeroAtTop )
dy = height - 1 - dy;
// remember x coordinate for "new sequence" detection
px = dx;
if( !useData )
continue;
// remember data point for tooltip
lastPoints.add( new Point( dx, dy ) );
lastDatas.add( data );
// paint rectangle to indicate data point
g.setColor( dataPointColor );
g.drawRect( dx - hitOffset, dy - hitOffset, hitOffset * 2, hitOffset * 2 );
// paint dot
if( data.dotColor != null ) {
int s1 = (int) Math.round( UIScale.scale( 1 ) * scaleFactor );
int s3 = (int) Math.round( UIScale.scale( 3 ) * scaleFactor );
g.setColor( data.dotColor );
g.fillRect( dx - s1, dy - s1, s3, s3 );
if( data.dotOnly )
continue;
}
// start of line?
if( lx < 0 ) {
// remember x/y coordinates for first line
lx = dx;
ly = dy;
continue;
}
if( isTemporaryValue && i > lastTemporaryValueIndex )
isTemporaryValue = false;
// draw line in sequence
g.setColor( isTemporaryValue ? temporaryValueColor : chartColor );
g.drawLine( lx, ly, dx, dy );
// remember x/y coordinates for next line
lx = dx;
ly = dy;
// check next data points for "temporary" value(s)
if( temporaryValueDetection && !isTemporaryValue ) {
// one or two values between two equal values are considered "temporary",
// which means that they are the target value for the following scroll animation
int stage = 0;
for( int j = i + 1; j < size && stage <= 2 && !isTemporaryValue; j++ ) {
Data nextData = chartData.get( j );
if( nextData.dotOnly )
continue; // ignore dots
// check whether next data point is within 10 milliseconds
if( nextData.time > data.time + 10 )
break;
if( stage >= 1 && stage <= 2 && nextData.value == data.value ) {
isTemporaryValue = true;
lastTemporaryValueIndex = j;
}
stage++;
}
}
}
}
}
private int chartWidth() {
int width = 0;
if( asynchron ) {
for( List<Data> chartData : asyncColor2dataMap.values() )
width = Math.max( width, chartWidth( chartData, null ) );
} else
width = Math.max( width, chartWidth( syncChartData, null ) );
return width;
}
private int chartWidth( List<Data> chartData, int[] lastSeqX ) {
long seqTime = 0;
int seqX = 0;
long ptime = 0;
int px = 0;
int oneSecondWidth = UIScale.scale( this.oneSecondWidth );
int seqGapWidth = (oneSecondWidth * NEW_SEQUENCE_GAP_MS) / 1000;
int size = chartData.size();
for( int i = 0; i < size; i++ ) {
Data data = chartData.get( i );
if( data.time > ptime + NEW_SEQUENCE_TIME_LAG_MS ) {
// start new sequence
seqTime = data.time;
seqX = (i > 0) ? px + seqGapWidth : 0;
px = seqX;
} else {
// line in sequence
int dx = (int) (seqX + (((data.time - seqTime) / 1000.) * oneSecondWidth ));
px = dx;
}
ptime = data.time;
}
if( lastSeqX != null )
lastSeqX[0] = seqX;
return px;
}
@Override
public Dimension getPreferredSize() {
return new Dimension( chartWidth(), 200 );
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension( chartWidth(), 200 );
}
@Override
public int getScrollableUnitIncrement( Rectangle visibleRect, int orientation, int direction ) {
return UIScale.scale( oneSecondWidth );
}
@Override
public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, int direction ) {
JViewport viewport = (JViewport) SwingUtilities.getAncestorOfClass( JViewport.class, this );
return (viewport != null) ? viewport.getWidth() : 200;
}
@Override
public boolean getScrollableTracksViewportWidth() {
JViewport viewport = (JViewport) SwingUtilities.getAncestorOfClass( JViewport.class, this );
return (viewport != null) ? viewport.getWidth() > chartWidth() : true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return true;
}
@Override
public String getToolTipText( MouseEvent e ) {
int x = (int) Math.round( e.getX() * lastSystemScaleFactor );
int y = (int) Math.round( e.getY() * lastSystemScaleFactor );
int hitOffset = (int) Math.round( UIScale.scale( HIT_OFFSET ) * lastSystemScaleFactor );
StringBuilder buf = null;
int pointsCount = lastPoints.size();
for( int i = 0; i < pointsCount; i++ ) {
Point pt = lastPoints.get( i );
// check X/Y coordinates
if( x < pt.x - hitOffset || x > pt.x + hitOffset ||
y < pt.y - hitOffset || y > pt.y + hitOffset )
continue;
if( buf == null ) {
buf = new StringBuilder( 5000 );
buf.append( "<html>" );
}
Data data = lastDatas.get( i );
buf.append( "<h2>" );
if( data.dotOnly )
buf.append( "DOT: " );
buf.append( data.name );
if( data.ivalue != Integer.MIN_VALUE )
buf.append( ' ' ).append( data.ivalue );
buf.append( " (" ).append( String.format( "%.3f", data.value ) ).append( ')' );
buf.append( "</h2>" );
StackTraceElement[] stackTrace = data.stack.getStackTrace();
for( int j = 0; j < stackTrace.length; j++ ) {
StackTraceElement stackElement = stackTrace[j];
String className = stackElement.getClassName();
String methodName = stackElement.getMethodName();
String classAndMethod = className + '.' + methodName;
// ignore methods from this class
if( className.startsWith( LineChartPanel.class.getName() ) )
continue;
int repeatCount = 0;
for( int k = j + 1; k < stackTrace.length; k++ ) {
if( !stackElement.equals( stackTrace[k] ) )
break;
repeatCount++;
}
j += repeatCount;
String highlight = methodHighlightMap.get( classAndMethod );
if( highlight == null )
highlight = methodHighlightMap.get( className );
if( highlight == null )
highlight = methodHighlightMap.get( methodName );
if( highlight != null )
buf.append( "<span color=\"" ).append( highlight ).append( "\">" );
// append method
buf.append( className )
.append( ".<b>" )
.append( methodName )
.append( "</b>" );
if( highlight != null )
buf.append( "</span>" );
// append source
buf.append( " <span color=\"#888888\">" );
if( stackElement.getFileName() != null ) {
buf.append( '(' );
buf.append( stackElement.getFileName() );
if( stackElement.getLineNumber() >= 0 )
buf.append( ':' ).append( stackElement.getLineNumber() );
buf.append( ')' );
} else
buf.append( "(Unknown Source)" );
buf.append( "</span>" );
// append repeat count
if( repeatCount > 0 )
buf.append( " <b>" ).append( repeatCount + 1 ).append( "x</b>" );
buf.append( "<br>" );
// break at some methods to make stack smaller
if( classAndMethod.equals( "java.awt.event.InvocationEvent.dispatch" ) ||
classAndMethod.equals( "java.awt.Component.processMouseEvent" ) ||
classAndMethod.equals( "java.awt.Component.processMouseWheelEvent" ) ||
classAndMethod.equals( "java.awt.Component.processMouseMotionEvent" ) ||
classAndMethod.equals( "javax.swing.JComponent.processKeyBinding" ) ||
classAndMethod.equals( "javax.swing.JComponent.paintComponent" ) ||
classAndMethod.equals( "com.formdev.flatlaf.util.Animator.timingEvent" ) )
break;
}
buf.append( "..." );
}
if( buf == null )
return null;
buf.append( "<html>" );
String toolTip = buf.toString();
// print to console
if( !Objects.equals( toolTip, lastToolTipPrinted ) ) {
lastToolTipPrinted = toolTip;
System.out.println( toolTip
.replace( "<br>", "\n" )
.replace( "<h2>", "\n---- " )
.replace( "</h2>", " ----\n" )
.replaceAll( "<[^>]+>", "" ) );
}
return buf.toString();
}
private void initTestData() {
// asynchron = true;
addTestSimpleLine( Color.red, 0.0, "red" );
addTestSimpleLine( Color.green, 0.1, "green" );
addTestSimpleLine( Color.blue, 0.2, "blue" );
addTestSimpleLine( Color.magenta, 0.3, "magenta" );
addTestMiddleDotOnly( Color.red, 0.0, "red" );
addTestMiddleDotOnly( Color.green, 0.1, "green" );
addTestMiddleDotOnly( Color.blue, 0.2, "blue" );
addTestMiddleDotOnly( Color.magenta, 0.3, "magenta" );
addTestLeadingDotOnly( Color.red, 0.0, "red" );
addTestLeadingDotOnly( Color.green, 0.1, "green" );
addTestLeadingDotOnly( Color.blue, 0.2, "blue" );
addTestLeadingDotOnly( Color.magenta, 0.3, "magenta" );
addTestTrailingDotOnly( Color.red, 0.0, "red" );
addTestTrailingDotOnly( Color.green, 0.1, "green" );
addTestTrailingDotOnly( Color.blue, 0.2, "blue" );
addTestTrailingDotOnly( Color.magenta, 0.3, "magenta" );
addTestSingleData( Color.red, 0.0, "red" );
addTestSingleData( Color.green, 0.1, "green" );
addTestSingleData( Color.blue, 0.2, "blue" );
addTestSingleData( Color.magenta, 0.3, "magenta" );
temporaryValueDetection = true;
addTestWithTemporaryValues( Color.red, 0.0, "red" );
addTestWithTemporaryValues( Color.green, 0.1, "green" );
addTestWithTemporaryValues( Color.blue, 0.2, "blue" );
addTestWithTemporaryValues( Color.magenta, 0.3, "magenta" );
}
private void addTestSimpleLine( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.0, null, false, name );
addTestValue( 50, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 50, chartColor, baseValue + 0.4, null, false, name );
testTime += 1000;
}
private void addTestMiddleDotOnly( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.0, null, false, name );
addTestValue( 20, chartColor, baseValue + 0.3, chartColor, true, name );
addTestValue( 30, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 20, chartColor, baseValue + 0.05, chartColor, true, name );
addTestValue( 30, chartColor, baseValue + 0.4, null, false, name );
testTime += 1000;
}
private void addTestLeadingDotOnly( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.05, chartColor, true, name );
addTestValue( 20, chartColor, baseValue + 0.0, null, false, name );
addTestValue( 50, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 30, chartColor, baseValue + 0.4, null, false, name );
testTime += 1000;
}
private void addTestTrailingDotOnly( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.0, null, false, name );
addTestValue( 50, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 30, chartColor, baseValue + 0.4, null, false, name );
addTestValue( 20, chartColor, baseValue + 0.05, chartColor, true, name );
testTime += 1000;
}
private void addTestSingleData( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.15, chartColor, false, name );
testTime += 1000;
}
private void addTestWithTemporaryValues( Color chartColor, double baseValue, String name ) {
addTestValue( 0, chartColor, baseValue + 0.0, null, false, name );
addTestValue( 50, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 5, chartColor, baseValue + 0.4, null, false, name );
addTestValue( 5, chartColor, baseValue + 0.1, null, false, name );
addTestValue( 40, chartColor, baseValue + 0.3, null, false, name );
testTime += 1000;
}
private void addTestValue( int timeDelta, Color chartColor, double value, Color dotColor, boolean dotOnly, String name ) {
testTime += timeDelta;
List<Data> chartData = asyncColor2dataMap.computeIfAbsent( chartColor, k -> new ArrayList<>() );
Data data = new Data( value, testIValue++, chartColor, dotColor, dotOnly, testTime, name, new Exception() );
if( asynchron )
chartData.add( data );
else
syncChartData.add( data );
lastUsedChartColor = chartColor;
}
private int testIValue;
private long testTime;
//TODO remove and use ColorFunctions.fade() when merging to main
private static Color fade( Color color, float amount ) {
int newAlpha = Math.round( 255 * amount );
return new Color( (color.getRGB() & 0xffffff) | (newAlpha << 24), true );
}
}
}

View File

@@ -1,123 +0,0 @@
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[grow,fill]"
"$rowConstraints": "[100:300,grow,fill][]"
} ) {
name: "this"
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "lineChartScrollPane"
add( new FormComponent( "com.formdev.flatlaf.testing.LineChartPanel$LineChart" ) {
name: "lineChart"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3,gapy 0"
"$columnConstraints": "[fill]para[fill]"
"$rowConstraints": "[][]"
} ) {
name: "legendPanel"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
add( new FormComponent( "javax.swing.JLabel" ) {
name: "xLabel"
"text": "X: time ({0}ms per line)"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "legend1Label"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "yLabel"
"text": "Y: "
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,gapx 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "yValueLabel"
"text": "value"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,gapx 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "yLabel2"
"text": " (10% per line)"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,gapx 0 0"
} )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer1"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "legend2Label"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "oneSecondWidthLabel"
"text": "Scale X:"
"displayedMnemonic": 65
"labelFor": new FormReference( "oneSecondWidthSlider" )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,alignx right,growx 0"
} )
add( new FormComponent( "javax.swing.JSlider" ) {
name: "oneSecondWidthSlider"
"minimum": 100
"maximum": 10000
"snapToTicks": true
"majorTickSpacing": 100
"value": 500
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "oneSecondWidthChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,alignx right,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "updateChartDelayedCheckBox"
"text": "Update chart delayed"
"mnemonic": 80
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "updateChartDelayedChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,alignx right,growx 0"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "clearChartButton"
"text": "Clear Chart"
"mnemonic": 67
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "clearChart", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,alignx right,growx 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 880, 300 )
} )
}
}

View File

@@ -25,6 +25,7 @@ import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
@@ -51,7 +52,6 @@ import java.util.prefs.Preferences;
import javax.lang.model.SourceVersion;
import javax.swing.*;
import net.miginfocom.swing.*;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
@@ -754,7 +754,8 @@ class FlatThemeFileEditor
private void about() {
JLabel titleLabel = new JLabel( "FlatLaf Theme Editor" );
titleLabel.putClientProperty( FlatClientProperties.STYLE_CLASS, "h1" );
Font titleFont = titleLabel.getFont();
titleLabel.setFont( titleFont.deriveFont( (float) titleFont.getSize() + UIScale.scale( 6 ) ) );
String link = "https://www.formdev.com/flatlaf/";
JLabel linkLabel = new JLabel( "<html><a href=\"#\">" + link + "</a></html>" );

View File

@@ -46,7 +46,6 @@ class FlatThemePreview
private final FlatThemePreviewAll allTab;
private final FlatThemePreviewButtons buttonsTab;
private final FlatThemePreviewSwitches switchesTab;
private final FlatThemePreviewFonts fontsTab;
private final Map<LazyValue, Object> lazyValueCache = new WeakHashMap<>();
private int runWithUIDefaultsGetterLevel;
@@ -62,11 +61,9 @@ class FlatThemePreview
allTab = new FlatThemePreviewAll( this );
buttonsTab = new FlatThemePreviewButtons( this );
switchesTab = new FlatThemePreviewSwitches( this );
fontsTab = new FlatThemePreviewFonts();
tabbedPane.addTab( "All", createPreviewTab( allTab ) );
tabbedPane.addTab( "Buttons", createPreviewTab( buttonsTab ) );
tabbedPane.addTab( "Switches", createPreviewTab( switchesTab ) );
tabbedPane.addTab( "Fonts", createPreviewTab( fontsTab ) );
selectRecentTab();
tabbedPane.addChangeListener( e -> selectedTabChanged() );
@@ -178,8 +175,7 @@ class FlatThemePreview
Object value = textArea.propertiesSupport.getParsedProperty( (String) key );
boolean isDefaultFont = "defaultFont".equals( key );
inGetDefaultFont = isDefaultFont;
inGetDefaultFont = "defaultFont".equals( key );
try {
if( value instanceof LazyValue ) {
value = lazyValueCache.computeIfAbsent( (LazyValue) value, k -> {
@@ -193,12 +189,6 @@ class FlatThemePreview
// System.out.println( key + " = " + value );
// for "defaultFont" never return a value that is not a font
// (e.g. a color for "defaultFont = #fff") to avoid StackOverflowError
// in Active.createValue()
if( isDefaultFont && !(value instanceof Font) )
return null;
// If value is null and is a property that is defined in a core theme,
// then force the value to null.
// This is necessary for cases where the current application Laf defines a property
@@ -206,7 +196,7 @@ class FlatThemePreview
// E.g. FlatLightLaf defines Button.focusedBackground, but in FlatDarkLaf
// it is not defined. Without this code, the preview for FlatDarkLaf would use
// Button.focusedBackground from FlatLightLaf if FlatLightLaf is the current application Laf.
if( value == null && FlatThemePropertiesBaseManager.getDefindedCoreKeys().contains( key ) && !isDefaultFont )
if( value == null && FlatThemePropertiesBaseManager.getDefindedCoreKeys().contains( key ) && !"defaultFont".equals( key ) )
return FlatLaf.NULL_VALUE;
return value;
@@ -225,7 +215,6 @@ class FlatThemePreview
{
tabbedPane.setLeadingComponent(previewLabel);
tabbedPane.setTabAreaAlignment(FlatTabbedPane.TabAreaAlignment.trailing);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
add(tabbedPane, BorderLayout.CENTER);
@@ -234,8 +223,8 @@ class FlatThemePreview
add(previewSeparator, BorderLayout.LINE_START);
//---- previewLabel ----
previewLabel.setText(" Preview ");
previewLabel.putClientProperty("FlatLaf.styleClass", "h2");
previewLabel.setText(" Preview ");
previewLabel.setFont(previewLabel.getFont().deriveFont(previewLabel.getFont().getSize() + 6f));
// JFormDesigner - End of component initialization //GEN-END:initComponents
}

View File

@@ -9,7 +9,6 @@ new FormModel {
name: "tabbedPane"
"leadingComponent": new FormReference( "previewLabel" )
"tabAreaAlignment": enum com.formdev.flatlaf.extras.components.FlatTabbedPane$TabAreaAlignment trailing
"tabLayoutPolicy": 1
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
@@ -25,8 +24,8 @@ new FormModel {
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "previewLabel"
"text": " Preview "
"$client.FlatLaf.styleClass": "h2"
"text": " Preview "
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 6, false )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 235 )
"size": new java.awt.Dimension( 176, 24 )

View File

@@ -560,7 +560,7 @@ class FlatThemePreviewAll
menuUnderlineSelectionButton.setButtonType(FlatButton.ButtonType.toolBarButton);
menuUnderlineSelectionButton.setToolTipText("menu underline selection");
menuUnderlineSelectionButton.setFocusable(false);
menuUnderlineSelectionButton.putClientProperty("FlatLaf.styleClass", "small");
menuUnderlineSelectionButton.setFont(menuUnderlineSelectionButton.getFont().deriveFont(menuUnderlineSelectionButton.getFont().getSize() - 2f));
menuUnderlineSelectionButton.addActionListener(e -> menuUnderlineSelectionChanged());
add(menuUnderlineSelectionButton, "cell 0 11");

View File

@@ -307,7 +307,7 @@ new FormModel {
"buttonType": enum com.formdev.flatlaf.extras.components.FlatButton$ButtonType toolBarButton
"toolTipText": "menu underline selection"
"focusable": false
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}

View File

@@ -232,25 +232,25 @@ class FlatThemePreviewButtons
//---- noneButton ----
noneButton.setText("none");
noneButton.setSelected(true);
noneButton.putClientProperty("FlatLaf.styleClass", "small");
noneButton.setFont(noneButton.getFont().deriveFont(noneButton.getFont().getSize() - 2f));
noneButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar1.add(noneButton);
//---- squareButton ----
squareButton.setText("square");
squareButton.putClientProperty("FlatLaf.styleClass", "small");
squareButton.setFont(squareButton.getFont().deriveFont(squareButton.getFont().getSize() - 2f));
squareButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar1.add(squareButton);
//---- roundRectButton ----
roundRectButton.setText("roundRect");
roundRectButton.putClientProperty("FlatLaf.styleClass", "small");
roundRectButton.setFont(roundRectButton.getFont().deriveFont(roundRectButton.getFont().getSize() - 2f));
roundRectButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar1.add(roundRectButton);
//---- tabButton ----
tabButton.setText("tab");
tabButton.putClientProperty("FlatLaf.styleClass", "small");
tabButton.setFont(tabButton.getFont().deriveFont(tabButton.getFont().getSize() - 2f));
tabButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar1.add(tabButton);
}
@@ -263,13 +263,13 @@ class FlatThemePreviewButtons
//---- toolBarButtonButton ----
toolBarButtonButton.setText("toolBarButton");
toolBarButtonButton.putClientProperty("FlatLaf.styleClass", "small");
toolBarButtonButton.setFont(toolBarButtonButton.getFont().deriveFont(toolBarButtonButton.getFont().getSize() - 2f));
toolBarButtonButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar2.add(toolBarButtonButton);
//---- borderlessButton ----
borderlessButton.setText("borderless");
borderlessButton.putClientProperty("FlatLaf.styleClass", "small");
borderlessButton.setFont(borderlessButton.getFont().deriveFont(borderlessButton.getFont().getSize() - 2f));
borderlessButton.addActionListener(e -> buttonTypeChanged());
buttonTypeToolBar2.add(borderlessButton);
}
@@ -279,7 +279,7 @@ class FlatThemePreviewButtons
//---- label11 ----
label11.setText("JButton");
label11.putClientProperty("FlatLaf.styleClass", "h3");
label11.setFont(label11.getFont().deriveFont(label11.getFont().getSize() + 4f));
add(label11, "cell 0 1 3 1");
//---- label27 ----
@@ -292,22 +292,22 @@ class FlatThemePreviewButtons
//---- label5 ----
label5.setText("regular");
label5.putClientProperty("FlatLaf.styleClass", "small");
label5.setFont(label5.getFont().deriveFont(label5.getFont().getSize() - 2f));
add(label5, "cell 1 3,alignx center,growx 0");
//---- label7 ----
label7.setText("default");
label7.putClientProperty("FlatLaf.styleClass", "small");
label7.setFont(label7.getFont().deriveFont(label7.getFont().getSize() - 2f));
add(label7, "cell 2 3,alignx center,growx 0");
//---- label6 ----
label6.setText("regular");
label6.putClientProperty("FlatLaf.styleClass", "small");
label6.setFont(label6.getFont().deriveFont(label6.getFont().getSize() - 2f));
add(label6, "cell 3 3,alignx center,growx 0");
//---- label8 ----
label8.setText("default");
label8.putClientProperty("FlatLaf.styleClass", "small");
label8.setFont(label8.getFont().deriveFont(label8.getFont().getSize() - 2f));
add(label8, "cell 4 3,alignx center,growx 0");
//---- label1 ----
@@ -435,7 +435,7 @@ class FlatThemePreviewButtons
//---- label12 ----
label12.setText("JToggleButton");
label12.putClientProperty("FlatLaf.styleClass", "h3");
label12.setFont(label12.getFont().deriveFont(label12.getFont().getSize() + 4f));
add(label12, "cell 0 9 3 1");
//---- label29 ----
@@ -448,22 +448,22 @@ class FlatThemePreviewButtons
//---- label13 ----
label13.setText("unsel.");
label13.putClientProperty("FlatLaf.styleClass", "small");
label13.setFont(label13.getFont().deriveFont(label13.getFont().getSize() - 2f));
add(label13, "cell 1 11,alignx center,growx 0");
//---- label14 ----
label14.setText("selected");
label14.putClientProperty("FlatLaf.styleClass", "small");
label14.setFont(label14.getFont().deriveFont(label14.getFont().getSize() - 2f));
add(label14, "cell 2 11,alignx center,growx 0");
//---- label15 ----
label15.setText("unsel.");
label15.putClientProperty("FlatLaf.styleClass", "small");
label15.setFont(label15.getFont().deriveFont(label15.getFont().getSize() - 2f));
add(label15, "cell 3 11,alignx center,growx 0");
//---- label16 ----
label16.setText("selected");
label16.putClientProperty("FlatLaf.styleClass", "small");
label16.setFont(label16.getFont().deriveFont(label16.getFont().getSize() - 2f));
add(label16, "cell 4 11,alignx center,growx 0");
//---- label17 ----
@@ -576,7 +576,7 @@ class FlatThemePreviewButtons
//---- label32 ----
label32.setText("Help Button");
label32.putClientProperty("FlatLaf.styleClass", "h3");
label32.setFont(label32.getFont().deriveFont(label32.getFont().getSize() + 4f));
add(label32, "cell 0 17 2 1");
//---- label9 ----

View File

@@ -33,7 +33,7 @@ new FormModel {
"text": "none"
"$buttonGroup": new FormReference( "buttonGroup1" )
"selected": true
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont0 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -43,7 +43,7 @@ new FormModel {
name: "squareButton"
"text": "square"
"$buttonGroup": new FormReference( "buttonGroup1" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -53,7 +53,7 @@ new FormModel {
name: "roundRectButton"
"text": "roundRect"
"$buttonGroup": new FormReference( "buttonGroup1" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -63,7 +63,7 @@ new FormModel {
name: "tabButton"
"text": "tab"
"$buttonGroup": new FormReference( "buttonGroup1" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -80,7 +80,7 @@ new FormModel {
name: "toolBarButtonButton"
"text": "toolBarButton"
"$buttonGroup": new FormReference( "buttonGroup1" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -90,7 +90,7 @@ new FormModel {
name: "borderlessButton"
"text": "borderless"
"$buttonGroup": new FormReference( "buttonGroup1" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -105,7 +105,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JButton"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont1 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1 3 1"
} )
@@ -124,28 +124,28 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label5"
"text": "regular"
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont2 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label7"
"text": "default"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6"
"text": "regular"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label8"
"text": "default"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3,alignx center,growx 0"
} )
@@ -317,7 +317,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label12"
"text": "JToggleButton"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9 3 1"
} )
@@ -336,28 +336,28 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label13"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label14"
"text": "selected"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label15"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label16"
"text": "selected"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 11,alignx center,growx 0"
} )
@@ -514,7 +514,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label32"
"text": "Help Button"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 17 2 1"
} )

View File

@@ -1,289 +0,0 @@
/*
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.themeeditor;
import java.awt.*;
import java.text.DecimalFormat;
import javax.swing.*;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatThemePreviewFonts
extends JPanel
{
private static final DecimalFormat SCALE_FORMAT = new DecimalFormat( "0.##x" );
public FlatThemePreviewFonts() {
initComponents();
scaleValueLabel.setText( SCALE_FORMAT.format( UIScale.getUserScaleFactor() ) );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JLabel headingsLabel = new JLabel();
FlatThemePreviewFonts.FontPreview h00Preview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview h0Preview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview h1Preview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview h2Preview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview h3Preview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview h4Preview = new FlatThemePreviewFonts.FontPreview();
JLabel textLabel = new JLabel();
FlatThemePreviewFonts.FontPreview largePreview = new FlatThemePreviewFonts.FontPreview();
defaultPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview mediumPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview smallPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview miniPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview lightPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview semiboldPreview = new FlatThemePreviewFonts.FontPreview();
FlatThemePreviewFonts.FontPreview monospacedPreview = new FlatThemePreviewFonts.FontPreview();
JLabel scaleLabel = new JLabel();
scaleValueLabel = new JLabel();
//======== this ========
setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
// columns
"[left]unrel",
// rows
"[]" +
"[bottom]" +
"[bottom]" +
"[bottom]" +
"[bottom]" +
"[bottom]" +
"[bottom]para" +
"[]" +
"[bottom]" +
"[bottom]" +
"[bottom]" +
"[bottom]" +
"[bottom]para" +
"[]" +
"[]para" +
"[]para" +
"[]"));
//---- headingsLabel ----
headingsLabel.setText("Headings");
headingsLabel.putClientProperty("FlatLaf.styleClass", "h3");
add(headingsLabel, "cell 0 0");
//---- h00Preview ----
h00Preview.setFontType("H00");
h00Preview.setFontStyle("h00");
add(h00Preview, "cell 0 1,gapx 12");
//---- h0Preview ----
h0Preview.setFontType("H0");
h0Preview.setFontStyle("h0");
add(h0Preview, "cell 0 2,gapx 12");
//---- h1Preview ----
h1Preview.setFontType("H1");
h1Preview.setFontStyle("h1");
h1Preview.setFontStyleRegular("h1.regular");
add(h1Preview, "cell 0 3,gapx 12");
//---- h2Preview ----
h2Preview.setFontType("H2");
h2Preview.setFontStyle("h2");
h2Preview.setFontStyleRegular("h2.regular");
add(h2Preview, "cell 0 4,gapx 12");
//---- h3Preview ----
h3Preview.setFontType("H3");
h3Preview.setFontStyle("h3");
h3Preview.setFontStyleRegular("h3.regular");
add(h3Preview, "cell 0 5,gapx 12");
//---- h4Preview ----
h4Preview.setFontType("H4");
h4Preview.setFontStyle("h4");
add(h4Preview, "cell 0 6,gapx 12");
//---- textLabel ----
textLabel.setText("Text");
textLabel.putClientProperty("FlatLaf.styleClass", "h3");
add(textLabel, "cell 0 7");
//---- largePreview ----
largePreview.setFontType("Large");
largePreview.setFontStyle("large");
add(largePreview, "cell 0 8,gapx 12");
//---- defaultPreview ----
defaultPreview.setFontType("Default");
add(defaultPreview, "cell 0 9,gapx 12");
//---- mediumPreview ----
mediumPreview.setFontType("Medium");
mediumPreview.setFontStyle("medium");
add(mediumPreview, "cell 0 10,gapx 12");
//---- smallPreview ----
smallPreview.setFontType("Small");
smallPreview.setFontStyle("small");
add(smallPreview, "cell 0 11,gapx 12");
//---- miniPreview ----
miniPreview.setFontType("Mini");
miniPreview.setFontStyle("mini");
add(miniPreview, "cell 0 12,gapx 12");
//---- lightPreview ----
lightPreview.setFontType("Light");
lightPreview.setFontStyle("light");
add(lightPreview, "cell 0 13,gapx 12");
//---- semiboldPreview ----
semiboldPreview.setFontType("Semibold");
semiboldPreview.setFontStyle("semibold");
add(semiboldPreview, "cell 0 14,gapx 12");
//---- monospacedPreview ----
monospacedPreview.setFontType("Monospaced");
monospacedPreview.setFontStyle("monospaced");
add(monospacedPreview, "cell 0 15,gapx 12");
//---- scaleLabel ----
scaleLabel.setText("Fonts in preview are scaled by:");
add(scaleLabel, "cell 0 16,gapx 12");
//---- scaleValueLabel ----
scaleValueLabel.setText("1x");
scaleValueLabel.putClientProperty("FlatLaf.styleClass", "h2");
add(scaleValueLabel, "cell 0 16");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private FlatThemePreviewFonts.FontPreview defaultPreview;
private JLabel scaleValueLabel;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class FontPreview --------------------------------------------------
static class FontPreview
extends JPanel
{
private String fontType;
private String fontStyle;
private String fontStyleRegular;
private FontPreview() {
initComponents();
updateDescription( previewLabel.getFont() );
previewLabel.addPropertyChangeListener( "font", e -> {
updateDescription( previewLabel.getFont() );
} );
preview2Label.setVisible( false );
}
public String getFontType() {
return fontType;
}
public void setFontType( String fontType ) {
this.fontType = fontType;
previewLabel.setText( fontType );
preview2Label.setText( " / " + fontType );
}
public String getFontStyle() {
return fontStyle;
}
public void setFontStyle( String fontStyle ) {
this.fontStyle = fontStyle;
previewLabel.putClientProperty( FlatClientProperties.STYLE_CLASS, fontStyle );
}
public String getFontStyleRegular() {
return fontStyleRegular;
}
public void setFontStyleRegular( String fontStyleRegular ) {
this.fontStyleRegular = fontStyleRegular;
preview2Label.putClientProperty( FlatClientProperties.STYLE_CLASS, fontStyleRegular );
preview2Label.setVisible( fontStyleRegular != null );
}
private void updateDescription( Font font ) {
int baseSize = getDefaultFont().getSize();
int fontSize = font.getSize();
descLabel.setText( String.format( "%s %d %s%s (%+d %s)",
font.getFamily(),
fontSize,
(font.getStyle() & Font.BOLD) != 0 ? " bold" : "",
(font.getStyle() & Font.ITALIC) != 0 ? " italic" : "",
fontSize - baseSize,
SCALE_FORMAT.format( (float) fontSize / baseSize ) ) );
}
private Font getDefaultFont() {
Font font = UIManager.getFont( "defaultFont" );
if( font == null )
font = UIManager.getFont( "Label.font" );
return font;
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
previewLabel = new JLabel();
preview2Label = new JLabel();
descLabel = new JLabel();
//======== this ========
setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
"[90,left]" +
"[fill]",
// rows
"[]0"));
//---- previewLabel ----
previewLabel.setText("preview");
add(previewLabel, "cell 0 0");
//---- preview2Label ----
preview2Label.setText("preview");
add(preview2Label, "cell 0 0,gapx 0");
//---- descLabel ----
descLabel.setText("description");
descLabel.putClientProperty("FlatLaf.styleClass", "medium");
add(descLabel, "cell 1 0");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel previewLabel;
private JLabel preview2Label;
private JLabel descLabel;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
}

View File

@@ -1,195 +0,0 @@
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
auxiliary() {
"JavaCodeGenerator.defaultVariableLocal": true
}
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[left]unrel"
"$rowConstraints": "[][bottom][bottom][bottom][bottom][bottom][bottom]para[][bottom][bottom][bottom][bottom][bottom]para[][]para[]para[]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "headingsLabel"
"text": "Headings"
"$client.FlatLaf.styleClass": "h3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h00Preview"
"fontType": "H00"
"fontStyle": "h00"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h0Preview"
"fontType": "H0"
"fontStyle": "h0"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h1Preview"
"fontType": "H1"
"fontStyle": "h1"
"fontStyleRegular": "h1.regular"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h2Preview"
"fontType": "H2"
"fontStyle": "h2"
"fontStyleRegular": "h2.regular"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h3Preview"
"fontType": "H3"
"fontStyle": "h3"
"fontStyleRegular": "h3.regular"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "h4Preview"
"fontType": "H4"
"fontStyle": "h4"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6,gapx 12"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "textLabel"
"text": "Text"
"$client.FlatLaf.styleClass": "h3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "largePreview"
"fontType": "Large"
"fontStyle": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "defaultPreview"
"fontType": "Default"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "mediumPreview"
"fontType": "Medium"
"fontStyle": "medium"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "smallPreview"
"fontType": "Small"
"fontStyle": "small"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 11,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "miniPreview"
"fontType": "Mini"
"fontStyle": "mini"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 12,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "lightPreview"
"fontType": "Light"
"fontStyle": "light"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 13,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "semiboldPreview"
"fontType": "Semibold"
"fontStyle": "semibold"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 14,gapx 12"
} )
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemePreviewFonts$FontPreview" ) {
name: "monospacedPreview"
"fontType": "Monospaced"
"fontStyle": "monospaced"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 15,gapx 12"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "scaleLabel"
"text": "Fonts in preview are scaled by:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 16,gapx 12"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "scaleValueLabel"
"text": "1x"
"$client.FlatLaf.styleClass": "h2"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 16"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 0 )
"size": new java.awt.Dimension( 335, 495 )
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[90,left][fill]"
"$rowConstraints": "[]0"
} ) {
name: "panel1"
auxiliary() {
"JavaCodeGenerator.className": "FontPreview"
"JavaCodeGenerator.variableName": "fontPreview"
}
add( new FormComponent( "javax.swing.JLabel" ) {
name: "previewLabel"
"text": "preview"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "preview2Label"
"text": "preview"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0,gapx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "descLabel"
"text": "description"
"$client.FlatLaf.styleClass": "medium"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 545 )
"size": new java.awt.Dimension( 235, 65 )
} )
}
}

View File

@@ -262,25 +262,25 @@ class FlatThemePreviewSwitches
//---- zoom1xButton ----
zoom1xButton.setText("1x");
zoom1xButton.setSelected(true);
zoom1xButton.putClientProperty("FlatLaf.styleClass", "small");
zoom1xButton.setFont(zoom1xButton.getFont().deriveFont(zoom1xButton.getFont().getSize() - 2f));
zoom1xButton.addActionListener(e -> zoomChanged());
zoomToolBar.add(zoom1xButton);
//---- zoom2xButton ----
zoom2xButton.setText("2x");
zoom2xButton.putClientProperty("FlatLaf.styleClass", "small");
zoom2xButton.setFont(zoom2xButton.getFont().deriveFont(zoom2xButton.getFont().getSize() - 2f));
zoom2xButton.addActionListener(e -> zoomChanged());
zoomToolBar.add(zoom2xButton);
//---- zoom3xButton ----
zoom3xButton.setText("3x");
zoom3xButton.putClientProperty("FlatLaf.styleClass", "small");
zoom3xButton.setFont(zoom3xButton.getFont().deriveFont(zoom3xButton.getFont().getSize() - 2f));
zoom3xButton.addActionListener(e -> zoomChanged());
zoomToolBar.add(zoom3xButton);
//---- zoom4xButton ----
zoom4xButton.setText("4x");
zoom4xButton.putClientProperty("FlatLaf.styleClass", "small");
zoom4xButton.setFont(zoom4xButton.getFont().deriveFont(zoom4xButton.getFont().getSize() - 2f));
zoom4xButton.addActionListener(e -> zoomChanged());
zoomToolBar.add(zoom4xButton);
zoomToolBar.addSeparator();
@@ -288,7 +288,6 @@ class FlatThemePreviewSwitches
//---- indeterminateButton ----
indeterminateButton.setText("indeterminate");
indeterminateButton.setSelected(true);
indeterminateButton.putClientProperty("FlatLaf.styleClass", "small");
indeterminateButton.addActionListener(e -> indeterminateChanged());
zoomToolBar.add(indeterminateButton);
}
@@ -298,7 +297,7 @@ class FlatThemePreviewSwitches
//---- label22 ----
label22.setText("JCheckBox");
label22.putClientProperty("FlatLaf.styleClass", "h3");
label22.setFont(label22.getFont().deriveFont(label22.getFont().getSize() + 4f));
add(label22, "cell 0 1 3 1");
//---- label1 ----
@@ -311,32 +310,32 @@ class FlatThemePreviewSwitches
//---- label23 ----
label23.setText("unsel.");
label23.putClientProperty("FlatLaf.styleClass", "small");
label23.setFont(label23.getFont().deriveFont(label23.getFont().getSize() - 2f));
add(label23, "cell 1 3,alignx center,growx 0");
//---- label28 ----
label28.setText("sel.");
label28.putClientProperty("FlatLaf.styleClass", "small");
label28.setFont(label28.getFont().deriveFont(label28.getFont().getSize() - 2f));
add(label28, "cell 2 3,alignx center,growx 0");
//---- label37 ----
label37.setText("ind.");
label37.putClientProperty("FlatLaf.styleClass", "small");
label37.setFont(label37.getFont().deriveFont(label37.getFont().getSize() - 2f));
add(label37, "cell 3 3,alignx center,growx 0");
//---- label24 ----
label24.setText("unsel.");
label24.putClientProperty("FlatLaf.styleClass", "small");
label24.setFont(label24.getFont().deriveFont(label24.getFont().getSize() - 2f));
add(label24, "cell 4 3,alignx center,growx 0");
//---- label29 ----
label29.setText("sel.");
label29.putClientProperty("FlatLaf.styleClass", "small");
label29.setFont(label29.getFont().deriveFont(label29.getFont().getSize() - 2f));
add(label29, "cell 5 3,alignx center,growx 0");
//---- label38 ----
label38.setText("ind.");
label38.putClientProperty("FlatLaf.styleClass", "small");
label38.setFont(label38.getFont().deriveFont(label38.getFont().getSize() - 2f));
add(label38, "cell 6 3,alignx center,growx 0");
//---- label17 ----
@@ -466,7 +465,7 @@ class FlatThemePreviewSwitches
//---- label27 ----
label27.setText("JRadioButton");
label27.putClientProperty("FlatLaf.styleClass", "h3");
label27.setFont(label27.getFont().deriveFont(label27.getFont().getSize() + 4f));
add(label27, "cell 0 9 3 1");
//---- label3 ----
@@ -479,22 +478,22 @@ class FlatThemePreviewSwitches
//---- label25 ----
label25.setText("unsel.");
label25.putClientProperty("FlatLaf.styleClass", "small");
label25.setFont(label25.getFont().deriveFont(label25.getFont().getSize() - 2f));
add(label25, "cell 1 11,alignx center,growx 0");
//---- label30 ----
label30.setText("sel.");
label30.putClientProperty("FlatLaf.styleClass", "small");
label30.setFont(label30.getFont().deriveFont(label30.getFont().getSize() - 2f));
add(label30, "cell 2 11,alignx center,growx 0");
//---- label26 ----
label26.setText("unsel.");
label26.putClientProperty("FlatLaf.styleClass", "small");
label26.setFont(label26.getFont().deriveFont(label26.getFont().getSize() - 2f));
add(label26, "cell 4 11,alignx center,growx 0");
//---- label31 ----
label31.setText("sel.");
label31.putClientProperty("FlatLaf.styleClass", "small");
label31.setFont(label31.getFont().deriveFont(label31.getFont().getSize() - 2f));
add(label31, "cell 5 11,alignx center,growx 0");
//---- label36 ----

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "17" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -32,7 +32,7 @@ new FormModel {
name: "zoom1xButton"
"text": "1x"
"selected": true
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont0 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"$buttonGroup": new FormReference( "buttonGroup1" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
@@ -42,7 +42,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "zoom2xButton"
"text": "2x"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
"$buttonGroup": &FormReference0 new FormReference( "buttonGroup1" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
@@ -52,7 +52,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "zoom3xButton"
"text": "3x"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
"$buttonGroup": #FormReference0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
@@ -62,7 +62,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "zoom4xButton"
"text": "4x"
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
"$buttonGroup": #FormReference0
auxiliary() {
"JavaCodeGenerator.variableLocal": false
@@ -76,7 +76,6 @@ new FormModel {
name: "indeterminateButton"
"text": "indeterminate"
"selected": true
"$client.FlatLaf.styleClass": "small"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -91,7 +90,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label22"
"text": "JCheckBox"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont1 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1 3 1"
} )
@@ -110,42 +109,42 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label23"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont2 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label28"
"text": "sel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label37"
"text": "ind."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label24"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label29"
"text": "sel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 3,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label38"
"text": "ind."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3,alignx center,growx 0"
} )
@@ -341,7 +340,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label27"
"text": "JRadioButton"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9 3 1"
} )
@@ -360,28 +359,28 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label25"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label30"
"text": "sel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label26"
"text": "unsel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 11,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label31"
"text": "sel."
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 11,alignx center,growx 0"
} )

View File

@@ -531,7 +531,6 @@ OptionPane.minimumSize
OptionPane.questionIcon
OptionPane.sameSizeButtons
OptionPane.setButtonMargin
OptionPane.showIcon
OptionPane.warningIcon
OptionPane.windowBindings
OptionPaneUI
@@ -632,13 +631,10 @@ RangeSliderUI
Resizable.resizeBorder
RootPane.activeBorderColor
RootPane.ancestorInputMap
RootPane.background
RootPane.border
RootPane.borderDragThickness
RootPane.cornerDragWidth
RootPane.defaultButtonWindowKeyBindings
RootPane.font
RootPane.foreground
RootPane.honorDialogMinimumSizeOnResize
RootPane.honorFrameMinimumSizeOnResize
RootPane.inactiveBorderColor
@@ -787,7 +783,6 @@ TabbedPane.buttonArc
TabbedPane.buttonHoverBackground
TabbedPane.buttonInsets
TabbedPane.buttonPressedBackground
TabbedPane.cardTabSelectionHeight
TabbedPane.closeArc
TabbedPane.closeCrossFilledSize
TabbedPane.closeCrossLineWidth
@@ -834,7 +829,6 @@ TabbedPane.tabRunOverlay
TabbedPane.tabSelectionHeight
TabbedPane.tabSeparatorColor
TabbedPane.tabSeparatorsFullHeight
TabbedPane.tabType
TabbedPane.tabWidthMode
TabbedPane.tabsOpaque
TabbedPane.tabsOverlapBorder
@@ -975,9 +969,7 @@ TitlePane.inactiveForeground
TitlePane.maximizeIcon
TitlePane.menuBarEmbedded
TitlePane.menuBarTitleGap
TitlePane.noIconLeftGap
TitlePane.restoreIcon
TitlePane.showIcon
TitlePane.titleMargins
TitlePane.unifiedBackground
TitlePane.useWindowDecorations
@@ -1099,22 +1091,6 @@ Viewport.background
Viewport.font
Viewport.foreground
ViewportUI
[style].h0
[style].h00
[style].h1
[style].h1.regular
[style].h2
[style].h2.regular
[style].h3
[style].h3.regular
[style].h4
[style].large
[style].light
[style].medium
[style].mini
[style].monospaced
[style].semibold
[style].small
activeCaption
activeCaptionBorder
activeCaptionText
@@ -1126,15 +1102,6 @@ controlShadow
controlText
defaultFont
desktop
h0.font
h00.font
h1.font
h1.regular.font
h2.font
h2.regular.font
h3.font
h3.regular.font
h4.font
html.missingImage
html.pendingImage
inactiveCaption
@@ -1144,16 +1111,9 @@ info
infoText
laf.dark
laf.scaleFactor
large.font
light.font
medium.font
menu
menuText
mini.font
monospaced.font
scrollbar
semibold.font
small.font
swingx/TaskPaneUI
text
textHighlight

View File

@@ -27,7 +27,6 @@ include( "flatlaf-theme-editor" )
includeProject( "flatlaf-natives-windows", "flatlaf-natives/flatlaf-natives-windows" )
includeProject( "flatlaf-natives-jna", "flatlaf-natives/flatlaf-natives-jna" )
includeProject( "flatlaf-testing-modular-app", "flatlaf-testing/flatlaf-testing-modular-app" )
fun includeProject( projectPath: String, projectDir: String ) {
include( projectPath )