Window decorations: support toolbox-style "small" window title bar (issue #659)

This commit is contained in:
Karl Tauber
2023-07-30 15:26:44 +02:00
parent dfe4404a17
commit 8e3c8ba6c5
22 changed files with 627 additions and 57 deletions

View File

@@ -5,6 +5,8 @@ FlatLaf Change Log
#### New features and improvements #### New features and improvements
- FlatLaf window decorations: Support toolbox-style "small" window title bar.
(issue #659)
- Extras: Class `FlatSVGIcon` now uses [JSVG](https://github.com/weisJ/jsvg) - Extras: Class `FlatSVGIcon` now uses [JSVG](https://github.com/weisJ/jsvg)
library (instead of svgSalamander) for rendering. JSVG provides improved SVG library (instead of svgSalamander) for rendering. JSVG provides improved SVG
rendering and uses less memory compared to svgSalamander. (PR #684) rendering and uses less memory compared to svgSalamander. (PR #684)

View File

@@ -17,6 +17,8 @@
package com.formdev.flatlaf; package com.formdev.flatlaf;
import java.awt.Color; import java.awt.Color;
import java.awt.IllegalComponentStateException;
import java.awt.Window;
import java.util.Objects; import java.util.Objects;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@@ -124,6 +126,7 @@ public interface FlatClientProperties
*/ */
String SQUARE_SIZE = "JButton.squareSize"; String SQUARE_SIZE = "JButton.squareSize";
//---- JComponent --------------------------------------------------------- //---- JComponent ---------------------------------------------------------
/** /**
@@ -266,6 +269,7 @@ public interface FlatClientProperties
*/ */
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"; String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
//---- Popup -------------------------------------------------------------- //---- Popup --------------------------------------------------------------
/** /**
@@ -305,6 +309,7 @@ public interface FlatClientProperties
*/ */
String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight"; String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight";
//---- JProgressBar ------------------------------------------------------- //---- JProgressBar -------------------------------------------------------
/** /**
@@ -323,6 +328,7 @@ public interface FlatClientProperties
*/ */
String PROGRESS_BAR_SQUARE = "JProgressBar.square"; String PROGRESS_BAR_SQUARE = "JProgressBar.square";
//---- JRootPane ---------------------------------------------------------- //---- JRootPane ----------------------------------------------------------
/** /**
@@ -472,6 +478,37 @@ public interface FlatClientProperties
*/ */
String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight"; String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight";
/**
* Specifies the style of the window title bar.
* Besides the default title bar style, you can use a Utility-style title bar,
* which is smaller than the default title bar.
* <p>
* On Windows 10/11, this requires FlatLaf window decorations.
* On macOS, Java supports this out of the box.
* <p>
* Note that this client property must be set before the window becomes displayable.
* Otherwise an {@link IllegalComponentStateException} is thrown.
* <p>
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong>
* {@link #WINDOW_STYLE_SMALL}
*
* @since 3.2
*/
String WINDOW_STYLE = "Window.style";
/**
* The window has Utility-style title bar, which is smaller than default title bar.
* <p>
* This is the same as using {@link Window#setType}( {@link Window.Type#UTILITY} ).
*
* @see #WINDOW_STYLE
* @since 3.2
*/
String WINDOW_STYLE_SMALL = "small";
//---- JScrollBar / JScrollPane ------------------------------------------- //---- JScrollBar / JScrollPane -------------------------------------------
/** /**
@@ -490,6 +527,7 @@ public interface FlatClientProperties
*/ */
String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling"; String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling";
//---- JSplitPane --------------------------------------------------------- //---- JSplitPane ---------------------------------------------------------
/** /**
@@ -524,6 +562,7 @@ public interface FlatClientProperties
*/ */
String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"; String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right";
//---- JTabbedPane -------------------------------------------------------- //---- JTabbedPane --------------------------------------------------------
/** /**
@@ -919,6 +958,7 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_TRAILING_COMPONENT = "JTabbedPane.trailingComponent"; String TABBED_PANE_TRAILING_COMPONENT = "JTabbedPane.trailingComponent";
//---- JTextField --------------------------------------------------------- //---- JTextField ---------------------------------------------------------
/** /**
@@ -1088,6 +1128,7 @@ public interface FlatClientProperties
*/ */
String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"; String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback";
//---- JToggleButton ------------------------------------------------------ //---- JToggleButton ------------------------------------------------------
/** /**
@@ -1129,6 +1170,7 @@ public interface FlatClientProperties
*/ */
String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"; String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground";
//---- JTree -------------------------------------------------------------- //---- JTree --------------------------------------------------------------
/** /**
@@ -1148,6 +1190,7 @@ public interface FlatClientProperties
*/ */
String TREE_PAINT_SELECTION = "JTree.paintSelection"; String TREE_PAINT_SELECTION = "JTree.paintSelection";
//---- helper methods ----------------------------------------------------- //---- helper methods -----------------------------------------------------
/** /**

View File

@@ -27,8 +27,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StreamTokenizer; import java.io.StreamTokenizer;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@@ -548,7 +552,7 @@ class UIDefaultsLoader
case INTEGERORFLOAT:return parseIntegerOrFloat( value ); case INTEGERORFLOAT:return parseIntegerOrFloat( value );
case FLOAT: return parseFloat( value ); case FLOAT: return parseFloat( value );
case BORDER: return parseBorder( value, resolver, addonClassLoaders ); case BORDER: return parseBorder( value, resolver, addonClassLoaders );
case ICON: return parseInstance( value, addonClassLoaders ); case ICON: return parseInstance( value, resolver, addonClassLoaders );
case INSETS: return parseInsets( value ); case INSETS: return parseInsets( value );
case DIMENSION: return parseDimension( value ); case DIMENSION: return parseDimension( value );
case COLOR: return parseColorOrFunction( value, resolver ); case COLOR: return parseColorOrFunction( value, resolver );
@@ -557,7 +561,7 @@ class UIDefaultsLoader
case SCALEDFLOAT: return parseScaledFloat( value ); case SCALEDFLOAT: return parseScaledFloat( value );
case SCALEDINSETS: return parseScaledInsets( value ); case SCALEDINSETS: return parseScaledInsets( value );
case SCALEDDIMENSION:return parseScaledDimension( value ); case SCALEDDIMENSION:return parseScaledDimension( value );
case INSTANCE: return parseInstance( value, addonClassLoaders ); case INSTANCE: return parseInstance( value, resolver, addonClassLoaders );
case CLASS: return parseClass( value, addonClassLoaders ); case CLASS: return parseClass( value, addonClassLoaders );
case GRAYFILTER: return parseGrayFilter( value ); case GRAYFILTER: return parseGrayFilter( value );
case UNKNOWN: case UNKNOWN:
@@ -623,7 +627,7 @@ class UIDefaultsLoader
throws IllegalArgumentException throws IllegalArgumentException
{ {
if( value.indexOf( ',' ) >= 0 ) { if( value.indexOf( ',' ) >= 0 ) {
// top,left,bottom,right[,lineColor[,lineThickness[,arc]]] // Syntax: top,left,bottom,right[,lineColor[,lineThickness[,arc]]]
List<String> parts = splitFunctionParams( value, ',' ); List<String> parts = splitFunctionParams( value, ',' );
Insets insets = parseInsets( value ); Insets insets = parseInsets( value );
ColorUIResource lineColor = (parts.size() >= 5) ColorUIResource lineColor = (parts.size() >= 5)
@@ -638,12 +642,28 @@ class UIDefaultsLoader
: new FlatEmptyBorder( insets ); : new FlatEmptyBorder( insets );
}; };
} else } else
return parseInstance( value, addonClassLoaders ); return parseInstance( value, resolver, addonClassLoaders );
} }
private static Object parseInstance( String value, List<ClassLoader> addonClassLoaders ) { private static Object parseInstance( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
return (LazyValue) t -> { return (LazyValue) t -> {
try { try {
if( value.indexOf( ',' ) >= 0 ) {
// Syntax: className,param1,param2,...
List<String> parts = splitFunctionParams( value, ',' );
String className = parts.get( 0 );
Class<?> cls = findClass( className, addonClassLoaders );
Constructor<?>[] constructors = cls.getDeclaredConstructors();
Object result = invokeConstructorOrStaticMethod( constructors, parts, resolver );
if( result != null )
return result;
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + className
+ "': no constructor found for parameters '"
+ value.substring( value.indexOf( ',' + 1 ) ) + "'.", null );
return null;
} else
return findClass( value, addonClassLoaders ).getDeclaredConstructor().newInstance(); return findClass( value, addonClassLoaders ).getDeclaredConstructor().newInstance();
} catch( Exception ex ) { } catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + value + "'.", ex ); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + value + "'.", ex );
@@ -1466,6 +1486,86 @@ class UIDefaultsLoader
return strs; return strs;
} }
private static Object invokeConstructorOrStaticMethod( Executable[] constructorsOrMethods,
List<String> parts, Function<String, String> resolver )
throws Exception
{
// order constructors/methods by parameter types:
// - String parameters to the end
// - int before float parameters
constructorsOrMethods = constructorsOrMethods.clone();
Arrays.sort( constructorsOrMethods, (c1, c2) -> {
Class<?>[] ptypes1 = c1.getParameterTypes();
Class<?>[] ptypes2 = c2.getParameterTypes();
if( ptypes1.length != ptypes2.length )
return ptypes1.length - ptypes2.length;
for( int i = 0; i < ptypes1.length; i++ ) {
Class<?> pt1 = ptypes1[i];
Class<?> pt2 = ptypes2[i];
if( pt1 == pt2 )
continue;
// order methods with String parameters to the end
if( pt1 == String.class )
return 2;
if( pt2 == String.class )
return -2;
// order int before float
if( pt1 == int.class )
return -1;
if( pt2 == int.class )
return 1;
}
return 0;
} );
// search for best constructor/method for given parameter values
for( Executable cm : constructorsOrMethods ) {
if( cm.getParameterCount() != parts.size() - 1 )
continue;
Object[] params = parseMethodParams( cm.getParameterTypes(), parts, resolver );
if( params == null )
continue;
// invoke constructor or static method
if( cm instanceof Constructor )
return ((Constructor<?>)cm).newInstance( params );
else
return ((Method)cm).invoke( null, params );
}
return null;
}
private static Object[] parseMethodParams( Class<?>[] paramTypes, List<String> parts, Function<String, String> resolver ) {
Object[] params = new Object[paramTypes.length];
try {
for( int i = 0; i < params.length; i++ ) {
Class<?> paramType = paramTypes[i];
String paramValue = parts.get( i + 1 );
if( paramType == String.class )
params[i] = paramValue;
else if( paramType == boolean.class )
params[i] = parseBoolean( paramValue );
else if( paramType == int.class )
params[i] = parseInteger( paramValue );
else if( paramType == float.class )
params[i] = parseFloat( paramValue );
else if( paramType == Color.class )
params[i] = parseColorOrFunction( resolver.apply( paramValue ), resolver );
else
return null; // unsupported parameter type
}
} catch( IllegalArgumentException ex ) {
return null; // failed to parse parameter for expected parameter type
}
return params;
}
/** /**
* For use in LazyValue to get value for given key from UIManager and report error * 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. * if not found. If key is prefixed by '?', then no error is reported.

View File

@@ -21,7 +21,6 @@ import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
@@ -30,6 +29,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* Base class for window icons. * Base class for window icons.
* *
* @uiDefault TitlePane.buttonSize Dimension * @uiDefault TitlePane.buttonSize Dimension
* @uiDefault TitlePane.buttonSymbolHeight int
* @uiDefault TitlePane.buttonHoverBackground Color * @uiDefault TitlePane.buttonHoverBackground Color
* @uiDefault TitlePane.buttonPressedBackground Color * @uiDefault TitlePane.buttonPressedBackground Color
* *
@@ -38,17 +38,22 @@ import com.formdev.flatlaf.util.HiDPIUtils;
public abstract class FlatWindowAbstractIcon public abstract class FlatWindowAbstractIcon
extends FlatAbstractIcon extends FlatAbstractIcon
{ {
private final int symbolHeight;
private final Color hoverBackground; private final Color hoverBackground;
private final Color pressedBackground; private final Color pressedBackground;
public FlatWindowAbstractIcon() { /** @since 3.2 */
this( UIManager.getDimension( "TitlePane.buttonSize" ), protected FlatWindowAbstractIcon( String windowStyle ) {
UIManager.getColor( "TitlePane.buttonHoverBackground" ), this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
UIManager.getColor( "TitlePane.buttonPressedBackground" ) ); FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ) );
} }
public FlatWindowAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) { /** @since 3.2 */
protected FlatWindowAbstractIcon( Dimension size, int symbolHeight, Color hoverBackground, Color pressedBackground ) {
super( size.width, size.height, null ); super( size.width, size.height, null );
this.symbolHeight = symbolHeight;
this.hoverBackground = hoverBackground; this.hoverBackground = hoverBackground;
this.pressedBackground = pressedBackground; this.pressedBackground = pressedBackground;
} }
@@ -80,4 +85,9 @@ public abstract class FlatWindowAbstractIcon
protected Color getForeground( Component c ) { protected Color getForeground( Component c ) {
return c.getForeground(); return c.getForeground();
} }
/** @since 3.2 */
protected int getSymbolHeight() {
return symbolHeight;
}
} }

