mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f842530537 | ||
|
|
63077bbb19 | ||
|
|
4dad337377 | ||
|
|
10a965d765 | ||
|
|
3e9c9c9066 | ||
|
|
8b5a738e65 | ||
|
|
2c041dce3a | ||
|
|
ef151c68f4 | ||
|
|
52feaac92a | ||
|
|
cddbb3d7d4 | ||
|
|
42764550e6 | ||
|
|
6ee737b314 | ||
|
|
f460ef7685 | ||
|
|
9977bcb468 | ||
|
|
7437d984c7 | ||
|
|
5cd0b2403c | ||
|
|
a372da22f3 | ||
|
|
8b10d3ba5a | ||
|
|
a8b15c6a12 | ||
|
|
23bac7e5fd | ||
|
|
b82ee2ef61 | ||
|
|
b7761f4b71 | ||
|
|
f9a4f9771c | ||
|
|
d2acb2c98a | ||
|
|
d60bd5df14 | ||
|
|
73b6ca3762 | ||
|
|
6c18431a30 | ||
|
|
a49d20249f | ||
|
|
ad384acd57 | ||
|
|
69851b7f3a | ||
|
|
92b53bf0df | ||
|
|
93e0496fd2 | ||
|
|
5151951f46 | ||
|
|
58dbccec2d | ||
|
|
90de14d013 | ||
|
|
5f961618bf | ||
|
|
37c375e2fa | ||
|
|
1758c175ed | ||
|
|
96f2a02cfa | ||
|
|
96d4bda6c8 | ||
|
|
02cf6050a1 | ||
|
|
38cf32a2e9 | ||
|
|
2ae7589d14 | ||
|
|
bcb2e1f0a1 | ||
|
|
14932d3f07 | ||
|
|
c3b9dc397d | ||
|
|
58b653f55d | ||
|
|
1dcdc42dde | ||
|
|
58a0a16985 | ||
|
|
a117243f14 | ||
|
|
22411060be | ||
|
|
045263ae58 |
68
CHANGELOG.md
68
CHANGELOG.md
@@ -1,6 +1,72 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 2.4
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- Native window decorations (Windows 10/11 only):
|
||||||
|
- There is now a small area at top of the embedded menu bar to resize the
|
||||||
|
window.
|
||||||
|
- Improved window title bar layout for small window widths:
|
||||||
|
- Width of iconify/maximize/close buttons is reduced (if necessary) to give
|
||||||
|
more space to embedded menu bar and title.
|
||||||
|
- Window title now has a minimum width to always allow moving window
|
||||||
|
(click-and-drag on window title). Instead, embedded menu bar is made
|
||||||
|
smaller.
|
||||||
|
- Option to show window icon beside window title, if menu bar is embedded or
|
||||||
|
title is centered. Set UI value `TitlePane.showIconBesideTitle` to `true`.
|
||||||
|
- No longer reduce height of window title bar if it has an embedded menu bar
|
||||||
|
and is maximized.
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- ComboBox: Fixed vertical alignment of text in popup list with text in combo
|
||||||
|
box in IntelliJ/Darcula themes.
|
||||||
|
- Menus: Fixed application freeze under very special conditions (invoking
|
||||||
|
`FlatLaf.initialize()` twice in NetBeans GUI builder) and using menu that has
|
||||||
|
submenus. See
|
||||||
|
[NetBeans issue #4231](https://github.com/apache/netbeans/issues/4231#issuecomment-1179611682)
|
||||||
|
for details.
|
||||||
|
- MenuItem: Fixed sometimes wrapped HTML text on HiDPI screens on Windows.
|
||||||
|
- TableHeader: Fixed exception when changing table structure (e.g. removing
|
||||||
|
column) from a table header popup menu action. (issue #532)
|
||||||
|
- `HiDPIUtils.paintAtScale1x()` now supports rotated graphics. (issue #557)
|
||||||
|
- Typography: No longer use `Consolas` or `Courier New` as monospaced font on
|
||||||
|
Windows because they have bad vertically placement.
|
||||||
|
- Native window decorations (Windows 10/11 only):
|
||||||
|
- Do not center window title if embedded menu bar is empty or has no menus at
|
||||||
|
left side, but some components at right side. (issue #558)
|
||||||
|
- Do not use window decorations if system property `sun.java2d.opengl` is
|
||||||
|
`true` on Windows 10. (issue #540)
|
||||||
|
- Fixed missing top window border in dark themes if window drop shadows are
|
||||||
|
disabled in system settings. (issue #554; Windows 10 only)
|
||||||
|
- Right-to-left component orientation of title bar was lost when switching
|
||||||
|
theme.
|
||||||
|
|
||||||
|
|
||||||
|
## 2.3
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- FileChooser: Added (optional) shortcuts panel. On Windows it contains "Recent
|
||||||
|
Items", "Desktop", "Documents", "This PC" and "Network". On macOS and Linux it
|
||||||
|
is empty/hidden. (issue #100)
|
||||||
|
- Button and ToggleButton: Added missing foreground colors for hover, pressed,
|
||||||
|
focused and selected states. (issue #535)
|
||||||
|
- Table: Optionally paint alternating rows below table if table is smaller than
|
||||||
|
scroll pane. Set UI value `Table.paintOutsideAlternateRows` to `true`.
|
||||||
|
Requires that `Table.alternateRowColor` is set to a color. (issue #504)
|
||||||
|
- ToggleButton: Made the underline placement of tab-style toggle buttons
|
||||||
|
configurable. (PR #530; issue #529)
|
||||||
|
- Added spanish translation. (PR #525)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- IntelliJ Themes: Fixed `TitledBorder` text color in "Monokai Pro" theme.
|
||||||
|
(issue #524)
|
||||||
|
|
||||||
|
|
||||||
## 2.2
|
## 2.2
|
||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
@@ -141,7 +207,7 @@ FlatLaf Change Log
|
|||||||
- Possibility to hide window title bar icon (for single window set client
|
- Possibility to hide window title bar icon (for single window set client
|
||||||
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
|
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
|
||||||
value `TitlePane.showIcon` to `false`).
|
value `TitlePane.showIcon` to `false`).
|
||||||
- OptionPane: Hide window title bar icon by default. Can be be made visibly by
|
- OptionPane: Hide window title bar icon by default. Can be made visibly by
|
||||||
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
||||||
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
||||||
(issue #416)
|
(issue #416)
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val releaseVersion = "2.2"
|
val releaseVersion = "2.4"
|
||||||
val developmentVersion = "2.3-SNAPSHOT"
|
val developmentVersion = "2.5-SNAPSHOT"
|
||||||
|
|
||||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest.attributes( "Multi-Release" to "true" )
|
|
||||||
|
|
||||||
from( sourceSets["module-info"].output ) {
|
from( sourceSets["module-info"].output ) {
|
||||||
include( "module-info.class" )
|
include( "module-info.class" )
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 2.1
|
#Version 2.3
|
||||||
|
|
||||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||||
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
||||||
@@ -30,6 +30,9 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY = "JTextFiel
|
|||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"
|
||||||
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
|
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
|
||||||
fld public final static java.lang.String STYLE = "FlatLaf.style"
|
fld public final static java.lang.String STYLE = "FlatLaf.style"
|
||||||
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
|
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
|
||||||
@@ -72,6 +75,7 @@ fld public final static java.lang.String TABBED_PANE_TRAILING_COMPONENT = "JTabb
|
|||||||
fld public final static java.lang.String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"
|
fld public final static java.lang.String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"
|
||||||
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"
|
||||||
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"
|
||||||
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_PLACEMENT = "JToggleButton.tab.underlinePlacement"
|
||||||
fld public final static java.lang.String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"
|
fld public final static java.lang.String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"
|
||||||
fld public final static java.lang.String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent"
|
fld public final static java.lang.String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent"
|
||||||
fld public final static java.lang.String TEXT_FIELD_LEADING_ICON = "JTextField.leadingIcon"
|
fld public final static java.lang.String TEXT_FIELD_LEADING_ICON = "JTextField.leadingIcon"
|
||||||
@@ -662,6 +666,7 @@ CLSS public com.formdev.flatlaf.util.SystemInfo
|
|||||||
cons public init()
|
cons public init()
|
||||||
fld public final static boolean isAARCH64
|
fld public final static boolean isAARCH64
|
||||||
fld public final static boolean isJava_11_orLater
|
fld public final static boolean isJava_11_orLater
|
||||||
|
fld public final static boolean isJava_12_orLater
|
||||||
fld public final static boolean isJava_15_orLater
|
fld public final static boolean isJava_15_orLater
|
||||||
fld public final static boolean isJava_17_orLater
|
fld public final static boolean isJava_17_orLater
|
||||||
fld public final static boolean isJava_18_orLater
|
fld public final static boolean isJava_18_orLater
|
||||||
@@ -670,6 +675,7 @@ fld public final static boolean isJetBrainsJVM
|
|||||||
fld public final static boolean isJetBrainsJVM_11_orLater
|
fld public final static boolean isJetBrainsJVM_11_orLater
|
||||||
fld public final static boolean isKDE
|
fld public final static boolean isKDE
|
||||||
fld public final static boolean isLinux
|
fld public final static boolean isLinux
|
||||||
|
fld public final static boolean isMacFullWindowContentSupported
|
||||||
fld public final static boolean isMacOS
|
fld public final static boolean isMacOS
|
||||||
fld public final static boolean isMacOS_10_11_ElCapitan_orLater
|
fld public final static boolean isMacOS_10_11_ElCapitan_orLater
|
||||||
fld public final static boolean isMacOS_10_14_Mojave_orLater
|
fld public final static boolean isMacOS_10_14_Mojave_orLater
|
||||||
|
|||||||
@@ -992,7 +992,22 @@ public interface FlatClientProperties
|
|||||||
//---- JToggleButton ------------------------------------------------------
|
//---- JToggleButton ------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Height of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
* Placement of underline if toggle button type is {@link #BUTTON_TYPE_TAB}
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||||
|
* <strong>SupportedValues:</strong>
|
||||||
|
* {@link SwingConstants#BOTTOM} (default)
|
||||||
|
* {@link SwingConstants#TOP},
|
||||||
|
* {@link SwingConstants#LEFT} or
|
||||||
|
* {@link SwingConstants#RIGHT}
|
||||||
|
*
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
String TAB_BUTTON_UNDERLINE_PLACEMENT = "JToggleButton.tab.underlinePlacement";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thickness of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.Integer}
|
* <strong>Value type</strong> {@link java.lang.Integer}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
private PopupFactory oldPopupFactory;
|
private PopupFactory oldPopupFactory;
|
||||||
private MnemonicHandler mnemonicHandler;
|
private MnemonicHandler mnemonicHandler;
|
||||||
private SubMenuUsabilityHelper subMenuUsabilityHelper;
|
private boolean subMenuUsabilityHelperInstalled;
|
||||||
|
|
||||||
private Consumer<UIDefaults> postInitialization;
|
private Consumer<UIDefaults> postInitialization;
|
||||||
private List<Function<Object, Object>> uiDefaultsGetters;
|
private List<Function<Object, Object>> uiDefaultsGetters;
|
||||||
@@ -232,6 +232,15 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
// do not initialize if this is not the current look and feel
|
||||||
|
// This is only necessary for special Laf usage. E.g. in GUI builders,
|
||||||
|
// which may use multiple Lafs and may invoke this method directly.
|
||||||
|
// This avoids that listeners and factories are installed multiple times.
|
||||||
|
// In case of the NetBeans GUI builder, which does not invoke uninitialize(),
|
||||||
|
// this also avoids that listeners stay registered in the system.
|
||||||
|
if( UIManager.getLookAndFeel() != this )
|
||||||
|
return;
|
||||||
|
|
||||||
if( SystemInfo.isMacOS )
|
if( SystemInfo.isMacOS )
|
||||||
initializeAqua();
|
initializeAqua();
|
||||||
|
|
||||||
@@ -246,8 +255,7 @@ public abstract class FlatLaf
|
|||||||
mnemonicHandler.install();
|
mnemonicHandler.install();
|
||||||
|
|
||||||
// install submenu usability helper
|
// install submenu usability helper
|
||||||
subMenuUsabilityHelper = new SubMenuUsabilityHelper();
|
subMenuUsabilityHelperInstalled = SubMenuUsabilityHelper.install();
|
||||||
subMenuUsabilityHelper.install();
|
|
||||||
|
|
||||||
// listen to desktop property changes to update UI if system font or scaling changes
|
// listen to desktop property changes to update UI if system font or scaling changes
|
||||||
if( SystemInfo.isWindows ) {
|
if( SystemInfo.isWindows ) {
|
||||||
@@ -304,6 +312,10 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uninitialize() {
|
public void uninitialize() {
|
||||||
|
// do not uninitialize if this is not the current look and feel
|
||||||
|
if( UIManager.getLookAndFeel() != this )
|
||||||
|
return;
|
||||||
|
|
||||||
// remove desktop property listener
|
// remove desktop property listener
|
||||||
if( desktopPropertyListener != null ) {
|
if( desktopPropertyListener != null ) {
|
||||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
@@ -329,9 +341,9 @@ public abstract class FlatLaf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// uninstall submenu usability helper
|
// uninstall submenu usability helper
|
||||||
if( subMenuUsabilityHelper != null ) {
|
if( subMenuUsabilityHelperInstalled ) {
|
||||||
subMenuUsabilityHelper.uninstall();
|
SubMenuUsabilityHelper.uninstall();
|
||||||
subMenuUsabilityHelper = null;
|
subMenuUsabilityHelperInstalled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore default link color
|
// restore default link color
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ class SubMenuUsabilityHelper
|
|||||||
private static final String KEY_USE_SAFE_TRIANGLE = "Menu.useSafeTriangle";
|
private static final String KEY_USE_SAFE_TRIANGLE = "Menu.useSafeTriangle";
|
||||||
private static final String KEY_SHOW_SAFE_TRIANGLE = "FlatLaf.debug.menu.showSafeTriangle";
|
private static final String KEY_SHOW_SAFE_TRIANGLE = "FlatLaf.debug.menu.showSafeTriangle";
|
||||||
|
|
||||||
|
// Using a static field to ensure that there is only one instance in the system.
|
||||||
|
// Multiple instances would freeze the application.
|
||||||
|
// https://github.com/apache/netbeans/issues/4231#issuecomment-1179616607
|
||||||
|
private static SubMenuUsabilityHelper instance;
|
||||||
|
|
||||||
private SubMenuEventQueue subMenuEventQueue;
|
private SubMenuEventQueue subMenuEventQueue;
|
||||||
private SafeTrianglePainter safeTrianglePainter;
|
private SafeTrianglePainter safeTrianglePainter;
|
||||||
private boolean changePending;
|
private boolean changePending;
|
||||||
@@ -74,13 +79,22 @@ class SubMenuUsabilityHelper
|
|||||||
|
|
||||||
private Rectangle invokerBounds;
|
private Rectangle invokerBounds;
|
||||||
|
|
||||||
void install() {
|
static synchronized boolean install() {
|
||||||
MenuSelectionManager.defaultManager().addChangeListener( this );
|
if( instance != null )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
instance = new SubMenuUsabilityHelper();
|
||||||
|
MenuSelectionManager.defaultManager().addChangeListener( instance );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstall() {
|
static synchronized void uninstall() {
|
||||||
MenuSelectionManager.defaultManager().removeChangeListener( this );
|
if( instance == null )
|
||||||
uninstallEventQueue();
|
return;
|
||||||
|
|
||||||
|
MenuSelectionManager.defaultManager().removeChangeListener( instance );
|
||||||
|
instance.uninstallEventQueue();
|
||||||
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -466,6 +466,10 @@ class UIDefaultsLoader
|
|||||||
if( knownValueTypes == null ) {
|
if( knownValueTypes == null ) {
|
||||||
// create lazy
|
// create lazy
|
||||||
knownValueTypes = new HashMap<>();
|
knownValueTypes = new HashMap<>();
|
||||||
|
// system colors
|
||||||
|
knownValueTypes.put( "activeCaptionBorder", ValueType.COLOR );
|
||||||
|
knownValueTypes.put( "inactiveCaptionBorder", ValueType.COLOR );
|
||||||
|
knownValueTypes.put( "windowBorder", ValueType.COLOR );
|
||||||
// SplitPane
|
// SplitPane
|
||||||
knownValueTypes.put( "SplitPane.dividerSize", ValueType.INTEGER );
|
knownValueTypes.put( "SplitPane.dividerSize", ValueType.INTEGER );
|
||||||
knownValueTypes.put( "SplitPaneDivider.gripDotSize", ValueType.INTEGER );
|
knownValueTypes.put( "SplitPaneDivider.gripDotSize", ValueType.INTEGER );
|
||||||
@@ -780,6 +784,7 @@ class UIDefaultsLoader
|
|||||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
||||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
||||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
case "contrast": return parseColorContrast( params, resolver, reportError );
|
||||||
|
case "over": return parseColorOver( params, resolver, reportError );
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
parseColorDepth--;
|
parseColorDepth--;
|
||||||
@@ -847,7 +852,7 @@ class UIDefaultsLoader
|
|||||||
int lightness = parsePercentage( params.get( 2 ) );
|
int lightness = parsePercentage( params.get( 2 ) );
|
||||||
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
||||||
|
|
||||||
float[] hsl = new float[] { hue, saturation, lightness };
|
float[] hsl = { hue, saturation, lightness };
|
||||||
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,6 +1046,33 @@ class UIDefaultsLoader
|
|||||||
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syntax: over(foreground,background)
|
||||||
|
* - foreground: a foreground color (e.g. #f00) or a color function;
|
||||||
|
* the alpha of this color is used as weight to mix the two colors
|
||||||
|
* - background: a background color (e.g. #f00) or a color function
|
||||||
|
*/
|
||||||
|
private static Object parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||||
|
String foregroundStr = params.get( 0 );
|
||||||
|
String backgroundStr = params.get( 1 );
|
||||||
|
|
||||||
|
// parse foreground color
|
||||||
|
ColorUIResource foreground = (ColorUIResource) parseColorOrFunction( resolver.apply( foregroundStr ), resolver, reportError );
|
||||||
|
if( foreground == null || foreground.getAlpha() == 255 )
|
||||||
|
return foreground;
|
||||||
|
|
||||||
|
Color foreground2 = new Color( foreground.getRGB() );
|
||||||
|
|
||||||
|
// parse background color
|
||||||
|
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
||||||
|
if( background == null )
|
||||||
|
return foreground2;
|
||||||
|
|
||||||
|
// create new color
|
||||||
|
float weight = foreground.getAlpha() / 255f;
|
||||||
|
return new ColorUIResource( ColorFunctions.mix( foreground2, background, weight ) );
|
||||||
|
}
|
||||||
|
|
||||||
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
||||||
boolean derived, Function<String, String> resolver, boolean reportError )
|
boolean derived, Function<String, String> resolver, boolean reportError )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,20 +78,27 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
||||||
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.focusedBackground Color optional
|
* @uiDefault Button.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.focusedForeground Color optional
|
||||||
* @uiDefault Button.hoverBackground Color optional
|
* @uiDefault Button.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.hoverForeground Color optional
|
||||||
* @uiDefault Button.pressedBackground Color optional
|
* @uiDefault Button.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.pressedForeground Color optional
|
||||||
* @uiDefault Button.selectedBackground Color
|
* @uiDefault Button.selectedBackground Color
|
||||||
* @uiDefault Button.selectedForeground Color
|
* @uiDefault Button.selectedForeground Color
|
||||||
* @uiDefault Button.disabledBackground Color optional
|
* @uiDefault Button.disabledBackground Color optional
|
||||||
* @uiDefault Button.disabledText Color
|
* @uiDefault Button.disabledText Color
|
||||||
* @uiDefault Button.disabledSelectedBackground Color
|
* @uiDefault Button.disabledSelectedBackground Color
|
||||||
|
* @uiDefault Button.disabledSelectedForeground Color optional
|
||||||
* @uiDefault Button.default.background Color
|
* @uiDefault Button.default.background Color
|
||||||
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
||||||
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.default.foreground Color
|
* @uiDefault Button.default.foreground Color
|
||||||
* @uiDefault Button.default.focusedBackground Color optional
|
* @uiDefault Button.default.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.default.focusedForeground Color optional
|
||||||
* @uiDefault Button.default.hoverBackground Color optional
|
* @uiDefault Button.default.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.default.hoverForeground Color optional
|
||||||
* @uiDefault Button.default.pressedBackground Color optional
|
* @uiDefault Button.default.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.default.pressedForeground Color optional
|
||||||
* @uiDefault Button.default.boldText boolean
|
* @uiDefault Button.default.boldText boolean
|
||||||
* @uiDefault Button.paintShadow boolean default is false
|
* @uiDefault Button.paintShadow boolean default is false
|
||||||
* @uiDefault Button.shadowWidth int default is 2
|
* @uiDefault Button.shadowWidth int default is 2
|
||||||
@@ -99,8 +106,13 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Button.default.shadowColor Color optional
|
* @uiDefault Button.default.shadowColor Color optional
|
||||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||||
* @uiDefault Button.toolbar.hoverBackground Color
|
* @uiDefault Button.toolbar.hoverBackground Color
|
||||||
|
* @uiDefault Button.toolbar.hoverForeground Color optional
|
||||||
* @uiDefault Button.toolbar.pressedBackground Color
|
* @uiDefault Button.toolbar.pressedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.pressedForeground Color optional
|
||||||
* @uiDefault Button.toolbar.selectedBackground Color
|
* @uiDefault Button.toolbar.selectedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.selectedForeground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedBackground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedForeground Color optional
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -117,20 +129,27 @@ public class FlatButtonUI
|
|||||||
protected Color startBackground;
|
protected Color startBackground;
|
||||||
protected Color endBackground;
|
protected Color endBackground;
|
||||||
@Styleable protected Color focusedBackground;
|
@Styleable protected Color focusedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color focusedForeground;
|
||||||
@Styleable protected Color hoverBackground;
|
@Styleable protected Color hoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color hoverForeground;
|
||||||
@Styleable protected Color pressedBackground;
|
@Styleable protected Color pressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color pressedForeground;
|
||||||
@Styleable protected Color selectedBackground;
|
@Styleable protected Color selectedBackground;
|
||||||
@Styleable protected Color selectedForeground;
|
@Styleable protected Color selectedForeground;
|
||||||
@Styleable protected Color disabledBackground;
|
@Styleable protected Color disabledBackground;
|
||||||
@Styleable protected Color disabledText;
|
@Styleable protected Color disabledText;
|
||||||
@Styleable protected Color disabledSelectedBackground;
|
@Styleable protected Color disabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color disabledSelectedForeground;
|
||||||
|
|
||||||
@Styleable(dot=true) protected Color defaultBackground;
|
@Styleable(dot=true) protected Color defaultBackground;
|
||||||
protected Color defaultEndBackground;
|
protected Color defaultEndBackground;
|
||||||
@Styleable(dot=true) protected Color defaultForeground;
|
@Styleable(dot=true) protected Color defaultForeground;
|
||||||
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultFocusedForeground;
|
||||||
@Styleable(dot=true) protected Color defaultHoverBackground;
|
@Styleable(dot=true) protected Color defaultHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultHoverForeground;
|
||||||
@Styleable(dot=true) protected Color defaultPressedBackground;
|
@Styleable(dot=true) protected Color defaultPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultPressedForeground;
|
||||||
@Styleable(dot=true) protected boolean defaultBoldText;
|
@Styleable(dot=true) protected boolean defaultBoldText;
|
||||||
|
|
||||||
@Styleable protected boolean paintShadow;
|
@Styleable protected boolean paintShadow;
|
||||||
@@ -139,8 +158,13 @@ public class FlatButtonUI
|
|||||||
@Styleable(dot=true) protected Color defaultShadowColor;
|
@Styleable(dot=true) protected Color defaultShadowColor;
|
||||||
|
|
||||||
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarHoverForeground;
|
||||||
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarPressedForeground;
|
||||||
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarSelectedForeground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedForeground;
|
||||||
|
|
||||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||||
/** @since 2 */ @Styleable protected String buttonType;
|
/** @since 2 */ @Styleable protected String buttonType;
|
||||||
@@ -190,20 +214,27 @@ public class FlatButtonUI
|
|||||||
startBackground = UIManager.getColor( prefix + "startBackground" );
|
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||||
endBackground = UIManager.getColor( prefix + "endBackground" );
|
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||||
|
focusedForeground = UIManager.getColor( prefix + "focusedForeground" );
|
||||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||||
|
hoverForeground = UIManager.getColor( prefix + "hoverForeground" );
|
||||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||||
|
pressedForeground = UIManager.getColor( prefix + "pressedForeground" );
|
||||||
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
||||||
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
||||||
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
||||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||||
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
||||||
|
disabledSelectedForeground = UIManager.getColor( prefix + "disabledSelectedForeground" );
|
||||||
|
|
||||||
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||||
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||||
|
defaultFocusedForeground = UIManager.getColor( "Button.default.focusedForeground" );
|
||||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||||
|
defaultHoverForeground = UIManager.getColor( "Button.default.hoverForeground" );
|
||||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||||
|
defaultPressedForeground = UIManager.getColor( "Button.default.pressedForeground" );
|
||||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
||||||
|
|
||||||
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
||||||
@@ -212,8 +243,13 @@ public class FlatButtonUI
|
|||||||
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||||
|
|
||||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||||
|
toolbarHoverForeground = UIManager.getColor( prefix + "toolbar.hoverForeground" );
|
||||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||||
|
toolbarPressedForeground = UIManager.getColor( prefix + "toolbar.pressedForeground" );
|
||||||
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||||
|
toolbarSelectedForeground = UIManager.getColor( prefix + "toolbar.selectedForeground" );
|
||||||
|
toolbarDisabledSelectedBackground = UIManager.getColor( prefix + "toolbar.disabledSelectedBackground" );
|
||||||
|
toolbarDisabledSelectedForeground = UIManager.getColor( prefix + "toolbar.disabledSelectedForeground" );
|
||||||
|
|
||||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||||
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
||||||
@@ -532,6 +568,8 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||||
|
if(foreground == null)
|
||||||
|
foreground=Color.red;
|
||||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||||
|
|
||||||
@@ -545,11 +583,14 @@ public class FlatButtonUI
|
|||||||
|
|
||||||
// selected state
|
// selected state
|
||||||
if( ((AbstractButton)c).isSelected() ) {
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
// in toolbar use same background colors for disabled and enabled because
|
// in toolbar, if toolbarDisabledSelectedBackground is null,
|
||||||
|
// use same background colors for disabled and enabled because
|
||||||
// we assume that toolbar icon is shown disabled
|
// we assume that toolbar icon is shown disabled
|
||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedBackground != null ? toolbarDisabledSelectedBackground : toolbarSelectedBackground)
|
||||||
|
: disabledSelectedBackground,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||||
@@ -614,18 +655,48 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Color getForeground( JComponent c ) {
|
protected Color getForeground( JComponent c ) {
|
||||||
if( !c.isEnabled() )
|
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||||
return disabledText;
|
|
||||||
|
|
||||||
if( ((AbstractButton)c).isSelected() && !(isToolBarButton( c ) || isBorderlessButton( c )) )
|
// selected state
|
||||||
return selectedForeground;
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : c.getForeground())
|
||||||
|
: selectedForeground,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
||||||
|
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
toolBarButton ? toolbarPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
// toolbar button
|
||||||
|
if( toolBarButton ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
c.getForeground(),
|
||||||
|
disabledText,
|
||||||
|
null,
|
||||||
|
toolbarHoverForeground,
|
||||||
|
toolbarPressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean def = isDefaultButton( c );
|
||||||
|
return buttonStateColor( c,
|
||||||
|
getForegroundBase( c, def ),
|
||||||
|
disabledText,
|
||||||
|
isCustomForeground( c.getForeground() ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
||||||
|
def ? defaultHoverForeground : hoverForeground,
|
||||||
|
def ? defaultPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
protected Color getForegroundBase( JComponent c, boolean def ) {
|
||||||
// use component foreground if explicitly set
|
// use component foreground if explicitly set
|
||||||
Color fg = c.getForeground();
|
Color fg = c.getForeground();
|
||||||
if( isCustomForeground( fg ) )
|
if( isCustomForeground( fg ) )
|
||||||
return fg;
|
return fg;
|
||||||
|
|
||||||
boolean def = isDefaultButton( c );
|
|
||||||
return def ? defaultForeground : fg;
|
return def ? defaultForeground : fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -608,7 +608,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
boolean shouldValidate = (c instanceof JPanel);
|
boolean shouldValidate = (c instanceof JPanel);
|
||||||
|
|
||||||
paddingBorder.install( c );
|
paddingBorder.install( c, 0 );
|
||||||
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
@@ -682,7 +682,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getSizeForComponent( Component comp ) {
|
protected Dimension getSizeForComponent( Component comp ) {
|
||||||
paddingBorder.install( comp );
|
paddingBorder.install( comp, 0 );
|
||||||
Dimension size = super.getSizeForComponent( comp );
|
Dimension size = super.getSizeForComponent( comp );
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
return size;
|
return size;
|
||||||
@@ -900,7 +900,7 @@ public class FlatComboBoxUI
|
|||||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
paddingBorder.install( c );
|
paddingBorder.install( c, Math.round( FlatUIUtils.getBorderFocusWidth( comboBox ) ) );
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -923,6 +923,7 @@ public class FlatComboBoxUI
|
|||||||
private Insets padding;
|
private Insets padding;
|
||||||
private JComponent rendererComponent;
|
private JComponent rendererComponent;
|
||||||
private Border rendererBorder;
|
private Border rendererBorder;
|
||||||
|
private int focusWidth;
|
||||||
|
|
||||||
CellPaddingBorder( Insets padding ) {
|
CellPaddingBorder( Insets padding ) {
|
||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
@@ -930,10 +931,12 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
// using synchronized to avoid problems with code that modifies combo box
|
// using synchronized to avoid problems with code that modifies combo box
|
||||||
// (model, selection, etc) not on AWT thread (which should be not done)
|
// (model, selection, etc) not on AWT thread (which should be not done)
|
||||||
synchronized void install( Component c ) {
|
synchronized void install( Component c, int focusWidth ) {
|
||||||
if( !(c instanceof JComponent) )
|
if( !(c instanceof JComponent) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.focusWidth = focusWidth;
|
||||||
|
|
||||||
JComponent jc = (JComponent) c;
|
JComponent jc = (JComponent) c;
|
||||||
Border oldBorder = jc.getBorder();
|
Border oldBorder = jc.getBorder();
|
||||||
if( oldBorder == this )
|
if( oldBorder == this )
|
||||||
@@ -987,6 +990,12 @@ public class FlatComboBoxUI
|
|||||||
insets.bottom = padding.bottom;
|
insets.bottom = padding.bottom;
|
||||||
insets.right = padding.right;
|
insets.right = padding.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if used in popup list, add focus width for exact vertical alignment
|
||||||
|
// of text in popup list with text in combobox
|
||||||
|
insets.left += focusWidth;
|
||||||
|
insets.right += focusWidth;
|
||||||
|
|
||||||
return insets;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class FlatEmptyBorder
|
|||||||
protected static Insets scaleInsets( Component c, Insets insets,
|
protected static Insets scaleInsets( Component c, Insets insets,
|
||||||
int top, int left, int bottom, int right )
|
int top, int left, int bottom, int right )
|
||||||
{
|
{
|
||||||
boolean leftToRight = left == right || c.getComponentOrientation().isLeftToRight();
|
boolean leftToRight = left == right || c == null || c.getComponentOrientation().isLeftToRight();
|
||||||
insets.left = scale( leftToRight ? left : right );
|
insets.left = scale( leftToRight ? left : right );
|
||||||
insets.top = scale( top );
|
insets.top = scale( top );
|
||||||
insets.right = scale( leftToRight ? right : left );
|
insets.right = scale( leftToRight ? right : left );
|
||||||
|
|||||||
@@ -19,11 +19,21 @@ package com.formdev.flatlaf.ui;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@@ -34,12 +44,16 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.JToggleButton;
|
||||||
|
import javax.swing.JToolBar;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
import javax.swing.filechooser.FileView;
|
import javax.swing.filechooser.FileView;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.metal.MetalFileChooserUI;
|
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -133,12 +147,21 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault FileChooser.listViewActionLabelText String
|
* @uiDefault FileChooser.listViewActionLabelText String
|
||||||
* @uiDefault FileChooser.detailsViewActionLabelText String
|
* @uiDefault FileChooser.detailsViewActionLabelText String
|
||||||
*
|
*
|
||||||
|
* <!-- FlatFileChooserUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.shortcuts.buttonSize Dimension optional; default is 84,64
|
||||||
|
* @uiDefault FileChooser.shortcuts.iconSize Dimension optional; default is 32,32
|
||||||
|
* @uiDefault FileChooser.shortcuts.filesFunction Function<File[], File[]>
|
||||||
|
* @uiDefault FileChooser.shortcuts.displayNameFunction Function<File, String>
|
||||||
|
* @uiDefault FileChooser.shortcuts.iconFunction Function<File, Icon>
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileChooserUI
|
public class FlatFileChooserUI
|
||||||
extends MetalFileChooserUI
|
extends MetalFileChooserUI
|
||||||
{
|
{
|
||||||
private final FlatFileView fileView = new FlatFileView();
|
private final FlatFileView fileView = new FlatFileView();
|
||||||
|
private FlatShortcutsPanel shortcutsPanel;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatFileChooserUI( (JFileChooser) c );
|
return new FlatFileChooserUI( (JFileChooser) c );
|
||||||
@@ -153,6 +176,25 @@ public class FlatFileChooserUI
|
|||||||
super.installComponents( fc );
|
super.installComponents( fc );
|
||||||
|
|
||||||
patchUI( fc );
|
patchUI( fc );
|
||||||
|
|
||||||
|
if( !UIManager.getBoolean( "FileChooser.noPlacesBar" ) ) { // same as in Windows L&F
|
||||||
|
FlatShortcutsPanel panel = createShortcutsPanel( fc );
|
||||||
|
if( panel.getComponentCount() > 0 ) {
|
||||||
|
shortcutsPanel = panel;
|
||||||
|
fc.add( shortcutsPanel, BorderLayout.LINE_START );
|
||||||
|
fc.addPropertyChangeListener( shortcutsPanel );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallComponents( JFileChooser fc ) {
|
||||||
|
super.uninstallComponents( fc );
|
||||||
|
|
||||||
|
if( shortcutsPanel != null ) {
|
||||||
|
fc.removePropertyChangeListener( shortcutsPanel );
|
||||||
|
shortcutsPanel = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void patchUI( JFileChooser fc ) {
|
private void patchUI( JFileChooser fc ) {
|
||||||
@@ -192,6 +234,25 @@ public class FlatFileChooserUI
|
|||||||
} catch( ArrayIndexOutOfBoundsException ex ) {
|
} catch( ArrayIndexOutOfBoundsException ex ) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put north, center and south components into a new panel so that
|
||||||
|
// the shortcuts panel (at west) gets full height
|
||||||
|
LayoutManager layout = fc.getLayout();
|
||||||
|
if( layout instanceof BorderLayout ) {
|
||||||
|
BorderLayout borderLayout = (BorderLayout) layout;
|
||||||
|
borderLayout.setHgap( 8 );
|
||||||
|
|
||||||
|
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
||||||
|
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
||||||
|
Component south = borderLayout.getLayoutComponent( BorderLayout.SOUTH );
|
||||||
|
if( north != null && center != null && south != null ) {
|
||||||
|
JPanel p = new JPanel( new BorderLayout( 0, 11 ) );
|
||||||
|
p.add( north, BorderLayout.NORTH );
|
||||||
|
p.add( center, BorderLayout.CENTER );
|
||||||
|
p.add( south, BorderLayout.SOUTH );
|
||||||
|
fc.add( p, BorderLayout.CENTER );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -250,9 +311,19 @@ public class FlatFileChooserUI
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
protected FlatShortcutsPanel createShortcutsPanel( JFileChooser fc ) {
|
||||||
|
return new FlatShortcutsPanel( fc );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
return UIScale.scale( super.getPreferredSize( c ) );
|
Dimension prefSize = super.getPreferredSize( c );
|
||||||
|
Dimension minSize = getMinimumSize( c );
|
||||||
|
int shortcutsPanelWidth = (shortcutsPanel != null) ? shortcutsPanel.getPreferredSize().width : 0;
|
||||||
|
return new Dimension(
|
||||||
|
Math.max( prefSize.width, minSize.width + shortcutsPanelWidth ),
|
||||||
|
Math.max( prefSize.height, minSize.height ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -316,4 +387,234 @@ public class FlatFileChooserUI
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatShortcutsPanel -------------------------------------------
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
public static class FlatShortcutsPanel
|
||||||
|
extends JToolBar
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
private final JFileChooser fc;
|
||||||
|
|
||||||
|
private final Dimension buttonSize;
|
||||||
|
private final Dimension iconSize;
|
||||||
|
private final Function<File[], File[]> filesFunction;
|
||||||
|
private final Function<File, String> displayNameFunction;
|
||||||
|
private final Function<File, Icon> iconFunction;
|
||||||
|
|
||||||
|
protected final File[] files;
|
||||||
|
protected final JToggleButton[] buttons;
|
||||||
|
protected final ButtonGroup buttonGroup;
|
||||||
|
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
public FlatShortcutsPanel( JFileChooser fc ) {
|
||||||
|
super( JToolBar.VERTICAL );
|
||||||
|
this.fc = fc;
|
||||||
|
setFloatable( false );
|
||||||
|
|
||||||
|
buttonSize = UIScale.scale( getUIDimension( "FileChooser.shortcuts.buttonSize", 84, 64 ) );
|
||||||
|
iconSize = getUIDimension( "FileChooser.shortcuts.iconSize", 32, 32 );
|
||||||
|
|
||||||
|
filesFunction = (Function<File[], File[]>) UIManager.get( "FileChooser.shortcuts.filesFunction" );
|
||||||
|
displayNameFunction = (Function<File, String>) UIManager.get( "FileChooser.shortcuts.displayNameFunction" );
|
||||||
|
iconFunction = (Function<File, Icon>) UIManager.get( "FileChooser.shortcuts.iconFunction" );
|
||||||
|
|
||||||
|
FileSystemView fsv = fc.getFileSystemView();
|
||||||
|
File[] files = getChooserShortcutPanelFiles( fsv );
|
||||||
|
if( filesFunction != null )
|
||||||
|
files = filesFunction.apply( files );
|
||||||
|
this.files = files;
|
||||||
|
|
||||||
|
// create toolbar buttons
|
||||||
|
buttons = new JToggleButton[files.length];
|
||||||
|
buttonGroup = new ButtonGroup();
|
||||||
|
for( int i = 0; i < files.length; i++ ) {
|
||||||
|
// wrap drive path
|
||||||
|
if( fsv.isFileSystemRoot( files[i] ) )
|
||||||
|
files[i] = fsv.createFileObject( files[i].getAbsolutePath() );
|
||||||
|
|
||||||
|
File file = files[i];
|
||||||
|
String name = getDisplayName( fsv, file );
|
||||||
|
Icon icon = getIcon( fsv, file );
|
||||||
|
|
||||||
|
// remove path from name
|
||||||
|
int lastSepIndex = name.lastIndexOf( File.separatorChar );
|
||||||
|
if( lastSepIndex >= 0 && lastSepIndex < name.length() - 1 )
|
||||||
|
name = name.substring( lastSepIndex + 1 );
|
||||||
|
|
||||||
|
// scale icon (if necessary)
|
||||||
|
if( icon instanceof ImageIcon )
|
||||||
|
icon = new ScaledImageIcon( (ImageIcon) icon, iconSize.width, iconSize.height );
|
||||||
|
else if( icon != null )
|
||||||
|
icon = new ShortcutIcon( icon, iconSize.width, iconSize.height );
|
||||||
|
|
||||||
|
// create button
|
||||||
|
JToggleButton button = createButton( name, icon );
|
||||||
|
button.addActionListener( e -> {
|
||||||
|
fc.setCurrentDirectory( file );
|
||||||
|
} );
|
||||||
|
|
||||||
|
add( button );
|
||||||
|
buttonGroup.add( button );
|
||||||
|
buttons[i] = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
directoryChanged( fc.getCurrentDirectory() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dimension getUIDimension( String key, int defaultWidth, int defaultHeight ) {
|
||||||
|
Dimension size = UIManager.getDimension( key );
|
||||||
|
if( size == null )
|
||||||
|
size = new Dimension( defaultWidth, defaultHeight );
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JToggleButton createButton( String name, Icon icon ) {
|
||||||
|
JToggleButton button = new JToggleButton( name, icon );
|
||||||
|
button.setVerticalTextPosition( SwingConstants.BOTTOM );
|
||||||
|
button.setHorizontalTextPosition( SwingConstants.CENTER );
|
||||||
|
button.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
|
button.setIconTextGap( 0 );
|
||||||
|
button.setPreferredSize( buttonSize );
|
||||||
|
button.setMaximumSize( buttonSize );
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected File[] getChooserShortcutPanelFiles( FileSystemView fsv ) {
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_12_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getChooserShortcutPanelFiles" );
|
||||||
|
File[] files = (File[]) m.invoke( fsv );
|
||||||
|
|
||||||
|
// on macOS and Linux, files consists only of the user home directory
|
||||||
|
if( files.length == 1 && files[0].equals( new File( System.getProperty( "user.home" ) ) ) )
|
||||||
|
files = new File[0];
|
||||||
|
|
||||||
|
return files;
|
||||||
|
} else if( SystemInfo.isWindows ) {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
Method m = cls.getMethod( "get", String.class );
|
||||||
|
return (File[]) m.invoke( null, "fileChooserShortcutPanelFolders" );
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
return new File[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getDisplayName( FileSystemView fsv, File file ) {
|
||||||
|
if( displayNameFunction != null ) {
|
||||||
|
String name = displayNameFunction.apply( file );
|
||||||
|
if( name != null )
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsv.getSystemDisplayName( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Icon getIcon( FileSystemView fsv, File file ) {
|
||||||
|
if( iconFunction != null ) {
|
||||||
|
Icon icon = iconFunction.apply( file );
|
||||||
|
if( icon != null )
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java 17+ supports getting larger system icons
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_17_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getSystemIcon", File.class, int.class, int.class );
|
||||||
|
return (Icon) m.invoke( fsv, file, iconSize.width, iconSize.height );
|
||||||
|
} else if( iconSize.width > 16 || iconSize.height > 16 ) {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
if( cls.isInstance( file ) ) {
|
||||||
|
Method m = file.getClass().getMethod( "getIcon", boolean.class );
|
||||||
|
m.setAccessible( true );
|
||||||
|
Image image = (Image) m.invoke( file, true );
|
||||||
|
if( image != null )
|
||||||
|
return new ImageIcon( image );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get system icon in default size 16x16
|
||||||
|
return fsv.getSystemIcon( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void directoryChanged( File file ) {
|
||||||
|
if( file != null ) {
|
||||||
|
String absolutePath = file.getAbsolutePath();
|
||||||
|
for( int i = 0; i < files.length; i++ ) {
|
||||||
|
// also compare path because otherwise selecting "Documents"
|
||||||
|
// in "Look in" combobox would not select "Documents" shortcut item
|
||||||
|
if( files[i].equals( file ) || files[i].getAbsolutePath().equals( absolutePath ) ) {
|
||||||
|
buttons[i].setSelected( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonGroup.clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case JFileChooser.DIRECTORY_CHANGED_PROPERTY:
|
||||||
|
directoryChanged( fc.getCurrentDirectory() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class ShortcutIcon -------------------------------------------------
|
||||||
|
|
||||||
|
private static class ShortcutIcon
|
||||||
|
implements Icon
|
||||||
|
{
|
||||||
|
private final Icon icon;
|
||||||
|
private final int iconWidth;
|
||||||
|
private final int iconHeight;
|
||||||
|
|
||||||
|
ShortcutIcon( Icon icon, int iconWidth, int iconHeight ) {
|
||||||
|
this.icon = icon;
|
||||||
|
this.iconWidth = iconWidth;
|
||||||
|
this.iconHeight = iconHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
try {
|
||||||
|
// set rendering hint for the case that the icon is a bitmap (not used for vector icons)
|
||||||
|
g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
|
||||||
|
|
||||||
|
double scale = (double) getIconWidth() / (double) icon.getIconWidth();
|
||||||
|
g2.translate( x, y );
|
||||||
|
g2.scale( scale, scale );
|
||||||
|
|
||||||
|
icon.paintIcon( c, g2, 0, 0 );
|
||||||
|
} finally {
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconWidth() {
|
||||||
|
return UIScale.scale( iconWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconHeight() {
|
||||||
|
return UIScale.scale( iconHeight );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
@@ -27,6 +29,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.ActionMap;
|
import javax.swing.ActionMap;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
@@ -40,11 +43,13 @@ import javax.swing.plaf.ActionMapUIResource;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicMenuBarUI;
|
import javax.swing.plaf.basic.BasicMenuBarUI;
|
||||||
|
import javax.swing.plaf.basic.DefaultMenuLayout;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
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;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
||||||
@@ -100,6 +105,10 @@ public class FlatMenuBarUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
LookAndFeel.installProperty( menuBar, "opaque", false );
|
LookAndFeel.installProperty( menuBar, "opaque", false );
|
||||||
|
|
||||||
|
LayoutManager layout = menuBar.getLayout();
|
||||||
|
if( layout == null || layout instanceof UIResource )
|
||||||
|
menuBar.setLayout( new FlatMenuBarLayout( menuBar ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,6 +230,130 @@ public class FlatMenuBarUI
|
|||||||
rootPane.getWindowDecorationStyle() != JRootPane.NONE;
|
rootPane.getWindowDecorationStyle() != JRootPane.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatMenuBarLayout --------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.4
|
||||||
|
*/
|
||||||
|
protected static class FlatMenuBarLayout
|
||||||
|
extends DefaultMenuLayout
|
||||||
|
{
|
||||||
|
public FlatMenuBarLayout( Container target ) {
|
||||||
|
super( target, BoxLayout.LINE_AXIS );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layoutContainer( Container target ) {
|
||||||
|
super.layoutContainer( target );
|
||||||
|
|
||||||
|
|
||||||
|
// The only purpose of the code below is to make sure that a horizontal glue,
|
||||||
|
// which can be used to move window and displays the window title in embedded menu bar,
|
||||||
|
// is always visible within the menu bar bounds and has a minimum width.
|
||||||
|
// If this is not the case, the horizontal glue is made larger and
|
||||||
|
// components that are on the left side of the glue are made smaller.
|
||||||
|
|
||||||
|
|
||||||
|
// get root pane and check whether this menu bar is the root pane menu bar
|
||||||
|
JRootPane rootPane = SwingUtilities.getRootPane( target );
|
||||||
|
if( rootPane == null || rootPane.getJMenuBar() != target )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// get title pane and check whether menu bar is embedded
|
||||||
|
FlatTitlePane titlePane = FlatRootPaneUI.getTitlePane( rootPane );
|
||||||
|
if( titlePane == null || !titlePane.isMenuBarEmbedded() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check whether there is a horizontal glue (used for window title in embedded menu bar)
|
||||||
|
// and check minimum width of horizontal glue
|
||||||
|
Component horizontalGlue = titlePane.findHorizontalGlue( (JMenuBar) target );
|
||||||
|
int minTitleWidth = UIScale.scale( titlePane.titleMinimumWidth );
|
||||||
|
if( horizontalGlue != null && horizontalGlue.getWidth() < minTitleWidth ) {
|
||||||
|
// get index of glue component
|
||||||
|
int glueIndex = -1;
|
||||||
|
Component[] components = target.getComponents();
|
||||||
|
for( int i = components.length - 1; i >= 0; i-- ) {
|
||||||
|
if( components[i] == horizontalGlue ) {
|
||||||
|
glueIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( glueIndex < 0 )
|
||||||
|
return; // should never happen
|
||||||
|
|
||||||
|
if( target.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
// left-to-right
|
||||||
|
|
||||||
|
// make horizontal glue wider (minimum title width)
|
||||||
|
int offset = minTitleWidth - horizontalGlue.getWidth();
|
||||||
|
horizontalGlue.setSize( minTitleWidth, horizontalGlue.getHeight() );
|
||||||
|
|
||||||
|
// check whether glue is fully visible
|
||||||
|
int minGlueX = target.getWidth() - target.getInsets().right - minTitleWidth;
|
||||||
|
if( minGlueX < horizontalGlue.getX() ) {
|
||||||
|
// move glue to the left to make it fully visible
|
||||||
|
offset -= (horizontalGlue.getX() - minGlueX);
|
||||||
|
horizontalGlue.setLocation( minGlueX, horizontalGlue.getY() );
|
||||||
|
|
||||||
|
// shrink and move components that are on the left side of the glue
|
||||||
|
for( int i = glueIndex - 1; i >= 0; i-- ) {
|
||||||
|
Component c = components[i];
|
||||||
|
if( c.getX() > minGlueX ) {
|
||||||
|
// move component and set width to zero
|
||||||
|
c.setBounds( minGlueX, c.getY(), 0, c.getHeight() );
|
||||||
|
} else {
|
||||||
|
// reduce size of component
|
||||||
|
c.setSize( minGlueX - c.getX(), c.getHeight() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move components that are on the right side of the glue
|
||||||
|
for( int i = glueIndex + 1; i < components.length; i++ ) {
|
||||||
|
Component c = components[i];
|
||||||
|
c.setLocation( c.getX() + offset, c.getY() );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// right-to-left
|
||||||
|
|
||||||
|
// make horizontal glue wider (minimum title width)
|
||||||
|
int offset = minTitleWidth - horizontalGlue.getWidth();
|
||||||
|
horizontalGlue.setBounds( horizontalGlue.getX() - offset, horizontalGlue.getY(),
|
||||||
|
minTitleWidth, horizontalGlue.getHeight() );
|
||||||
|
|
||||||
|
// check whether glue is fully visible
|
||||||
|
int minGlueX = target.getInsets().left;
|
||||||
|
if( minGlueX > horizontalGlue.getX() ) {
|
||||||
|
// move glue to the right to make it fully visible
|
||||||
|
offset -= (horizontalGlue.getX() - minGlueX);
|
||||||
|
horizontalGlue.setLocation( minGlueX, horizontalGlue.getY() );
|
||||||
|
|
||||||
|
// shrink and move components that are on the right side of the glue
|
||||||
|
int x = horizontalGlue.getX() + horizontalGlue.getWidth();
|
||||||
|
for( int i = glueIndex - 1; i >= 0; i-- ) {
|
||||||
|
Component c = components[i];
|
||||||
|
if( c.getX() + c.getWidth() < x ) {
|
||||||
|
// move component and set width to zero
|
||||||
|
c.setBounds( x, c.getY(), 0, c.getHeight() );
|
||||||
|
} else {
|
||||||
|
// move component and reduce size
|
||||||
|
c.setBounds( x, c.getY(), c.getWidth() - (x - c.getX()), c.getHeight() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move components that are on the left side of the glue
|
||||||
|
for( int i = glueIndex + 1; i < components.length; i++ ) {
|
||||||
|
Component c = components[i];
|
||||||
|
c.setLocation( c.getX() - offset, c.getY() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---- class TakeFocus ----------------------------------------------------
|
//---- class TakeFocus ----------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -446,6 +446,19 @@ debug*/
|
|||||||
protected static void paintHTMLText( Graphics g, JMenuItem menuItem,
|
protected static void paintHTMLText( Graphics g, JMenuItem menuItem,
|
||||||
Rectangle textRect, View htmlView, Color selectionForeground )
|
Rectangle textRect, View htmlView, Color selectionForeground )
|
||||||
{
|
{
|
||||||
|
// On Windows, using Segoe UI font, Java 15 or older and scaling greater than 1,
|
||||||
|
// the width of the HTML view may be initially too small (because component
|
||||||
|
// is not connected to a GraphicsConfiguration when getPreferredSize() is invoked).
|
||||||
|
// Since Java 16, this seems to be fixed somehow by doing popup menu layout twice.
|
||||||
|
//
|
||||||
|
// If using a too small width for htmlView.paint(), the view would rearrange
|
||||||
|
// its children and wrap them to two lines. To avoid this, use view preferred X span
|
||||||
|
// for painting. Core Lafs actually do the same in class MenuItemLayoutHelper.
|
||||||
|
//
|
||||||
|
// Example HTML text that causes the problem: "<html>some <b>HTML</b> <i>text</i></html>"
|
||||||
|
textRect = new Rectangle( textRect );
|
||||||
|
textRect.width = (int) htmlView.getPreferredSpan( View.X_AXIS );
|
||||||
|
|
||||||
if( isArmedOrSelected( menuItem ) && selectionForeground != null )
|
if( isArmedOrSelected( menuItem ) && selectionForeground != null )
|
||||||
g = new GraphicsProxyWithTextColor( (Graphics2D) g, selectionForeground );
|
g = new GraphicsProxyWithTextColor( (Graphics2D) g, selectionForeground );
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.NativeLibrary;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to load FlatLaf native library (.dll, .so or .dylib),
|
||||||
|
* if available for current operating system and CPU architecture.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
class FlatNativeLibrary
|
||||||
|
{
|
||||||
|
private static NativeLibrary nativeLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads native library (if available) and returns whether loaded successfully.
|
||||||
|
* Returns {@code false} if no native library is available.
|
||||||
|
*/
|
||||||
|
static synchronized boolean isLoaded() {
|
||||||
|
initialize();
|
||||||
|
return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initialize() {
|
||||||
|
if( nativeLibrary != null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
String libraryName;
|
||||||
|
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
||||||
|
// Windows: requires Windows 10 (x86 or x86_64)
|
||||||
|
|
||||||
|
libraryName = "flatlaf-windows-x86";
|
||||||
|
if( SystemInfo.isX86_64 )
|
||||||
|
libraryName += "_64";
|
||||||
|
|
||||||
|
// load jawt native library
|
||||||
|
loadJAWT();
|
||||||
|
} else
|
||||||
|
return; // no native library available for current OS or CPU architecture
|
||||||
|
|
||||||
|
// load native library
|
||||||
|
nativeLibrary = createNativeLibrary( libraryName );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||||
|
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||||
|
if( libraryPath != null ) {
|
||||||
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
|
if( libraryFile.exists() )
|
||||||
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
else
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadJAWT() {
|
||||||
|
if( SystemInfo.isJava_9_orLater )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||||
|
// is not found when running application with <jdk>/bin/java.exe.
|
||||||
|
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||||
|
// jawt.dll is located in <jdk>/jre/bin/.
|
||||||
|
// Java 9 and later do not have this problem.
|
||||||
|
try {
|
||||||
|
System.loadLibrary( "jawt" );
|
||||||
|
} catch( UnsatisfiedLinkError ex ) {
|
||||||
|
// log error only if native library jawt.dll not already loaded
|
||||||
|
String message = ex.getMessage();
|
||||||
|
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,11 +42,13 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
public class FlatNativeWindowBorder
|
public class FlatNativeWindowBorder
|
||||||
{
|
{
|
||||||
// can use window decorations if:
|
// can use window decorations if:
|
||||||
// - on Windows 10
|
// - on Windows 10 or later
|
||||||
|
// - not if system property "sun.java2d.opengl" is true on Windows 10
|
||||||
// - not when running in JetBrains Projector, Webswing or WinPE
|
// - not when running in JetBrains Projector, Webswing or WinPE
|
||||||
// - not disabled via system property
|
// - not disabled via system property
|
||||||
private static final boolean canUseWindowDecorations =
|
private static final boolean canUseWindowDecorations =
|
||||||
SystemInfo.isWindows_10_orLater &&
|
SystemInfo.isWindows_10_orLater &&
|
||||||
|
(SystemInfo.isWindows_11_orLater || !FlatSystemProperties.getBoolean( "sun.java2d.opengl", false )) &&
|
||||||
!SystemInfo.isProjector &&
|
!SystemInfo.isProjector &&
|
||||||
!SystemInfo.isWebswing &&
|
!SystemInfo.isWebswing &&
|
||||||
!SystemInfo.isWinPE &&
|
!SystemInfo.isWinPE &&
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class FlatPopupMenuUI
|
|||||||
|
|
||||||
LayoutManager layout = popupMenu.getLayout();
|
LayoutManager layout = popupMenu.getLayout();
|
||||||
if( layout == null || layout instanceof UIResource )
|
if( layout == null || layout instanceof UIResource )
|
||||||
popupMenu.setLayout( new FlatMenuLayout( popupMenu, BoxLayout.Y_AXIS ) );
|
popupMenu.setLayout( new FlatPopupMenuLayout( popupMenu, BoxLayout.Y_AXIS ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -230,12 +230,15 @@ public class FlatPopupMenuUI
|
|||||||
return screenBounds.height - screenInsets.top - screenInsets.bottom;
|
return screenBounds.height - screenInsets.top - screenInsets.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatMenuLayout -----------------------------------------------
|
//---- class FlatPopupMenuLayout ------------------------------------------
|
||||||
|
|
||||||
protected static class FlatMenuLayout
|
/**
|
||||||
|
* @since 2.4
|
||||||
|
*/
|
||||||
|
protected static class FlatPopupMenuLayout
|
||||||
extends DefaultMenuLayout
|
extends DefaultMenuLayout
|
||||||
{
|
{
|
||||||
public FlatMenuLayout( Container target, int axis ) {
|
public FlatPopupMenuLayout( Container target, int axis ) {
|
||||||
super( target, axis );
|
super( target, axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,12 @@ public class FlatRootPaneUI
|
|||||||
((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded();
|
((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.4 */
|
||||||
|
protected static FlatTitlePane getTitlePane( JRootPane rootPane ) {
|
||||||
|
RootPaneUI ui = rootPane.getUI();
|
||||||
|
return ui instanceof FlatRootPaneUI ? ((FlatRootPaneUI)ui).titlePane : null;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatRootLayout -----------------------------------------------
|
//---- class FlatRootLayout -----------------------------------------------
|
||||||
|
|
||||||
protected class FlatRootLayout
|
protected class FlatRootLayout
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import javax.swing.event.MouseInputListener;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||||
|
import javax.swing.table.JTableHeader;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
import javax.swing.table.TableColumnModel;
|
import javax.swing.table.TableColumnModel;
|
||||||
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;
|
||||||
@@ -195,6 +197,8 @@ public class FlatTableHeaderUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
fixDraggedAndResizingColumns( header );
|
||||||
|
|
||||||
TableColumnModel columnModel = header.getColumnModel();
|
TableColumnModel columnModel = header.getColumnModel();
|
||||||
if( columnModel.getColumnCount() <= 0 )
|
if( columnModel.getColumnCount() <= 0 )
|
||||||
return;
|
return;
|
||||||
@@ -269,6 +273,32 @@ public class FlatTableHeaderUI
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fixDraggedAndResizingColumns( JTableHeader header ) {
|
||||||
|
if( header == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Dragged column may be outdated in the case that the table structure
|
||||||
|
// was changed from a table header popup menu action. In this case
|
||||||
|
// the paint methods in BasicTableHeaderUI and BasicTableUI would throw exceptions.
|
||||||
|
TableColumn draggedColumn = header.getDraggedColumn();
|
||||||
|
if( draggedColumn != null && !isValidColumn( header.getColumnModel(), draggedColumn ) )
|
||||||
|
header.setDraggedColumn( null );
|
||||||
|
|
||||||
|
// also clear outdated resizing column (although this seems not cause exceptions)
|
||||||
|
TableColumn resizingColumn = header.getResizingColumn();
|
||||||
|
if( resizingColumn != null && !isValidColumn( header.getColumnModel(), resizingColumn ) )
|
||||||
|
header.setResizingColumn( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidColumn( TableColumnModel cm, TableColumn column ) {
|
||||||
|
int count = cm.getColumnCount();
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
if( cm.getColumn( i ) == column )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Table.intercellSpacing Dimension
|
* @uiDefault Table.intercellSpacing Dimension
|
||||||
* @uiDefault Table.selectionInactiveBackground Color
|
* @uiDefault Table.selectionInactiveBackground Color
|
||||||
* @uiDefault Table.selectionInactiveForeground Color
|
* @uiDefault Table.selectionInactiveForeground Color
|
||||||
|
* @uiDefault Table.paintOutsideAlternateRows boolean
|
||||||
*
|
*
|
||||||
* <!-- FlatTableCellBorder -->
|
* <!-- FlatTableCellBorder -->
|
||||||
*
|
*
|
||||||
@@ -95,7 +96,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatTableUI
|
public class FlatTableUI
|
||||||
extends BasicTableUI
|
extends BasicTableUI
|
||||||
implements StyleableUI
|
implements StyleableUI, FlatViewportUI.ViewportPainter
|
||||||
{
|
{
|
||||||
protected boolean showHorizontalLines;
|
protected boolean showHorizontalLines;
|
||||||
protected boolean showVerticalLines;
|
protected boolean showVerticalLines;
|
||||||
@@ -313,6 +314,8 @@ public class FlatTableUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
FlatTableHeaderUI.fixDraggedAndResizingColumns( table.getTableHeader() );
|
||||||
|
|
||||||
boolean horizontalLines = table.getShowHorizontalLines();
|
boolean horizontalLines = table.getShowHorizontalLines();
|
||||||
boolean verticalLines = table.getShowVerticalLines();
|
boolean verticalLines = table.getShowVerticalLines();
|
||||||
if( horizontalLines || verticalLines ) {
|
if( horizontalLines || verticalLines ) {
|
||||||
@@ -421,4 +424,38 @@ public class FlatTableUI
|
|||||||
? (viewport != rowHeader)
|
? (viewport != rowHeader)
|
||||||
: (viewport == rowHeader || rowHeader == null);
|
: (viewport == rowHeader || rowHeader == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
@Override
|
||||||
|
public void paintViewport( Graphics g, JComponent c, JViewport viewport ) {
|
||||||
|
int viewportWidth = viewport.getWidth();
|
||||||
|
int viewportHeight = viewport.getHeight();
|
||||||
|
|
||||||
|
// fill viewport background in same color as table background
|
||||||
|
if( viewport.isOpaque() ) {
|
||||||
|
g.setColor( table.getBackground() );
|
||||||
|
g.fillRect( 0, 0, viewportWidth, viewportHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint alternating empty rows
|
||||||
|
boolean paintOutside = UIManager.getBoolean( "Table.paintOutsideAlternateRows" );
|
||||||
|
Color alternateColor;
|
||||||
|
if( paintOutside && (alternateColor = UIManager.getColor( "Table.alternateRowColor" )) != null ) {
|
||||||
|
g.setColor( alternateColor );
|
||||||
|
|
||||||
|
int rowCount = table.getRowCount();
|
||||||
|
|
||||||
|
// paint alternating empty rows below the table
|
||||||
|
int tableHeight = table.getHeight();
|
||||||
|
if( tableHeight < viewportHeight ) {
|
||||||
|
int tableWidth = table.getWidth();
|
||||||
|
int rowHeight = table.getRowHeight();
|
||||||
|
|
||||||
|
for( int y = tableHeight, row = rowCount; y < viewportHeight; y += rowHeight, row++ ) {
|
||||||
|
if( row % 2 != 0 )
|
||||||
|
g.fillRect( 0, y, tableWidth, rowHeight );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.awt.Container;
|
|||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.GraphicsConfiguration;
|
import java.awt.GraphicsConfiguration;
|
||||||
@@ -50,13 +51,13 @@ import javax.accessibility.AccessibleContext;
|
|||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.AbstractBorder;
|
import javax.swing.border.AbstractBorder;
|
||||||
@@ -83,10 +84,14 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TitlePane.iconMargins Insets
|
* @uiDefault TitlePane.iconMargins Insets
|
||||||
* @uiDefault TitlePane.titleMargins Insets
|
* @uiDefault TitlePane.titleMargins Insets
|
||||||
* @uiDefault TitlePane.menuBarEmbedded boolean
|
* @uiDefault TitlePane.menuBarEmbedded boolean
|
||||||
|
* @uiDefault TitlePane.titleMinimumWidth int
|
||||||
|
* @uiDefault TitlePane.buttonMinimumWidth int
|
||||||
* @uiDefault TitlePane.buttonMaximizedHeight int
|
* @uiDefault TitlePane.buttonMaximizedHeight int
|
||||||
* @uiDefault TitlePane.centerTitle boolean
|
* @uiDefault TitlePane.centerTitle boolean
|
||||||
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
|
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
|
||||||
|
* @uiDefault TitlePane.showIconBesideTitle boolean
|
||||||
* @uiDefault TitlePane.menuBarTitleGap int
|
* @uiDefault TitlePane.menuBarTitleGap int
|
||||||
|
* @uiDefault TitlePane.menuBarResizeHeight int
|
||||||
* @uiDefault TitlePane.closeIcon Icon
|
* @uiDefault TitlePane.closeIcon Icon
|
||||||
* @uiDefault TitlePane.iconifyIcon Icon
|
* @uiDefault TitlePane.iconifyIcon Icon
|
||||||
* @uiDefault TitlePane.maximizeIcon Icon
|
* @uiDefault TitlePane.maximizeIcon Icon
|
||||||
@@ -107,10 +112,15 @@ public class FlatTitlePane
|
|||||||
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
||||||
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
||||||
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||||
|
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 );
|
||||||
|
/** @since 2.4 */ protected final int buttonMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.buttonMinimumWidth", 30 );
|
||||||
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
||||||
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
|
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
|
||||||
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true );
|
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true );
|
||||||
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 20 );
|
/** @since 2.4 */ protected final boolean showIconBesideTitle = UIManager.getBoolean( "TitlePane.showIconBesideTitle" );
|
||||||
|
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 40 );
|
||||||
|
/** @since 2.4 */ protected final int menuBarTitleMinimumGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleMinimumGap", 12 );
|
||||||
|
/** @since 2.4 */ protected final int menuBarResizeHeight = FlatUIUtils.getUIInt( "TitlePane.menuBarResizeHeight", 4 );
|
||||||
|
|
||||||
protected final JRootPane rootPane;
|
protected final JRootPane rootPane;
|
||||||
|
|
||||||
@@ -142,6 +152,8 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
// necessary for closing window with double-click on icon
|
// necessary for closing window with double-click on icon
|
||||||
iconLabel.addMouseListener( handler );
|
iconLabel.addMouseListener( handler );
|
||||||
|
|
||||||
|
applyComponentOrientation( rootPane.getComponentOrientation() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
||||||
@@ -163,7 +175,6 @@ public class FlatTitlePane
|
|||||||
};
|
};
|
||||||
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
|
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
|
||||||
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
|
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
|
||||||
titleLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
|
|
||||||
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
||||||
leftPanel.setOpaque( false );
|
leftPanel.setOpaque( false );
|
||||||
@@ -183,18 +194,52 @@ public class FlatTitlePane
|
|||||||
setLayout( new BorderLayout() {
|
setLayout( new BorderLayout() {
|
||||||
@Override
|
@Override
|
||||||
public void layoutContainer( Container target ) {
|
public void layoutContainer( Container target ) {
|
||||||
super.layoutContainer( target );
|
// compute available bounds
|
||||||
|
|
||||||
// make left panel (with embedded menu bar) smaller if horizontal space is rare
|
|
||||||
// to avoid that embedded menu bar overlaps button bar
|
|
||||||
Insets insets = target.getInsets();
|
Insets insets = target.getInsets();
|
||||||
int width = target.getWidth() - insets.left - insets.right;
|
int x = insets.left;
|
||||||
if( leftPanel.getWidth() + buttonPanel.getWidth() > width ) {
|
int y = insets.top;
|
||||||
int oldWidth = leftPanel.getWidth();
|
int w = target.getWidth() - insets.left - insets.right;
|
||||||
int newWidth = Math.max( width - buttonPanel.getWidth(), 0 );
|
int h = target.getHeight() - insets.top - insets.bottom;
|
||||||
leftPanel.setSize( newWidth, leftPanel.getHeight() );
|
|
||||||
if( !getComponentOrientation().isLeftToRight() )
|
// compute widths
|
||||||
leftPanel.setLocation( leftPanel.getX() + (oldWidth - newWidth), leftPanel.getY() );
|
int leftWidth = leftPanel.getPreferredSize().width;
|
||||||
|
int buttonsWidth = buttonPanel.getPreferredSize().width;
|
||||||
|
int titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
int minTitleWidth = UIScale.scale( titleMinimumWidth );
|
||||||
|
|
||||||
|
// increase minimum width if icon is show besides the title
|
||||||
|
Icon icon = titleLabel.getIcon();
|
||||||
|
if( icon != null ) {
|
||||||
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
|
int iconTextGap = titleLabel.getComponentOrientation().isLeftToRight() ? iconInsets.right : iconInsets.left;
|
||||||
|
minTitleWidth += icon.getIconWidth() + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if title is too small, reduce width of buttons
|
||||||
|
if( titleWidth < minTitleWidth ) {
|
||||||
|
buttonsWidth = Math.max( buttonsWidth - (minTitleWidth - titleWidth), buttonPanel.getMinimumSize().width );
|
||||||
|
titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if title is still too small, reduce width of left panel (icon and embedded menu bar)
|
||||||
|
if( titleWidth < minTitleWidth ) {
|
||||||
|
int minLeftWidth = iconLabel.isVisible()
|
||||||
|
? iconLabel.getWidth() - iconLabel.getInsets().right
|
||||||
|
: UIScale.scale( noIconLeftGap );
|
||||||
|
leftWidth = Math.max( leftWidth - (minTitleWidth - titleWidth), minLeftWidth );
|
||||||
|
titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( target.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
// left-to-right
|
||||||
|
leftPanel.setBounds( x, y, leftWidth, h );
|
||||||
|
titleLabel.setBounds( x + leftWidth, y, titleWidth, h );
|
||||||
|
buttonPanel.setBounds( x + leftWidth + titleWidth, y, buttonsWidth, h );
|
||||||
|
} else {
|
||||||
|
// right-to-left
|
||||||
|
buttonPanel.setBounds( x, y, buttonsWidth, h );
|
||||||
|
titleLabel.setBounds( x + buttonsWidth, y, titleWidth, h );
|
||||||
|
leftPanel.setBounds( x + buttonsWidth + titleWidth, y, leftWidth, h );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If menu bar is embedded and contains a horizontal glue component,
|
// If menu bar is embedded and contains a horizontal glue component,
|
||||||
@@ -233,10 +278,7 @@ public class FlatTitlePane
|
|||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
Dimension size = super.getPreferredSize();
|
Dimension size = super.getPreferredSize();
|
||||||
if( buttonMaximizedHeight > 0 &&
|
if( buttonMaximizedHeight > 0 && isWindowMaximized() && !hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ) ) {
|
||||||
window instanceof Frame &&
|
|
||||||
(((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
|
||||||
{
|
|
||||||
// make title pane height smaller when frame is maximized
|
// make title pane height smaller when frame is maximized
|
||||||
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
||||||
}
|
}
|
||||||
@@ -259,7 +301,13 @@ 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( UIManager.getIcon( iconKey ) ) {
|
||||||
|
@Override
|
||||||
|
public Dimension getMinimumSize() {
|
||||||
|
// allow the button to shrink if space is rare
|
||||||
|
return new Dimension( UIScale.scale( buttonMinimumWidth ), super.getMinimumSize().height );
|
||||||
|
}
|
||||||
|
};
|
||||||
button.setFocusable( false );
|
button.setFocusable( false );
|
||||||
button.setContentAreaFilled( false );
|
button.setContentAreaFilled( false );
|
||||||
button.setBorder( BorderFactory.createEmptyBorder() );
|
button.setBorder( BorderFactory.createEmptyBorder() );
|
||||||
@@ -356,11 +404,12 @@ public class FlatTitlePane
|
|||||||
boolean hasIcon = (images != null && !images.isEmpty());
|
boolean hasIcon = (images != null && !images.isEmpty());
|
||||||
|
|
||||||
// set icon
|
// set icon
|
||||||
iconLabel.setIcon( hasIcon ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
iconLabel.setIcon( hasIcon && !showIconBesideTitle ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
||||||
|
titleLabel.setIcon( hasIcon && showIconBesideTitle ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
||||||
|
|
||||||
// show/hide icon
|
// show/hide icon
|
||||||
iconLabel.setVisible( hasIcon );
|
iconLabel.setVisible( hasIcon && !showIconBesideTitle );
|
||||||
leftPanel.setBorder( hasIcon ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) );
|
leftPanel.setBorder( hasIcon && !showIconBesideTitle ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) );
|
||||||
|
|
||||||
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
||||||
}
|
}
|
||||||
@@ -567,6 +616,11 @@ debug*/
|
|||||||
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
|
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.4 */
|
||||||
|
protected boolean isWindowMaximized() {
|
||||||
|
return window instanceof Frame && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximizes the window.
|
* Maximizes the window.
|
||||||
*/
|
*/
|
||||||
@@ -729,7 +783,7 @@ debug*/
|
|||||||
List<Rectangle> hitTestSpots = new ArrayList<>();
|
List<Rectangle> hitTestSpots = new ArrayList<>();
|
||||||
Rectangle appIconBounds = null;
|
Rectangle appIconBounds = null;
|
||||||
|
|
||||||
if( iconLabel.isVisible() ) {
|
if( !showIconBesideTitle && iconLabel.isVisible() ) {
|
||||||
// compute real icon size (without insets; 1px larger for easier hitting)
|
// compute real icon size (without insets; 1px larger for easier hitting)
|
||||||
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
|
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
|
||||||
Insets iconInsets = iconLabel.getInsets();
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
@@ -741,9 +795,7 @@ debug*/
|
|||||||
|
|
||||||
// if frame is maximized, increase icon bounds to upper-left corner
|
// if frame is maximized, increase icon bounds to upper-left corner
|
||||||
// of window to allow closing window via double-click in upper-left corner
|
// of window to allow closing window via double-click in upper-left corner
|
||||||
if( window instanceof Frame &&
|
if( isWindowMaximized() ) {
|
||||||
(((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
|
||||||
{
|
|
||||||
iconBounds.height += iconBounds.y;
|
iconBounds.height += iconBounds.y;
|
||||||
iconBounds.y = 0;
|
iconBounds.y = 0;
|
||||||
|
|
||||||
@@ -758,6 +810,38 @@ debug*/
|
|||||||
hitTestSpots.add( iconBounds );
|
hitTestSpots.add( iconBounds );
|
||||||
else
|
else
|
||||||
appIconBounds = iconBounds;
|
appIconBounds = iconBounds;
|
||||||
|
} else if( showIconBesideTitle && titleLabel.getIcon() != null && titleLabel.getUI() instanceof FlatTitleLabelUI ) {
|
||||||
|
FlatTitleLabelUI ui = (FlatTitleLabelUI) titleLabel.getUI();
|
||||||
|
|
||||||
|
// compute real icon bounds
|
||||||
|
Insets insets = titleLabel.getInsets();
|
||||||
|
Rectangle viewR = new Rectangle( insets.left, insets.top,
|
||||||
|
titleLabel.getWidth() - insets.left - insets.right,
|
||||||
|
titleLabel.getHeight() - insets.top - insets.bottom );
|
||||||
|
Rectangle iconR = new Rectangle();
|
||||||
|
Rectangle textR = new Rectangle();
|
||||||
|
ui.layoutCL( titleLabel, titleLabel.getFontMetrics( titleLabel.getFont() ),
|
||||||
|
titleLabel.getText(), titleLabel.getIcon(),
|
||||||
|
viewR, iconR, textR );
|
||||||
|
|
||||||
|
// Windows shows the window system menu only in the upper-left corner
|
||||||
|
if( iconR.x == 0 ) {
|
||||||
|
// convert icon location to window coordinates
|
||||||
|
Point location = SwingUtilities.convertPoint( titleLabel, 0, 0, window );
|
||||||
|
iconR.x += location.x;
|
||||||
|
iconR.y += location.y;
|
||||||
|
|
||||||
|
// make icon bounds 1px larger for easier hitting
|
||||||
|
iconR.x -= 1;
|
||||||
|
iconR.y -= 1;
|
||||||
|
iconR.width += 2;
|
||||||
|
iconR.height += 2;
|
||||||
|
|
||||||
|
if( hasJBRCustomDecoration() )
|
||||||
|
hitTestSpots.add( iconR );
|
||||||
|
else
|
||||||
|
appIconBounds = iconR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle r = getNativeHitTestSpot( buttonPanel );
|
Rectangle r = getNativeHitTestSpot( buttonPanel );
|
||||||
@@ -768,6 +852,15 @@ debug*/
|
|||||||
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
|
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
|
||||||
r = getNativeHitTestSpot( menuBar );
|
r = getNativeHitTestSpot( menuBar );
|
||||||
if( r != null ) {
|
if( r != null ) {
|
||||||
|
// if frame is resizable and not maximized, make menu bar hit test spot smaller at top
|
||||||
|
// to have a small area above the menu bar to resize the window
|
||||||
|
if( window instanceof Frame && ((Frame)window).isResizable() && !isWindowMaximized() ) {
|
||||||
|
// limit to 8, because Windows does not use a larger height
|
||||||
|
int resizeHeight = UIScale.scale( Math.min( menuBarResizeHeight, 8 ) );
|
||||||
|
r.y += resizeHeight;
|
||||||
|
r.height -= resizeHeight;
|
||||||
|
}
|
||||||
|
|
||||||
Component horizontalGlue = findHorizontalGlue( menuBar );
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
if( horizontalGlue != null ) {
|
if( horizontalGlue != null ) {
|
||||||
// If menu bar is embedded and contains a horizontal glue component,
|
// If menu bar is embedded and contains a horizontal glue component,
|
||||||
@@ -854,7 +947,7 @@ debug*/
|
|||||||
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
|
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
|
||||||
insets.bottom += UIScale.scale( 1 );
|
insets.bottom += UIScale.scale( 1 );
|
||||||
|
|
||||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) )
|
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||||
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
|
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
|
||||||
|
|
||||||
return insets;
|
return insets;
|
||||||
@@ -873,7 +966,7 @@ debug*/
|
|||||||
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
|
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) )
|
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||||
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,10 +974,6 @@ debug*/
|
|||||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getBorder() : null;
|
return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getBorder() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isWindowMaximized( Component c ) {
|
|
||||||
return window instanceof Frame && (((Frame) window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatTitleLabelUI ---------------------------------------------
|
//---- class FlatTitleLabelUI ---------------------------------------------
|
||||||
@@ -898,32 +987,101 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
protected String layoutCL( JLabel label, FontMetrics fontMetrics, String text, Icon icon,
|
||||||
boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() );
|
Rectangle viewR, Rectangle iconR, Rectangle textR )
|
||||||
int labelWidth = l.getWidth();
|
{
|
||||||
int textWidth = labelWidth - (textX * 2);
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
int gap = UIScale.scale( menuBarTitleGap );
|
boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( menuBar );
|
||||||
|
boolean hasEmbeddedLeadingMenus = hasEmbeddedMenuBar && hasLeadingMenus( menuBar );
|
||||||
|
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
// The passed in textX coordinate is always to horizontally center the text within the label bounds.
|
if( hasEmbeddedMenuBar ) {
|
||||||
// Modify textX so that the text is painted either centered within the window bounds or leading aligned.
|
int minGap = UIScale.scale( menuBarTitleMinimumGap );
|
||||||
boolean center = hasEmbeddedMenuBar ? centerTitleIfMenuBarEmbedded : centerTitle;
|
|
||||||
if( center ) {
|
// apply minimum leading gap (between embedded menu bar and title)
|
||||||
// If window is wide enough, center title within window bounds.
|
if( hasEmbeddedLeadingMenus ) {
|
||||||
// Otherwise, leave it centered within free space (label bounds).
|
if( leftToRight )
|
||||||
int centeredTextX = ((l.getParent().getWidth() - textWidth) / 2) - l.getX();
|
viewR.x += minGap;
|
||||||
if( centeredTextX >= gap && centeredTextX + textWidth <= labelWidth - gap )
|
viewR.width -= minGap;
|
||||||
textX = centeredTextX;
|
}
|
||||||
} else {
|
|
||||||
// leading aligned
|
// apply minimum trailing gap (between title and right aligned components of embedded menu bar)
|
||||||
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
Insets insets = l.getInsets();
|
if( horizontalGlue != null && menuBar.getComponent( menuBar.getComponentCount() - 1 ) != horizontalGlue ) {
|
||||||
int leadingInset = hasEmbeddedMenuBar ? gap : (leftToRight ? insets.left : insets.right);
|
if( !leftToRight )
|
||||||
int leadingTextX = leftToRight ? leadingInset : labelWidth - leadingInset - textWidth;
|
viewR.x += minGap;
|
||||||
if( leftToRight ? leadingTextX < textX : leadingTextX > textX )
|
viewR.width -= minGap;
|
||||||
textX = leadingTextX;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.paintEnabledText( l, g, s, textX, textY );
|
// compute icon width and gap (if icon is show besides the title)
|
||||||
|
int iconTextGap = 0;
|
||||||
|
int iconWidthAndGap = 0;
|
||||||
|
if( icon != null ) {
|
||||||
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
|
iconTextGap = leftToRight ? iconInsets.right : iconInsets.left;
|
||||||
|
iconWidthAndGap = icon.getIconWidth() + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// layout title and icon (if show besides the title)
|
||||||
|
String clippedText = SwingUtilities.layoutCompoundLabel( label, fontMetrics, text, icon,
|
||||||
|
label.getVerticalAlignment(), label.getHorizontalAlignment(),
|
||||||
|
label.getVerticalTextPosition(), label.getHorizontalTextPosition(),
|
||||||
|
viewR, iconR, textR,
|
||||||
|
iconTextGap );
|
||||||
|
|
||||||
|
// compute text X location
|
||||||
|
if( !clippedText.equals( text ) ) {
|
||||||
|
// if text is clipped, align to left (or right)
|
||||||
|
textR.x = leftToRight
|
||||||
|
? viewR.x + iconWidthAndGap
|
||||||
|
: viewR.x + viewR.width - iconWidthAndGap - textR.width;
|
||||||
|
} else {
|
||||||
|
int leadingGap = hasEmbeddedLeadingMenus ? UIScale.scale( menuBarTitleGap - menuBarTitleMinimumGap ) : 0;
|
||||||
|
|
||||||
|
boolean center = hasEmbeddedLeadingMenus ? centerTitleIfMenuBarEmbedded : centerTitle;
|
||||||
|
if( center ) {
|
||||||
|
// If window is wide enough, center title within window bounds.
|
||||||
|
// Otherwise, center within free space (label bounds).
|
||||||
|
Container parent = label.getParent();
|
||||||
|
int centeredTextX = (parent != null) ? ((parent.getWidth() - textR.width - iconWidthAndGap) / 2) + iconWidthAndGap - label.getX() : -1;
|
||||||
|
textR.x = (centeredTextX >= viewR.x + leadingGap && centeredTextX + textR.width <= viewR.x + viewR.width - leadingGap)
|
||||||
|
? centeredTextX
|
||||||
|
: viewR.x + ((viewR.width - textR.width - iconWidthAndGap) / 2) + iconWidthAndGap;
|
||||||
|
} else {
|
||||||
|
// leading aligned with leading gap, which is reduced if space is rare
|
||||||
|
textR.x = leftToRight
|
||||||
|
? Math.min( viewR.x + leadingGap + iconWidthAndGap, viewR.x + viewR.width - textR.width )
|
||||||
|
: Math.max( viewR.x + viewR.width - leadingGap - iconWidthAndGap - textR.width, viewR.x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute icon X location (relative to text X location)
|
||||||
|
if( icon != null ) {
|
||||||
|
iconR.x = leftToRight
|
||||||
|
? textR.x - iconWidthAndGap
|
||||||
|
: textR.x + textR.width + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clippedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasLeadingMenus( JMenuBar menuBar ) {
|
||||||
|
// check whether menu bar is empty
|
||||||
|
if( menuBar.getComponentCount() == 0 || menuBar.getWidth() == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check whether menu bar has a leading glue component
|
||||||
|
// (no menus/components at left side)
|
||||||
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
|
if( horizontalGlue != null ) {
|
||||||
|
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
||||||
|
if( (leftToRight && horizontalGlue.getX() == 0) ||
|
||||||
|
(!leftToRight && horizontalGlue.getX() + horizontalGlue.getWidth() == menuBar.getWidth()) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import java.awt.Component;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.*;
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JToggleButton;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||||
@@ -51,15 +48,29 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault ToggleButton.iconTextGap int
|
* @uiDefault ToggleButton.iconTextGap int
|
||||||
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
||||||
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault ToggleButton.pressedBackground Color
|
* @uiDefault ToggleButton.focusedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.focusedForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.hoverBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.hoverForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.pressedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.pressedForeground Color optional
|
||||||
* @uiDefault ToggleButton.selectedBackground Color
|
* @uiDefault ToggleButton.selectedBackground Color
|
||||||
* @uiDefault ToggleButton.selectedForeground Color
|
* @uiDefault ToggleButton.selectedForeground Color
|
||||||
* @uiDefault ToggleButton.disabledBackground Color optional
|
* @uiDefault ToggleButton.disabledBackground Color optional
|
||||||
* @uiDefault ToggleButton.disabledText Color
|
* @uiDefault ToggleButton.disabledText Color
|
||||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||||
|
* @uiDefault ToggleButton.disabledSelectedForeground Color optional
|
||||||
|
* @uiDefault Button.paintShadow boolean default is false
|
||||||
|
* @uiDefault Button.shadowWidth int default is 2
|
||||||
|
* @uiDefault Button.shadowColor Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.hoverForeground Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.pressedForeground Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.selectedForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.toolbar.disabledSelectedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.toolbar.disabledSelectedForeground Color optional
|
||||||
*
|
*
|
||||||
* <!-- FlatToggleButtonUI -->
|
* <!-- FlatToggleButtonUI -->
|
||||||
*
|
*
|
||||||
@@ -67,8 +78,11 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault ToggleButton.tab.underlineColor Color
|
* @uiDefault ToggleButton.tab.underlineColor Color
|
||||||
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
||||||
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.tab.selectedForeground Color optional
|
||||||
* @uiDefault ToggleButton.tab.hoverBackground Color
|
* @uiDefault ToggleButton.tab.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.tab.hoverForeground Color optional
|
||||||
* @uiDefault ToggleButton.tab.focusBackground Color
|
* @uiDefault ToggleButton.tab.focusBackground Color
|
||||||
|
* @uiDefault ToggleButton.tab.focusForeground Color optional
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -80,8 +94,11 @@ public class FlatToggleButtonUI
|
|||||||
@Styleable(dot=true) protected Color tabUnderlineColor;
|
@Styleable(dot=true) protected Color tabUnderlineColor;
|
||||||
@Styleable(dot=true) protected Color tabDisabledUnderlineColor;
|
@Styleable(dot=true) protected Color tabDisabledUnderlineColor;
|
||||||
@Styleable(dot=true) protected Color tabSelectedBackground;
|
@Styleable(dot=true) protected Color tabSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabSelectedForeground;
|
||||||
@Styleable(dot=true) protected Color tabHoverBackground;
|
@Styleable(dot=true) protected Color tabHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabHoverForeground;
|
||||||
@Styleable(dot=true) protected Color tabFocusBackground;
|
@Styleable(dot=true) protected Color tabFocusBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabFocusForeground;
|
||||||
|
|
||||||
private boolean defaults_initialized = false;
|
private boolean defaults_initialized = false;
|
||||||
|
|
||||||
@@ -114,8 +131,11 @@ public class FlatToggleButtonUI
|
|||||||
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
||||||
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
||||||
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
||||||
|
tabSelectedForeground = UIManager.getColor( "ToggleButton.tab.selectedForeground" );
|
||||||
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
||||||
|
tabHoverForeground = UIManager.getColor( "ToggleButton.tab.hoverForeground" );
|
||||||
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
||||||
|
tabFocusForeground = UIManager.getColor( "ToggleButton.tab.focusForeground" );
|
||||||
|
|
||||||
defaults_initialized = true;
|
defaults_initialized = true;
|
||||||
}
|
}
|
||||||
@@ -142,6 +162,7 @@ public class FlatToggleButtonUI
|
|||||||
b.repaint();
|
b.repaint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TAB_BUTTON_UNDERLINE_PLACEMENT:
|
||||||
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
||||||
case TAB_BUTTON_UNDERLINE_COLOR:
|
case TAB_BUTTON_UNDERLINE_COLOR:
|
||||||
case TAB_BUTTON_SELECTED_BACKGROUND:
|
case TAB_BUTTON_SELECTED_BACKGROUND:
|
||||||
@@ -196,13 +217,42 @@ public class FlatToggleButtonUI
|
|||||||
|
|
||||||
// paint underline if selected
|
// paint underline if selected
|
||||||
if( selected ) {
|
if( selected ) {
|
||||||
int underlineHeight = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
int underlineThickness = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
||||||
g.setColor( c.isEnabled()
|
g.setColor( c.isEnabled()
|
||||||
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
||||||
: tabDisabledUnderlineColor );
|
: tabDisabledUnderlineColor );
|
||||||
g.fillRect( 0, height - underlineHeight, width, underlineHeight );
|
int placement = clientPropertyInt( c, TAB_BUTTON_UNDERLINE_PLACEMENT, SwingConstants.BOTTOM );
|
||||||
|
switch (placement) {
|
||||||
|
case SwingConstants.TOP:
|
||||||
|
g.fillRect( 0, 0, width, underlineThickness );
|
||||||
|
break;
|
||||||
|
case SwingConstants.LEFT:
|
||||||
|
g.fillRect( 0, 0, underlineThickness, height );
|
||||||
|
break;
|
||||||
|
case SwingConstants.RIGHT:
|
||||||
|
g.fillRect( width - underlineThickness, 0, underlineThickness, height );
|
||||||
|
break;
|
||||||
|
case SwingConstants.BOTTOM:
|
||||||
|
default:
|
||||||
|
g.fillRect( 0, height - underlineThickness, width, underlineThickness );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
super.paintBackground( g, c );
|
super.paintBackground( g, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Color getForeground( JComponent c ) {
|
||||||
|
if( isTabButton( c ) ) {
|
||||||
|
if( !c.isEnabled() )
|
||||||
|
return disabledText;
|
||||||
|
|
||||||
|
if( tabSelectedForeground != null && ((AbstractButton)c).isSelected() )
|
||||||
|
return tabSelectedForeground;
|
||||||
|
|
||||||
|
return buttonStateColor( c, c.getForeground(), disabledText,
|
||||||
|
tabFocusForeground, tabHoverForeground, null );
|
||||||
|
} else
|
||||||
|
return super.getForeground( c );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicViewportUI;
|
import javax.swing.plaf.basic.BasicViewportUI;
|
||||||
@@ -43,15 +43,28 @@ public class FlatViewportUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
Component view = ((JViewport)c).getView();
|
super.paint( g, c );
|
||||||
if( c.isOpaque() && view instanceof JTable ) {
|
|
||||||
// paint viewport background in same color as table background
|
|
||||||
g.setColor( view.getBackground() );
|
|
||||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
|
||||||
|
|
||||||
paint( g, c );
|
Component view = ((JViewport)c).getView();
|
||||||
} else
|
if( view instanceof JComponent ) {
|
||||||
super.update( g, c );
|
try {
|
||||||
|
Method m = view.getClass().getMethod( "getUI" );
|
||||||
|
Object ui = m.invoke( view );
|
||||||
|
if( ui instanceof ViewportPainter )
|
||||||
|
((ViewportPainter)ui).paintViewport( g, (JComponent) view, (JViewport) c );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface ViewportPainter ------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public interface ViewportPainter {
|
||||||
|
void paintViewport( Graphics g, JComponent c, JViewport viewport );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.awt.Window;
|
|||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -38,9 +37,7 @@ import javax.swing.Timer;
|
|||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import javax.swing.event.EventListenerList;
|
import javax.swing.event.EventListenerList;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.NativeLibrary;
|
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -84,7 +81,6 @@ class FlatWindowsNativeWindowBorder
|
|||||||
private Color colorizationColor;
|
private Color colorizationColor;
|
||||||
private int colorizationColorBalance;
|
private int colorizationColorBalance;
|
||||||
|
|
||||||
private static NativeLibrary nativeLibrary;
|
|
||||||
private static FlatWindowsNativeWindowBorder instance;
|
private static FlatWindowsNativeWindowBorder instance;
|
||||||
|
|
||||||
static FlatNativeWindowBorder.Provider getInstance() {
|
static FlatNativeWindowBorder.Provider getInstance() {
|
||||||
@@ -96,31 +92,8 @@ class FlatWindowsNativeWindowBorder
|
|||||||
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
|
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// load native library
|
|
||||||
if( nativeLibrary == null ) {
|
|
||||||
if( !SystemInfo.isJava_9_orLater ) {
|
|
||||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
|
||||||
// is not found when running application with <jdk>/bin/java.exe.
|
|
||||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
|
||||||
// jawt.dll is located in <jdk>/jre/bin/.
|
|
||||||
// Java 9 and later does not have this problem.
|
|
||||||
try {
|
|
||||||
System.loadLibrary( "jawt" );
|
|
||||||
} catch( UnsatisfiedLinkError ex ) {
|
|
||||||
// log error only if native library jawt.dll not already loaded
|
|
||||||
String message = ex.getMessage();
|
|
||||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nativeLibrary = createNativeLibrary();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether native library was successfully loaded
|
// check whether native library was successfully loaded
|
||||||
if( !nativeLibrary.isLoaded() )
|
if( !FlatNativeLibrary.isLoaded() )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// create new instance
|
// create new instance
|
||||||
@@ -129,23 +102,6 @@ class FlatWindowsNativeWindowBorder
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeLibrary createNativeLibrary() {
|
|
||||||
String libraryName = "flatlaf-windows-x86";
|
|
||||||
if( SystemInfo.isX86_64 )
|
|
||||||
libraryName += "_64";
|
|
||||||
|
|
||||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
|
||||||
if( libraryPath != null ) {
|
|
||||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
|
||||||
if( libraryFile.exists() )
|
|
||||||
return new NativeLibrary( libraryFile, true );
|
|
||||||
else
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
private FlatWindowsNativeWindowBorder() {
|
private FlatWindowsNativeWindowBorder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,11 +195,13 @@ public class JBRCustomDecorations
|
|||||||
{
|
{
|
||||||
private static JBRWindowTopBorder instance;
|
private static JBRWindowTopBorder instance;
|
||||||
|
|
||||||
private final Color defaultActiveBorder = new Color( 0x707070 );
|
private final Color activeLightColor = new Color( 0x707070 );
|
||||||
|
private final Color activeDarkColor = new Color( 0x2D2E2F );
|
||||||
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
||||||
|
private final Color inactiveDarkColor = new Color( 0x494A4B );
|
||||||
|
|
||||||
private boolean colorizationAffectsBorders;
|
private boolean colorizationAffectsBorders;
|
||||||
private Color activeColor = defaultActiveBorder;
|
private Color activeColor;
|
||||||
|
|
||||||
static JBRWindowTopBorder getInstance() {
|
static JBRWindowTopBorder getInstance() {
|
||||||
if( instance == null )
|
if( instance == null )
|
||||||
@@ -250,7 +252,7 @@ public class JBRCustomDecorations
|
|||||||
|
|
||||||
private Color calculateActiveBorderColor() {
|
private Color calculateActiveBorderColor() {
|
||||||
if( !colorizationAffectsBorders )
|
if( !colorizationAffectsBorders )
|
||||||
return defaultActiveBorder;
|
return null;
|
||||||
|
|
||||||
Color colorizationColor = getColorizationColor();
|
Color colorizationColor = getColorizationColor();
|
||||||
if( colorizationColor != null ) {
|
if( colorizationColor != null ) {
|
||||||
@@ -285,15 +287,11 @@ public class JBRCustomDecorations
|
|||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
Window window = SwingUtilities.windowForComponent( c );
|
Window window = SwingUtilities.windowForComponent( c );
|
||||||
boolean active = window != null && window.isActive();
|
boolean active = window != null && window.isActive();
|
||||||
|
boolean dark = FlatLaf.isLafDark();
|
||||||
|
|
||||||
// paint top border
|
g.setColor( active
|
||||||
// - in light themes
|
? (activeColor != null ? activeColor : (dark ? activeDarkColor : activeLightColor))
|
||||||
// - in dark themes only for active windows if colorization affects borders
|
: (dark ? inactiveDarkColor : inactiveLightColor) );
|
||||||
boolean paintTopBorder = !FlatLaf.isLafDark() || (active && colorizationAffectsBorders);
|
|
||||||
if( !paintTopBorder )
|
|
||||||
return;
|
|
||||||
|
|
||||||
g.setColor( active ? activeColor : inactiveLightColor );
|
|
||||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ public class MigLayoutVisualPadding
|
|||||||
//---- class FlatMigInsets ------------------------------------------------
|
//---- class FlatMigInsets ------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker class to identify our visual paddings and leaf paddings,
|
* Marker class to identify our visual paddings and leave paddings
|
||||||
* which were set from outside, untouched.
|
* set from outside untouched.
|
||||||
*/
|
*/
|
||||||
private static class FlatMigInsets
|
private static class FlatMigInsets
|
||||||
extends Insets
|
extends Insets
|
||||||
|
|||||||
@@ -48,30 +48,55 @@ public class HiDPIUtils
|
|||||||
*/
|
*/
|
||||||
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height, Painter painter ) {
|
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height, Painter painter ) {
|
||||||
// save original transform
|
// save original transform
|
||||||
AffineTransform transform = g.getTransform();
|
AffineTransform t = g.getTransform();
|
||||||
|
|
||||||
|
// get scale X/Y and shear X/Y
|
||||||
|
double scaleX = t.getScaleX();
|
||||||
|
double scaleY = t.getScaleY();
|
||||||
|
double shearX = t.getShearX();
|
||||||
|
double shearY = t.getShearY();
|
||||||
|
|
||||||
|
// check whether rotated
|
||||||
|
// (also check for negative scale X/Y because shear X/Y are zero for 180 degrees rotation)
|
||||||
|
boolean rotated = (shearX != 0 || shearY != 0 || scaleX <= 0 || scaleY <= 0);
|
||||||
|
if( rotated ) {
|
||||||
|
// resulting scale X/Y values are always positive
|
||||||
|
scaleX = Math.hypot( scaleX, shearX );
|
||||||
|
scaleY = Math.hypot( scaleY, shearY );
|
||||||
|
} else {
|
||||||
|
// make scale X/Y positive
|
||||||
|
scaleX = Math.abs( scaleX );
|
||||||
|
scaleY = Math.abs( scaleY );
|
||||||
|
}
|
||||||
|
|
||||||
// check whether scaled
|
// check whether scaled
|
||||||
if( transform.getScaleX() == 1 && transform.getScaleY() == 1 ) {
|
if( scaleX == 1 && scaleY == 1 ) {
|
||||||
painter.paint( g, x, y, width, height, 1 );
|
painter.paint( g, x, y, width, height, 1 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale rectangle
|
// scale rectangle
|
||||||
Rectangle2D.Double scaledRect = scale( transform, x, y, width, height );
|
Rectangle2D.Double scaledRect = scale( scaleX, scaleY, t, x, y, width, height );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// unscale to factor 1.0 and move origin (to whole numbers)
|
// unscale to factor 1.0, keep rotation and move origin (to whole numbers)
|
||||||
g.setTransform( new AffineTransform( 1, 0, 0, 1,
|
AffineTransform t1x;
|
||||||
Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) ) );
|
if( rotated ) {
|
||||||
|
t1x = new AffineTransform( t.getScaleX(), t.getShearY(), t.getShearX(), t.getScaleY(),
|
||||||
|
Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) );
|
||||||
|
t1x.scale( 1. / scaleX, 1. / scaleY );
|
||||||
|
} else
|
||||||
|
t1x = new AffineTransform( 1, 0, 0, 1, Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) );
|
||||||
|
g.setTransform( t1x );
|
||||||
|
|
||||||
int swidth = (int) scaledRect.width;
|
int swidth = (int) scaledRect.width;
|
||||||
int sheight = (int) scaledRect.height;
|
int sheight = (int) scaledRect.height;
|
||||||
|
|
||||||
// paint
|
// paint
|
||||||
painter.paint( g, 0, 0, swidth, sheight, transform.getScaleX() );
|
painter.paint( g, 0, 0, swidth, sheight, scaleX );
|
||||||
} finally {
|
} finally {
|
||||||
// restore original transform
|
// restore original transform
|
||||||
g.setTransform( transform );
|
g.setTransform( t );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,20 +105,16 @@ public class HiDPIUtils
|
|||||||
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
||||||
* which is used by Graphics.fillRect().
|
* which is used by Graphics.fillRect().
|
||||||
*/
|
*/
|
||||||
private static Rectangle2D.Double scale( AffineTransform transform, int x, int y, int width, int height ) {
|
private static Rectangle2D.Double scale( double scaleX, double scaleY, AffineTransform t, int x, int y, int width, int height ) {
|
||||||
double dx1 = transform.getScaleX();
|
double px = (x * scaleX) + t.getTranslateX();
|
||||||
double dy2 = transform.getScaleY();
|
double py = (y * scaleY) + t.getTranslateY();
|
||||||
double px = x * dx1 + transform.getTranslateX();
|
|
||||||
double py = y * dy2 + transform.getTranslateY();
|
|
||||||
dx1 *= width;
|
|
||||||
dy2 *= height;
|
|
||||||
|
|
||||||
double newx = normalize( px );
|
double newX = normalize( px );
|
||||||
double newy = normalize( py );
|
double newY = normalize( py );
|
||||||
dx1 = normalize( px + dx1 ) - newx;
|
double newWidth = normalize( px + (width * scaleX) ) - newX;
|
||||||
dy2 = normalize( py + dy2 ) - newy;
|
double newHeight = normalize( py + (height * scaleY) ) - newY;
|
||||||
|
|
||||||
return new Rectangle2D.Double( newx, newy, dx1, dy2 );
|
return new Rectangle2D.Double( newX, newY, newWidth, newHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double normalize( double value ) {
|
private static double normalize( double value ) {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class SystemInfo
|
|||||||
public static final long javaVersion;
|
public static final long javaVersion;
|
||||||
public static final boolean isJava_9_orLater;
|
public static final boolean isJava_9_orLater;
|
||||||
public static final boolean isJava_11_orLater;
|
public static final boolean isJava_11_orLater;
|
||||||
|
/** @since 2.3 */ public static final boolean isJava_12_orLater;
|
||||||
public static final boolean isJava_15_orLater;
|
public static final boolean isJava_15_orLater;
|
||||||
/** @since 2 */ public static final boolean isJava_17_orLater;
|
/** @since 2 */ public static final boolean isJava_17_orLater;
|
||||||
/** @since 2 */ public static final boolean isJava_18_orLater;
|
/** @since 2 */ public static final boolean isJava_18_orLater;
|
||||||
@@ -66,6 +67,9 @@ public class SystemInfo
|
|||||||
/** @since 1.1.2 */ public static final boolean isWebswing;
|
/** @since 1.1.2 */ public static final boolean isWebswing;
|
||||||
/** @since 1.1.1 */ public static final boolean isWinPE;
|
/** @since 1.1.1 */ public static final boolean isWinPE;
|
||||||
|
|
||||||
|
// features
|
||||||
|
/** @since 2.3 */ public static final boolean isMacFullWindowContentSupported;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// platforms
|
// platforms
|
||||||
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
||||||
@@ -92,6 +96,7 @@ public class SystemInfo
|
|||||||
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||||
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||||
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||||
|
isJava_12_orLater = (javaVersion >= toVersion( 12, 0, 0, 0 ));
|
||||||
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||||
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
|
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
|
||||||
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
|
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
|
||||||
@@ -108,6 +113,12 @@ public class SystemInfo
|
|||||||
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
||||||
isWebswing = (System.getProperty( "webswing.rootDir" ) != null);
|
isWebswing = (System.getProperty( "webswing.rootDir" ) != null);
|
||||||
isWinPE = isWindows && "X:\\Windows\\System32".equalsIgnoreCase( System.getProperty( "user.dir" ) );
|
isWinPE = isWindows && "X:\\Windows\\System32".equalsIgnoreCase( System.getProperty( "user.dir" ) );
|
||||||
|
|
||||||
|
// features
|
||||||
|
// available since Java 12; backported to Java 11.0.8 and 8u292
|
||||||
|
isMacFullWindowContentSupported =
|
||||||
|
javaVersion >= toVersion( 11, 0, 8, 0 ) ||
|
||||||
|
(javaVersion >= toVersion( 1, 8, 0, 292 ) && !isJava_9_orLater);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long scanVersion( String version ) {
|
public static long scanVersion( String version ) {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ light.font = +0
|
|||||||
semibold.font = +0
|
semibold.font = +0
|
||||||
|
|
||||||
# monospaced
|
# monospaced
|
||||||
[win]monospaced.font = Consolas, "Courier New", Monospaced
|
[win]monospaced.font = Monospaced
|
||||||
[mac]monospaced.font = Menlo, Monospaced
|
[mac]monospaced.font = Menlo, Monospaced
|
||||||
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
|
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
|
||||||
monospaced.font = Monospaced
|
monospaced.font = Monospaced
|
||||||
@@ -789,11 +789,16 @@ TitlePane.noIconLeftGap = 8
|
|||||||
TitlePane.iconSize = 16,16
|
TitlePane.iconSize = 16,16
|
||||||
TitlePane.iconMargins = 3,8,3,8
|
TitlePane.iconMargins = 3,8,3,8
|
||||||
TitlePane.titleMargins = 3,0,3,0
|
TitlePane.titleMargins = 3,0,3,0
|
||||||
|
TitlePane.titleMinimumWidth = 60
|
||||||
TitlePane.buttonSize = 44,30
|
TitlePane.buttonSize = 44,30
|
||||||
|
TitlePane.buttonMinimumWidth = 30
|
||||||
TitlePane.buttonMaximizedHeight = 22
|
TitlePane.buttonMaximizedHeight = 22
|
||||||
TitlePane.centerTitle = false
|
TitlePane.centerTitle = false
|
||||||
TitlePane.centerTitleIfMenuBarEmbedded = true
|
TitlePane.centerTitleIfMenuBarEmbedded = true
|
||||||
TitlePane.menuBarTitleGap = 20
|
TitlePane.showIconBesideTitle = false
|
||||||
|
TitlePane.menuBarTitleGap = 40
|
||||||
|
TitlePane.menuBarTitleMinimumGap = 12
|
||||||
|
TitlePane.menuBarResizeHeight = 4
|
||||||
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
||||||
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
||||||
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
||||||
@@ -829,6 +834,7 @@ ToggleButton.tab.underlineHeight = 2
|
|||||||
ToggleButton.tab.underlineColor = $TabbedPane.underlineColor
|
ToggleButton.tab.underlineColor = $TabbedPane.underlineColor
|
||||||
ToggleButton.tab.disabledUnderlineColor = $TabbedPane.disabledUnderlineColor
|
ToggleButton.tab.disabledUnderlineColor = $TabbedPane.disabledUnderlineColor
|
||||||
ToggleButton.tab.selectedBackground = $?TabbedPane.selectedBackground
|
ToggleButton.tab.selectedBackground = $?TabbedPane.selectedBackground
|
||||||
|
ToggleButton.tab.selectedForeground = $?TabbedPane.selectedForeground
|
||||||
ToggleButton.tab.hoverBackground = $TabbedPane.hoverColor
|
ToggleButton.tab.hoverBackground = $TabbedPane.hoverColor
|
||||||
ToggleButton.tab.focusBackground = $TabbedPane.focusColor
|
ToggleButton.tab.focusBackground = $TabbedPane.focusColor
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ ToggleButton.endBackground = $ToggleButton.background
|
|||||||
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||||
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||||
|
|
||||||
|
[Monokai_Pro]TitledBorder.titleColor = @foreground
|
||||||
|
|
||||||
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
#---- FileChooser ----
|
||||||
|
|
||||||
|
#fields
|
||||||
|
FileChooser.lookInLabel.textAndMnemonic = Buscar &en:
|
||||||
|
FileChooser.saveInLabelText = Guardar en:
|
||||||
|
FileChooser.fileNameLabel.textAndMnemonic = &Nombre de fichero:
|
||||||
|
FileChooser.folderNameLabel.textAndMnemonic = &Nombre de carpeta:
|
||||||
|
FileChooser.filesOfTypeLabel.textAndMnemonic = Ficheros de &Tipo:
|
||||||
|
|
||||||
|
# toolbar
|
||||||
|
FileChooser.upFolderToolTipText = Subir un nivel
|
||||||
|
FileChooser.upFolderAccessibleName = Subir
|
||||||
|
FileChooser.homeFolderToolTipText = Inicio
|
||||||
|
FileChooser.homeFolderAccessibleName = Inicio
|
||||||
|
FileChooser.newFolderToolTipText = Crear nueva carpeta
|
||||||
|
FileChooser.newFolderAccessibleName = Nueva carpeta
|
||||||
|
FileChooser.listViewButtonToolTipText = Lista
|
||||||
|
FileChooser.listViewButtonAccessibleName = Lista
|
||||||
|
FileChooser.detailsViewButtonToolTipText = Detalles
|
||||||
|
FileChooser.detailsViewButtonAccessibleName = Detalles
|
||||||
|
|
||||||
|
# details table header
|
||||||
|
FileChooser.fileNameHeaderText = Nombre
|
||||||
|
FileChooser.fileSizeHeaderText = Tama\u00F1o
|
||||||
|
FileChooser.fileTypeHeaderText = Tipo
|
||||||
|
FileChooser.fileDateHeaderText = Modificado
|
||||||
|
FileChooser.fileAttrHeaderText = Atributos
|
||||||
|
|
||||||
|
# popup menu
|
||||||
|
FileChooser.viewMenuLabelText = Ver
|
||||||
|
FileChooser.refreshActionLabelText = Refrescar
|
||||||
|
FileChooser.newFolderActionLabelText = Nueva carpeta
|
||||||
|
FileChooser.listViewActionLabelText = Lista
|
||||||
|
FileChooser.detailsViewActionLabelText = Detalles
|
||||||
|
|
||||||
|
|
||||||
|
#---- SplitPaneDivider ----
|
||||||
|
|
||||||
|
SplitPaneDivider.collapseLeftToolTipText = Contraer Panel Izquierdo
|
||||||
|
SplitPaneDivider.collapseRightToolTipText = Contraer panel Derecho
|
||||||
|
SplitPaneDivider.collapseTopToolTipText = Contraer panel Superior
|
||||||
|
SplitPaneDivider.collapseBottomToolTipText = Contraer Panel Inferior
|
||||||
|
SplitPaneDivider.expandLeftToolTipText = Expandir Panel Izquierdo
|
||||||
|
SplitPaneDivider.expandRightToolTipText = Expandir Panel Derecho
|
||||||
|
SplitPaneDivider.expandTopToolTipText = Expandir Panel Superior
|
||||||
|
SplitPaneDivider.expandBottomToolTipText = Expandir Panel Inferior
|
||||||
|
|
||||||
|
|
||||||
|
#---- TabbedPane ----
|
||||||
|
|
||||||
|
TabbedPane.moreTabsButtonToolTipText = Mostrar Pesta\u00F1as Ocultas
|
||||||
@@ -96,19 +96,26 @@ public class TestFlatStyleableInfo
|
|||||||
"minimumWidth", int.class,
|
"minimumWidth", int.class,
|
||||||
|
|
||||||
"focusedBackground", Color.class,
|
"focusedBackground", Color.class,
|
||||||
|
"focusedForeground", Color.class,
|
||||||
"hoverBackground", Color.class,
|
"hoverBackground", Color.class,
|
||||||
|
"hoverForeground", Color.class,
|
||||||
"pressedBackground", Color.class,
|
"pressedBackground", Color.class,
|
||||||
|
"pressedForeground", Color.class,
|
||||||
"selectedBackground", Color.class,
|
"selectedBackground", Color.class,
|
||||||
"selectedForeground", Color.class,
|
"selectedForeground", Color.class,
|
||||||
"disabledBackground", Color.class,
|
"disabledBackground", Color.class,
|
||||||
"disabledText", Color.class,
|
"disabledText", Color.class,
|
||||||
"disabledSelectedBackground", Color.class,
|
"disabledSelectedBackground", Color.class,
|
||||||
|
"disabledSelectedForeground", Color.class,
|
||||||
|
|
||||||
"default.background", Color.class,
|
"default.background", Color.class,
|
||||||
"default.foreground", Color.class,
|
"default.foreground", Color.class,
|
||||||
"default.focusedBackground", Color.class,
|
"default.focusedBackground", Color.class,
|
||||||
|
"default.focusedForeground", Color.class,
|
||||||
"default.hoverBackground", Color.class,
|
"default.hoverBackground", Color.class,
|
||||||
|
"default.hoverForeground", Color.class,
|
||||||
"default.pressedBackground", Color.class,
|
"default.pressedBackground", Color.class,
|
||||||
|
"default.pressedForeground", Color.class,
|
||||||
"default.boldText", boolean.class,
|
"default.boldText", boolean.class,
|
||||||
|
|
||||||
"paintShadow", boolean.class,
|
"paintShadow", boolean.class,
|
||||||
@@ -118,8 +125,13 @@ public class TestFlatStyleableInfo
|
|||||||
|
|
||||||
"toolbar.spacingInsets", Insets.class,
|
"toolbar.spacingInsets", Insets.class,
|
||||||
"toolbar.hoverBackground", Color.class,
|
"toolbar.hoverBackground", Color.class,
|
||||||
|
"toolbar.hoverForeground", Color.class,
|
||||||
"toolbar.pressedBackground", Color.class,
|
"toolbar.pressedBackground", Color.class,
|
||||||
|
"toolbar.pressedForeground", Color.class,
|
||||||
"toolbar.selectedBackground", Color.class,
|
"toolbar.selectedBackground", Color.class,
|
||||||
|
"toolbar.selectedForeground", Color.class,
|
||||||
|
"toolbar.disabledSelectedBackground", Color.class,
|
||||||
|
"toolbar.disabledSelectedForeground", Color.class,
|
||||||
|
|
||||||
"buttonType", String.class,
|
"buttonType", String.class,
|
||||||
"squareSize", boolean.class,
|
"squareSize", boolean.class,
|
||||||
@@ -863,8 +875,11 @@ public class TestFlatStyleableInfo
|
|||||||
"tab.underlineColor", Color.class,
|
"tab.underlineColor", Color.class,
|
||||||
"tab.disabledUnderlineColor", Color.class,
|
"tab.disabledUnderlineColor", Color.class,
|
||||||
"tab.selectedBackground", Color.class,
|
"tab.selectedBackground", Color.class,
|
||||||
|
"tab.selectedForeground", Color.class,
|
||||||
"tab.hoverBackground", Color.class,
|
"tab.hoverBackground", Color.class,
|
||||||
"tab.focusBackground", Color.class
|
"tab.hoverForeground", Color.class,
|
||||||
|
"tab.focusBackground", Color.class,
|
||||||
|
"tab.focusForeground", Color.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// FlatToggleButtonUI extends FlatButtonUI
|
// FlatToggleButtonUI extends FlatButtonUI
|
||||||
|
|||||||
@@ -221,19 +221,26 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( b, "minimumWidth: 100" );
|
ui.applyStyle( b, "minimumWidth: 100" );
|
||||||
|
|
||||||
ui.applyStyle( b, "focusedBackground: #fff" );
|
ui.applyStyle( b, "focusedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "focusedForeground: #fff" );
|
||||||
ui.applyStyle( b, "hoverBackground: #fff" );
|
ui.applyStyle( b, "hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "pressedBackground: #fff" );
|
ui.applyStyle( b, "pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "selectedBackground: #fff" );
|
ui.applyStyle( b, "selectedBackground: #fff" );
|
||||||
ui.applyStyle( b, "selectedForeground: #fff" );
|
ui.applyStyle( b, "selectedForeground: #fff" );
|
||||||
ui.applyStyle( b, "disabledBackground: #fff" );
|
ui.applyStyle( b, "disabledBackground: #fff" );
|
||||||
ui.applyStyle( b, "disabledText: #fff" );
|
ui.applyStyle( b, "disabledText: #fff" );
|
||||||
ui.applyStyle( b, "disabledSelectedBackground: #fff" );
|
ui.applyStyle( b, "disabledSelectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "disabledSelectedForeground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( b, "default.background: #fff" );
|
ui.applyStyle( b, "default.background: #fff" );
|
||||||
ui.applyStyle( b, "default.foreground: #fff" );
|
ui.applyStyle( b, "default.foreground: #fff" );
|
||||||
ui.applyStyle( b, "default.focusedBackground: #fff" );
|
ui.applyStyle( b, "default.focusedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.focusedForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.hoverBackground: #fff" );
|
ui.applyStyle( b, "default.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.pressedBackground: #fff" );
|
ui.applyStyle( b, "default.pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.boldText: true" );
|
ui.applyStyle( b, "default.boldText: true" );
|
||||||
|
|
||||||
ui.applyStyle( b, "paintShadow: true" );
|
ui.applyStyle( b, "paintShadow: true" );
|
||||||
@@ -243,8 +250,13 @@ public class TestFlatStyling
|
|||||||
|
|
||||||
ui.applyStyle( b, "toolbar.spacingInsets: 1,2,3,4" );
|
ui.applyStyle( b, "toolbar.spacingInsets: 1,2,3,4" );
|
||||||
ui.applyStyle( b, "toolbar.hoverBackground: #fff" );
|
ui.applyStyle( b, "toolbar.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "toolbar.pressedBackground: #fff" );
|
ui.applyStyle( b, "toolbar.pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "toolbar.selectedBackground: #fff" );
|
ui.applyStyle( b, "toolbar.selectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.selectedForeground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.disabledSelectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.disabledSelectedForeground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( b, "buttonType: help" );
|
ui.applyStyle( b, "buttonType: help" );
|
||||||
ui.applyStyle( b, "squareSize: true" );
|
ui.applyStyle( b, "squareSize: true" );
|
||||||
@@ -1073,8 +1085,11 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( b, "tab.underlineColor: #fff" );
|
ui.applyStyle( b, "tab.underlineColor: #fff" );
|
||||||
ui.applyStyle( b, "tab.disabledUnderlineColor: #fff" );
|
ui.applyStyle( b, "tab.disabledUnderlineColor: #fff" );
|
||||||
ui.applyStyle( b, "tab.selectedBackground: #fff" );
|
ui.applyStyle( b, "tab.selectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.selectedForeground: #fff" );
|
||||||
ui.applyStyle( b, "tab.hoverBackground: #fff" );
|
ui.applyStyle( b, "tab.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "tab.focusBackground: #fff" );
|
ui.applyStyle( b, "tab.focusBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.focusForeground: #fff" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import com.formdev.flatlaf.FlatLightLaf;
|
|||||||
import com.formdev.flatlaf.demo.HintManager.Hint;
|
import com.formdev.flatlaf.demo.HintManager.Hint;
|
||||||
import com.formdev.flatlaf.demo.extras.*;
|
import com.formdev.flatlaf.demo.extras.*;
|
||||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||||
import com.formdev.flatlaf.extras.FlatDesktop;
|
|
||||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
|
import com.formdev.flatlaf.extras.FlatDesktop;
|
||||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||||
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
||||||
import com.formdev.flatlaf.extras.components.FlatButton;
|
import com.formdev.flatlaf.extras.components.FlatButton;
|
||||||
@@ -82,13 +82,33 @@ class DemoFrame
|
|||||||
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
||||||
tabbedPane.setSelectedIndex( tabIndex );
|
tabbedPane.setSelectedIndex( tabIndex );
|
||||||
|
|
||||||
// hide some menu items on macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// hide menu items that are in macOS application menu
|
||||||
exitMenuItem.setVisible( false );
|
exitMenuItem.setVisible( false );
|
||||||
aboutMenuItem.setVisible( false );
|
aboutMenuItem.setVisible( false );
|
||||||
|
|
||||||
// do not use HTML text on macOS
|
// do not use HTML text in menu items because this is not supported in macOS screen menu
|
||||||
htmlMenuItem.setText( "some text" );
|
htmlMenuItem.setText( "some text" );
|
||||||
|
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
|
// expand window content into window title bar and make title bar transparent
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||||
|
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||||
|
|
||||||
|
// hide window title
|
||||||
|
if( SystemInfo.isJava_17_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||||
|
else
|
||||||
|
setTitle( null );
|
||||||
|
|
||||||
|
// add gap to left side of toolbar
|
||||||
|
toolBar.add( Box.createHorizontalStrut( 70 ), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||||
|
if( !SystemInfo.isJava_11_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// integrate into macOS screen menu
|
// integrate into macOS screen menu
|
||||||
@@ -322,8 +342,8 @@ class DemoFrame
|
|||||||
// add font families
|
// add font families
|
||||||
fontMenu.addSeparator();
|
fontMenu.addSeparator();
|
||||||
ArrayList<String> families = new ArrayList<>( Arrays.asList(
|
ArrayList<String> families = new ArrayList<>( Arrays.asList(
|
||||||
"Arial", "Cantarell", "Comic Sans MS", "Courier New", "DejaVu Sans",
|
"Arial", "Cantarell", "Comic Sans MS", "DejaVu Sans",
|
||||||
"Dialog", "Liberation Sans", "Monospaced", "Noto Sans", "Roboto",
|
"Dialog", "Liberation Sans", "Noto Sans", "Roboto",
|
||||||
"SansSerif", "Segoe UI", "Serif", "Tahoma", "Ubuntu", "Verdana" ) );
|
"SansSerif", "Segoe UI", "Serif", "Tahoma", "Ubuntu", "Verdana" ) );
|
||||||
if( !families.contains( currentFamily ) )
|
if( !families.contains( currentFamily ) )
|
||||||
families.add( currentFamily );
|
families.add( currentFamily );
|
||||||
@@ -433,9 +453,9 @@ class DemoFrame
|
|||||||
lafClass == FlatIntelliJLaf.class ||
|
lafClass == FlatIntelliJLaf.class ||
|
||||||
lafClass == FlatDarculaLaf.class;
|
lafClass == FlatDarculaLaf.class;
|
||||||
|
|
||||||
accentColorLabel.setEnabled( isAccentColorSupported );
|
accentColorLabel.setVisible( isAccentColorSupported );
|
||||||
for( int i = 0; i < accentColorButtons.length; i++ )
|
for( int i = 0; i < accentColorButtons.length; i++ )
|
||||||
accentColorButtons[i].setEnabled( isAccentColorSupported );
|
accentColorButtons[i].setVisible( isAccentColorSupported );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class FlatLafDemo
|
|||||||
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
// macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
// enable screen menu bar
|
// enable screen menu bar
|
||||||
// (moves menu bar from JFrame window to top of screen)
|
// (moves menu bar from JFrame window to top of screen)
|
||||||
@@ -51,6 +51,7 @@ public class FlatLafDemo
|
|||||||
// - "system": use current macOS appearance (light or dark)
|
// - "system": use current macOS appearance (light or dark)
|
||||||
// - "NSAppearanceNameAqua": use light appearance
|
// - "NSAppearanceNameAqua": use light appearance
|
||||||
// - "NSAppearanceNameDarkAqua": use dark appearance
|
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||||
|
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import javax.swing.plaf.UIResource;
|
|||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.ui.MigLayoutVisualPadding;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -113,6 +114,7 @@ public class FlatInspector
|
|||||||
private int inspectParentLevel;
|
private int inspectParentLevel;
|
||||||
private boolean wasModifierKeyPressed;
|
private boolean wasModifierKeyPressed;
|
||||||
private boolean showClassHierarchy;
|
private boolean showClassHierarchy;
|
||||||
|
private long lastWhen;
|
||||||
|
|
||||||
private JComponent highlightFigure;
|
private JComponent highlightFigure;
|
||||||
private Popup popup;
|
private Popup popup;
|
||||||
@@ -131,8 +133,22 @@ public class FlatInspector
|
|||||||
(((KeyEvent)e).getModifiersEx() & KEY_MODIFIERS_MASK) == (keyStroke.getModifiers() & KEY_MODIFIERS_MASK) )
|
(((KeyEvent)e).getModifiersEx() & KEY_MODIFIERS_MASK) == (keyStroke.getModifiers() & KEY_MODIFIERS_MASK) )
|
||||||
{
|
{
|
||||||
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
||||||
if( activeWindow instanceof RootPaneContainer ) {
|
RootPaneContainer rootPaneContainer = null;
|
||||||
JRootPane rootPane = ((RootPaneContainer)activeWindow).getRootPane();
|
if( activeWindow instanceof RootPaneContainer )
|
||||||
|
rootPaneContainer = (RootPaneContainer) activeWindow;
|
||||||
|
else {
|
||||||
|
// search for root pain container in children
|
||||||
|
// (e.g. for Swing embedded into SWT)
|
||||||
|
for( Component child : activeWindow.getComponents() ) {
|
||||||
|
if( child instanceof RootPaneContainer ) {
|
||||||
|
rootPaneContainer = (RootPaneContainer) child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rootPaneContainer != null ) {
|
||||||
|
JRootPane rootPane = rootPaneContainer.getRootPane();
|
||||||
FlatInspector inspector = (FlatInspector) rootPane.getClientProperty( FlatInspector.class );
|
FlatInspector inspector = (FlatInspector) rootPane.getClientProperty( FlatInspector.class );
|
||||||
if( inspector == null ) {
|
if( inspector == null ) {
|
||||||
inspector = new FlatInspector( rootPane );
|
inspector = new FlatInspector( rootPane );
|
||||||
@@ -172,6 +188,11 @@ public class FlatInspector
|
|||||||
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT )
|
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT )
|
||||||
wasModifierKeyPressed = true;
|
wasModifierKeyPressed = true;
|
||||||
} else if( id == KeyEvent.KEY_RELEASED && wasModifierKeyPressed ) {
|
} else if( id == KeyEvent.KEY_RELEASED && wasModifierKeyPressed ) {
|
||||||
|
// ignore duplicate events (for Swing embedded into SWT)
|
||||||
|
if( (keyEvent.getWhen() - lastWhen) <= 5 )
|
||||||
|
return;
|
||||||
|
lastWhen = keyEvent.getWhen();
|
||||||
|
|
||||||
if( keyCode == KeyEvent.VK_CONTROL ) {
|
if( keyCode == KeyEvent.VK_CONTROL ) {
|
||||||
inspectParentLevel++;
|
inspectParentLevel++;
|
||||||
int parentLevel = inspect( lastX, lastY );
|
int parentLevel = inspect( lastX, lastY );
|
||||||
@@ -464,6 +485,15 @@ public class FlatInspector
|
|||||||
if( margin != null )
|
if( margin != null )
|
||||||
appendRow( buf, "Margin", toString( margin ) );
|
appendRow( buf, "Margin", toString( margin ) );
|
||||||
|
|
||||||
|
if( c instanceof JComponent ) {
|
||||||
|
Object value = ((JComponent)c).getClientProperty( MigLayoutVisualPadding.VISUAL_PADDING_PROPERTY );
|
||||||
|
Insets visualPadding = (value instanceof int[])
|
||||||
|
? new Insets( ((int[])value)[0], ((int[])value)[1], ((int[])value)[2], ((int[])value)[3] )
|
||||||
|
: (value instanceof Insets ? (Insets) value : null);
|
||||||
|
if( visualPadding != null )
|
||||||
|
appendRow( buf, "Mig visual padding", toString( visualPadding ) );
|
||||||
|
}
|
||||||
|
|
||||||
Dimension prefSize = c.getPreferredSize();
|
Dimension prefSize = c.getPreferredSize();
|
||||||
Dimension minSize = c.getMinimumSize();
|
Dimension minSize = c.getMinimumSize();
|
||||||
Dimension maxSize = c.getMaximumSize();
|
Dimension maxSize = c.getMaximumSize();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package com.formdev.flatlaf.extras.components;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.*;
|
||||||
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,16 +116,37 @@ public class FlatToggleButton
|
|||||||
putClientProperty( OUTLINE, outline );
|
putClientProperty( OUTLINE, outline );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
|
* If underline placement is not specified, returns {@link #BOTTOM} as the default
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public int getTabUnderlinePlacement() {
|
||||||
|
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_PLACEMENT, BOTTOM );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns height of underline if toggle button type is {@link ButtonType#tab}.
|
* Specifies placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
|
*
|
||||||
|
* @param placement One of the following constants defined in SwingConstants:
|
||||||
|
* {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, or {@link #RIGHT}.
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public void setTabUnderlinePlacement( int placement ) {
|
||||||
|
putClientProperty( TAB_BUTTON_UNDERLINE_PLACEMENT, (placement >= 0) ? placement : null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
*/
|
*/
|
||||||
public int getTabUnderlineHeight() {
|
public int getTabUnderlineHeight() {
|
||||||
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_HEIGHT, "ToggleButton.tab.underlineHeight" );
|
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_HEIGHT, "ToggleButton.tab.underlineHeight" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies height of underline if toggle button type is {@link ButtonType#tab}.
|
* Specifies thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
*/
|
*/
|
||||||
public void setTabUnderlineHeight( int tabUnderlineHeight ) {
|
public void setTabUnderlineHeight( int tabUnderlineHeight ) {
|
||||||
putClientProperty( TAB_BUTTON_UNDERLINE_HEIGHT, (tabUnderlineHeight >= 0) ? tabUnderlineHeight : null );
|
putClientProperty( TAB_BUTTON_UNDERLINE_HEIGHT, (tabUnderlineHeight >= 0) ? tabUnderlineHeight : null );
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
|
|
||||||
#---- monospaced ----
|
#---- monospaced ----
|
||||||
|
|
||||||
- monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
|
- monospaced.font [active] Monospaced plain 12 javax.swing.plaf.FontUIResource [UI]
|
||||||
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
|
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1214,6 +1214,7 @@ TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI
|
|||||||
TitlePane.background #303234 HSL 210 4 20 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.background #303234 HSL 210 4 20 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.buttonHoverBackground #55585c HSL 214 4 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse)
|
TitlePane.buttonHoverBackground #55585c HSL 214 4 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse)
|
||||||
TitlePane.buttonMaximizedHeight 22
|
TitlePane.buttonMaximizedHeight 22
|
||||||
|
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.centerTitle false
|
TitlePane.centerTitle false
|
||||||
@@ -1233,11 +1234,15 @@ TitlePane.inactiveBackground #303234 HSL 210 4 20 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarTitleGap 20
|
TitlePane.menuBarResizeHeight 4
|
||||||
|
TitlePane.menuBarTitleGap 40
|
||||||
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
||||||
TitlePane.showIcon true
|
TitlePane.showIcon true
|
||||||
|
TitlePane.showIconBesideTitle 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.unifiedBackground true
|
TitlePane.unifiedBackground true
|
||||||
TitlePane.useWindowDecorations true
|
TitlePane.useWindowDecorations true
|
||||||
|
|
||||||
@@ -1545,7 +1550,7 @@ mini.font [active] Segoe UI plain 9 javax.swing.plaf.Fon
|
|||||||
|
|
||||||
#---- monospaced ----
|
#---- monospaced ----
|
||||||
|
|
||||||
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
|
monospaced.font [active] Monospaced plain 12 javax.swing.plaf.FontUIResource [UI]
|
||||||
|
|
||||||
|
|
||||||
#---- ----
|
#---- ----
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
|
|
||||||
#---- monospaced ----
|
#---- monospaced ----
|
||||||
|
|
||||||
- monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
|
- monospaced.font [active] Monospaced plain 12 javax.swing.plaf.FontUIResource [UI]
|
||||||
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
|
+ monospaced.font [active] Menlo plain 13 javax.swing.plaf.FontUIResource [UI]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1219,6 +1219,7 @@ TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI
|
|||||||
TitlePane.background #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.background #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.buttonHoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
|
TitlePane.buttonHoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
|
||||||
TitlePane.buttonMaximizedHeight 22
|
TitlePane.buttonMaximizedHeight 22
|
||||||
|
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.centerTitle false
|
TitlePane.centerTitle false
|
||||||
@@ -1238,11 +1239,15 @@ TitlePane.inactiveBackground #ffffff HSL 0 0 100 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarTitleGap 20
|
TitlePane.menuBarResizeHeight 4
|
||||||
|
TitlePane.menuBarTitleGap 40
|
||||||
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
||||||
TitlePane.showIcon true
|
TitlePane.showIcon true
|
||||||
|
TitlePane.showIconBesideTitle 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.unifiedBackground true
|
TitlePane.unifiedBackground true
|
||||||
TitlePane.useWindowDecorations true
|
TitlePane.useWindowDecorations true
|
||||||
|
|
||||||
@@ -1550,7 +1555,7 @@ mini.font [active] Segoe UI plain 9 javax.swing.plaf.Fon
|
|||||||
|
|
||||||
#---- monospaced ----
|
#---- monospaced ----
|
||||||
|
|
||||||
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
|
monospaced.font [active] Monospaced plain 12 javax.swing.plaf.FontUIResource [UI]
|
||||||
|
|
||||||
|
|
||||||
#---- ----
|
#---- ----
|
||||||
|
|||||||
@@ -73,43 +73,57 @@ Button.default.endBorderColor #0000ff HSL 240 100 50 javax.swing.plaf.Colo
|
|||||||
Button.default.focusColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.focusColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.focusedBorderColor #537699 HSL 210 30 46 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.focusedBorderColor #537699 HSL 210 30 46 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.default.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.foreground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.foreground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.default.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.default.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.startBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.startBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.default.startBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.default.startBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.defaultButtonFollowsFocus false
|
Button.defaultButtonFollowsFocus false
|
||||||
Button.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
Button.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.disabledBorderColor #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
Button.disabledBorderColor #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.disabledForeground #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
Button.disabledForeground #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.disabledSelectedBackground #112233 HSL 210 50 13 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.disabledSelectedForeground #ffcccc HSL 0 100 90 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
Button.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.endBackground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
Button.endBackground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.endBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.endBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.focusedBorderColor #466d94 HSL 210 36 43 javax.swing.plaf.ColorUIResource [UI]
|
Button.focusedBorderColor #466d94 HSL 210 36 43 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.font [active] $defaultFont [UI]
|
Button.font [active] $defaultFont [UI]
|
||||||
Button.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Button.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.hoverBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.iconTextGap 4
|
Button.iconTextGap 4
|
||||||
Button.innerFocusWidth 1
|
Button.innerFocusWidth 1
|
||||||
Button.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
Button.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
Button.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
Button.minimumWidth 72
|
Button.minimumWidth 72
|
||||||
Button.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.rollover true
|
Button.rollover true
|
||||||
Button.selectedBackground #ffbbbb HSL 0 100 87 javax.swing.plaf.ColorUIResource [UI]
|
Button.selectedBackground #ffbbbb HSL 0 100 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.selectedForeground #332211 HSL 30 50 13 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
Button.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.startBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Button.startBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.startBorderColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Button.startBorderColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.textIconGap 4
|
Button.textIconGap 4
|
||||||
Button.textShiftOffset 0
|
Button.textShiftOffset 0
|
||||||
|
Button.toolbar.disabledSelectedBackground #cccccc HSL 0 0 80 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.toolbar.disabledSelectedForeground #886666 HSL 0 14 47 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Button.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.toolbar.hoverForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.toolbar.margin 3,3,3,3 javax.swing.plaf.InsetsUIResource [UI]
|
Button.toolbar.margin 3,3,3,3 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
Button.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
Button.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.toolbar.pressedForeground #666666 HSL 0 0 40 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
Button.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Button.toolbar.selectedForeground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Button.toolbar.spacingInsets 1,2,1,2 javax.swing.plaf.InsetsUIResource [UI]
|
Button.toolbar.spacingInsets 1,2,1,2 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
ButtonUI com.formdev.flatlaf.ui.FlatButtonUI
|
ButtonUI com.formdev.flatlaf.ui.FlatButtonUI
|
||||||
|
|
||||||
@@ -1235,6 +1249,7 @@ TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI
|
|||||||
TitlePane.background #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.background #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.borderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.borderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.buttonMaximizedHeight 22
|
TitlePane.buttonMaximizedHeight 22
|
||||||
|
TitlePane.buttonMinimumWidth 30
|
||||||
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
|
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
TitlePane.centerTitle false
|
TitlePane.centerTitle false
|
||||||
TitlePane.centerTitleIfMenuBarEmbedded true
|
TitlePane.centerTitleIfMenuBarEmbedded true
|
||||||
@@ -1252,11 +1267,15 @@ TitlePane.inactiveBackground #008800 HSL 120 100 27 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarTitleGap 20
|
TitlePane.menuBarResizeHeight 4
|
||||||
|
TitlePane.menuBarTitleGap 40
|
||||||
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
||||||
TitlePane.showIcon true
|
TitlePane.showIcon true
|
||||||
|
TitlePane.showIconBesideTitle 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.unifiedBackground true
|
TitlePane.unifiedBackground true
|
||||||
TitlePane.useWindowDecorations true
|
TitlePane.useWindowDecorations true
|
||||||
|
|
||||||
@@ -1280,31 +1299,43 @@ ToggleButton.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.F
|
|||||||
ToggleButton.darkShadow #696969 HSL 0 0 41 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.darkShadow #696969 HSL 0 0 41 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.disabledBackground #e0e0e0 HSL 0 0 88 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.disabledSelectedBackground #44dd44 HSL 120 69 57 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.disabledSelectedBackground #44dd44 HSL 120 69 57 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.disabledSelectedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.disabledText #000088 HSL 240 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.focusedBackground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.focusedForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.font [active] $defaultFont [UI]
|
ToggleButton.font [active] $defaultFont [UI]
|
||||||
ToggleButton.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.hoverBackground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.iconTextGap 4
|
ToggleButton.iconTextGap 4
|
||||||
ToggleButton.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
ToggleButton.margin 2,14,2,14 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
ToggleButton.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.pressedBackground #ffc800 HSL 47 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.pressedForeground #0080ff HSL 210 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.rollover true
|
ToggleButton.rollover true
|
||||||
ToggleButton.selectedBackground #44ff44 HSL 120 100 63 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.selectedBackground #44ff44 HSL 120 100 63 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.selectedForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.selectedForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.disabledUnderlineColor #7a7a7a HSL 0 0 48 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.tab.disabledUnderlineColor #7a7a7a HSL 0 0 48 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.focusBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.tab.focusBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.tab.focusForeground #008800 HSL 120 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.hoverBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.tab.hoverBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.selectedBackground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.tab.hoverForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.tab.selectedBackground #008800 HSL 120 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.tab.selectedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.underlineColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.tab.underlineColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.tab.underlineHeight 2
|
ToggleButton.tab.underlineHeight 2
|
||||||
ToggleButton.textIconGap 4
|
ToggleButton.textIconGap 4
|
||||||
ToggleButton.textShiftOffset 0
|
ToggleButton.textShiftOffset 0
|
||||||
|
ToggleButton.toolbar.disabledSelectedBackground #cccccc HSL 0 0 80 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.toolbar.disabledSelectedForeground #886666 HSL 0 14 47 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.toolbar.hoverBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.toolbar.hoverForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.toolbar.pressedBackground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.toolbar.pressedForeground #666666 HSL 0 0 40 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButton.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
ToggleButton.toolbar.selectedBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
ToggleButton.toolbar.selectedForeground #880000 HSL 0 100 27 javax.swing.plaf.ColorUIResource [UI]
|
||||||
ToggleButtonUI com.formdev.flatlaf.ui.FlatToggleButtonUI
|
ToggleButtonUI com.formdev.flatlaf.ui.FlatToggleButtonUI
|
||||||
|
|
||||||
|
|
||||||
@@ -1563,7 +1594,7 @@ mini.font [active] Segoe UI plain 9 javax.swing.plaf.Fon
|
|||||||
|
|
||||||
#---- monospaced ----
|
#---- monospaced ----
|
||||||
|
|
||||||
monospaced.font [active] Consolas plain 12 javax.swing.plaf.FontUIResource [UI]
|
monospaced.font [active] Monospaced plain 12 javax.swing.plaf.FontUIResource [UI]
|
||||||
|
|
||||||
|
|
||||||
#---- ----
|
#---- ----
|
||||||
|
|||||||
@@ -16,7 +16,12 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.testing;
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIcon;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,6 +33,24 @@ public class FlatChooserTest
|
|||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
|
||||||
|
|
||||||
|
UIManager.put( "FileChooser.shortcuts.filesFunction", (Function<File[], File[]>) files -> {
|
||||||
|
ArrayList<File> list = new ArrayList<>( Arrays.asList( files ) );
|
||||||
|
list.add( 0, new File( System.getProperty( "user.home" ) ) );
|
||||||
|
return list.toArray( new File[list.size()] );
|
||||||
|
} );
|
||||||
|
|
||||||
|
UIManager.put( "FileChooser.shortcuts.displayNameFunction", (Function<File, String>) file -> {
|
||||||
|
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||||
|
return "Home";
|
||||||
|
return null;
|
||||||
|
} );
|
||||||
|
UIManager.put( "FileChooser.shortcuts.iconFunction", (Function<File, Icon>) file -> {
|
||||||
|
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||||
|
return new FlatFileChooserHomeFolderIcon();
|
||||||
|
return null;
|
||||||
|
} );
|
||||||
|
|
||||||
frame.showFrame( FlatChooserTest::new );
|
frame.showFrame( FlatChooserTest::new );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,20 @@ public class FlatComponents2Test
|
|||||||
table1.setModel( tableModel );
|
table1.setModel( tableModel );
|
||||||
xTable1.setModel( tableModel );
|
xTable1.setModel( tableModel );
|
||||||
|
|
||||||
|
// table header popup menu
|
||||||
|
JMenuItem addMenuItem = new JMenuItem( "Add column" );
|
||||||
|
addMenuItem.addActionListener( e -> {
|
||||||
|
tableModel.setColumnCount( tableModel.getColumnCount() + 1 );
|
||||||
|
});
|
||||||
|
JMenuItem removeMenuItem = new JMenuItem( "Remove last column" );
|
||||||
|
removeMenuItem.addActionListener( e -> {
|
||||||
|
tableModel.setColumnCount( tableModel.getColumnCount() - 1 );
|
||||||
|
});
|
||||||
|
JPopupMenu popupMenu = new JPopupMenu();
|
||||||
|
popupMenu.add( addMenuItem );
|
||||||
|
popupMenu.add( removeMenuItem );
|
||||||
|
table1.getTableHeader().setComponentPopupMenu( popupMenu );
|
||||||
|
|
||||||
// table column editors
|
// table column editors
|
||||||
initTableEditors( table1 );
|
initTableEditors( table1 );
|
||||||
initTableEditors( xTable1 );
|
initTableEditors( xTable1 );
|
||||||
@@ -336,6 +350,16 @@ public class FlatComponents2Test
|
|||||||
table.setSurrendersFocusOnKeystroke( focusCellEditorCheckBox.isSelected() );
|
table.setSurrendersFocusOnKeystroke( focusCellEditorCheckBox.isSelected() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void alternatingRowsChanged() {
|
||||||
|
UIManager.put( "Table.alternateRowColor", alternatingRowsCheckBox.isSelected() ? Color.orange : null );
|
||||||
|
table1ScrollPane.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paintOutsideAlternateRowsChanged() {
|
||||||
|
UIManager.put( "Table.paintOutsideAlternateRows", paintOutsideAlternateRowsCheckBox.isSelected() ? true : null );
|
||||||
|
table1ScrollPane.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
private void treeRendererChanged() {
|
private void treeRendererChanged() {
|
||||||
Object sel = treeRendererComboBox.getSelectedItem();
|
Object sel = treeRendererComboBox.getSelectedItem();
|
||||||
if( !(sel instanceof String) )
|
if( !(sel instanceof String) )
|
||||||
@@ -493,8 +517,10 @@ public class FlatComponents2Test
|
|||||||
focusCellEditorCheckBox = new JCheckBox();
|
focusCellEditorCheckBox = new JCheckBox();
|
||||||
showVerticalLinesCheckBox = new JCheckBox();
|
showVerticalLinesCheckBox = new JCheckBox();
|
||||||
columnSelectionCheckBox = new JCheckBox();
|
columnSelectionCheckBox = new JCheckBox();
|
||||||
|
alternatingRowsCheckBox = new JCheckBox();
|
||||||
intercellSpacingCheckBox = new JCheckBox();
|
intercellSpacingCheckBox = new JCheckBox();
|
||||||
rowHeaderCheckBox = new JCheckBox();
|
rowHeaderCheckBox = new JCheckBox();
|
||||||
|
paintOutsideAlternateRowsCheckBox = new JCheckBox();
|
||||||
redGridColorCheckBox = new JCheckBox();
|
redGridColorCheckBox = new JCheckBox();
|
||||||
tableHeaderButtonCheckBox = new JCheckBox();
|
tableHeaderButtonCheckBox = new JCheckBox();
|
||||||
|
|
||||||
@@ -875,6 +901,11 @@ public class FlatComponents2Test
|
|||||||
columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged());
|
columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged());
|
||||||
tableOptionsPanel.add(columnSelectionCheckBox, "cell 1 2");
|
tableOptionsPanel.add(columnSelectionCheckBox, "cell 1 2");
|
||||||
|
|
||||||
|
//---- alternatingRowsCheckBox ----
|
||||||
|
alternatingRowsCheckBox.setText("alternating rows");
|
||||||
|
alternatingRowsCheckBox.addActionListener(e -> alternatingRowsChanged());
|
||||||
|
tableOptionsPanel.add(alternatingRowsCheckBox, "cell 2 2");
|
||||||
|
|
||||||
//---- intercellSpacingCheckBox ----
|
//---- intercellSpacingCheckBox ----
|
||||||
intercellSpacingCheckBox.setText("intercell spacing");
|
intercellSpacingCheckBox.setText("intercell spacing");
|
||||||
intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged());
|
intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged());
|
||||||
@@ -885,6 +916,11 @@ public class FlatComponents2Test
|
|||||||
rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
|
rowHeaderCheckBox.addActionListener(e -> rowHeaderChanged());
|
||||||
tableOptionsPanel.add(rowHeaderCheckBox, "cell 1 3");
|
tableOptionsPanel.add(rowHeaderCheckBox, "cell 1 3");
|
||||||
|
|
||||||
|
//---- paintOutsideAlternateRowsCheckBox ----
|
||||||
|
paintOutsideAlternateRowsCheckBox.setText("outside alternating rows");
|
||||||
|
paintOutsideAlternateRowsCheckBox.addActionListener(e -> paintOutsideAlternateRowsChanged());
|
||||||
|
tableOptionsPanel.add(paintOutsideAlternateRowsCheckBox, "cell 2 3");
|
||||||
|
|
||||||
//---- redGridColorCheckBox ----
|
//---- redGridColorCheckBox ----
|
||||||
redGridColorCheckBox.setText("red grid color");
|
redGridColorCheckBox.setText("red grid color");
|
||||||
redGridColorCheckBox.addActionListener(e -> redGridColorChanged());
|
redGridColorCheckBox.addActionListener(e -> redGridColorChanged());
|
||||||
@@ -927,8 +963,10 @@ public class FlatComponents2Test
|
|||||||
private JCheckBox focusCellEditorCheckBox;
|
private JCheckBox focusCellEditorCheckBox;
|
||||||
private JCheckBox showVerticalLinesCheckBox;
|
private JCheckBox showVerticalLinesCheckBox;
|
||||||
private JCheckBox columnSelectionCheckBox;
|
private JCheckBox columnSelectionCheckBox;
|
||||||
|
private JCheckBox alternatingRowsCheckBox;
|
||||||
private JCheckBox intercellSpacingCheckBox;
|
private JCheckBox intercellSpacingCheckBox;
|
||||||
private JCheckBox rowHeaderCheckBox;
|
private JCheckBox rowHeaderCheckBox;
|
||||||
|
private JCheckBox paintOutsideAlternateRowsCheckBox;
|
||||||
private JCheckBox redGridColorCheckBox;
|
private JCheckBox redGridColorCheckBox;
|
||||||
private JCheckBox tableHeaderButtonCheckBox;
|
private JCheckBox tableHeaderButtonCheckBox;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
@@ -1150,6 +1188,7 @@ public class FlatComponents2Test
|
|||||||
{ "item 12", null, "December", null, null, null },
|
{ "item 12", null, "December", null, null, null },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private int columnCount = columnNames.length;
|
||||||
private int rowCount = rows.length;
|
private int rowCount = rows.length;
|
||||||
private final Map<Integer, Object[]> moreRowsMap = new HashMap<>();
|
private final Map<Integer, Object[]> moreRowsMap = new HashMap<>();
|
||||||
|
|
||||||
@@ -1157,6 +1196,16 @@ public class FlatComponents2Test
|
|||||||
setRowCount( rowCount );
|
setRowCount( rowCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setColumnCount( int columnCount ) {
|
||||||
|
if( columnCount > columnNames.length )
|
||||||
|
columnCount = columnNames.length;
|
||||||
|
|
||||||
|
this.columnCount = columnCount;
|
||||||
|
|
||||||
|
// fire event
|
||||||
|
fireTableStructureChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void setRowCount( int rowCount ) {
|
void setRowCount( int rowCount ) {
|
||||||
int oldRowCount = this.rowCount;
|
int oldRowCount = this.rowCount;
|
||||||
this.rowCount = rowCount;
|
this.rowCount = rowCount;
|
||||||
@@ -1175,7 +1224,7 @@ public class FlatComponents2Test
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnCount() {
|
public int getColumnCount() {
|
||||||
return columnNames.length;
|
return columnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.5.0.404" Java: "17.0.2" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -485,6 +485,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 2"
|
"value": "cell 1 2"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "alternatingRowsCheckBox"
|
||||||
|
"text": "alternating rows"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alternatingRowsChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 2"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "intercellSpacingCheckBox"
|
name: "intercellSpacingCheckBox"
|
||||||
"text": "intercell spacing"
|
"text": "intercell spacing"
|
||||||
@@ -505,6 +515,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 3"
|
"value": "cell 1 3"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "paintOutsideAlternateRowsCheckBox"
|
||||||
|
"text": "outside alternating rows"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "paintOutsideAlternateRowsChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 3"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "redGridColorCheckBox"
|
name: "redGridColorCheckBox"
|
||||||
"text": "red grid color"
|
"text": "red grid color"
|
||||||
|
|||||||
@@ -181,6 +181,10 @@ public class FlatMenusTest
|
|||||||
JMenuItem menuItem45 = new JMenuItem();
|
JMenuItem menuItem45 = new JMenuItem();
|
||||||
JMenuItem menuItem46 = new JMenuItem();
|
JMenuItem menuItem46 = new JMenuItem();
|
||||||
JMenuItem menuItem47 = new JMenuItem();
|
JMenuItem menuItem47 = new JMenuItem();
|
||||||
|
JMenu menu13 = new JMenu();
|
||||||
|
JMenuItem menuItem48 = new JMenuItem();
|
||||||
|
JMenuItem menuItem49 = new JMenuItem();
|
||||||
|
JMenuItem menuItem50 = new JMenuItem();
|
||||||
menuBar2 = new JMenuBar();
|
menuBar2 = new JMenuBar();
|
||||||
JMenu menu8 = new JMenu();
|
JMenu menu8 = new JMenu();
|
||||||
FlatMenusTest.LargerMenuItem menuItem13 = new FlatMenusTest.LargerMenuItem();
|
FlatMenusTest.LargerMenuItem menuItem13 = new FlatMenusTest.LargerMenuItem();
|
||||||
@@ -442,6 +446,24 @@ public class FlatMenusTest
|
|||||||
menu12.add(menuItem47);
|
menu12.add(menuItem47);
|
||||||
}
|
}
|
||||||
menuBar1.add(menu12);
|
menuBar1.add(menu12);
|
||||||
|
|
||||||
|
//======== menu13 ========
|
||||||
|
{
|
||||||
|
menu13.setText("HTML");
|
||||||
|
|
||||||
|
//---- menuItem48 ----
|
||||||
|
menuItem48.setText("<html>some <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>");
|
||||||
|
menu13.add(menuItem48);
|
||||||
|
|
||||||
|
//---- menuItem49 ----
|
||||||
|
menuItem49.setText("<html>some longer <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>");
|
||||||
|
menu13.add(menuItem49);
|
||||||
|
|
||||||
|
//---- menuItem50 ----
|
||||||
|
menuItem50.setText("<html>another <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>");
|
||||||
|
menu13.add(menuItem50);
|
||||||
|
}
|
||||||
|
menuBar1.add(menu13);
|
||||||
}
|
}
|
||||||
add(menuBar1, "cell 1 0 2 1,growx");
|
add(menuBar1, "cell 1 0 2 1,growx");
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,22 @@ new FormModel {
|
|||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/test64.png" )
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/test64.png" )
|
||||||
} )
|
} )
|
||||||
} )
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||||
|
name: "menu13"
|
||||||
|
"text": "HTML"
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "menuItem48"
|
||||||
|
"text": "<html>some <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "menuItem49"
|
||||||
|
"text": "<html>some longer <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "menuItem50"
|
||||||
|
"text": "<html>another <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>"
|
||||||
|
} )
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 0 2 1,growx"
|
"value": "cell 1 0 2 1,growx"
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import javax.swing.*;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatPaintingHiDPITest
|
||||||
|
extends JPanel
|
||||||
|
{
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatPaintingHiDPITest" );
|
||||||
|
frame.showFrame( FlatPaintingHiDPITest::new );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatPaintingHiDPITest() {
|
||||||
|
initComponents();
|
||||||
|
sliderChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sliderChanged() {
|
||||||
|
painter.translateX = translateXSlider.getValue();
|
||||||
|
painter.translateY = translateYSlider.getValue();
|
||||||
|
painter.scaleX = scaleXSlider.getValue();
|
||||||
|
painter.scaleY = scaleYSlider.getValue();
|
||||||
|
painter.rotate = rotateSlider.getValue();
|
||||||
|
painter.repaint();
|
||||||
|
|
||||||
|
AffineTransform t = new AffineTransform();
|
||||||
|
t.translate( painter.translateX, painter.translateY );
|
||||||
|
t.scale( painter.scaleX / 100., painter.scaleY / 100. );
|
||||||
|
t.rotate( Math.toRadians( painter.rotate ) );
|
||||||
|
|
||||||
|
tScaleXLabel.setText( Double.toString( t.getScaleX() ) );
|
||||||
|
tScaleYLabel.setText( Double.toString( t.getScaleY() ) );
|
||||||
|
tShearXLabel.setText( Double.toString( t.getShearX() ) );
|
||||||
|
tShearYLabel.setText( Double.toString( t.getShearY() ) );
|
||||||
|
tTranslateXLabel.setText( Double.toString( t.getTranslateX() ) );
|
||||||
|
tTranslateYLabel.setText( Double.toString( t.getTranslateY() ) );
|
||||||
|
|
||||||
|
double scaleX = Math.hypot( t.getScaleX(), t.getShearX() );
|
||||||
|
double scaleY = Math.hypot( t.getScaleY(), t.getShearY() );
|
||||||
|
if( t.getScaleX() < 0 )
|
||||||
|
scaleX = -scaleX;
|
||||||
|
if( t.getScaleY() < 0 )
|
||||||
|
scaleY = -scaleY;
|
||||||
|
|
||||||
|
double rotation = Math.atan2( t.getShearY(), t.getScaleY() );
|
||||||
|
double rotationDegrees = Math.toDegrees( rotation );
|
||||||
|
cScaleXLabel.setText( Double.toString( scaleX ) );
|
||||||
|
cScaleYLabel.setText( Double.toString( scaleY ) );
|
||||||
|
cRotationDegreesLabel.setText( Double.toString( rotationDegrees ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset() {
|
||||||
|
translateXSlider.setValue( 100 );
|
||||||
|
translateYSlider.setValue( 100 );
|
||||||
|
scaleXSlider.setValue( 100 );
|
||||||
|
scaleYSlider.setValue( 100 );
|
||||||
|
rotateSlider.setValue( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JLabel translateXLabel = new JLabel();
|
||||||
|
translateXSlider = new JSlider();
|
||||||
|
JLabel translateYLabel = new JLabel();
|
||||||
|
translateYSlider = new JSlider();
|
||||||
|
JLabel scaleXLabel = new JLabel();
|
||||||
|
scaleXSlider = new JSlider();
|
||||||
|
JLabel scaleYLabel = new JLabel();
|
||||||
|
scaleYSlider = new JSlider();
|
||||||
|
JLabel rotateLabel = new JLabel();
|
||||||
|
rotateSlider = new JSlider();
|
||||||
|
JPanel panel1 = new JPanel();
|
||||||
|
JLabel tLabel = new JLabel();
|
||||||
|
JLabel xLabel = new JLabel();
|
||||||
|
JLabel yLabel = new JLabel();
|
||||||
|
JLabel tScaleLabel = new JLabel();
|
||||||
|
tScaleXLabel = new JLabel();
|
||||||
|
tScaleYLabel = new JLabel();
|
||||||
|
JLabel tShearLabel = new JLabel();
|
||||||
|
tShearXLabel = new JLabel();
|
||||||
|
tShearYLabel = new JLabel();
|
||||||
|
JLabel tTranslateLabel = new JLabel();
|
||||||
|
tTranslateXLabel = new JLabel();
|
||||||
|
tTranslateYLabel = new JLabel();
|
||||||
|
JLabel cLabel = new JLabel();
|
||||||
|
JLabel cScaleLabel = new JLabel();
|
||||||
|
cScaleXLabel = new JLabel();
|
||||||
|
cScaleYLabel = new JLabel();
|
||||||
|
JLabel cRotationLabel = new JLabel();
|
||||||
|
cRotationDegreesLabel = new JLabel();
|
||||||
|
JButton resetButton = new JButton();
|
||||||
|
painter = new FlatPaintingHiDPITest.HiDPI1xPainter();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setBorder(null);
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[fill]" +
|
||||||
|
"[400,fill]para" +
|
||||||
|
"[grow,fill]",
|
||||||
|
// rows
|
||||||
|
"[fill]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[grow]"));
|
||||||
|
|
||||||
|
//---- translateXLabel ----
|
||||||
|
translateXLabel.setText("TranslateX:");
|
||||||
|
add(translateXLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- translateXSlider ----
|
||||||
|
translateXSlider.setMaximum(500);
|
||||||
|
translateXSlider.setPaintLabels(true);
|
||||||
|
translateXSlider.setPaintTicks(true);
|
||||||
|
translateXSlider.setMajorTickSpacing(100);
|
||||||
|
translateXSlider.setMinorTickSpacing(25);
|
||||||
|
translateXSlider.setValue(100);
|
||||||
|
translateXSlider.addChangeListener(e -> sliderChanged());
|
||||||
|
add(translateXSlider, "cell 1 0");
|
||||||
|
|
||||||
|
//---- translateYLabel ----
|
||||||
|
translateYLabel.setText("TranslateY:");
|
||||||
|
add(translateYLabel, "cell 0 1");
|
||||||
|
|
||||||
|
//---- translateYSlider ----
|
||||||
|
translateYSlider.setMaximum(500);
|
||||||
|
translateYSlider.setPaintLabels(true);
|
||||||
|
translateYSlider.setPaintTicks(true);
|
||||||
|
translateYSlider.setMajorTickSpacing(100);
|
||||||
|
translateYSlider.setMinorTickSpacing(25);
|
||||||
|
translateYSlider.setValue(100);
|
||||||
|
translateYSlider.addChangeListener(e -> sliderChanged());
|
||||||
|
add(translateYSlider, "cell 1 1");
|
||||||
|
|
||||||
|
//---- scaleXLabel ----
|
||||||
|
scaleXLabel.setText("ScaleX:");
|
||||||
|
add(scaleXLabel, "cell 0 2");
|
||||||
|
|
||||||
|
//---- scaleXSlider ----
|
||||||
|
scaleXSlider.setMaximum(300);
|
||||||
|
scaleXSlider.setValue(100);
|
||||||
|
scaleXSlider.setPaintTicks(true);
|
||||||
|
scaleXSlider.setPaintLabels(true);
|
||||||
|
scaleXSlider.setMajorTickSpacing(50);
|
||||||
|
scaleXSlider.setSnapToTicks(true);
|
||||||
|
scaleXSlider.setMinorTickSpacing(10);
|
||||||
|
scaleXSlider.setMinimum(-100);
|
||||||
|
scaleXSlider.addChangeListener(e -> sliderChanged());
|
||||||
|
add(scaleXSlider, "cell 1 2");
|
||||||
|
|
||||||
|
//---- scaleYLabel ----
|
||||||
|
scaleYLabel.setText("ScaleY:");
|
||||||
|
add(scaleYLabel, "cell 0 3");
|
||||||
|
|
||||||
|
//---- scaleYSlider ----
|
||||||
|
scaleYSlider.setMaximum(300);
|
||||||
|
scaleYSlider.setValue(100);
|
||||||
|
scaleYSlider.setPaintTicks(true);
|
||||||
|
scaleYSlider.setPaintLabels(true);
|
||||||
|
scaleYSlider.setMajorTickSpacing(50);
|
||||||
|
scaleYSlider.setSnapToTicks(true);
|
||||||
|
scaleYSlider.setMinorTickSpacing(10);
|
||||||
|
scaleYSlider.setMinimum(-100);
|
||||||
|
scaleYSlider.addChangeListener(e -> sliderChanged());
|
||||||
|
add(scaleYSlider, "cell 1 3");
|
||||||
|
|
||||||
|
//---- rotateLabel ----
|
||||||
|
rotateLabel.setText("Rotate:");
|
||||||
|
add(rotateLabel, "cell 0 4");
|
||||||
|
|
||||||
|
//---- rotateSlider ----
|
||||||
|
rotateSlider.setMaximum(360);
|
||||||
|
rotateSlider.setMinimum(-360);
|
||||||
|
rotateSlider.setValue(0);
|
||||||
|
rotateSlider.setMajorTickSpacing(90);
|
||||||
|
rotateSlider.setPaintLabels(true);
|
||||||
|
rotateSlider.setPaintTicks(true);
|
||||||
|
rotateSlider.addChangeListener(e -> sliderChanged());
|
||||||
|
add(rotateSlider, "cell 1 4");
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setLayout(new MigLayout(
|
||||||
|
"hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[fill]" +
|
||||||
|
"[50,fill]" +
|
||||||
|
"[50,fill]",
|
||||||
|
// rows
|
||||||
|
"[]" +
|
||||||
|
"[]0" +
|
||||||
|
"[]0" +
|
||||||
|
"[]para" +
|
||||||
|
"[]" +
|
||||||
|
"[]0" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- tLabel ----
|
||||||
|
tLabel.setText("AffineTransform:");
|
||||||
|
panel1.add(tLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- xLabel ----
|
||||||
|
xLabel.setText("X");
|
||||||
|
panel1.add(xLabel, "cell 1 0,alignx center,growx 0");
|
||||||
|
|
||||||
|
//---- yLabel ----
|
||||||
|
yLabel.setText("Y");
|
||||||
|
panel1.add(yLabel, "cell 2 0,alignx center,growx 0");
|
||||||
|
|
||||||
|
//---- tScaleLabel ----
|
||||||
|
tScaleLabel.setText("Scale:");
|
||||||
|
panel1.add(tScaleLabel, "cell 0 1,gapx indent");
|
||||||
|
|
||||||
|
//---- tScaleXLabel ----
|
||||||
|
tScaleXLabel.setText("text");
|
||||||
|
panel1.add(tScaleXLabel, "cell 1 1");
|
||||||
|
|
||||||
|
//---- tScaleYLabel ----
|
||||||
|
tScaleYLabel.setText("text");
|
||||||
|
panel1.add(tScaleYLabel, "cell 2 1");
|
||||||
|
|
||||||
|
//---- tShearLabel ----
|
||||||
|
tShearLabel.setText("Shear:");
|
||||||
|
panel1.add(tShearLabel, "cell 0 2,gapx indent");
|
||||||
|
|
||||||
|
//---- tShearXLabel ----
|
||||||
|
tShearXLabel.setText("text");
|
||||||
|
panel1.add(tShearXLabel, "cell 1 2");
|
||||||
|
|
||||||
|
//---- tShearYLabel ----
|
||||||
|
tShearYLabel.setText("text");
|
||||||
|
panel1.add(tShearYLabel, "cell 2 2");
|
||||||
|
|
||||||
|
//---- tTranslateLabel ----
|
||||||
|
tTranslateLabel.setText("Translate:");
|
||||||
|
panel1.add(tTranslateLabel, "cell 0 3,gapx indent");
|
||||||
|
|
||||||
|
//---- tTranslateXLabel ----
|
||||||
|
tTranslateXLabel.setText("text");
|
||||||
|
panel1.add(tTranslateXLabel, "cell 1 3");
|
||||||
|
|
||||||
|
//---- tTranslateYLabel ----
|
||||||
|
tTranslateYLabel.setText("text");
|
||||||
|
panel1.add(tTranslateYLabel, "cell 2 3");
|
||||||
|
|
||||||
|
//---- cLabel ----
|
||||||
|
cLabel.setText("Computed:");
|
||||||
|
panel1.add(cLabel, "cell 0 4");
|
||||||
|
|
||||||
|
//---- cScaleLabel ----
|
||||||
|
cScaleLabel.setText("Scale:");
|
||||||
|
panel1.add(cScaleLabel, "cell 0 5,gapx indent");
|
||||||
|
|
||||||
|
//---- cScaleXLabel ----
|
||||||
|
cScaleXLabel.setText("text");
|
||||||
|
panel1.add(cScaleXLabel, "cell 1 5");
|
||||||
|
|
||||||
|
//---- cScaleYLabel ----
|
||||||
|
cScaleYLabel.setText("text");
|
||||||
|
panel1.add(cScaleYLabel, "cell 2 5");
|
||||||
|
|
||||||
|
//---- cRotationLabel ----
|
||||||
|
cRotationLabel.setText("Rotation:");
|
||||||
|
panel1.add(cRotationLabel, "cell 0 6,gapx indent");
|
||||||
|
|
||||||
|
//---- cRotationDegreesLabel ----
|
||||||
|
cRotationDegreesLabel.setText("text");
|
||||||
|
panel1.add(cRotationDegreesLabel, "cell 1 6");
|
||||||
|
}
|
||||||
|
add(panel1, "cell 2 0 1 4");
|
||||||
|
|
||||||
|
//---- resetButton ----
|
||||||
|
resetButton.setText("Reset");
|
||||||
|
resetButton.addActionListener(e -> reset());
|
||||||
|
add(resetButton, "cell 2 4,align left bottom,grow 0 0");
|
||||||
|
add(painter, "cell 0 5 3 1,grow,width 600,height 400");
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JSlider translateXSlider;
|
||||||
|
private JSlider translateYSlider;
|
||||||
|
private JSlider scaleXSlider;
|
||||||
|
private JSlider scaleYSlider;
|
||||||
|
private JSlider rotateSlider;
|
||||||
|
private JLabel tScaleXLabel;
|
||||||
|
private JLabel tScaleYLabel;
|
||||||
|
private JLabel tShearXLabel;
|
||||||
|
private JLabel tShearYLabel;
|
||||||
|
private JLabel tTranslateXLabel;
|
||||||
|
private JLabel tTranslateYLabel;
|
||||||
|
private JLabel cScaleXLabel;
|
||||||
|
private JLabel cScaleYLabel;
|
||||||
|
private JLabel cRotationDegreesLabel;
|
||||||
|
private FlatPaintingHiDPITest.HiDPI1xPainter painter;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
|
//---- class HiDPI1xPainter -----------------------------------------------
|
||||||
|
|
||||||
|
public static class HiDPI1xPainter
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
int translateX;
|
||||||
|
int translateY;
|
||||||
|
int scaleX;
|
||||||
|
int scaleY;
|
||||||
|
int rotate;
|
||||||
|
|
||||||
|
public HiDPI1xPainter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
int width = getWidth();
|
||||||
|
int height = getHeight();
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
try {
|
||||||
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|
||||||
|
g2.setColor( Color.blue );
|
||||||
|
g2.drawRect( 0, 0, width - 1, height - 1 );
|
||||||
|
|
||||||
|
g2.setColor( Color.cyan );
|
||||||
|
g2.drawLine( 0, translateY, width, translateY );
|
||||||
|
g2.drawLine( translateX, 0, translateX, height );
|
||||||
|
|
||||||
|
g2.translate( translateX, translateY );
|
||||||
|
g2.scale( scaleX / 100., scaleY / 100. );
|
||||||
|
g2.rotate( Math.toRadians( rotate ) );
|
||||||
|
|
||||||
|
g2.setColor( Color.red );
|
||||||
|
g2.fillRect( 0, 0, 100, 50 );
|
||||||
|
|
||||||
|
g2.setColor( Color.green );
|
||||||
|
HiDPIUtils.paintAtScale1x( g2, 0, 0, 100, 50,
|
||||||
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
g2d.fillRect( x2 + 10, y2 + 10, width2 - 20, height2 - 20 );
|
||||||
|
} );
|
||||||
|
} finally {
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
JFDML JFormDesigner: "8.0.0.0.122" Java: "17.0.2" 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": "hidemode 3"
|
||||||
|
"$columnConstraints": "[fill][400,fill]para[grow,fill]"
|
||||||
|
"$rowConstraints": "[fill][][][][][grow]"
|
||||||
|
} ) {
|
||||||
|
name: "this"
|
||||||
|
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "translateXLabel"
|
||||||
|
"text": "TranslateX:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "translateXSlider"
|
||||||
|
"maximum": 500
|
||||||
|
"paintLabels": true
|
||||||
|
"paintTicks": true
|
||||||
|
"majorTickSpacing": 100
|
||||||
|
"minorTickSpacing": 25
|
||||||
|
"value": 100
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "sliderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "translateYLabel"
|
||||||
|
"text": "TranslateY:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "translateYSlider"
|
||||||
|
"maximum": 500
|
||||||
|
"paintLabels": true
|
||||||
|
"paintTicks": true
|
||||||
|
"majorTickSpacing": 100
|
||||||
|
"minorTickSpacing": 25
|
||||||
|
"value": 100
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "sliderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "scaleXLabel"
|
||||||
|
"text": "ScaleX:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "scaleXSlider"
|
||||||
|
"maximum": 300
|
||||||
|
"value": 100
|
||||||
|
"paintTicks": true
|
||||||
|
"paintLabels": true
|
||||||
|
"majorTickSpacing": 50
|
||||||
|
"snapToTicks": true
|
||||||
|
"minorTickSpacing": 10
|
||||||
|
"minimum": -100
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "sliderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "scaleYLabel"
|
||||||
|
"text": "ScaleY:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "scaleYSlider"
|
||||||
|
"maximum": 300
|
||||||
|
"value": 100
|
||||||
|
"paintTicks": true
|
||||||
|
"paintLabels": true
|
||||||
|
"majorTickSpacing": 50
|
||||||
|
"snapToTicks": true
|
||||||
|
"minorTickSpacing": 10
|
||||||
|
"minimum": -100
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "sliderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "rotateLabel"
|
||||||
|
"text": "Rotate:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "rotateSlider"
|
||||||
|
"maximum": 360
|
||||||
|
"minimum": -360
|
||||||
|
"value": 0
|
||||||
|
"majorTickSpacing": 90
|
||||||
|
"paintLabels": true
|
||||||
|
"paintTicks": true
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "sliderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 4"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "hidemode 3"
|
||||||
|
"$columnConstraints": "[fill][50,fill][50,fill]"
|
||||||
|
"$rowConstraints": "[][]0[]0[]para[][]0[]"
|
||||||
|
} ) {
|
||||||
|
name: "panel1"
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tLabel"
|
||||||
|
"text": "AffineTransform:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "xLabel"
|
||||||
|
"text": "X"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0,alignx center,growx 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "yLabel"
|
||||||
|
"text": "Y"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 0,alignx center,growx 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tScaleLabel"
|
||||||
|
"text": "Scale:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1,gapx indent"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tScaleXLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tScaleYLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tShearLabel"
|
||||||
|
"text": "Shear:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2,gapx indent"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tShearXLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tShearYLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tTranslateLabel"
|
||||||
|
"text": "Translate:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3,gapx indent"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tTranslateXLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tTranslateYLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cLabel"
|
||||||
|
"text": "Computed:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cScaleLabel"
|
||||||
|
"text": "Scale:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5,gapx indent"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cScaleXLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cScaleYLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cRotationLabel"
|
||||||
|
"text": "Rotation:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6,gapx indent"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "cRotationDegreesLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 0 1 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "resetButton"
|
||||||
|
"text": "Reset"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "reset", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 4,align left bottom,grow 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingHiDPITest$HiDPI1xPainter" ) {
|
||||||
|
name: "painter"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5 3 1,grow,width 600,height 400"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 0 )
|
||||||
|
"size": new java.awt.Dimension( 685, 680 )
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,12 +22,14 @@ import java.awt.Font;
|
|||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.util.Arrays;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.text.StyleContext;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
||||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.JavaCompatibility;
|
import com.formdev.flatlaf.util.JavaCompatibility;
|
||||||
@@ -57,18 +59,60 @@ public class FlatPaintingStringTest
|
|||||||
FlatPaintingStringTest() {
|
FlatPaintingStringTest() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
|
String[] availableFontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||||
|
.getAvailableFontFamilyNames().clone();
|
||||||
|
Arrays.sort( availableFontFamilyNames );
|
||||||
|
|
||||||
|
Font currentFont = UIManager.getFont( "Label.font" );
|
||||||
|
String currentFamily = currentFont.getFamily();
|
||||||
|
|
||||||
|
// initialize font families combobox
|
||||||
|
String[] families = {
|
||||||
|
// regular
|
||||||
|
"Arial", "Cantarell", "DejaVu Sans",
|
||||||
|
"Dialog", "Helvetica Neue", "Inter", "Liberation Sans", "Noto Sans", "Open Sans", "Roboto",
|
||||||
|
"SansSerif", "Segoe UI", "Tahoma", "Ubuntu", "Verdana", ".SF NS Text",
|
||||||
|
|
||||||
|
// light, semibold
|
||||||
|
"Segoe UI Light", "Segoe UI Semibold",
|
||||||
|
"HelveticaNeue-Thin", "HelveticaNeue-Medium",
|
||||||
|
"Lato Light", "Ubuntu Light", "Cantarell Light",
|
||||||
|
"Lato Semibold", "Ubuntu Medium", "Montserrat SemiBold",
|
||||||
|
|
||||||
|
// monospaced
|
||||||
|
"Monospaced", "Consolas", "Courier New", "Menlo", "Liberation Mono", "Ubuntu Mono",
|
||||||
|
};
|
||||||
|
Arrays.sort( families, String.CASE_INSENSITIVE_ORDER );
|
||||||
|
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
|
||||||
|
model.addElement( currentFamily );
|
||||||
|
for( String family : families ) {
|
||||||
|
if( !family.equals( currentFamily ) && Arrays.binarySearch( availableFontFamilyNames, family ) >= 0 )
|
||||||
|
model.addElement( family );
|
||||||
|
}
|
||||||
|
fontField.setModel( model );
|
||||||
|
fontField.setSelectedItem( currentFamily );
|
||||||
|
updateFontMetricsLabel();
|
||||||
|
|
||||||
add( new JLabel() );
|
add( new JLabel() );
|
||||||
add( new JLabel( "none" ) );
|
add( new JLabel( "none" ) );
|
||||||
add( new JLabel( "flatlaf" ) );
|
add( new JLabel( "flatlaf" ) );
|
||||||
add( new JLabel( "0.25*scale" ) );
|
add( new JLabel() );
|
||||||
add( new JLabel( "0.5*scale" ) );
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
|
add( new JLabel( "0.125" ) );
|
||||||
add( new JLabel( "0.25" ) );
|
add( new JLabel( "0.25" ) );
|
||||||
add( new JLabel( "0.5" ) );
|
add( new JLabel( "0.5" ) );
|
||||||
add( new JLabel( "0.625" ) );
|
add( new JLabel( "0.625" ) );
|
||||||
add( new JLabel( "0.75" ) );
|
add( new JLabel( "0.75" ) );
|
||||||
add( new JLabel( "0.875" ) );
|
add( new JLabel( "0.875" ) );
|
||||||
|
add( new JLabel( "1" ) );
|
||||||
|
add( new JLabel( "1.25" ) );
|
||||||
|
add( new JLabel() );
|
||||||
|
add( new JLabel( "0.25*scale" ) );
|
||||||
|
add( new JLabel( "0.5*scale" ) );
|
||||||
|
add( new JLabel( "ty" ) );
|
||||||
} else {
|
} else {
|
||||||
|
add( new JLabel( "0.25*scale" ) );
|
||||||
|
add( new JLabel( "0.5*scale" ) );
|
||||||
add( new JLabel( "0.625*scale" ) );
|
add( new JLabel( "0.625*scale" ) );
|
||||||
add( new JLabel( "0.75*scale" ) );
|
add( new JLabel( "0.75*scale" ) );
|
||||||
add( new JLabel( "0.875*scale" ) );
|
add( new JLabel( "0.875*scale" ) );
|
||||||
@@ -80,16 +124,14 @@ public class FlatPaintingStringTest
|
|||||||
? HiDPIUtils.computeTextYCorrection( g )
|
? HiDPIUtils.computeTextYCorrection( g )
|
||||||
: (scaleFactor > 1 ? -(0.625f * scaleFactor) : 0);
|
: (scaleFactor > 1 ? -(0.625f * scaleFactor) : 0);
|
||||||
};
|
};
|
||||||
YCorrectionFunction oneQSysScale = (g, scaleFactor) -> -(0.25f * scaleFactor);
|
YCorrectionFunction ty = (g, scaleFactor) -> {
|
||||||
YCorrectionFunction halfSysScale = (g, scaleFactor) -> -(0.5f * scaleFactor);
|
// Based on translateY, which is the scaled Y coordinate translation of the graphics context.
|
||||||
YCorrectionFunction fiveEightsQSysScale = (g, scaleFactor) -> -(0.625f * scaleFactor);
|
// When painting whole window, translateY is from top of window, and this works fine.
|
||||||
YCorrectionFunction threeQSysScale = (g, scaleFactor) -> -(0.75f * scaleFactor);
|
// But when repainting only parts of the window, then translateY starts somewhere
|
||||||
YCorrectionFunction sevenEightsSysScale = (g, scaleFactor) -> -(0.875f * scaleFactor);
|
// else and the text if (re-)painted at the wrong Y location.
|
||||||
YCorrectionFunction oneQ = (g, scaleFactor) -> -0.25f;
|
double y = g.getTransform().getTranslateY();
|
||||||
YCorrectionFunction half = (g, scaleFactor) -> -0.5f;
|
return (float) -(y - (int) y);
|
||||||
YCorrectionFunction fiveEights = (g, scaleFactor) -> -0.625f;
|
};
|
||||||
YCorrectionFunction threeQ = (g, scaleFactor) -> -0.75f;
|
|
||||||
YCorrectionFunction sevenEights = (g, scaleFactor) -> -0.875f;
|
|
||||||
|
|
||||||
float[] scaleFactors = new float[] { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 3f, 3.5f, 4f };
|
float[] scaleFactors = new float[] { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 3f, 3.5f, 4f };
|
||||||
|
|
||||||
@@ -98,34 +140,72 @@ public class FlatPaintingStringTest
|
|||||||
|
|
||||||
add( scaleFactor, none );
|
add( scaleFactor, none );
|
||||||
add( scaleFactor, flatlaf );
|
add( scaleFactor, flatlaf );
|
||||||
add( scaleFactor, oneQSysScale );
|
add( new JLabel( " " ) );
|
||||||
add( scaleFactor, halfSysScale );
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
add( scaleFactor, oneQ );
|
add( scaleFactor, (g, sf) -> -0.125f );
|
||||||
add( scaleFactor, half );
|
add( scaleFactor, (g, sf) -> -0.25f );
|
||||||
add( scaleFactor, fiveEights );
|
add( scaleFactor, (g, sf) -> -0.5f );
|
||||||
add( scaleFactor, threeQ );
|
add( scaleFactor, (g, sf) -> -0.625f );
|
||||||
add( scaleFactor, sevenEights );
|
add( scaleFactor, (g, sf) -> -0.75f );
|
||||||
|
add( scaleFactor, (g, sf) -> -0.875f );
|
||||||
|
add( scaleFactor, (g, sf) -> -1f );
|
||||||
|
add( scaleFactor, (g, sf) -> -1.25f );
|
||||||
|
add( new JLabel( " " ) );
|
||||||
|
add( scaleFactor, (g, sf) -> -(0.25f * sf) );
|
||||||
|
add( scaleFactor, (g, sf) -> -(0.5f * sf) );
|
||||||
|
add( scaleFactor, ty );
|
||||||
} else {
|
} else {
|
||||||
add( scaleFactor, fiveEightsQSysScale );
|
add( scaleFactor, (g, sf) -> -(0.25f * sf) );
|
||||||
add( scaleFactor, threeQSysScale );
|
add( scaleFactor, (g, sf) -> -(0.5f * sf) );
|
||||||
add( scaleFactor, sevenEightsSysScale );
|
add( scaleFactor, (g, sf) -> -(0.625f * sf) );
|
||||||
|
add( scaleFactor, (g, sf) -> -(0.75f * sf) );
|
||||||
|
add( scaleFactor, (g, sf) -> -(0.875f * sf) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add( new JLabel( String.valueOf( scaleFactor ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add( float scaleFactor, YCorrectionFunction correctionFunction ) {
|
private void add( float scaleFactor, YCorrectionFunction correctionFunction ) {
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" );
|
add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" );
|
||||||
add( new Painter( scaleFactor, correctionFunction, 0.25f ), "gapx 0 0" );
|
add( new Painter( scaleFactor, correctionFunction, 1 ), "gapx 0 0" );
|
||||||
add( new Painter( scaleFactor, correctionFunction, 0.5f ), "gapx 0 0" );
|
add( new Painter( scaleFactor, correctionFunction, 2 ), "gapx 0 0" );
|
||||||
add( new Painter( scaleFactor, correctionFunction, 0.75f ), "gapx 0 0" );
|
add( new Painter( scaleFactor, correctionFunction, 3 ), "gapx 0 0" );
|
||||||
} else
|
} else
|
||||||
add( new Painter( scaleFactor, correctionFunction, 0 ) );
|
add( new Painter( scaleFactor, correctionFunction, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fontChanged() {
|
||||||
|
String family = (String) fontField.getSelectedItem();
|
||||||
|
|
||||||
|
Font font = UIManager.getFont( "defaultFont" );
|
||||||
|
if( font.getFamily().equals( family ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Font newFont = StyleContext.getDefaultStyleContext().getFont( family, font.getStyle(), font.getSize() );
|
||||||
|
UIManager.put( "defaultFont", newFont );
|
||||||
|
updateFontMetricsLabel();
|
||||||
|
|
||||||
|
FlatLaf.updateUILater();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFontMetricsLabel() {
|
||||||
|
Font font = UIManager.getFont( "defaultFont" );
|
||||||
|
FontMetrics fm = getFontMetrics( font );
|
||||||
|
fontMetricsLabel.setText( String.format( "%s %d height %d ascent %d descent %d max ascent %d max descent %d leading %d",
|
||||||
|
font.getFamily(), font.getSize(),
|
||||||
|
fm.getHeight(), fm.getAscent(), fm.getDescent(),
|
||||||
|
fm.getMaxAscent(), fm.getMaxDescent(), fm.getLeading()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JPanel panel1 = new JPanel();
|
||||||
|
JLabel fontLabel = new JLabel();
|
||||||
|
fontField = new JComboBox<>();
|
||||||
|
fontMetricsLabel = new JLabel();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setBorder(null);
|
setBorder(null);
|
||||||
@@ -134,11 +214,40 @@ public class FlatPaintingStringTest
|
|||||||
// columns
|
// columns
|
||||||
"[fill]",
|
"[fill]",
|
||||||
// rows
|
// rows
|
||||||
|
"[top]unrel" +
|
||||||
"[top]"));
|
"[top]"));
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setLayout(new MigLayout(
|
||||||
|
"hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[fill]" +
|
||||||
|
"[fill]" +
|
||||||
|
"[fill]",
|
||||||
|
// rows
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- fontLabel ----
|
||||||
|
fontLabel.setText("Font:");
|
||||||
|
panel1.add(fontLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- fontField ----
|
||||||
|
fontField.setMaximumRowCount(20);
|
||||||
|
fontField.addActionListener(e -> fontChanged());
|
||||||
|
panel1.add(fontField, "cell 1 0");
|
||||||
|
|
||||||
|
//---- fontMetricsLabel ----
|
||||||
|
fontMetricsLabel.setText("text");
|
||||||
|
panel1.add(fontMetricsLabel, "cell 2 0");
|
||||||
|
}
|
||||||
|
add(panel1, "north");
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
}
|
}
|
||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JComboBox<String> fontField;
|
||||||
|
private JLabel fontMetricsLabel;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
private interface YCorrectionFunction {
|
private interface YCorrectionFunction {
|
||||||
@@ -152,17 +261,29 @@ public class FlatPaintingStringTest
|
|||||||
{
|
{
|
||||||
private final float scaleFactor;
|
private final float scaleFactor;
|
||||||
private final YCorrectionFunction correctionFunction;
|
private final YCorrectionFunction correctionFunction;
|
||||||
private final float yOffset;
|
private final int yOffset;
|
||||||
|
|
||||||
public Painter( float scaleFactor, YCorrectionFunction correctionFunction, float yOffset ) {
|
public Painter( float scaleFactor, YCorrectionFunction correctionFunction, int yOffset ) {
|
||||||
super( "E" );
|
super( "E" );
|
||||||
this.scaleFactor = scaleFactor;
|
this.scaleFactor = scaleFactor;
|
||||||
this.correctionFunction = correctionFunction;
|
this.correctionFunction = correctionFunction;
|
||||||
this.yOffset = yOffset;
|
this.yOffset = yOffset;
|
||||||
setBorder( new EmptyBorder( 2, 0, 2, 0 ) );
|
|
||||||
|
updateFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
super.updateUI();
|
||||||
|
updateFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFont() {
|
||||||
|
if( scaleFactor == 0 )
|
||||||
|
return; // invoked from super constructor
|
||||||
|
|
||||||
if( !SystemInfo.isJava_9_orLater ) {
|
if( !SystemInfo.isJava_9_orLater ) {
|
||||||
Font font = getFont();
|
Font font = UIManager.getFont( "defaultFont" );
|
||||||
setFont( font.deriveFont( (float) Math.round( font.getSize() * scaleFactor ) ) );
|
setFont( font.deriveFont( (float) Math.round( font.getSize() * scaleFactor ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,35 +291,36 @@ public class FlatPaintingStringTest
|
|||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
Dimension size = super.getPreferredSize();
|
Dimension size = super.getPreferredSize();
|
||||||
Insets insets = getInsets();
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
int leftRight = insets.left + insets.right;
|
// compute component size using JRE scaling
|
||||||
return new Dimension(
|
//
|
||||||
scale( size.width -leftRight ) + leftRight,
|
// The y offset is used to simulate different vertical component positions,
|
||||||
scale( size.height ) );
|
// which may result in different component heights.
|
||||||
|
// E.g. scaling following bounds by 150% results in different heights:
|
||||||
|
// 0,0, 10,15 --> [x=0,y=0,width=15,height=22]
|
||||||
|
// 0,1, 10,15 --> [x=0,y=1,width=15,height=23]
|
||||||
|
Rectangle r = scaleTo1x( scaleFactor, 0, yOffset, size.width, size.height );
|
||||||
|
return new Dimension( r.width, r.height );
|
||||||
|
} else
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent( Graphics g ) {
|
protected void paintComponent( Graphics g ) {
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g2 );
|
|
||||||
|
|
||||||
// simulate component y position at a fraction
|
|
||||||
if( scaleFactor > 1 && SystemInfo.isJava_9_orLater )
|
|
||||||
g2.translate( 0, yOffset );
|
|
||||||
|
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
int height = getHeight();
|
int height = getHeight();
|
||||||
Insets insets = getInsets();
|
|
||||||
FontMetrics fm = getFontMetrics( getFont() );
|
FontMetrics fm = getFontMetrics( getFont() );
|
||||||
|
|
||||||
// paint lines at 1x
|
// paint lines at 1x
|
||||||
HiDPIUtils.paintAtScale1x( g2, 0, 0, width, height,
|
HiDPIUtils.paintAtScale1x( g2, 0, 0, width, height,
|
||||||
(g2d, x2, y2, width2, height2, scaleFactor2) -> {
|
(g2d, x2, y2, width2, height2, scaleFactor2) -> {
|
||||||
// g.setColor( Color.blue );
|
g.setColor( Color.blue );
|
||||||
// g.drawLine( 0, 0, width2, 0 );
|
g.drawLine( 0, 0, width2, 0 );
|
||||||
// g.drawLine( 0, height2 - 1, width2, height2 - 1 );
|
g.drawLine( 0, height2 - 1, width2, height2 - 1 );
|
||||||
|
|
||||||
int baseline = (int) Math.round( (insets.top + fm.getAscent()) * scaleFactor2
|
int baseline = (int) Math.round( fm.getAscent() * scaleFactor2
|
||||||
* (SystemInfo.isJava_9_orLater ? scaleFactor : 1f) ) - 1;
|
* (SystemInfo.isJava_9_orLater ? scaleFactor : 1f) ) - 1;
|
||||||
int topline = height2 - baseline - 1;
|
int topline = height2 - baseline - 1;
|
||||||
|
|
||||||
@@ -207,8 +329,15 @@ public class FlatPaintingStringTest
|
|||||||
g.drawLine( 0, topline, width2, topline );
|
g.drawLine( 0, topline, width2, topline );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// move x before scaling to have same left inset at all scale factors
|
// simulate different vertical component positions
|
||||||
g.translate( insets.left, 0 );
|
if( yOffset > 0 && SystemInfo.isJava_9_orLater ) {
|
||||||
|
double ty = yOffset * scaleFactor;
|
||||||
|
ty -= (int) ty;
|
||||||
|
if( ty == 0 )
|
||||||
|
return; // no need to paint
|
||||||
|
|
||||||
|
g2.translate( 0, ty );
|
||||||
|
}
|
||||||
|
|
||||||
// scale
|
// scale
|
||||||
if( SystemInfo.isJava_9_orLater )
|
if( SystemInfo.isJava_9_orLater )
|
||||||
@@ -232,21 +361,36 @@ public class FlatPaintingStringTest
|
|||||||
|
|
||||||
// draw string
|
// draw string
|
||||||
g.setColor( getForeground() );
|
g.setColor( getForeground() );
|
||||||
int y = insets.top + fm.getAscent();
|
int y = fm.getAscent();
|
||||||
JavaCompatibility.drawStringUnderlineCharAt( this, cg, "E", -1, 0, y );
|
JavaCompatibility.drawStringUnderlineCharAt( this, cg, "E", -1, 0, y );
|
||||||
|
|
||||||
// set tooltip text
|
// set tooltip text
|
||||||
if( getToolTipText() == null ) {
|
AffineTransform t = g2.getTransform();
|
||||||
AffineTransform t = g2.getTransform();
|
double textY = t.getTranslateY() + (y * t.getScaleY());
|
||||||
double textY = t.getTranslateY() + (y * t.getScaleY());
|
setToolTipText( textY + " + " + yCorrection + " = " + (textY + yCorrection) );
|
||||||
setToolTipText( textY + " + " + yCorrection + " = " + (textY + yCorrection) );
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatUIUtils.resetRenderingHints( g2, oldRenderingHints );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int scale( int value ) {
|
/**
|
||||||
return SystemInfo.isJava_9_orLater ? Math.round( value * scaleFactor ) : value;
|
* Scales a rectangle in the same way as the JRE does in
|
||||||
|
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
||||||
|
* which is used by Graphics.fillRect().
|
||||||
|
*
|
||||||
|
* This is a copy of HiDPIUtils.scale()
|
||||||
|
*/
|
||||||
|
public static Rectangle scaleTo1x( double scaleFactor, int x, int y, int width, int height ) {
|
||||||
|
double px = (x * scaleFactor);
|
||||||
|
double py = (y * scaleFactor);
|
||||||
|
|
||||||
|
double newX = normalize( px );
|
||||||
|
double newY = normalize( py );
|
||||||
|
double newWidth = normalize( px + (width * scaleFactor) ) - newX;
|
||||||
|
double newHeight = normalize( py + (height * scaleFactor) ) - newY;
|
||||||
|
|
||||||
|
return new Rectangle( (int) Math.floor( newX ), (int) Math.floor( newY ), (int) newWidth, (int) newHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double normalize( double value ) {
|
||||||
|
return Math.floor( value + 0.25 ) + 0.25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.5.0.404" Java: "17.0.2" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -9,10 +9,45 @@ new FormModel {
|
|||||||
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": "insets dialog,hidemode 3"
|
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||||
"$columnConstraints": "[fill]"
|
"$columnConstraints": "[fill]"
|
||||||
"$rowConstraints": "[top]"
|
"$rowConstraints": "[top]unrel[top]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "this"
|
name: "this"
|
||||||
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE
|
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "hidemode 3"
|
||||||
|
"$columnConstraints": "[fill][fill][fill]"
|
||||||
|
"$rowConstraints": "[]"
|
||||||
|
} ) {
|
||||||
|
name: "panel1"
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fontLabel"
|
||||||
|
"text": "Font:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||||
|
name: "fontField"
|
||||||
|
"maximumRowCount": 20
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.typeParameters": "String"
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "fontChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fontMetricsLabel"
|
||||||
|
"text": "text"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 0"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "north"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 0, 0 )
|
"location": new java.awt.Point( 0, 0 )
|
||||||
"size": new java.awt.Dimension( 450, 300 )
|
"size": new java.awt.Dimension( 450, 300 )
|
||||||
|
|||||||
@@ -241,6 +241,23 @@ public class FlatWindowDecorationsTest
|
|||||||
if( c instanceof Box.Filler )
|
if( c instanceof Box.Filler )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*debug
|
||||||
|
menuBar.add( new Box.Filler( new Dimension(), new Dimension(),
|
||||||
|
new Dimension( Short.MAX_VALUE, Short.MAX_VALUE ) )
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
int w = getWidth();
|
||||||
|
int h = getHeight();
|
||||||
|
g.setColor( Color.blue );
|
||||||
|
g.drawRect( 0, 0, w - 1, h - 1 );
|
||||||
|
g.drawLine( 0, 0, w, h );
|
||||||
|
g.drawLine( 0, h, w, 0 );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
debug*/
|
||||||
|
|
||||||
menuBar.add( Box.createGlue() );
|
menuBar.add( Box.createGlue() );
|
||||||
menuBar.revalidate();
|
menuBar.revalidate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,9 +78,15 @@ controlDkShadow = #696969
|
|||||||
Button.startBackground = #fff
|
Button.startBackground = #fff
|
||||||
Button.endBackground = #bbb
|
Button.endBackground = #bbb
|
||||||
Button.focusedBackground = #0ff
|
Button.focusedBackground = #0ff
|
||||||
|
Button.focusedForeground = #00f
|
||||||
Button.hoverBackground = #ff0
|
Button.hoverBackground = #ff0
|
||||||
|
Button.hoverForeground = #00f
|
||||||
Button.pressedBackground = #FFC800
|
Button.pressedBackground = #FFC800
|
||||||
|
Button.pressedForeground = #0080ff
|
||||||
Button.selectedBackground = #fbb
|
Button.selectedBackground = #fbb
|
||||||
|
Button.selectedForeground = #321
|
||||||
|
Button.disabledSelectedBackground = #123
|
||||||
|
Button.disabledSelectedForeground = #fcc
|
||||||
|
|
||||||
Button.borderColor = #0f0
|
Button.borderColor = #0f0
|
||||||
Button.startBorderColor = #00f
|
Button.startBorderColor = #00f
|
||||||
@@ -95,8 +101,11 @@ Button.default.startBackground = #ddd
|
|||||||
Button.default.endBackground = #888
|
Button.default.endBackground = #888
|
||||||
Button.default.foreground = #800
|
Button.default.foreground = #800
|
||||||
Button.default.focusedBackground = #0ff
|
Button.default.focusedBackground = #0ff
|
||||||
|
Button.default.focusedForeground = #00f
|
||||||
Button.default.hoverBackground = #ff0
|
Button.default.hoverBackground = #ff0
|
||||||
|
Button.default.hoverForeground = #00f
|
||||||
Button.default.pressedBackground = #FFC800
|
Button.default.pressedBackground = #FFC800
|
||||||
|
Button.default.pressedForeground = #0080ff
|
||||||
Button.default.startBorderColor = #f00
|
Button.default.startBorderColor = #f00
|
||||||
Button.default.endBorderColor = #00f
|
Button.default.endBorderColor = #00f
|
||||||
Button.default.hoverBorderColor = #f00
|
Button.default.hoverBorderColor = #f00
|
||||||
@@ -104,8 +113,13 @@ Button.default.focusedBorderColor = #537699
|
|||||||
Button.default.focusColor = #f00
|
Button.default.focusColor = #f00
|
||||||
|
|
||||||
Button.toolbar.hoverBackground = #fff
|
Button.toolbar.hoverBackground = #fff
|
||||||
|
Button.toolbar.hoverForeground = #000
|
||||||
Button.toolbar.pressedBackground = #eee
|
Button.toolbar.pressedBackground = #eee
|
||||||
|
Button.toolbar.pressedForeground = #666
|
||||||
Button.toolbar.selectedBackground = #ddd
|
Button.toolbar.selectedBackground = #ddd
|
||||||
|
Button.toolbar.selectedForeground = #800
|
||||||
|
Button.toolbar.disabledSelectedBackground = #ccc
|
||||||
|
Button.toolbar.disabledSelectedForeground = #866
|
||||||
|
|
||||||
|
|
||||||
#---- CheckBox ----
|
#---- CheckBox ----
|
||||||
@@ -422,12 +436,28 @@ ToggleButton.background = #ddf
|
|||||||
ToggleButton.selectedBackground = #4f4
|
ToggleButton.selectedBackground = #4f4
|
||||||
ToggleButton.selectedForeground = #000
|
ToggleButton.selectedForeground = #000
|
||||||
ToggleButton.disabledSelectedBackground = #4d4
|
ToggleButton.disabledSelectedBackground = #4d4
|
||||||
|
ToggleButton.disabledSelectedForeground = #fff
|
||||||
|
|
||||||
ToggleButton.focusedBackground = #0ff
|
ToggleButton.focusedBackground = #0ff
|
||||||
|
ToggleButton.focusedForeground = #00f
|
||||||
ToggleButton.hoverBackground = #ff0
|
ToggleButton.hoverBackground = #ff0
|
||||||
|
ToggleButton.hoverForeground = #00f
|
||||||
ToggleButton.pressedBackground = #FFC800
|
ToggleButton.pressedBackground = #FFC800
|
||||||
|
ToggleButton.pressedForeground = #0080ff
|
||||||
|
|
||||||
|
ToggleButton.toolbar.hoverBackground = #fff
|
||||||
|
ToggleButton.toolbar.hoverForeground = #000
|
||||||
|
ToggleButton.toolbar.pressedBackground = #eee
|
||||||
|
ToggleButton.toolbar.pressedForeground = #666
|
||||||
ToggleButton.toolbar.selectedBackground = #ddd
|
ToggleButton.toolbar.selectedBackground = #ddd
|
||||||
|
ToggleButton.toolbar.selectedForeground = #800
|
||||||
|
ToggleButton.toolbar.disabledSelectedBackground = #ccc
|
||||||
|
ToggleButton.toolbar.disabledSelectedForeground = #866
|
||||||
|
|
||||||
|
ToggleButton.tab.selectedBackground = #080
|
||||||
|
ToggleButton.tab.selectedForeground = #fff
|
||||||
|
ToggleButton.tab.hoverForeground = #00f
|
||||||
|
ToggleButton.tab.focusForeground = #080
|
||||||
|
|
||||||
|
|
||||||
#---- ToolBar ----
|
#---- ToolBar ----
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ dependencies {
|
|||||||
implementation( "com.miglayout:miglayout-swing:5.3" )
|
implementation( "com.miglayout:miglayout-swing:5.3" )
|
||||||
implementation( "com.fifesoft:rsyntaxtextarea:3.1.4" )
|
implementation( "com.fifesoft:rsyntaxtextarea:3.1.4" )
|
||||||
implementation( "com.fifesoft:autocomplete:3.1.3" )
|
implementation( "com.fifesoft:autocomplete:3.1.3" )
|
||||||
implementation( "com.fifesoft:rstaui:3.1.3" )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -482,6 +482,10 @@ class FlatCompletionProvider
|
|||||||
"dark", colorParamDesc,
|
"dark", colorParamDesc,
|
||||||
"light", colorParamDesc,
|
"light", colorParamDesc,
|
||||||
"threshold", "(optional) 0-100%, default is 43%" );
|
"threshold", "(optional) 0-100%, default is 43%" );
|
||||||
|
|
||||||
|
addFunction( "over",
|
||||||
|
"foreground", colorParamDesc,
|
||||||
|
"background", colorParamDesc );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFunction( String name, String... paramNamesAndDescs ) {
|
private void addFunction( String name, String... paramNamesAndDescs ) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.themeeditor;
|
package com.formdev.flatlaf.themeeditor;
|
||||||
|
|
||||||
import java.awt.Container;
|
import java.awt.EventQueue;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -26,7 +26,6 @@ import javax.swing.border.MatteBorder;
|
|||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
import com.formdev.flatlaf.extras.components.*;
|
import com.formdev.flatlaf.extras.components.*;
|
||||||
import org.fife.rsta.ui.CollapsibleSectionPanel;
|
|
||||||
import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
||||||
@@ -44,9 +43,13 @@ import net.miginfocom.swing.*;
|
|||||||
class FlatFindReplaceBar
|
class FlatFindReplaceBar
|
||||||
extends JPanel
|
extends JPanel
|
||||||
{
|
{
|
||||||
|
static final String PROP_CLOSED = "closed";
|
||||||
|
|
||||||
private final RSyntaxTextArea textArea;
|
private final RSyntaxTextArea textArea;
|
||||||
|
|
||||||
private SearchContext context;
|
private SearchContext context;
|
||||||
|
private boolean inSetContext;
|
||||||
|
private boolean markAllPending;
|
||||||
|
|
||||||
FlatFindReplaceBar( RSyntaxTextArea textArea ) {
|
FlatFindReplaceBar( RSyntaxTextArea textArea ) {
|
||||||
this.textArea = textArea;
|
this.textArea = textArea;
|
||||||
@@ -74,6 +77,10 @@ class FlatFindReplaceBar
|
|||||||
regexToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/regex.svg" ) );
|
regexToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/regex.svg" ) );
|
||||||
closeButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/close.svg" ) );
|
closeButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/close.svg" ) );
|
||||||
|
|
||||||
|
registerKeyboardAction( e -> close(),
|
||||||
|
KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ),
|
||||||
|
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||||
|
|
||||||
SearchContext context = new SearchContext();
|
SearchContext context = new SearchContext();
|
||||||
context.setSearchWrap( true );
|
context.setSearchWrap( true );
|
||||||
setSearchContext( context );
|
setSearchContext( context );
|
||||||
@@ -93,29 +100,32 @@ class FlatFindReplaceBar
|
|||||||
void setSearchContext( SearchContext context ) {
|
void setSearchContext( SearchContext context ) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
findField.setText( context.getSearchFor() );
|
inSetContext = true;
|
||||||
replaceField.setText( context.getReplaceWith() );
|
try {
|
||||||
matchCaseToggleButton.setSelected( context.getMatchCase() );
|
findField.setText( context.getSearchFor() );
|
||||||
matchWholeWordToggleButton.setSelected( context.getWholeWord() );
|
replaceField.setText( context.getReplaceWith() );
|
||||||
regexToggleButton.setSelected( context.isRegularExpression() );
|
matchCaseToggleButton.setSelected( context.getMatchCase() );
|
||||||
|
matchWholeWordToggleButton.setSelected( context.getWholeWord() );
|
||||||
|
regexToggleButton.setSelected( context.isRegularExpression() );
|
||||||
|
} finally {
|
||||||
|
inSetContext = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void activate( boolean findEditorSelection ) {
|
||||||
public boolean requestFocusInWindow() {
|
// use selected text of editor for searching
|
||||||
// invoked from CollapsibleSectionPanel
|
if( findEditorSelection ) {
|
||||||
|
String selectedText = textArea.getSelectedText();
|
||||||
// use selected text in editor for searching
|
if( !StringUtils.isEmpty( selectedText ) && selectedText.indexOf( '\n' ) < 0 )
|
||||||
String selectedText = textArea.getSelectedText();
|
findField.setText( selectedText );
|
||||||
if( !StringUtils.isEmpty( selectedText ) && selectedText.indexOf( '\n' ) < 0 )
|
else
|
||||||
findField.setText( selectedText );
|
findField.selectAll();
|
||||||
else
|
}
|
||||||
findField.selectAll();
|
|
||||||
|
|
||||||
// if showing bar, highlight matches in editor
|
// if showing bar, highlight matches in editor
|
||||||
// (not invoking this from addNotify() because this would break the slide-in animation)
|
|
||||||
markAll();
|
markAll();
|
||||||
|
|
||||||
return findField.requestFocusInWindow();
|
findField.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -142,7 +152,20 @@ class FlatFindReplaceBar
|
|||||||
}
|
}
|
||||||
|
|
||||||
void markAll() {
|
void markAll() {
|
||||||
findOrMarkAll( false );
|
if( inSetContext )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// do mark all only once
|
||||||
|
if( markAllPending )
|
||||||
|
return;
|
||||||
|
markAllPending = true;
|
||||||
|
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
markAllPending = false;
|
||||||
|
|
||||||
|
findOrMarkAll( false );
|
||||||
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findOrMarkAll( boolean find ) {
|
private void findOrMarkAll( boolean find ) {
|
||||||
@@ -254,11 +277,8 @@ class FlatFindReplaceBar
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void close() {
|
private void close() {
|
||||||
Container parent = getParent();
|
setVisible( false );
|
||||||
if( parent instanceof CollapsibleSectionPanel )
|
firePropertyChange( PROP_CLOSED, false, true );
|
||||||
((CollapsibleSectionPanel)parent).hideBottomComponent();
|
|
||||||
else if( parent != null )
|
|
||||||
parent.remove( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
public class FlatLafThemeEditor
|
public class FlatLafThemeEditor
|
||||||
{
|
{
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
// macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
// enable screen menu bar
|
// enable screen menu bar
|
||||||
// (moves menu bar from JFrame window to top of screen)
|
// (moves menu bar from JFrame window to top of screen)
|
||||||
@@ -41,6 +41,7 @@ public class FlatLafThemeEditor
|
|||||||
// - "system": use current macOS appearance (light or dark)
|
// - "system": use current macOS appearance (light or dark)
|
||||||
// - "NSAppearanceNameAqua": use light appearance
|
// - "NSAppearanceNameAqua": use light appearance
|
||||||
// - "NSAppearanceNameDarkAqua": use dark appearance
|
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||||
|
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import org.fife.rsta.ui.CollapsibleSectionPanel;
|
|
||||||
import org.fife.ui.autocomplete.AutoCompletion;
|
import org.fife.ui.autocomplete.AutoCompletion;
|
||||||
import org.fife.ui.autocomplete.CompletionProvider;
|
import org.fife.ui.autocomplete.CompletionProvider;
|
||||||
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
|
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
|
||||||
@@ -48,6 +47,7 @@ import org.fife.ui.rsyntaxtextarea.TokenTypes;
|
|||||||
import org.fife.ui.rtextarea.Gutter;
|
import org.fife.ui.rtextarea.Gutter;
|
||||||
import org.fife.ui.rtextarea.RTextArea;
|
import org.fife.ui.rtextarea.RTextArea;
|
||||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
|
import org.fife.ui.rtextarea.SearchContext;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +62,10 @@ class FlatThemeEditorPane
|
|||||||
|
|
||||||
private static final String FLATLAF_STYLE = "text/flatlaf";
|
private static final String FLATLAF_STYLE = "text/flatlaf";
|
||||||
|
|
||||||
private final CollapsibleSectionPanel collapsiblePanel;
|
private static boolean findReplaceVisible;
|
||||||
|
private static SearchContext findReplaceContext;
|
||||||
|
|
||||||
|
private final JPanel editorPanel;
|
||||||
private final RTextScrollPane scrollPane;
|
private final RTextScrollPane scrollPane;
|
||||||
private final FlatSyntaxTextArea textArea;
|
private final FlatSyntaxTextArea textArea;
|
||||||
private final ErrorStrip errorStrip;
|
private final ErrorStrip errorStrip;
|
||||||
@@ -115,11 +118,11 @@ class FlatThemeEditorPane
|
|||||||
// create error strip
|
// create error strip
|
||||||
errorStrip = new ErrorStrip( textArea );
|
errorStrip = new ErrorStrip( textArea );
|
||||||
|
|
||||||
// create collapsible panel
|
// create editor panel
|
||||||
collapsiblePanel = new CollapsibleSectionPanel();
|
editorPanel = new JPanel( new BorderLayout() );
|
||||||
collapsiblePanel.add( scrollPane );
|
editorPanel.add( scrollPane );
|
||||||
collapsiblePanel.add( errorStrip, BorderLayout.LINE_END );
|
editorPanel.add( errorStrip, BorderLayout.LINE_END );
|
||||||
add( collapsiblePanel, BorderLayout.CENTER );
|
add( editorPanel, BorderLayout.CENTER );
|
||||||
|
|
||||||
updateTheme();
|
updateTheme();
|
||||||
}
|
}
|
||||||
@@ -166,6 +169,13 @@ class FlatThemeEditorPane
|
|||||||
scrollPane.getGutter().setLineNumberFont( font );
|
scrollPane.getGutter().setLineNumberFont( font );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selected() {
|
||||||
|
if( findReplaceVisible )
|
||||||
|
showFindReplaceBar( false );
|
||||||
|
else
|
||||||
|
hideFindReplaceBar();
|
||||||
|
}
|
||||||
|
|
||||||
void windowActivated() {
|
void windowActivated() {
|
||||||
if( preview != null )
|
if( preview != null )
|
||||||
preview.repaint();
|
preview.repaint();
|
||||||
@@ -261,13 +271,30 @@ class FlatThemeEditorPane
|
|||||||
return (window instanceof JFrame) ? ((JFrame)window).getTitle() : null;
|
return (window instanceof JFrame) ? ((JFrame)window).getTitle() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showFindReplaceBar() {
|
void showFindReplaceBar( boolean findEditorSelection ) {
|
||||||
if( findReplaceBar == null ) {
|
if( findReplaceBar == null ) {
|
||||||
findReplaceBar = new FlatFindReplaceBar( textArea );
|
findReplaceBar = new FlatFindReplaceBar( textArea );
|
||||||
collapsiblePanel.addBottomComponent( findReplaceBar );
|
findReplaceBar.addPropertyChangeListener( FlatFindReplaceBar.PROP_CLOSED, e -> {
|
||||||
|
findReplaceVisible = false;
|
||||||
|
textArea.requestFocusInWindow();
|
||||||
|
} );
|
||||||
|
editorPanel.add( findReplaceBar, BorderLayout.SOUTH );
|
||||||
|
editorPanel.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
collapsiblePanel.showBottomComponent( findReplaceBar );
|
findReplaceVisible = true;
|
||||||
|
if( findReplaceContext == null )
|
||||||
|
findReplaceContext = findReplaceBar.getSearchContext();
|
||||||
|
else
|
||||||
|
findReplaceBar.setSearchContext( findReplaceContext );
|
||||||
|
|
||||||
|
findReplaceBar.setVisible( true );
|
||||||
|
findReplaceBar.activate( findEditorSelection );
|
||||||
|
}
|
||||||
|
|
||||||
|
void hideFindReplaceBar() {
|
||||||
|
if( findReplaceBar != null )
|
||||||
|
findReplaceBar.setVisible( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void showPreview( boolean show ) {
|
void showPreview( boolean show ) {
|
||||||
|
|||||||
@@ -173,10 +173,30 @@ class FlatThemeFileEditor
|
|||||||
|
|
||||||
enableDisableActions();
|
enableDisableActions();
|
||||||
|
|
||||||
// hide some menu items on macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// hide menu items that are in macOS application menu
|
||||||
exitMenuItem.setVisible( false );
|
exitMenuItem.setVisible( false );
|
||||||
aboutMenuItem.setVisible( false );
|
aboutMenuItem.setVisible( false );
|
||||||
|
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
|
// expand window content into window title bar and make title bar transparent
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||||
|
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||||
|
|
||||||
|
// hide window title
|
||||||
|
if( SystemInfo.isJava_17_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||||
|
else
|
||||||
|
setTitle( null );
|
||||||
|
|
||||||
|
// add gap to left side of toolbar
|
||||||
|
controlPanel.add( Box.createHorizontalStrut( 70 ), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||||
|
if( !SystemInfo.isJava_11_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// integrate into macOS screen menu
|
// integrate into macOS screen menu
|
||||||
@@ -316,6 +336,7 @@ class FlatThemeFileEditor
|
|||||||
|
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
activateEditor();
|
activateEditor();
|
||||||
|
notifyEditorSelected();
|
||||||
} );
|
} );
|
||||||
saveState();
|
saveState();
|
||||||
enableDisableActions();
|
enableDisableActions();
|
||||||
@@ -365,7 +386,17 @@ class FlatThemeFileEditor
|
|||||||
String n2 = toSortName( f2.getName() );
|
String n2 = toSortName( f2.getName() );
|
||||||
return n1.compareToIgnoreCase( n2 );
|
return n1.compareToIgnoreCase( n2 );
|
||||||
} );
|
} );
|
||||||
return propertiesFiles;
|
|
||||||
|
File themesDir = new File( dir, "themes" );
|
||||||
|
if( !themesDir.isDirectory() )
|
||||||
|
return propertiesFiles;
|
||||||
|
|
||||||
|
// get files from "themes" sub-directory
|
||||||
|
File[] themesFiles = getPropertiesFiles( themesDir );
|
||||||
|
File[] allFiles = new File[propertiesFiles.length + themesFiles.length];
|
||||||
|
System.arraycopy( propertiesFiles, 0, allFiles, 0, propertiesFiles.length );
|
||||||
|
System.arraycopy( themesFiles, 0, allFiles, propertiesFiles.length, themesFiles.length );
|
||||||
|
return allFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toSortName( String name ) {
|
private String toSortName( String name ) {
|
||||||
@@ -418,11 +449,13 @@ class FlatThemeFileEditor
|
|||||||
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
||||||
String filename = (themeEditorPane != null) ? themeEditorPane.getFile().getName() : null;
|
String filename = (themeEditorPane != null) ? themeEditorPane.getFile().getName() : null;
|
||||||
putPrefsString( state, KEY_RECENT_FILE, filename );
|
putPrefsString( state, KEY_RECENT_FILE, filename );
|
||||||
|
|
||||||
|
notifyEditorSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableDisableActions() {
|
private void enableDisableActions() {
|
||||||
boolean dirOpen = (directoryField.getSelectedItem() != null);
|
boolean dirOpen = (directoryField.getSelectedItem() != null);
|
||||||
boolean editorOpen = (dirOpen &&tabbedPane.getSelectedIndex() >= 0);
|
boolean editorOpen = (dirOpen && tabbedPane.getSelectedIndex() >= 0);
|
||||||
|
|
||||||
// enable/disable buttons
|
// enable/disable buttons
|
||||||
newButton.setEnabled( dirOpen );
|
newButton.setEnabled( dirOpen );
|
||||||
@@ -450,12 +483,21 @@ class FlatThemeFileEditor
|
|||||||
FlatIntelliJLaf.NAME,
|
FlatIntelliJLaf.NAME,
|
||||||
FlatDarculaLaf.NAME,
|
FlatDarculaLaf.NAME,
|
||||||
} );
|
} );
|
||||||
|
JCheckBox genJavaClassCheckBox = new JCheckBox( "Generate Java class" );
|
||||||
|
genJavaClassCheckBox.setMnemonic( 'G' );
|
||||||
|
|
||||||
|
File themesDir = new File( dir, "themes" );
|
||||||
|
JCheckBox useThemesDirCheckBox = themesDir.isDirectory()
|
||||||
|
? new JCheckBox( "Create in 'themes' directory", true )
|
||||||
|
: null;
|
||||||
|
|
||||||
JOptionPane optionPane = new JOptionPane( new Object[] {
|
JOptionPane optionPane = new JOptionPane( new Object[] {
|
||||||
new JLabel( "Theme name:" ),
|
new JLabel( "Theme name:" ),
|
||||||
themeNameField,
|
themeNameField,
|
||||||
new JLabel( "Base Theme:" ),
|
new JLabel( "Base Theme:" ),
|
||||||
baseThemeField,
|
baseThemeField,
|
||||||
|
genJavaClassCheckBox,
|
||||||
|
useThemesDirCheckBox,
|
||||||
}, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION ) {
|
}, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION ) {
|
||||||
@Override
|
@Override
|
||||||
public void selectInitialValue() {
|
public void selectInitialValue() {
|
||||||
@@ -477,7 +519,8 @@ class FlatThemeFileEditor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = new File( dir, themeName + ".properties" );
|
File dir2 = (useThemesDirCheckBox != null && useThemesDirCheckBox.isSelected()) ? themesDir : dir;
|
||||||
|
File file = new File( dir2, themeName + ".properties" );
|
||||||
if( file.exists() ) {
|
if( file.exists() ) {
|
||||||
JOptionPane.showMessageDialog( this, "Theme '" + themeName + "' already exists.", title, JOptionPane.INFORMATION_MESSAGE );
|
JOptionPane.showMessageDialog( this, "Theme '" + themeName + "' already exists.", title, JOptionPane.INFORMATION_MESSAGE );
|
||||||
return;
|
return;
|
||||||
@@ -486,7 +529,8 @@ class FlatThemeFileEditor
|
|||||||
try {
|
try {
|
||||||
String baseTheme = (String) baseThemeField.getSelectedItem();
|
String baseTheme = (String) baseThemeField.getSelectedItem();
|
||||||
createTheme( file, baseTheme );
|
createTheme( file, baseTheme );
|
||||||
createThemeClass( dir, themeName, baseTheme );
|
if( genJavaClassCheckBox.isSelected() )
|
||||||
|
createThemeClass( dir2, themeName, baseTheme );
|
||||||
openFile( file, true );
|
openFile( file, true );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@@ -646,6 +690,12 @@ class FlatThemeFileEditor
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyEditorSelected() {
|
||||||
|
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
||||||
|
if( themeEditorPane != null )
|
||||||
|
themeEditorPane.selected();
|
||||||
|
}
|
||||||
|
|
||||||
private void activateEditor() {
|
private void activateEditor() {
|
||||||
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
||||||
if( themeEditorPane != null )
|
if( themeEditorPane != null )
|
||||||
@@ -668,7 +718,7 @@ class FlatThemeFileEditor
|
|||||||
private void find() {
|
private void find() {
|
||||||
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
||||||
if( themeEditorPane != null )
|
if( themeEditorPane != null )
|
||||||
themeEditorPane.showFindReplaceBar();
|
themeEditorPane.showFindReplaceBar( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertColor() {
|
private void insertColor() {
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public class FlatThemeTokenMaker
|
|||||||
tokenMap.put( "tint", TOKEN_FUNCTION );
|
tokenMap.put( "tint", TOKEN_FUNCTION );
|
||||||
tokenMap.put( "shade", TOKEN_FUNCTION );
|
tokenMap.put( "shade", TOKEN_FUNCTION );
|
||||||
tokenMap.put( "contrast", TOKEN_FUNCTION );
|
tokenMap.put( "contrast", TOKEN_FUNCTION );
|
||||||
|
tokenMap.put( "over", TOKEN_FUNCTION );
|
||||||
|
|
||||||
// function options
|
// function options
|
||||||
tokenMap.put( "relative", Token.RESERVED_WORD );
|
tokenMap.put( "relative", Token.RESERVED_WORD );
|
||||||
@@ -201,6 +202,11 @@ public class FlatThemeTokenMaker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIdentifierChar( int languageIndex, char ch ) {
|
||||||
|
return super.isIdentifierChar( languageIndex, ch ) || ch == '@';
|
||||||
|
}
|
||||||
|
|
||||||
/*debug
|
/*debug
|
||||||
private java.util.HashMap<Integer, String> tokenTypeStrMap;
|
private java.util.HashMap<Integer, String> tokenTypeStrMap;
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,13 @@ Button.default.endBorderColor
|
|||||||
Button.default.focusColor
|
Button.default.focusColor
|
||||||
Button.default.focusedBackground
|
Button.default.focusedBackground
|
||||||
Button.default.focusedBorderColor
|
Button.default.focusedBorderColor
|
||||||
|
Button.default.focusedForeground
|
||||||
Button.default.foreground
|
Button.default.foreground
|
||||||
Button.default.hoverBackground
|
Button.default.hoverBackground
|
||||||
Button.default.hoverBorderColor
|
Button.default.hoverBorderColor
|
||||||
|
Button.default.hoverForeground
|
||||||
Button.default.pressedBackground
|
Button.default.pressedBackground
|
||||||
|
Button.default.pressedForeground
|
||||||
Button.default.startBackground
|
Button.default.startBackground
|
||||||
Button.default.startBorderColor
|
Button.default.startBorderColor
|
||||||
Button.defaultButtonFollowsFocus
|
Button.defaultButtonFollowsFocus
|
||||||
@@ -34,23 +37,27 @@ Button.disabledBackground
|
|||||||
Button.disabledBorderColor
|
Button.disabledBorderColor
|
||||||
Button.disabledForeground
|
Button.disabledForeground
|
||||||
Button.disabledSelectedBackground
|
Button.disabledSelectedBackground
|
||||||
|
Button.disabledSelectedForeground
|
||||||
Button.disabledText
|
Button.disabledText
|
||||||
Button.endBackground
|
Button.endBackground
|
||||||
Button.endBorderColor
|
Button.endBorderColor
|
||||||
Button.focusInputMap
|
Button.focusInputMap
|
||||||
Button.focusedBackground
|
Button.focusedBackground
|
||||||
Button.focusedBorderColor
|
Button.focusedBorderColor
|
||||||
|
Button.focusedForeground
|
||||||
Button.font
|
Button.font
|
||||||
Button.foreground
|
Button.foreground
|
||||||
Button.highlight
|
Button.highlight
|
||||||
Button.hoverBackground
|
Button.hoverBackground
|
||||||
Button.hoverBorderColor
|
Button.hoverBorderColor
|
||||||
|
Button.hoverForeground
|
||||||
Button.iconTextGap
|
Button.iconTextGap
|
||||||
Button.innerFocusWidth
|
Button.innerFocusWidth
|
||||||
Button.light
|
Button.light
|
||||||
Button.margin
|
Button.margin
|
||||||
Button.minimumWidth
|
Button.minimumWidth
|
||||||
Button.pressedBackground
|
Button.pressedBackground
|
||||||
|
Button.pressedForeground
|
||||||
Button.rollover
|
Button.rollover
|
||||||
Button.selectedBackground
|
Button.selectedBackground
|
||||||
Button.selectedForeground
|
Button.selectedForeground
|
||||||
@@ -59,10 +66,15 @@ Button.startBackground
|
|||||||
Button.startBorderColor
|
Button.startBorderColor
|
||||||
Button.textIconGap
|
Button.textIconGap
|
||||||
Button.textShiftOffset
|
Button.textShiftOffset
|
||||||
|
Button.toolbar.disabledSelectedBackground
|
||||||
|
Button.toolbar.disabledSelectedForeground
|
||||||
Button.toolbar.hoverBackground
|
Button.toolbar.hoverBackground
|
||||||
|
Button.toolbar.hoverForeground
|
||||||
Button.toolbar.margin
|
Button.toolbar.margin
|
||||||
Button.toolbar.pressedBackground
|
Button.toolbar.pressedBackground
|
||||||
|
Button.toolbar.pressedForeground
|
||||||
Button.toolbar.selectedBackground
|
Button.toolbar.selectedBackground
|
||||||
|
Button.toolbar.selectedForeground
|
||||||
Button.toolbar.spacingInsets
|
Button.toolbar.spacingInsets
|
||||||
ButtonUI
|
ButtonUI
|
||||||
Caret.width
|
Caret.width
|
||||||
@@ -185,6 +197,7 @@ ComboBox.buttonShadow
|
|||||||
ComboBox.buttonStyle
|
ComboBox.buttonStyle
|
||||||
ComboBox.disabledBackground
|
ComboBox.disabledBackground
|
||||||
ComboBox.disabledForeground
|
ComboBox.disabledForeground
|
||||||
|
ComboBox.editableBackground
|
||||||
ComboBox.editorColumns
|
ComboBox.editorColumns
|
||||||
ComboBox.focusedBackground
|
ComboBox.focusedBackground
|
||||||
ComboBox.font
|
ComboBox.font
|
||||||
@@ -252,6 +265,8 @@ FileChooser.homeFolderIcon
|
|||||||
FileChooser.listViewIcon
|
FileChooser.listViewIcon
|
||||||
FileChooser.newFolderIcon
|
FileChooser.newFolderIcon
|
||||||
FileChooser.readOnly
|
FileChooser.readOnly
|
||||||
|
FileChooser.shortcuts.buttonSize
|
||||||
|
FileChooser.shortcuts.iconSize
|
||||||
FileChooser.upFolderIcon
|
FileChooser.upFolderIcon
|
||||||
FileChooser.useSystemExtensionHiding
|
FileChooser.useSystemExtensionHiding
|
||||||
FileChooser.usesSingleFilePane
|
FileChooser.usesSingleFilePane
|
||||||
@@ -714,6 +729,7 @@ Separator.stripeIndent
|
|||||||
Separator.stripeWidth
|
Separator.stripeWidth
|
||||||
SeparatorUI
|
SeparatorUI
|
||||||
Slider.background
|
Slider.background
|
||||||
|
Slider.disabledThumbBorderColor
|
||||||
Slider.disabledThumbColor
|
Slider.disabledThumbColor
|
||||||
Slider.disabledTrackColor
|
Slider.disabledTrackColor
|
||||||
Slider.focus
|
Slider.focus
|
||||||
@@ -964,6 +980,7 @@ TitlePane.background
|
|||||||
TitlePane.borderColor
|
TitlePane.borderColor
|
||||||
TitlePane.buttonHoverBackground
|
TitlePane.buttonHoverBackground
|
||||||
TitlePane.buttonMaximizedHeight
|
TitlePane.buttonMaximizedHeight
|
||||||
|
TitlePane.buttonMinimumWidth
|
||||||
TitlePane.buttonPressedBackground
|
TitlePane.buttonPressedBackground
|
||||||
TitlePane.buttonSize
|
TitlePane.buttonSize
|
||||||
TitlePane.centerTitle
|
TitlePane.centerTitle
|
||||||
@@ -983,11 +1000,15 @@ TitlePane.inactiveBackground
|
|||||||
TitlePane.inactiveForeground
|
TitlePane.inactiveForeground
|
||||||
TitlePane.maximizeIcon
|
TitlePane.maximizeIcon
|
||||||
TitlePane.menuBarEmbedded
|
TitlePane.menuBarEmbedded
|
||||||
|
TitlePane.menuBarResizeHeight
|
||||||
TitlePane.menuBarTitleGap
|
TitlePane.menuBarTitleGap
|
||||||
|
TitlePane.menuBarTitleMinimumGap
|
||||||
TitlePane.noIconLeftGap
|
TitlePane.noIconLeftGap
|
||||||
TitlePane.restoreIcon
|
TitlePane.restoreIcon
|
||||||
TitlePane.showIcon
|
TitlePane.showIcon
|
||||||
|
TitlePane.showIconBesideTitle
|
||||||
TitlePane.titleMargins
|
TitlePane.titleMargins
|
||||||
|
TitlePane.titleMinimumWidth
|
||||||
TitlePane.unifiedBackground
|
TitlePane.unifiedBackground
|
||||||
TitlePane.useWindowDecorations
|
TitlePane.useWindowDecorations
|
||||||
TitledBorder.border
|
TitledBorder.border
|
||||||
@@ -999,32 +1020,44 @@ ToggleButton.border
|
|||||||
ToggleButton.darkShadow
|
ToggleButton.darkShadow
|
||||||
ToggleButton.disabledBackground
|
ToggleButton.disabledBackground
|
||||||
ToggleButton.disabledSelectedBackground
|
ToggleButton.disabledSelectedBackground
|
||||||
|
ToggleButton.disabledSelectedForeground
|
||||||
ToggleButton.disabledText
|
ToggleButton.disabledText
|
||||||
ToggleButton.focusInputMap
|
ToggleButton.focusInputMap
|
||||||
ToggleButton.focusedBackground
|
ToggleButton.focusedBackground
|
||||||
|
ToggleButton.focusedForeground
|
||||||
ToggleButton.font
|
ToggleButton.font
|
||||||
ToggleButton.foreground
|
ToggleButton.foreground
|
||||||
ToggleButton.highlight
|
ToggleButton.highlight
|
||||||
ToggleButton.hoverBackground
|
ToggleButton.hoverBackground
|
||||||
|
ToggleButton.hoverForeground
|
||||||
ToggleButton.iconTextGap
|
ToggleButton.iconTextGap
|
||||||
ToggleButton.light
|
ToggleButton.light
|
||||||
ToggleButton.margin
|
ToggleButton.margin
|
||||||
ToggleButton.pressedBackground
|
ToggleButton.pressedBackground
|
||||||
|
ToggleButton.pressedForeground
|
||||||
ToggleButton.rollover
|
ToggleButton.rollover
|
||||||
ToggleButton.selectedBackground
|
ToggleButton.selectedBackground
|
||||||
ToggleButton.selectedForeground
|
ToggleButton.selectedForeground
|
||||||
ToggleButton.shadow
|
ToggleButton.shadow
|
||||||
ToggleButton.tab.disabledUnderlineColor
|
ToggleButton.tab.disabledUnderlineColor
|
||||||
ToggleButton.tab.focusBackground
|
ToggleButton.tab.focusBackground
|
||||||
|
ToggleButton.tab.focusForeground
|
||||||
ToggleButton.tab.hoverBackground
|
ToggleButton.tab.hoverBackground
|
||||||
|
ToggleButton.tab.hoverForeground
|
||||||
ToggleButton.tab.selectedBackground
|
ToggleButton.tab.selectedBackground
|
||||||
|
ToggleButton.tab.selectedForeground
|
||||||
ToggleButton.tab.underlineColor
|
ToggleButton.tab.underlineColor
|
||||||
ToggleButton.tab.underlineHeight
|
ToggleButton.tab.underlineHeight
|
||||||
ToggleButton.textIconGap
|
ToggleButton.textIconGap
|
||||||
ToggleButton.textShiftOffset
|
ToggleButton.textShiftOffset
|
||||||
|
ToggleButton.toolbar.disabledSelectedBackground
|
||||||
|
ToggleButton.toolbar.disabledSelectedForeground
|
||||||
ToggleButton.toolbar.hoverBackground
|
ToggleButton.toolbar.hoverBackground
|
||||||
|
ToggleButton.toolbar.hoverForeground
|
||||||
ToggleButton.toolbar.pressedBackground
|
ToggleButton.toolbar.pressedBackground
|
||||||
|
ToggleButton.toolbar.pressedForeground
|
||||||
ToggleButton.toolbar.selectedBackground
|
ToggleButton.toolbar.selectedBackground
|
||||||
|
ToggleButton.toolbar.selectedForeground
|
||||||
ToggleButtonUI
|
ToggleButtonUI
|
||||||
ToolBar.ancestorInputMap
|
ToolBar.ancestorInputMap
|
||||||
ToolBar.arrowKeysOnlyNavigation
|
ToolBar.arrowKeysOnlyNavigation
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ Prop.6.selectionForeground = contrast($Prop.6.selectionBackground,#000,#fff)
|
|||||||
Prop.7.selectionBackground = #FF9500
|
Prop.7.selectionBackground = #FF9500
|
||||||
Prop.7.selectionForeground = contrast($Prop.7.selectionBackground,#000,#fff)
|
Prop.7.selectionForeground = contrast($Prop.7.selectionBackground,#000,#fff)
|
||||||
|
|
||||||
|
Prop.colorFunc60 = over(#fff8,#f00)
|
||||||
|
Prop.colorFunc61 = over(#fff8,#0f0)
|
||||||
|
Prop.colorFunc62 = over(#f000,#0f0)
|
||||||
|
Prop.colorFunc63 = over(#f00,#0f0)
|
||||||
|
Prop.colorFunc64 = over(#f008,null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@varStyle1 = #f0f
|
@varStyle1 = #f0f
|
||||||
|
|||||||
Reference in New Issue
Block a user