View File

@@ -21,8 +21,8 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
/** /**
@@ -38,18 +38,27 @@ import com.formdev.flatlaf.util.SystemInfo;
public class FlatWindowCloseIcon public class FlatWindowCloseIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
private final Color hoverForeground = UIManager.getColor( "TitlePane.closeHoverForeground" ); private final Color hoverForeground;
private final Color pressedForeground = UIManager.getColor( "TitlePane.closePressedForeground" ); private final Color pressedForeground;
public FlatWindowCloseIcon() { public FlatWindowCloseIcon() {
super( UIManager.getDimension( "TitlePane.buttonSize" ), this( null );
UIManager.getColor( "TitlePane.closeHoverBackground" ), }
UIManager.getColor( "TitlePane.closePressedBackground" ) );
/** @since 3.2 */
public FlatWindowCloseIcon( String windowStyle ) {
super( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
FlatUIUtils.getSubUIColor( "TitlePane.closeHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ) );
hoverForeground = FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle );
pressedForeground = FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
int ix2 = ix + iwh - 1; int ix2 = ix + iwh - 1;

View File

@@ -27,11 +27,17 @@ public class FlatWindowIconifyIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowIconifyIcon() { public FlatWindowIconifyIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowIconifyIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iw = (int) (10 * scaleFactor); int iw = (int) (getSymbolHeight() * scaleFactor);
int ih = (int) scaleFactor; int ih = (int) scaleFactor;
int ix = x + ((width - iw) / 2); int ix = x + ((width - iw) / 2);
int iy = y + ((height - ih) / 2); int iy = y + ((height - ih) / 2);

View File

@@ -29,11 +29,17 @@ public class FlatWindowMaximizeIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowMaximizeIcon() { public FlatWindowMaximizeIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowMaximizeIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;

View File

@@ -32,18 +32,24 @@ public class FlatWindowRestoreIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowRestoreIcon() { public FlatWindowRestoreIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowRestoreIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 ); int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int arcOuter = (int) (arc + (1.5 * scaleFactor)); int arcOuter = (int) (arc + (1.5 * scaleFactor));
int rwh = (int) (8 * scaleFactor); int rwh = (int) ((getSymbolHeight() - 2) * scaleFactor);
int ro2 = iwh - rwh; int ro2 = iwh - rwh;
// upper-right rectangle // upper-right rectangle

View File

@@ -23,6 +23,7 @@ import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.IllegalComponentStateException;
import java.awt.Insets; import java.awt.Insets;
import java.awt.LayoutManager; import java.awt.LayoutManager;
import java.awt.LayoutManager2; import java.awt.LayoutManager2;
@@ -366,6 +367,11 @@ public class FlatRootPaneUI
case FlatClientProperties.GLASS_PANE_FULL_HEIGHT: case FlatClientProperties.GLASS_PANE_FULL_HEIGHT:
rootPane.revalidate(); rootPane.revalidate();
break; break;
case FlatClientProperties.WINDOW_STYLE:
if( rootPane.isDisplayable() )
throw new IllegalComponentStateException( "The client property 'Window.style' must be set before the window becomes displayable." );
break;
} }
} }

View File

@@ -97,6 +97,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean * @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.showIconBesideTitle boolean * @uiDefault TitlePane.showIconBesideTitle boolean
* @uiDefault TitlePane.menuBarTitleGap int * @uiDefault TitlePane.menuBarTitleGap int
* @uiDefault TitlePane.menuBarTitleMinimumGap int
* @uiDefault TitlePane.menuBarResizeHeight int * @uiDefault TitlePane.menuBarResizeHeight int
* @uiDefault TitlePane.closeIcon Icon * @uiDefault TitlePane.closeIcon Icon
* @uiDefault TitlePane.iconifyIcon Icon * @uiDefault TitlePane.iconifyIcon Icon
@@ -110,29 +111,30 @@ public class FlatTitlePane
{ {
private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles"; private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" ); /** @since 2.5 */ protected final Font titleFont;
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" ); protected final Color activeBackground;
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" ); protected final Color inactiveBackground;
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" ); protected final Color activeForeground;
protected final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" ); protected final Color inactiveForeground;
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" ); protected final Color embeddedForeground;
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" ); protected final Color borderColor;
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true ); /** @since 2 */ protected final boolean showIcon;
/** @since 2.5 */ protected final boolean showIconInDialogs = FlatUIUtils.getUIBoolean( "TitlePane.showIconInDialogs", true ); /** @since 2.5 */ protected final boolean showIconInDialogs;
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 ); /** @since 2 */ protected final int noIconLeftGap;
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" ); protected final Dimension iconSize;
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 ); /** @since 2.4 */ protected final int titleMinimumWidth;
/** @since 2.4 */ protected final int buttonMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.buttonMinimumWidth", 30 ); /** @since 2.4 */ protected final int buttonMinimumWidth;
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" ); protected final int buttonMaximizedHeight;
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" ); protected final boolean centerTitle;
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true ); protected final boolean centerTitleIfMenuBarEmbedded;
/** @since 2.4 */ protected final boolean showIconBesideTitle = UIManager.getBoolean( "TitlePane.showIconBesideTitle" ); /** @since 2.4 */ protected final boolean showIconBesideTitle;
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 40 ); protected final int menuBarTitleGap;
/** @since 2.4 */ protected final int menuBarTitleMinimumGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleMinimumGap", 12 ); /** @since 2.4 */ protected final int menuBarTitleMinimumGap;
/** @since 2.4 */ protected final int menuBarResizeHeight = FlatUIUtils.getUIInt( "TitlePane.menuBarResizeHeight", 4 ); /** @since 2.4 */ protected final int menuBarResizeHeight;
protected final JRootPane rootPane; protected final JRootPane rootPane;
protected final String windowStyle;
protected JPanel leftPanel; protected JPanel leftPanel;
protected JLabel iconLabel; protected JLabel iconLabel;
@@ -151,6 +153,34 @@ public class FlatTitlePane
public FlatTitlePane( JRootPane rootPane ) { public FlatTitlePane( JRootPane rootPane ) {
this.rootPane = rootPane; this.rootPane = rootPane;
Window w = SwingUtilities.getWindowAncestor( rootPane );
String defaultWindowStyle = (w != null && w.getType() == Window.Type.UTILITY) ? WINDOW_STYLE_SMALL : null;
windowStyle = clientProperty( rootPane, WINDOW_STYLE, defaultWindowStyle, String.class );
titleFont = FlatUIUtils.getSubUIFont( "TitlePane.font", windowStyle );
activeBackground = FlatUIUtils.getSubUIColor( "TitlePane.background", windowStyle );
inactiveBackground = FlatUIUtils.getSubUIColor( "TitlePane.inactiveBackground", windowStyle );
activeForeground = FlatUIUtils.getSubUIColor( "TitlePane.foreground", windowStyle );
inactiveForeground = FlatUIUtils.getSubUIColor( "TitlePane.inactiveForeground", windowStyle );
embeddedForeground = FlatUIUtils.getSubUIColor( "TitlePane.embeddedForeground", windowStyle );
// not using windowStyle here because TitlePane.borderColor is also used in FlatRootPaneUI
borderColor = UIManager.getColor( "TitlePane.borderColor" );
showIcon = FlatUIUtils.getSubUIBoolean( "TitlePane.showIcon", windowStyle, true );
showIconInDialogs = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconInDialogs", windowStyle, true );
noIconLeftGap = FlatUIUtils.getSubUIInt( "TitlePane.noIconLeftGap", windowStyle, 8 );
iconSize = FlatUIUtils.getSubUIDimension( "TitlePane.iconSize", windowStyle );
titleMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.titleMinimumWidth", windowStyle, 60 );
buttonMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.buttonMinimumWidth", windowStyle, 30 );
buttonMaximizedHeight = FlatUIUtils.getSubUIInt( "TitlePane.buttonMaximizedHeight", windowStyle, 0 );
centerTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitle", windowStyle, false );
centerTitleIfMenuBarEmbedded = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", windowStyle, true );
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
menuBarTitleGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleGap", windowStyle, 40 );
menuBarTitleMinimumGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleMinimumGap", windowStyle, 12 );
menuBarResizeHeight = FlatUIUtils.getSubUIInt( "TitlePane.menuBarResizeHeight", windowStyle, 4 );
handler = createHandler(); handler = createHandler();
setBorder( createTitlePaneBorder() ); setBorder( createTitlePaneBorder() );
@@ -183,8 +213,8 @@ public class FlatTitlePane
setUI( new FlatTitleLabelUI() ); setUI( new FlatTitleLabelUI() );
} }
}; };
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) ); iconLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle ) ) );
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) ); titleLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle ) ) );
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) ); leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
leftPanel.setOpaque( false ); leftPanel.setOpaque( false );
@@ -311,7 +341,7 @@ public class FlatTitlePane
} }
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) { protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
JButton button = new JButton( UIManager.getIcon( iconKey ) ) { JButton button = new JButton( FlatUIUtils.getSubUIIcon( iconKey, windowStyle ) ) {
@Override @Override
public Dimension getMinimumSize() { public Dimension getMinimumSize() {
// allow the button to shrink if space is rare // allow the button to shrink if space is rare

View File

@@ -39,10 +39,12 @@ import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JToolBar; import javax.swing.JToolBar;
import javax.swing.LayoutFocusTraversalPolicy; import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.RootPaneContainer;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI; import javax.swing.plaf.basic.BasicToolBarUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -156,6 +158,13 @@ public class FlatToolBarUI
} }
} }
@Override
protected RootPaneContainer createFloatingWindow( JToolBar toolbar ) {
RootPaneContainer floatingWindow = super.createFloatingWindow( toolbar );
floatingWindow.getRootPane().putClientProperty( FlatClientProperties.WINDOW_STYLE, FlatClientProperties.WINDOW_STYLE_SMALL );
return floatingWindow;
}
@Override @Override
protected ContainerListener createToolBarContListener() { protected ContainerListener createToolBarContListener() {
return new ToolBarContListener() { return new ToolBarContListener() {

View File

@@ -46,6 +46,7 @@ import java.util.IdentityHashMap;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
@@ -166,6 +167,88 @@ public class FlatUIUtils
return defaultValue; return defaultValue;
} }
/** @since 3.2 */
public static Color getSubUIColor( String key, String subKey ) {
if( subKey != null ) {
Color value = UIManager.getColor( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getColor( key );
}
/** @since 3.2 */
public static boolean getSubUIBoolean( String key, String subKey, boolean defaultValue ) {
if( subKey != null ) {
Object value = UIManager.get( buildSubKey( key, subKey ) );
if( value instanceof Boolean )
return (Boolean) value;
}
return getUIBoolean( key, defaultValue );
}
/** @since 3.2 */
public static int getSubUIInt( String key, String subKey, int defaultValue ) {
if( subKey != null ) {
Object value = UIManager.get( buildSubKey( key, subKey ) );
if( value instanceof Integer )
return (Integer) value;
}
return getUIInt( key, defaultValue );
}
/** @since 3.2 */
public static Insets getSubUIInsets( String key, String subKey ) {
if( subKey != null ) {
Insets value = UIManager.getInsets( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getInsets( key );
}
/** @since 3.2 */
public static Dimension getSubUIDimension( String key, String subKey ) {
if( subKey != null ) {
Dimension value = UIManager.getDimension( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getDimension( key );
}
/** @since 3.2 */
public static Icon getSubUIIcon( String key, String subKey ) {
if( subKey != null ) {
Icon value = UIManager.getIcon( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getIcon( key );
}
/** @since 3.2 */
public static Font getSubUIFont( String key, String subKey ) {
if( subKey != null ) {
Font value = UIManager.getFont( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getFont( key );
}
/**
* Inserts {@code subKey} at last dot in {@code key}.
* <p>
* E.g. {@code buildSubKey( "TitlePane.font", "small" )} returns {@code "TitlePane.small.font"}.
*/
private static String buildSubKey( String key, String subKey ) {
int dot = key.lastIndexOf( '.' );
return (dot >= 0)
? key.substring( 0, dot ) + '.' + subKey + '.' + key.substring( dot + 1 )
: key;
}
/** @since 1.1.2 */ /** @since 1.1.2 */
public static boolean getBoolean( JComponent c, String systemPropertyKey, public static boolean getBoolean( JComponent c, String systemPropertyKey,
String clientPropertyKey, String uiKey, boolean defaultValue ) String clientPropertyKey, String uiKey, boolean defaultValue )

View File

@@ -808,6 +808,7 @@ TitlePane.titleMinimumWidth = 60
TitlePane.buttonSize = 44,30 TitlePane.buttonSize = 44,30
TitlePane.buttonMinimumWidth = 30 TitlePane.buttonMinimumWidth = 30
TitlePane.buttonMaximizedHeight = 22 TitlePane.buttonMaximizedHeight = 22
TitlePane.buttonSymbolHeight = 10
TitlePane.centerTitle = false TitlePane.centerTitle = false
TitlePane.centerTitleIfMenuBarEmbedded = true TitlePane.centerTitleIfMenuBarEmbedded = true
TitlePane.showIconBesideTitle = false TitlePane.showIconBesideTitle = false
@@ -829,6 +830,16 @@ TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,90%)
TitlePane.closeHoverForeground = #fff TitlePane.closeHoverForeground = #fff
TitlePane.closePressedForeground = #fff TitlePane.closePressedForeground = #fff
# window style "small"
TitlePane.small.font = -1
TitlePane.small.showIcon = false
TitlePane.small.buttonSize = 30,20
TitlePane.small.buttonSymbolHeight = 8
TitlePane.small.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon, small
TitlePane.small.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon, small
TitlePane.small.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon, small
TitlePane.small.restoreIcon = com.formdev.flatlaf.icons.FlatWindowRestoreIcon, small
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Insets; import java.awt.Insets;
import java.util.Objects;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.UIDefaults.ActiveValue; import javax.swing.UIDefaults.ActiveValue;
@@ -153,4 +154,102 @@ public class TestUIDefaultsLoader
new Font( name, style, size ), new Font( name, style, size ),
((ActiveValue)UIDefaultsLoader.parseValue( "dummyFont", actualStyle, null )).createValue( null ) ); ((ActiveValue)UIDefaultsLoader.parseValue( "dummyFont", actualStyle, null )).createValue( null ) );
} }
@Test
void parseInstance() {
String className = TestInstance.class.getName();
assertEquals( new TestInstance(), ((LazyValue)UIDefaultsLoader.parseValue( "dummyIcon", className, null )).createValue( null ) );
assertInstanceEquals( new TestInstance(), null );
assertInstanceEquals( new TestInstance( "some string" ), "some string" );
assertInstanceEquals( new TestInstance( false ), "false" );
assertInstanceEquals( new TestInstance( true ), "true" );
assertInstanceEquals( new TestInstance( 123 ), "123" );
assertInstanceEquals( new TestInstance( 123.456f ), "123.456" );
assertInstanceEquals( new TestInstance( Color.red ), "#f00" );
assertInstanceEquals( new TestInstance( "some string", true ), "some string, true" );
assertInstanceEquals( new TestInstance( "some string", true, 123 ), "some string, true, 123" );
assertInstanceEquals( new TestInstance( "some string", 123, true ), "some string, 123, true" );
assertInstanceEquals( new TestInstance( "some string", 123.456f, true ), "some string, 123.456, true" );
assertInstanceEquals( new TestInstance( 123, "some string" ), "123, some string" );
}
private void assertInstanceEquals( TestInstance expected, String params ) {
String value = TestInstance.class.getName() + (params != null ? "," + params : "");
assertEquals( expected, ((LazyValue)UIDefaultsLoader.parseValue( "dummyIcon", value, null )).createValue( null ) );
}
//---- class TestInstance -------------------------------------------------
public static class TestInstance
{
private String s;
private boolean b;
private int i;
private float f;
private Color color;
public TestInstance() {
}
public TestInstance( String s ) {
this.s = s;
}
public TestInstance( boolean b ) {
this.b = b;
}
public TestInstance( int i ) {
this.i = i;
}
public TestInstance( float f ) {
this.f = f;
}
public TestInstance( Color color ) {
this.color = color;
}
public TestInstance( String s, boolean b ) {
this.s = s;
this.b = b;
}
public TestInstance( String s, boolean b, int i ) {
this.s = s;
this.b = b;
this.i = i;
}
public TestInstance( String s, int i, boolean b ) {
this.s = s;
this.b = b;
this.i = i;
}
public TestInstance( String s, float f, boolean b ) {
this.s = s;
this.b = b;
this.f = f;
}
protected TestInstance( int i, String s ) {
this.s = s;
this.i = i;
}
@Override
public boolean equals( Object obj ) {
if( !(obj instanceof TestInstance) )
return false;
TestInstance inst = (TestInstance) obj;
return Objects.equals( s, inst.s ) &&
b == inst.b &&
i == inst.i &&
f == inst.f &&
Objects.equals( color, inst.color );
}
}
} }

View File

@@ -1238,6 +1238,7 @@ TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) TitlePane.buttonPressedBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
@@ -1264,6 +1265,14 @@ TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWin
TitlePane.showIcon true TitlePane.showIcon true
TitlePane.showIconBesideTitle false TitlePane.showIconBesideTitle false
TitlePane.showIconInDialogs true TitlePane.showIconInDialogs true
TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.small.buttonSymbolHeight 8
TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.small.showIcon false
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.titleMinimumWidth 60 TitlePane.titleMinimumWidth 60
TitlePane.unifiedBackground true TitlePane.unifiedBackground true

View File

@@ -1243,6 +1243,7 @@ TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #ebebeb HSL 0 0 92 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse) TitlePane.buttonPressedBackground #ebebeb HSL 0 0 92 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
@@ -1269,6 +1270,14 @@ TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWin
TitlePane.showIcon true TitlePane.showIcon true
TitlePane.showIconBesideTitle false TitlePane.showIconBesideTitle false
TitlePane.showIconInDialogs true TitlePane.showIconInDialogs true
TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.small.buttonSymbolHeight 8
TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.small.showIcon false
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.titleMinimumWidth 60 TitlePane.titleMinimumWidth 60
TitlePane.unifiedBackground true TitlePane.unifiedBackground true

View File

@@ -1248,6 +1248,7 @@ TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #4c4c4c HSL 0 0 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) TitlePane.buttonPressedBackground #4c4c4c HSL 0 0 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
@@ -1274,6 +1275,14 @@ TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWin
TitlePane.showIcon true TitlePane.showIcon true
TitlePane.showIconBesideTitle false TitlePane.showIconBesideTitle false
TitlePane.showIconInDialogs true TitlePane.showIconInDialogs true
TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.small.buttonSymbolHeight 8
TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.small.showIcon false
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.titleMinimumWidth 60 TitlePane.titleMinimumWidth 60
TitlePane.unifiedBackground true TitlePane.unifiedBackground true

View File

@@ -1252,6 +1252,7 @@ TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #d8d8d8 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse) TitlePane.buttonPressedBackground #d8d8d8 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
@@ -1278,6 +1279,14 @@ TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWin
TitlePane.showIcon true TitlePane.showIcon true
TitlePane.showIconBesideTitle false TitlePane.showIconBesideTitle false
TitlePane.showIconInDialogs true TitlePane.showIconInDialogs true
TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.small.buttonSymbolHeight 8
TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.small.showIcon false
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.titleMinimumWidth 60 TitlePane.titleMinimumWidth 60
TitlePane.unifiedBackground true TitlePane.unifiedBackground true

View File

@@ -1278,6 +1278,7 @@ TitlePane.borderColor #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
@@ -1303,6 +1304,14 @@ TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWin
TitlePane.showIcon true TitlePane.showIcon true
TitlePane.showIconBesideTitle false TitlePane.showIconBesideTitle false
TitlePane.showIconInDialogs true TitlePane.showIconInDialogs true
TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.small.buttonSymbolHeight 8
TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
TitlePane.small.showIcon false
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.titleMinimumWidth 60 TitlePane.titleMinimumWidth 60
TitlePane.unifiedBackground true TitlePane.unifiedBackground true

View File

@@ -361,6 +361,7 @@ debug*/
private void openDialog() { private void openDialog() {
Window owner = SwingUtilities.windowForComponent( this ); Window owner = SwingUtilities.windowForComponent( this );
JDialog dialog = new JDialog( owner, "Dialog", ModalityType.DOCUMENT_MODAL ); JDialog dialog = new JDialog( owner, "Dialog", ModalityType.DOCUMENT_MODAL );
initWindowType( dialog );
dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE ); dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
dialog.add( new FlatWindowDecorationsTest() ); dialog.add( new FlatWindowDecorationsTest() );
dialog.pack(); dialog.pack();
@@ -371,6 +372,7 @@ debug*/
private void openFrame() { private void openFrame() {
FlatWindowDecorationsTest comp = new FlatWindowDecorationsTest(); FlatWindowDecorationsTest comp = new FlatWindowDecorationsTest();
JFrame frame = new JFrame( "Frame" ); JFrame frame = new JFrame( "Frame" );
initWindowType( frame );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.add( comp ); frame.add( comp );
frame.setJMenuBar( comp.menuBar ); frame.setJMenuBar( comp.menuBar );
@@ -379,6 +381,13 @@ debug*/
frame.setVisible( true ); frame.setVisible( true );
} }
private void initWindowType( Window window ) {
if( typeUtilityRadioButton.isSelected() )
window.setType( Window.Type.UTILITY );
else if( typeSmallRadioButton.isSelected() )
((RootPaneContainer)window).getRootPane().putClientProperty( "Window.style", "small" );
}
private void decorationStyleChanged() { private void decorationStyleChanged() {
int style; int style;
if( styleFrameRadioButton.isSelected() ) if( styleFrameRadioButton.isSelected() )
@@ -536,6 +545,9 @@ debug*/
colorizeMenusCheckBox = new JCheckBox(); colorizeMenusCheckBox = new JCheckBox();
JButton openDialogButton = new JButton(); JButton openDialogButton = new JButton();
JButton openFrameButton = new JButton(); JButton openFrameButton = new JButton();
typeNormalRadioButton = new JRadioButton();
typeUtilityRadioButton = new JRadioButton();
typeSmallRadioButton = new JRadioButton();
menuBar = new JMenuBar(); menuBar = new JMenuBar();
JMenu fileMenu = new JMenu(); JMenu fileMenu = new JMenu();
JMenuItem newMenuItem = new JMenuItem(); JMenuItem newMenuItem = new JMenuItem();
@@ -567,7 +579,7 @@ debug*/
setLayout(new MigLayout( setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3", "ltr,insets dialog,hidemode 3",
// columns // columns
"[fill]" + "[left]" +
"[fill]" + "[fill]" +
"[fill]" + "[fill]" +
"[fill]", "[fill]",
@@ -617,7 +629,7 @@ debug*/
maximizedBoundsCheckBox.addActionListener(e -> maximizedBoundsChanged()); maximizedBoundsCheckBox.addActionListener(e -> maximizedBoundsChanged());
panel7.add(maximizedBoundsCheckBox, "cell 0 4"); panel7.add(maximizedBoundsCheckBox, "cell 0 4");
} }
add(panel7, "cell 0 0"); add(panel7, "cell 0 0,growx");
//======== panel4 ======== //======== panel4 ========
{ {
@@ -818,7 +830,7 @@ debug*/
styleFileChooserRadioButton.addActionListener(e -> decorationStyleChanged()); styleFileChooserRadioButton.addActionListener(e -> decorationStyleChanged());
panel1.add(styleFileChooserRadioButton, "cell 0 8"); panel1.add(styleFileChooserRadioButton, "cell 0 8");
} }
add(panel1, "cell 0 1"); add(panel1, "cell 0 1,growx");
//======== panel2 ======== //======== panel2 ========
{ {
@@ -900,13 +912,26 @@ debug*/
//---- openDialogButton ---- //---- openDialogButton ----
openDialogButton.setText("Open Dialog"); openDialogButton.setText("Open Dialog");
openDialogButton.addActionListener(e -> openDialog()); openDialogButton.addActionListener(e -> openDialog());
add(openDialogButton, "cell 0 2"); add(openDialogButton, "cell 0 2 3 1");
//---- openFrameButton ---- //---- openFrameButton ----
openFrameButton.setText("Open Frame"); openFrameButton.setText("Open Frame");
openFrameButton.setMnemonic('A'); openFrameButton.setMnemonic('A');
openFrameButton.addActionListener(e -> openFrame()); openFrameButton.addActionListener(e -> openFrame());
add(openFrameButton, "cell 0 2"); add(openFrameButton, "cell 0 2 3 1");
//---- typeNormalRadioButton ----
typeNormalRadioButton.setText("Normal");
typeNormalRadioButton.setSelected(true);
add(typeNormalRadioButton, "cell 0 2 3 1");
//---- typeUtilityRadioButton ----
typeUtilityRadioButton.setText("Utility");
add(typeUtilityRadioButton, "cell 0 2 3 1");
//---- typeSmallRadioButton ----
typeSmallRadioButton.setText("Small");
add(typeSmallRadioButton, "cell 0 2 3 1");
//======== menuBar ======== //======== menuBar ========
{ {
@@ -1095,6 +1120,12 @@ debug*/
iconButtonGroup.add(iconTestRandomRadioButton); iconButtonGroup.add(iconTestRandomRadioButton);
iconButtonGroup.add(iconTestMRIRadioButton); iconButtonGroup.add(iconTestMRIRadioButton);
iconButtonGroup.add(iconTestDynMRIRadioButton); iconButtonGroup.add(iconTestDynMRIRadioButton);
//---- typeButtonGroup ----
ButtonGroup typeButtonGroup = new ButtonGroup();
typeButtonGroup.add(typeNormalRadioButton);
typeButtonGroup.add(typeUtilityRadioButton);
typeButtonGroup.add(typeSmallRadioButton);
// JFormDesigner - End of component initialization //GEN-END:initComponents // JFormDesigner - End of component initialization //GEN-END:initComponents
} }
@@ -1138,6 +1169,9 @@ debug*/
private JCheckBox colorizeTitleBarCheckBox; private JCheckBox colorizeTitleBarCheckBox;
private JCheckBox colorizeMenuBarCheckBox; private JCheckBox colorizeMenuBarCheckBox;
private JCheckBox colorizeMenusCheckBox; private JCheckBox colorizeMenusCheckBox;
private JRadioButton typeNormalRadioButton;
private JRadioButton typeUtilityRadioButton;
private JRadioButton typeSmallRadioButton;
private JMenuBar menuBar; private JMenuBar menuBar;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.2" encoding: "UTF-8" JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -8,7 +8,7 @@ new FormModel {
} }
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3" "$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][fill][fill]" "$columnConstraints": "[left][fill][fill][fill]"
"$rowConstraints": "[fill][fill][]" "$rowConstraints": "[fill][fill][]"
} ) { } ) {
name: "this" name: "this"
@@ -72,7 +72,7 @@ new FormModel {
"value": "cell 0 4" "value": "cell 0 4"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0" "value": "cell 0 0,growx"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,hidemode 3,gap 0 0" "$layoutConstraints": "ltr,hidemode 3,gap 0 0"
@@ -378,7 +378,7 @@ new FormModel {
"value": "cell 0 8" "value": "cell 0 8"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1" "value": "cell 0 1,growx"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[left]" "$columnConstraints": "[left]"
@@ -501,7 +501,7 @@ new FormModel {
"text": "Open Dialog" "text": "Open Dialog"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openDialog", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openDialog", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2" "value": "cell 0 2 3 1"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "openFrameButton" name: "openFrameButton"
@@ -509,7 +509,38 @@ new FormModel {
"mnemonic": 65 "mnemonic": 65
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openFrame", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openFrame", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2" "value": "cell 0 2 3 1"
} )
add( new FormComponent( "javax.swing.JRadioButton" ) {
name: "typeNormalRadioButton"
"text": "Normal"
"selected": true
"$buttonGroup": new FormReference( "typeButtonGroup" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1"
} )
add( new FormComponent( "javax.swing.JRadioButton" ) {
name: "typeUtilityRadioButton"
"text": "Utility"
"$buttonGroup": new FormReference( "typeButtonGroup" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1"
} )
add( new FormComponent( "javax.swing.JRadioButton" ) {
name: "typeSmallRadioButton"
"text": "Small"
"$buttonGroup": new FormReference( "typeButtonGroup" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
@@ -692,5 +723,10 @@ new FormModel {
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 615 ) "location": new java.awt.Point( 0, 615 )
} ) } )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "typeButtonGroup"
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 669 )
} )
} }
} }

View File

@@ -1012,6 +1012,7 @@ TitlePane.buttonMaximizedHeight
TitlePane.buttonMinimumWidth TitlePane.buttonMinimumWidth
TitlePane.buttonPressedBackground TitlePane.buttonPressedBackground
TitlePane.buttonSize TitlePane.buttonSize
TitlePane.buttonSymbolHeight
TitlePane.centerTitle TitlePane.centerTitle
TitlePane.centerTitleIfMenuBarEmbedded TitlePane.centerTitleIfMenuBarEmbedded
TitlePane.closeHoverBackground TitlePane.closeHoverBackground
@@ -1038,6 +1039,40 @@ TitlePane.restoreIcon
TitlePane.showIcon TitlePane.showIcon
TitlePane.showIconBesideTitle TitlePane.showIconBesideTitle
TitlePane.showIconInDialogs TitlePane.showIconInDialogs
TitlePane.small.background
TitlePane.small.buttonHoverBackground
TitlePane.small.buttonMaximizedHeight
TitlePane.small.buttonMinimumWidth
TitlePane.small.buttonPressedBackground
TitlePane.small.buttonSize
TitlePane.small.buttonSymbolHeight
TitlePane.small.centerTitle
TitlePane.small.centerTitleIfMenuBarEmbedded
TitlePane.small.closeHoverBackground
TitlePane.small.closeHoverForeground
TitlePane.small.closeIcon
TitlePane.small.closePressedBackground
TitlePane.small.closePressedForeground
TitlePane.small.embeddedForeground
TitlePane.small.font
TitlePane.small.foreground
TitlePane.small.icon
TitlePane.small.iconMargins
TitlePane.small.iconSize
TitlePane.small.iconifyIcon
TitlePane.small.inactiveBackground
TitlePane.small.inactiveForeground
TitlePane.small.maximizeIcon
TitlePane.small.menuBarResizeHeight
TitlePane.small.menuBarTitleGap
TitlePane.small.menuBarTitleMinimumGap
TitlePane.small.noIconLeftGap
TitlePane.small.restoreIcon
TitlePane.small.showIcon
TitlePane.small.showIconBesideTitle
TitlePane.small.showIconInDialogs
TitlePane.small.titleMargins
TitlePane.small.titleMinimumWidth
TitlePane.titleMargins TitlePane.titleMargins
TitlePane.titleMinimumWidth TitlePane.titleMinimumWidth
TitlePane.unifiedBackground TitlePane.unifiedBackground