Compare commits

...

42 Commits
1.3 ... 1.5

Author SHA1 Message Date
Karl Tauber
6fcee03752 release 1.5 2021-08-04 15:13:58 +02:00
Karl Tauber
5782ceeb5d README.md: added descriptions to addons 2021-08-04 14:27:57 +02:00
Karl Tauber
f752db5892 FileChooser: fixed missing (localized) texts when FlatLaf is loaded in special classloader
(e.g. plugin system in Apache NetBeans)

https://issues.apache.org/jira/browse/NETBEANS-5865
2021-08-04 11:15:18 +02:00
Karl Tauber
bce58bc97b SwingX: added search and clear icons to JXSearchField (issue #359) 2021-08-03 17:52:49 +02:00
Karl Tauber
d373687bc4 Testing: added FlatSingleComponentTest to easier test/debug single components 2021-08-03 15:16:04 +02:00
Karl Tauber
e5e510c825 Demo: fixed inconsistent behavior when first changing font size and then font family, which did loose user scale factor on Windows in Java 9+ (issue #352) 2021-08-02 19:16:38 +02:00
Karl Tauber
29064ec72f Button and TextComponent: do not apply minimum width/height if margins are set (issue #364) 2021-08-02 18:36:10 +02:00
Karl Tauber
953eee1dc8 TableHeader: made getRolloverColumn() public to allow usage in custom renderers (issue #336) 2021-08-02 18:01:08 +02:00
Karl Tauber
75f76f4875 ComboBox and Spinner: limit arrow button width if component has large preferred height (issue #361) 2021-08-02 15:27:25 +02:00
Karl Tauber
ecfbe68c33 Native window decorations: updated DLLs (issues #357 and #339)
built by GitHub Actions:
https://github.com/JFormDesigner/FlatLaf/actions/runs/1085691279
2021-07-31 21:22:09 +02:00
Karl Tauber
7f02eb9cf0 Native window decorations: when window is initially shown, fill background with window background color (instead of white), which avoids flickering in dark themes (issue #339) 2021-07-31 21:05:01 +02:00
Karl Tauber
4ab90065dc Native window decorations: when resizing a window to the right or to the bottom, then first fill the new space with the window background color (instead of black) before the layout is updated (issue #339) 2021-07-31 18:02:10 +02:00
Karl Tauber
d3e39a1359 Native window decorations: fixed occasional application crash on Windows 10 in flatlaf-windows.dll (issue #357) 2021-07-30 23:06:09 +02:00
Karl Tauber
60e5861de4 InternalFrame: limit internal frame bounds to parent bounds on resize; honor maximum size of internal frame (issue #362) 2021-07-29 16:44:50 +02:00
Karl Tauber
ca7f5045ae Popup: fixed incorrectly placed drop shadow for medium-weight popups in maximized windows (issue #358) 2021-07-29 15:39:16 +02:00
Karl Tauber
b0997fb5d2 release 1.4 2021-07-13 11:02:10 +02:00
Karl Tauber
37dab9fb22 TabbedPane: fixed rendering of tab separators in scroll layout if scaled on HiDPI screens 2021-07-12 11:48:34 +02:00
Karl Tauber
fb44c8fbe4 TextField: fixed location of placeholder text if paddings are used (e.g. in ComboBox) (for commit a9dcf09d13) 2021-07-10 21:05:26 +02:00
Karl Tauber
94375b7d36 Extras: added support for client property JTextField.padding (for commit a9dcf09d13) 2021-07-10 20:59:34 +02:00
Karl Tauber
8b585deb78 ToolBar: support focusable buttons in toolbar (issue #346)
fixed focusable state when switching to/from other Laf
2021-07-10 13:32:30 +02:00
Karl Tauber
4d8b544aed UIDefaultsKeysDump: also use FlatTestLaf, which adds missing keys to FlatLafUIKeys.txt 2021-07-10 13:28:02 +02:00
Karl Tauber
548d651d29 PasswordField: move the lower bar of the caps lock icon up a half pixel 2021-07-10 11:03:13 +02:00
Karl Tauber
0b342acec9 PasswordField: paint caps lock icon on left side in right-to-left component orientation 2021-07-09 15:14:29 +02:00
Karl Tauber
cc6d3c1b1a PasswordField: Caps lock icon no longer painted over long text (issue #172) 2021-07-09 15:03:16 +02:00
Karl Tauber
74a748d92e use LoggingFacade instead of printStackTrace() in flatlaf-extras and flatlaf-demo 2021-07-09 13:22:37 +02:00
Karl Tauber
1de81d0af5 ComboBox: fixed StackOverflowError when using single renderer instance in multiple comboboxes (regression since commit 4507ce359d) 2021-07-09 11:39:35 +02:00
Karl Tauber
ff9ef21f67 OptionPane: align wrapped lines to the right if component orientation is right-to-left (issue #350) 2021-07-08 17:53:44 +02:00
Karl Tauber
266a546478 Window decorations: window title bar width is no longer considered when calculating preferred/minimum width of window (issue #351) 2021-07-08 16:54:34 +02:00
Karl Tauber
87407ca832 Table and PopupFactory: use StackWalker in Java 9+ for better performance (issue #334) 2021-07-08 14:02:50 +02:00
Karl Tauber
90282d4436 UI defaults dumps updated for issue #335 2021-07-08 00:02:33 +02:00
Karl Tauber
abbe6d6c1f ToolBar: paint focus indicator for focused button in toolbar (issue #346) 2021-07-07 18:17:45 +02:00
Karl Tauber
a28f701e6f OptionPane: do not make child components, which are derived from JPanel, non-opaque (issue #349) 2021-07-07 10:57:54 +02:00
Karl Tauber
4cdc995a7f ComboBox: simplified code in configureEditor() 2021-07-05 23:14:05 +02:00
Karl Tauber
c708205593 TestFlatComponentSizes: shortened combobox text because unit tests on GitHub Actions use font size 15 2021-07-05 20:06:07 +02:00
Karl Tauber
a22c6c8013 ComboBox (not editable):
- increased size of internal renderer pane to the component border so that it can paint within the whole component
- increase combo box size if a custom renderer uses a border with insets that are larger than the default combo box padding (`2,6,2,6`)
2021-07-05 18:41:17 +02:00
Karl Tauber
b576f473e5 fixed component heights at 1.25x, 1.75x and 2.25x scaling factors (Java 8 only) so that Button, ComboBox, Spinner and TextField components (including subclasses) have same heights 2021-07-05 15:15:37 +02:00
Karl Tauber
0b127caa83 ComboBox: fixed minimum width if focusWidth > 0 (to be equal with button minimum width)
added some unit tests to compare component sizes
2021-07-05 11:07:32 +02:00
Karl Tauber
4507ce359d ComboBox: reworked uninstall of CellPaddingBorder, which is temporary used for cell renderers, to make it easier to understand and reliable
(tested using FlatCustomBordersTest, FlatNetBeansTest, etc)
2021-07-03 10:43:55 +02:00
Karl Tauber
3e14f28dc2 ComboBox (editable) and Spinner: increased size of internal text field to the component border so that it behaves like plain text field (issue #330) 2021-07-02 18:43:37 +02:00
Karl Tauber
a9dcf09d13 TextField: support adding extra padding
(for #172, #173 and #330)
2021-07-02 15:38:45 +02:00
Karl Tauber
c8998c2bcf PasswordField: UI delegate FlatPasswordFieldUI now extends FlatTextFieldUI (instead of BasicPasswordFieldUI) to avoid duplicate code and for easier extensibility (e.g. for #173 and #341) 2021-07-02 14:03:54 +02:00
Karl Tauber
10bf1295bc CHANGELOG.md: fixed UI key ComboBox.popupFocusedBackground to ComboBox.popupBackground 2021-07-02 10:52:30 +02:00
88 changed files with 3368 additions and 378 deletions

View File

@@ -1,6 +1,80 @@
FlatLaf Change Log
==================
## 1.5
#### New features and improvements
- SwingX: Added search and clear icons to `JXSearchField`. (issue #359)
#### Fixed bugs
- Button and TextComponent: Do not apply minimum width/height if margins are
set. (issue #364)
- ComboBox and Spinner: Limit arrow button width if component has large
preferred height. (issue #361)
- FileChooser: Fixed missing (localized) texts when FlatLaf is loaded in special
classloader (e.g. plugin system in Apache NetBeans).
- InternalFrame: Limit internal frame bounds to parent bounds on resize. Also
honor maximum size of internal frame. (issue #362)
- Popup: Fixed incorrectly placed drop shadow for medium-weight popups in
maximized windows. (issue #358)
- Native window decorations (Windows 10 only):
- Fixed occasional application crash in `flatlaf-windows.dll`. (issue #357)
- When window is initially shown, fill background with window background color
(instead of white), which avoids flickering in dark themes. (issue 339)
- When resizing a window at the right/bottom edge, then first fill the new
space with the window background color (instead of black) before the layout
is updated.
- When resizing a window at the left/top edge, then first fill the new space
with the window background color (instead of garbage) before the layout is
updated.
## 1.4
#### New features and improvements
- TextField, FormattedTextField and PasswordField: Support adding extra padding.
(set client property `JTextField.padding` to `Insets`).
- PasswordField: UI delegate `FlatPasswordFieldUI` now extends `FlatTextFieldUI`
(instead of `BasicPasswordFieldUI`) to avoid duplicate code and for easier
extensibility.
- Table and PopupFactory: Use `StackWalker` in Java 9+ for better performance.
(issue #334)
- ToolBar: Paint focus indicator for focused button in toolbar. (issue #346)
- ToolBar: Support focusable buttons in toolbar (set UI value
`ToolBar.focusableButtons` to `true`). (issue #346)
#### Fixed bugs
- ComboBox (editable) and Spinner: Increased size of internal text field to the
component border so that it behaves like plain text field (mouse click to left
of text now positions caret to first character instead of opening ComboBox
popup; mouse cursor is now of type "text" within the whole component, except
for arrow buttons). (issue #330)
- ComboBox (not editable): Increased size of internal renderer pane to the
component border so that it can paint within the whole component. Also
increase combo box size if a custom renderer uses a border with insets that
are larger than the default combo box padding (`2,6,2,6`).
- Fixed component heights at `1.25x`, `1.75x` and `2.25x` scaling factors (Java
8 only) so that Button, ComboBox, Spinner and TextField components (including
subclasses) have same heights. This increases heights of Button and TextField
components by:
- `2px` at `1.75x` in **Light** and **Dark** themes
- `2px` at `1.25x` and `2.25x` in **IntelliJ** and **Darcula** themes
- OptionPane: Do not make child components, which are derived from `JPanel`,
non-opaque. (issue #349)
- OptionPane: Align wrapped lines to the right if component orientation is
right-to-left. (issue #350)
- PasswordField: Caps lock icon no longer painted over long text. (issue #172)
- PasswordField: Paint caps lock icon on left side in right-to-left component
orientation.
- Window decorations: Window title bar width is no longer considered when
calculating preferred/minimum width of window. (issue #351)
## 1.3
#### New features and improvements
@@ -10,7 +84,7 @@ FlatLaf Change Log
`PasswordField.focusedBackground`, `FormattedTextField.focusedBackground`,
`TextArea.focusedBackground`, `TextPane.focusedBackground`,
`EditorPane.focusedBackground`, `ComboBox.focusedBackground`,
`ComboBox.buttonFocusedBackground`, `ComboBox.popupFocusedBackground` and
`ComboBox.buttonFocusedBackground`, `ComboBox.popupBackground` and
`Spinner.focusedBackground`). (issue #335)
#### Fixed bugs

View File

@@ -67,10 +67,13 @@ docs).
Addons
------
- [IntelliJ Themes Pack](flatlaf-intellij-themes)
- [Extras](flatlaf-extras)
- [SwingX](flatlaf-swingx)
- [JIDE Common Layer](flatlaf-jide-oss)
- [IntelliJ Themes Pack](flatlaf-intellij-themes) - bundles many popular
open-source 3rd party themes
- [Extras](flatlaf-extras) - SVG icon, tri-state check box, UI inspectors, and
more
- [SwingX](flatlaf-swingx) - support for SwingX components
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
components
Getting started

View File

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

View File

@@ -21,6 +21,12 @@ plugins {
`flatlaf-publish`
}
dependencies {
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" )
testImplementation( "org.junit.jupiter:junit-jupiter-params" )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
}
java {
withSourcesJar()
withJavadocJar()
@@ -52,6 +58,11 @@ tasks {
named<Jar>( "javadocJar" ) {
archiveBaseName.set( "flatlaf" )
}
test {
useJUnitPlatform()
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
flatlafPublish {

View File

@@ -733,6 +733,18 @@ public interface FlatClientProperties
*/
String PLACEHOLDER_TEXT = "JTextField.placeholderText";
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link java.awt.Insets}
*
* @since 1.4
*/
String TEXT_FIELD_PADDING = "JTextField.padding";
//---- JToggleButton ------------------------------------------------------
/**

View File

@@ -32,10 +32,13 @@ import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -66,6 +69,7 @@ import com.formdev.flatlaf.ui.FlatRootPaneUI;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -356,8 +360,8 @@ public abstract class FlatLaf
// (can be queried without using FlatLaf API)
defaults.put( "laf.dark", isDark() );
// add resource bundle for localized texts
defaults.addResourceBundle( "com.formdev.flatlaf.resources.Bundle" );
// init resource bundle for localized texts
initResourceBundle( defaults, "com.formdev.flatlaf.resources.Bundle" );
// initialize some defaults (for overriding) that are used in UI delegates,
// but are not set in BasicLookAndFeel
@@ -453,6 +457,45 @@ public abstract class FlatLaf
return null;
}
private void initResourceBundle( UIDefaults defaults, String bundleName ) {
// add resource bundle for localized texts
defaults.addResourceBundle( bundleName );
// Check whether Swing can not load the FlatLaf resource bundle,
// which can happen in applications that use some plugin system
// and load FlatLaf in a plugin that uses its own classloader.
// (e.g. Apache NetBeans)
if( defaults.get( "FileChooser.fileNameHeaderText" ) != null )
return;
// load FlatLaf resource bundle and add content to defaults
try {
ResourceBundle bundle = ResourceBundle.getBundle( bundleName, defaults.getDefaultLocale() );
Enumeration<String> keys = bundle.getKeys();
while( keys.hasMoreElements() ) {
String key = keys.nextElement();
String value = bundle.getString( key );
String baseKey = StringUtils.removeTrailing( key, ".textAndMnemonic" );
if( baseKey != key ) {
String text = value.replace( "&", "" );
String mnemonic = null;
int index = value.indexOf( '&' );
if( index >= 0 )
mnemonic = Integer.toString( Character.toUpperCase( value.charAt( index + 1 ) ) );
defaults.put( baseKey + "Text", text );
if( mnemonic != null )
defaults.put( baseKey + "Mnemonic", mnemonic );
} else
defaults.put( key, value );
}
} catch( MissingResourceException ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
private void initFonts( UIDefaults defaults ) {
FontUIResource uiFont = null;

View File

@@ -309,6 +309,9 @@ class LinuxFontPolicy
* - running on JetBrains Runtime 11 or later and scaling is enabled in system Settings
*/
private static boolean isSystemScaling() {
if( GraphicsEnvironment.isHeadless() )
return true;
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
return UIScale.getSystemScaleFactor( gc ) > 1;

View File

@@ -44,7 +44,7 @@ public class FlatCapsLockIcon
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
<rect width="6" height="2" x="5" y="12" fill="#FFF"/>
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
</g>
</svg>
@@ -52,7 +52,7 @@ public class FlatCapsLockIcon
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
path.append( new Rectangle2D.Float( 5, 12, 6, 2 ), false );
path.append( new Rectangle2D.Float( 5, 11.5f, 6, 2 ), false );
path.append( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 11,8, 11,10, 5,10, 5,8 ), false );
g.fill( path );
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.icons;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "clear" icon for search fields.
*
* @uiDefault SearchField.clearIconColor Color
* @uiDefault SearchField.clearIconHoverColor Color
* @uiDefault SearchField.clearIconPressedColor Color
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatClearIcon
extends FlatAbstractIcon
{
protected Color clearIconColor = UIManager.getColor( "SearchField.clearIconColor" );
protected Color clearIconHoverColor = UIManager.getColor( "SearchField.clearIconHoverColor" );
protected Color clearIconPressedColor = UIManager.getColor( "SearchField.clearIconPressedColor" );
public FlatClearIcon() {
super( 16, 16, null );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
if( c instanceof AbstractButton ) {
ButtonModel model = ((AbstractButton)c).getModel();
if( model.isPressed() || model.isRollover() ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" d="M8,1.75 C11.4517797,1.75 14.25,4.54822031 14.25,8 C14.25,11.4517797 11.4517797,14.25 8,14.25 C4.54822031,14.25 1.75,11.4517797 1.75,8 C1.75,4.54822031 4.54822031,1.75 8,1.75 Z M10.5,4.5 L8,7 L5.5,4.5 L4.5,5.5 L7,8 L4.5,10.5 L5.5,11.5 L8,9 L10.5,11.5 L11.5,10.5 L9,8 L11.5,5.5 L10.5,4.5 Z"/>
</svg>
*/
// paint filled circle with cross
g.setColor( model.isPressed() ? clearIconPressedColor : clearIconHoverColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Ellipse2D.Float( 1.75f, 1.75f, 12.5f, 12.5f ), false );
path.append( FlatUIUtils.createPath( 4.5,5.5, 5.5,4.5, 8,7, 10.5,4.5, 11.5,5.5, 9,8, 11.5,10.5, 10.5,11.5, 8,9, 5.5,11.5, 4.5,10.5, 7,8 ), false );
g.fill( path );
return;
}
}
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="none" stroke="#7F8B91" stroke-linecap="square" stroke-opacity=".5" d="M5,5 L11,11 M5,11 L11,5"/>
</svg>
*/
// paint cross
g.setColor( clearIconColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Line2D.Float( 5,5, 11,11 ), false );
path.append( new Line2D.Float( 5,11, 11,5 ), false );
g.draw( path );
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.icons;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "search" icon for search fields.
*
* @uiDefault SearchField.searchIconColor Color
* @uiDefault SearchField.searchIconHoverColor Color
* @uiDefault SearchField.searchIconPressedColor Color
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatSearchIcon
extends FlatAbstractIcon
{
protected Color searchIconColor = UIManager.getColor( "SearchField.searchIconColor" );
protected Color searchIconHoverColor = UIManager.getColor( "SearchField.searchIconHoverColor" );
protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
public FlatSearchIcon() {
super( 16, 16, null );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="10.813 9.75 14 12.938 12.938 14 9.75 10.813"/>
<path fill="#7F8B91" d="M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z M7,3 C4.790861,3 3,4.790861 3,7 C3,9.209139 4.790861,11 7,11 C9.209139,11 11,9.209139 11,7 C11,4.790861 9.209139,3 7,3 Z"/>
</g>
</svg>
*/
g.setColor( FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
null, searchIconHoverColor, searchIconPressedColor ) );
// paint magnifier
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
g.fill( area );
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.icons;
import java.awt.Component;
import java.awt.Graphics2D;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "search with history" icon for search fields.
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatSearchWithHistoryIcon
extends FlatSearchIcon
{
public FlatSearchWithHistoryIcon() {
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="8.813 9.75 12 12.938 10.938 14 7.75 10.813"/>
<path fill="#7F8B91" d="M5,2 C7.76142375,2 10,4.23857625 10,7 C10,9.76142375 7.76142375,12 5,12 C2.23857625,12 0,9.76142375 0,7 C0,4.23857625 2.23857625,2 5,2 Z M5,3 C2.790861,3 1,4.790861 1,7 C1,9.209139 2.790861,11 5,11 C7.209139,11 9,9.209139 9,7 C9,4.790861 7.209139,3 5,3 Z"/>
<polygon fill="#7F8B91" points="11 7 16 7 13.5 10"/>
</g>
</svg>
*/
// paint magnifier
g.translate( -2, 0 );
super.paintIcon( c, g );
g.translate( 2, 0 );
// paint history arrow
g.fill( FlatUIUtils.createPath( 11,7, 16,7, 13.5,10 ) );
}
}

View File

@@ -176,13 +176,14 @@ public class FlatBorder
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
float focusWidth = scale( (float) getFocusWidth( c ) );
float ow = focusWidth + scale( (float) getLineWidth( c ) );
int ow = Math.round( focusWidth + scale( (float) getLineWidth( c ) ) );
insets = super.getBorderInsets( c, insets );
insets.top = Math.round( scale( (float) insets.top ) + ow );
insets.left = Math.round( scale( (float) insets.left ) + ow );
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow );
insets.right = Math.round( scale( (float) insets.right ) + ow );
insets.top = scale( insets.top ) + ow;
insets.left = scale( insets.left ) + ow;
insets.bottom = scale( insets.bottom ) + ow;
insets.right = scale( insets.right ) + ow;
if( isCellEditor( c ) ) {
// remove top and bottom insets if used as cell editor

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import javax.swing.AbstractButton;
@@ -42,11 +43,13 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Button.default.hoverBorderColor Color optional
* @uiDefault Button.default.focusedBorderColor Color
* @uiDefault Button.default.focusColor Color
* @uiDefault Button.toolbar.focusColor Color optional; defaults to Component.focusColor
* @uiDefault Button.borderWidth int
* @uiDefault Button.default.borderWidth int
* @uiDefault Button.innerFocusWidth int or float optional; defaults to Component.innerFocusWidth
* @uiDefault Button.toolbar.margin Insets
* @uiDefault Button.toolbar.spacingInsets Insets
* @uiDefault Button.toolbar.focusWidth int or float optional; default is 1
* @uiDefault Button.arc int
*
* @author Karl Tauber
@@ -64,11 +67,15 @@ public class FlatButtonBorder
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
/** @since 1.4 */
protected final Color toolbarFocusColor = UIManager.getColor( "Button.toolbar.focusColor" );
protected final int borderWidth = UIManager.getInt( "Button.borderWidth" );
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
protected final float buttonInnerFocusWidth = FlatUIUtils.getUIFloat( "Button.innerFocusWidth", innerFocusWidth );
protected final Insets toolbarMargin = UIManager.getInsets( "Button.toolbar.margin" );
protected final Insets toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" );
/** @since 1.4 */
protected final float toolbarFocusWidth = FlatUIUtils.getUIFloat( "Button.toolbar.focusWidth", 1.5f );
protected final int arc = UIManager.getInt( "Button.arc" );
@Override
@@ -79,11 +86,41 @@ public class FlatButtonBorder
!FlatButtonUI.isHelpButton( c ) &&
!FlatToggleButtonUI.isTabButton( c ) )
super.paintBorder( c, g, x, y, width, height );
else if( FlatButtonUI.isToolBarButton( c ) && isFocused( c ) )
paintToolBarFocus( c, g, x, y, width, height );
}
/**
* @since 1.4
*/
protected void paintToolBarFocus( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
float focusWidth = UIScale.scale( toolbarFocusWidth );
float arc = UIScale.scale( (float) getArc( c ) );
Color outlineColor = getOutlineColor( c );
Insets spacing = UIScale.scale( toolbarSpacingInsets );
x += spacing.left;
y += spacing.top;
width -= spacing.left + spacing.right;
height -= spacing.top + spacing.bottom;
g2.setColor( (outlineColor != null) ? outlineColor : getFocusColor( c ) );
// not using paintComponentOuterBorder() here because its round edges look too "thick"
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, 0, focusWidth, arc );
} finally {
g2.dispose();
}
}
@Override
protected Color getFocusColor( Component c ) {
return FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c );
return (toolbarFocusColor != null && FlatButtonUI.isToolBarButton( c ))
? toolbarFocusColor
: (FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c ));
}
@Override

View File

@@ -30,6 +30,7 @@ import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.geom.RoundRectangle2D;
import java.beans.PropertyChangeEvent;
import java.util.Objects;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
@@ -129,6 +130,7 @@ public class FlatButtonUI
protected Color toolbarSelectedBackground;
private Icon helpButtonIcon;
private Insets defaultMargin;
private boolean defaults_initialized = false;
@@ -184,6 +186,7 @@ public class FlatButtonUI
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
defaultMargin = UIManager.getInsets( prefix + "margin" );
defaults_initialized = true;
}
@@ -499,16 +502,23 @@ public class FlatButtonUI
} else if( isIconOnlyOrSingleCharacter && ((AbstractButton)c).getIcon() == null ) {
// make single-character-no-icon button square (increase width)
prefSize.width = Math.max( prefSize.width, prefSize.height );
} else if( !isIconOnlyOrSingleCharacter && !isToolBarButton( c ) && c.getBorder() instanceof FlatButtonBorder ) {
} else if( !isIconOnlyOrSingleCharacter && !isToolBarButton( c ) &&
c.getBorder() instanceof FlatButtonBorder && hasDefaultMargins( c ) )
{
// apply minimum width/height
float focusWidth = FlatUIUtils.getBorderFocusWidth( c );
prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + Math.round( focusWidth * 2 ) );
prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) ) + Math.round( focusWidth * 2 ) );
int fw = Math.round( FlatUIUtils.getBorderFocusWidth( c ) * 2 );
prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + fw );
prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) ) + fw );
}
return prefSize;
}
private boolean hasDefaultMargins( JComponent c ) {
Insets margin = ((AbstractButton)c).getMargin();
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
}
//---- class FlatButtonListener -------------------------------------------
protected class FlatButtonListener

View File

@@ -18,10 +18,13 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import javax.swing.JFormattedTextField;
import javax.swing.plaf.UIResource;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
@@ -61,6 +64,19 @@ public class FlatCaret
}
}
@Override
protected void adjustVisibility( Rectangle nloc ) {
JTextComponent c = getComponent();
if( c != null && c.getUI() instanceof FlatTextFieldUI ) {
Insets padding = ((FlatTextFieldUI)c.getUI()).getPadding();
if( padding != null ) {
nloc.x -= padding.left;
nloc.y -= padding.top;
}
}
super.adjustVisibility( nloc );
}
@Override
public void focusGained( FocusEvent e ) {
if( !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) )
@@ -127,4 +143,23 @@ public class FlatCaret
moveDot( doc.getLength() );
}
}
/**
* @since 1.4
*/
public void scrollCaretToVisible() {
JTextComponent c = getComponent();
if( c == null || c.getUI() == null )
return;
try {
Rectangle loc = c.getUI().modelToView( c, getDot(), getDotBias() );
if( loc != null ) {
adjustVisibility( loc );
damage( loc );
}
} catch( BadLocationException ex ) {
// ignore
}
}
}

View File

@@ -17,11 +17,13 @@
package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale;
import static com.formdev.flatlaf.util.UIScale.unscale;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -39,7 +41,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
@@ -68,7 +69,6 @@ import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
@@ -137,7 +137,7 @@ public class FlatComboBoxUI
protected boolean hover;
protected boolean pressed;
private WeakReference<Component> lastRendererComponent;
private CellPaddingBorder paddingBorder;
public static ComponentUI createUI( JComponent c ) {
return new FlatComboBoxUI();
@@ -222,8 +222,7 @@ public class FlatComboBoxUI
if( maximumRowCount > 0 && maximumRowCount != 8 && comboBox.getMaximumRowCount() == 8 )
comboBox.setMaximumRowCount( maximumRowCount );
// scale
padding = UIScale.scale( padding );
paddingBorder = new CellPaddingBorder( padding );
MigLayoutVisualPadding.install( comboBox );
}
@@ -250,6 +249,8 @@ public class FlatComboBoxUI
popupBackground = null;
paddingBorder.uninstall();
MigLayoutVisualPadding.uninstall( comboBox );
}
@@ -261,8 +262,12 @@ public class FlatComboBoxUI
super.layoutContainer( parent );
if( arrowButton != null ) {
// limit button width to height of a raw combobox (without insets)
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
Insets insets = getInsets();
int buttonWidth = parent.getPreferredSize().height - insets.top - insets.bottom;
int buttonWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
if( buttonWidth != arrowButton.getWidth() ) {
// set width of arrow button to preferred height of combobox
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
@@ -276,11 +281,6 @@ public class FlatComboBoxUI
editor.setBounds( rectangleForCurrentValue() );
}
}
if( editor != null && padding != null ) {
// fix editor bounds by subtracting padding
editor.setBounds( FlatUIUtils.subtractInsets( editor.getBounds(), padding ) );
}
}
};
}
@@ -371,6 +371,7 @@ public class FlatComboBoxUI
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
updateEditorPadding();
updateEditorColors();
// macOS
@@ -387,6 +388,25 @@ public class FlatComboBoxUI
}
}
private void updateEditorPadding() {
if( !(editor instanceof JTextField) )
return;
JTextField textField = (JTextField) editor;
Insets insets = textField.getInsets();
Insets pad = padding;
if( insets.top != 0 || insets.left != 0 || insets.bottom != 0 || insets.right != 0 ) {
// if text field has custom border, subtract text field insets from padding
pad = new Insets(
unscale( Math.max( scale( padding.top ) - insets.top, 0 ) ),
unscale( Math.max( scale( padding.left ) - insets.left, 0 ) ),
unscale( Math.max( scale( padding.bottom ) - insets.bottom, 0 ) ),
unscale( Math.max( scale( padding.right ) - insets.right, 0 ) )
);
}
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, pad );
}
private void updateEditorColors() {
// use non-UIResource colors because when SwingUtilities.updateComponentTreeUI()
// is used, then the editor is updated after the combobox and the
@@ -471,30 +491,24 @@ public class FlatComboBoxUI
@Override
@SuppressWarnings( "unchecked" )
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
if( renderer == null )
renderer = new DefaultListCellRenderer();
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
c.setFont( comboBox.getFont() );
c.applyComponentOrientation( comboBox.getComponentOrientation() );
uninstallCellPaddingBorder( c );
boolean enabled = comboBox.isEnabled();
c.setBackground( getBackground( enabled ) );
c.setForeground( getForeground( enabled ) );
boolean shouldValidate = (c instanceof JPanel);
if( padding != null )
bounds = FlatUIUtils.subtractInsets( bounds, padding );
// increase the size of the rendering area to make sure that the text
// is vertically aligned with other component types (e.g. JTextField)
Insets rendererInsets = getRendererComponentInsets( c );
if( rendererInsets != null )
bounds = FlatUIUtils.addInsets( bounds, rendererInsets );
paddingBorder.install( c );
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
paddingBorder.uninstall();
}
@Override
@@ -526,77 +540,49 @@ public class FlatComboBoxUI
@Override
public Dimension getMinimumSize( JComponent c ) {
Dimension minimumSize = super.getMinimumSize( c );
minimumSize.width = Math.max( minimumSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) );
int fw = Math.round( FlatUIUtils.getBorderFocusWidth( c ) * 2 );
minimumSize.width = Math.max( minimumSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + fw );
return minimumSize;
}
@Override
protected Dimension getDefaultSize() {
@SuppressWarnings( "unchecked" )
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
paddingBorder.uninstall();
Dimension size = super.getDefaultSize();
uninstallCellPaddingBorder( renderer );
paddingBorder.uninstall();
return size;
}
@Override
protected Dimension getDisplaySize() {
@SuppressWarnings( "unchecked" )
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
paddingBorder.uninstall();
Dimension displaySize = super.getDisplaySize();
paddingBorder.uninstall();
// remove padding added in super.getDisplaySize()
int displayWidth = displaySize.width - padding.left - padding.right;
int displayHeight = displaySize.height - padding.top - padding.bottom;
// recalculate width without hardcoded 100 under special conditions
if( displaySize.width == 100 + padding.left + padding.right &&
if( displayWidth == 100 &&
comboBox.isEditable() &&
comboBox.getItemCount() == 0 &&
comboBox.getPrototypeDisplayValue() == null )
{
int width = getDefaultSize().width;
width = Math.max( width, editor.getPreferredSize().width );
width += padding.left + padding.right;
displaySize = new Dimension( width, displaySize.height );
displayWidth = Math.max( getDefaultSize().width, editor.getPreferredSize().width );
}
uninstallCellPaddingBorder( renderer );
return displaySize;
return new Dimension( displayWidth, displayHeight );
}
@Override
protected Dimension getSizeForComponent( Component comp ) {
paddingBorder.install( comp );
Dimension size = super.getSizeForComponent( comp );
// remove the renderer border top/bottom insets from the size to make sure that
// the combobox gets the same height as other component types (e.g. JTextField)
Insets rendererInsets = getRendererComponentInsets( comp );
if( rendererInsets != null )
size = new Dimension( size.width, size.height - rendererInsets.top - rendererInsets.bottom );
paddingBorder.uninstall();
return size;
}
private Insets getRendererComponentInsets( Component rendererComponent ) {
if( rendererComponent instanceof JComponent ) {
Border rendererBorder = ((JComponent)rendererComponent).getBorder();
if( rendererBorder != null )
return rendererBorder.getBorderInsets( rendererComponent );
}
return null;
}
private void uninstallCellPaddingBorder( Object o ) {
CellPaddingBorder.uninstall( o );
if( lastRendererComponent != null ) {
CellPaddingBorder.uninstall( lastRendererComponent );
lastRendererComponent = null;
}
}
private boolean isCellRenderer() {
return comboBox.getParent() instanceof CellRendererPane;
}
@@ -660,13 +646,11 @@ public class FlatComboBoxUI
protected class FlatComboPopup
extends BasicComboPopup
{
private CellPaddingBorder paddingBorder;
protected FlatComboPopup( JComboBox combo ) {
super( combo );
// BasicComboPopup listens to JComboBox.componentOrientation and updates
// the component orientation of the list, scroller and popup, but when
// the component orientation of the list, scroll pane and popup, but when
// switching the LaF and a new combo popup is created, the component
// orientation is not applied.
ComponentOrientation o = comboBox.getComponentOrientation();
@@ -745,6 +729,19 @@ public class FlatComboBoxUI
};
}
@Override
protected int getPopupHeightForRowCount( int maxRowCount ) {
int height = super.getPopupHeightForRowCount( maxRowCount );
paddingBorder.uninstall();
return height;
}
@Override
protected void paintChildren( Graphics g ) {
super.paintChildren( g );
paddingBorder.uninstall();
}
//---- class PopupListCellRenderer -----
private class PopupListCellRenderer
@@ -754,22 +751,15 @@ public class FlatComboBoxUI
public Component getListCellRendererComponent( JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus )
{
ListCellRenderer renderer = comboBox.getRenderer();
CellPaddingBorder.uninstall( renderer );
CellPaddingBorder.uninstall( lastRendererComponent );
paddingBorder.uninstall();
ListCellRenderer renderer = comboBox.getRenderer();
if( renderer == null )
renderer = new DefaultListCellRenderer();
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
c.applyComponentOrientation( comboBox.getComponentOrientation() );
if( c instanceof JComponent ) {
if( paddingBorder == null )
paddingBorder = new CellPaddingBorder( padding );
paddingBorder.install( (JComponent) c );
}
lastRendererComponent = (c != renderer) ? new WeakReference<>( c ) : null;
paddingBorder.install( c );
return c;
}
@@ -779,49 +769,69 @@ public class FlatComboBoxUI
//---- class CellPaddingBorder --------------------------------------------
/**
* Cell padding border used only in popup list.
*
* Cell padding border used in popup list and for current value if not editable.
* <p>
* The insets are the union of the cell padding and the renderer border insets,
* which vertically aligns text in popup list with text in combobox.
*
* The renderer border is painted on the outside of this border.
* <p>
* The renderer border is painted on the outer side of this border.
*/
private static class CellPaddingBorder
extends AbstractBorder
{
private final Insets padding;
private JComponent rendererComponent;
private Border rendererBorder;
CellPaddingBorder( Insets padding ) {
this.padding = padding;
}
void install( JComponent rendererComponent ) {
Border oldBorder = rendererComponent.getBorder();
if( !(oldBorder instanceof CellPaddingBorder) ) {
rendererBorder = oldBorder;
rendererComponent.setBorder( this );
}
}
static void uninstall( Object o ) {
if( o instanceof WeakReference )
o = ((WeakReference<?>)o).get();
if( !(o instanceof JComponent) )
void install( Component c ) {
if( !(c instanceof JComponent) )
return;
JComponent rendererComponent = (JComponent) o;
Border border = rendererComponent.getBorder();
if( border instanceof CellPaddingBorder ) {
CellPaddingBorder paddingBorder = (CellPaddingBorder) border;
rendererComponent.setBorder( paddingBorder.rendererBorder );
paddingBorder.rendererBorder = null;
}
JComponent jc = (JComponent) c;
Border oldBorder = jc.getBorder();
if( oldBorder == this )
return; // already installed
// component already has a padding border --> uninstall it
// (may happen if single renderer instance is used in multiple comboboxes)
if( oldBorder instanceof CellPaddingBorder )
((CellPaddingBorder)oldBorder).uninstall();
// this border can be installed only at one component
// (may happen if a renderer returns varying components)
uninstall();
// remember component where this border was installed for uninstall
rendererComponent = jc;
// remember old border and replace it
rendererBorder = jc.getBorder();
rendererComponent.setBorder( this );
}
/**
* Uninstall border from previously installed component.
* Because this border is installed in PopupListCellRenderer.getListCellRendererComponent(),
* there is no single place to uninstall it.
* This is the reason why this method is called from various places.
*/
void uninstall() {
if( rendererComponent == null )
return;
if( rendererComponent.getBorder() == this )
rendererComponent.setBorder( rendererBorder );
rendererComponent = null;
rendererBorder = null;
}
@Override
public Insets getBorderInsets( Component c, Insets insets ) {
Insets padding = scale( this.padding );
if( rendererBorder != null ) {
Insets insideInsets = rendererBorder.getBorderInsets( c );
insets.top = Math.max( padding.top, insideInsets.top );

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
@@ -65,6 +66,8 @@ public class FlatEditorPaneUI
protected boolean isIntelliJTheme;
protected Color focusedBackground;
private Insets defaultMargin;
private Object oldHonorDisplayProperties;
private FocusListener focusListener;
@@ -81,6 +84,8 @@ public class FlatEditorPaneUI
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
// use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true );
@@ -128,15 +133,19 @@ public class FlatEditorPaneUI
@Override
public Dimension getPreferredSize( JComponent c ) {
return applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth );
return applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth, defaultMargin );
}
@Override
public Dimension getMinimumSize( JComponent c ) {
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth, defaultMargin );
}
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) {
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth, Insets defaultMargin ) {
// do not apply minimum width if JTextComponent.margin is set
if( !FlatTextFieldUI.hasDefaultMargins( c, defaultMargin ) )
return size;
// Assume that text area is in a scroll pane (that displays the border)
// and subtract 1px border line width.
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding

View File

@@ -39,8 +39,6 @@ import javax.swing.plaf.ComponentUI;
*
* <!-- FlatTextFieldUI -->
*
* @uiDefault TextComponent.arc int
* @uiDefault Component.focusWidth int
* @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault FormattedTextField.placeholderForeground Color

View File

@@ -22,7 +22,10 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.Border;
@@ -160,12 +163,30 @@ public class FlatOptionPaneUI
if( msg instanceof String && BasicHTML.isHTMLString( (String) msg ) )
maxll = Integer.MAX_VALUE;
// fix right-to-left alignment if super.addMessageComponents() breaks longer lines
// into multiple labels and puts them into a box that aligns them to the left
if( msg instanceof Box ) {
Box box = (Box) msg;
if( "OptionPane.verticalBox".equals( box.getName() ) &&
box.getLayout() instanceof BoxLayout &&
((BoxLayout)box.getLayout()).getAxis() == BoxLayout.Y_AXIS )
{
box.addPropertyChangeListener( "componentOrientation", e -> {
float alignX = box.getComponentOrientation().isLeftToRight() ? 0 : 1;
for( Component c : box.getComponents() ) {
if( c instanceof JLabel && "OptionPane.label".equals( c.getName() ) )
((JLabel)c).setAlignmentX( alignX );
}
} );
}
}
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
}
private void updateChildPanels( Container c ) {
for( Component child : c.getComponents() ) {
if( child instanceof JPanel ) {
if( child.getClass() == JPanel.class ) {
JPanel panel = (JPanel)child;
// make sub-panel non-opaque for OptionPane.background
@@ -177,9 +198,8 @@ public class FlatOptionPaneUI
panel.setBorder( new NonUIResourceBorder( border ) );
}
if( child instanceof Container ) {
if( child instanceof Container )
updateChildPanels( (Container) child );
}
}
}

View File

@@ -16,30 +16,31 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPasswordFieldUI;
import javax.swing.text.Caret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.util.HiDPIUtils;
import javax.swing.text.PasswordView;
import javax.swing.text.View;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
*
* <!-- BasicPasswordFieldUI -->
* <!-- BasicTextFieldUI -->
*
* @uiDefault PasswordField.font Font
* @uiDefault PasswordField.background Color
@@ -52,74 +53,66 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
* @uiDefault PasswordField.border Border
* @uiDefault PasswordField.margin Insets
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds
*
* <!-- FlatPasswordFieldUI -->
* <!-- FlatTextFieldUI -->
*
* @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault PasswordField.placeholderForeground Color
* @uiDefault PasswordField.focusedBackground Color optional
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
* @uiDefault TextComponent.selectAllOnMouseClick boolean
*
* <!-- FlatPasswordFieldUI -->
*
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
*
* @author Karl Tauber
*/
public class FlatPasswordFieldUI
extends BasicPasswordFieldUI
extends FlatTextFieldUI
{
protected int minimumWidth;
protected boolean isIntelliJTheme;
protected Color placeholderForeground;
protected Color focusedBackground;
protected boolean showCapsLock;
protected Icon capsLockIcon;
private FocusListener focusListener;
private KeyListener capsLockListener;
public static ComponentUI createUI( JComponent c ) {
return new FlatPasswordFieldUI();
}
@Override
protected String getPropertyPrefix() {
return "PasswordField";
}
@Override
protected void installDefaults() {
super.installDefaults();
String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
Character echoChar = (Character) UIManager.get( prefix + ".echoChar" );
if( echoChar != null )
LookAndFeel.installProperty( getComponent(), "echoChar", echoChar );
showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );
LookAndFeel.installProperty( getComponent(), "opaque", false );
MigLayoutVisualPadding.install( getComponent() );
}
@Override
protected void uninstallDefaults() {
super.uninstallDefaults();
placeholderForeground = null;
focusedBackground = null;
capsLockIcon = null;
MigLayoutVisualPadding.uninstall( getComponent() );
}
@Override
protected void installListeners() {
super.installListeners();
// necessary to update focus border and background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), null );
// update caps lock indicator
capsLockListener = new KeyAdapter() {
@Override
@@ -131,12 +124,13 @@ public class FlatPasswordFieldUI
repaint( e );
}
private void repaint( KeyEvent e ) {
if( e.getKeyCode() == KeyEvent.VK_CAPS_LOCK )
if( e.getKeyCode() == KeyEvent.VK_CAPS_LOCK ) {
e.getComponent().repaint();
scrollCaretToVisible();
}
}
};
getComponent().addFocusListener( focusListener );
getComponent().addKeyListener( capsLockListener );
}
@@ -144,59 +138,74 @@ public class FlatPasswordFieldUI
protected void uninstallListeners() {
super.uninstallListeners();
getComponent().removeFocusListener( focusListener );
getComponent().removeKeyListener( capsLockListener );
focusListener = null;
capsLockListener = null;
}
@Override
protected Caret createCaret() {
return new FlatCaret( UIManager.getString( "TextComponent.selectAllOnFocusPolicy" ),
UIManager.getBoolean( "TextComponent.selectAllOnMouseClick" ) );
protected void installKeyboardActions() {
super.installKeyboardActions();
// map "select-word" action (double-click) to "select-line" action
ActionMap map = SwingUtilities.getUIActionMap( getComponent() );
if( map != null && map.get( DefaultEditorKit.selectWordAction ) != null ) {
Action selectLineAction = map.get( DefaultEditorKit.selectLineAction );
if( selectLineAction != null )
map.put( DefaultEditorKit.selectWordAction, selectLineAction );
}
}
@Override
protected void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e );
FlatTextFieldUI.propertyChange( getComponent(), e );
public View create( Element elem ) {
return new PasswordView( elem );
}
@Override
protected void paintSafely( Graphics g ) {
FlatTextFieldUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
FlatTextFieldUI.paintPlaceholder( g, getComponent(), placeholderForeground );
paintCapsLock( g );
// safe and restore clipping area because super.paintSafely() modifies it
// and the caps lock icon would be truncated
Shape oldClip = g.getClip();
super.paintSafely( g );
g.setClip( oldClip );
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
paintCapsLock( g );
}
protected void paintCapsLock( Graphics g ) {
if( !showCapsLock )
if( !isCapsLockVisible() )
return;
JTextComponent c = getComponent();
if( !FlatUIUtils.isPermanentFocusOwner( c ) ||
!Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK ) )
return;
int y = (c.getHeight() - capsLockIcon.getIconHeight()) / 2;
int x = c.getWidth() - capsLockIcon.getIconWidth() - y;
int x = c.getComponentOrientation().isLeftToRight()
? c.getWidth() - capsLockIcon.getIconWidth() - y
: y;
capsLockIcon.paintIcon( c, g, x, y );
}
@Override
protected void paintBackground( Graphics g ) {
// background is painted elsewhere
/**
* @since 1.4
*/
protected boolean isCapsLockVisible() {
if( !showCapsLock )
return false;
JTextComponent c = getComponent();
return FlatUIUtils.isPermanentFocusOwner( c ) &&
Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK );
}
/**
* @since 1.4
*/
@Override
public Dimension getPreferredSize( JComponent c ) {
return FlatTextFieldUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth );
}
protected Insets getPadding() {
Insets padding = super.getPadding();
if( !isCapsLockVisible() )
return padding;
@Override
public Dimension getMinimumSize( JComponent c ) {
return FlatTextFieldUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
boolean ltr = getComponent().getComponentOrientation().isLeftToRight();
int iconWidth = capsLockIcon.getIconWidth();
return FlatUIUtils.addInsets( padding, new Insets( 0, ltr ? 0 : iconWidth, 0, ltr ? iconWidth : 0 ) );
}
}

View File

@@ -44,6 +44,7 @@ import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.Border;
import com.formdev.flatlaf.FlatClientProperties;
@@ -260,13 +261,7 @@ public class FlatPopupFactory
}
private boolean wasInvokedFromToolTipManager() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for( StackTraceElement stackTraceElement : stackTrace ) {
if( "javax.swing.ToolTipManager".equals( stackTraceElement.getClassName() ) &&
"showTipWindow".equals( stackTraceElement.getMethodName() ) )
return true;
}
return false;
return StackUtils.wasInvokedFrom( ToolTipManager.class.getName(), "showTipWindow", 8 );
}
//---- class NonFlashingPopup ---------------------------------------------
@@ -494,6 +489,9 @@ public class FlatPopupFactory
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
layeredPane.add( dropShadowPanel, JLayeredPane.POPUP_LAYER, 0 );
moveMediumWeightDropShadow();
resizeMediumWeightDropShadow();
mediumPanelListener = new ComponentListener() {
@Override
public void componentShown( ComponentEvent e ) {
@@ -509,17 +507,12 @@ public class FlatPopupFactory
@Override
public void componentMoved( ComponentEvent e ) {
if( dropShadowPanel != null && mediumWeightPanel != null ) {
Point location = mediumWeightPanel.getLocation();
Insets insets = dropShadowPanel.getInsets();
dropShadowPanel.setLocation( location.x - insets.left, location.y - insets.top );
}
moveMediumWeightDropShadow();
}
@Override
public void componentResized( ComponentEvent e ) {
if( dropShadowPanel != null )
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
resizeMediumWeightDropShadow();
}
};
mediumWeightPanel.addComponentListener( mediumPanelListener );
@@ -535,5 +528,18 @@ public class FlatPopupFactory
parent.repaint( bounds.x, bounds.y, bounds.width, bounds.height );
}
}
private void moveMediumWeightDropShadow() {
if( dropShadowPanel != null && mediumWeightPanel != null ) {
Point location = mediumWeightPanel.getLocation();
Insets insets = dropShadowPanel.getInsets();
dropShadowPanel.setLocation( location.x - insets.left, location.y - insets.top );
}
}
private void resizeMediumWeightDropShadow() {
if( dropShadowPanel != null && mediumWeightPanel != null )
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
}
}
}

View File

@@ -342,7 +342,7 @@ public class FlatRootPaneUI
? getSizeFunc.apply( rootPane.getContentPane() )
: rootPane.getSize();
int width = Math.max( titlePaneSize.width, contentSize.width );
int width = contentSize.width; // title pane width is not considered here
int height = titlePaneSize.height + contentSize.height;
if( titlePane == null || !titlePane.isMenuBarEmbedded() ) {
JMenuBar menuBar = rootPane.getJMenuBar();

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
@@ -123,9 +124,6 @@ public class FlatSpinnerUI
buttonPressedArrowColor = UIManager.getColor( "Spinner.buttonPressedArrowColor" );
padding = UIManager.getInsets( "Spinner.padding" );
// scale
padding = scale( padding );
MigLayoutVisualPadding.install( spinner );
}
@@ -184,6 +182,7 @@ public class FlatSpinnerUI
if( textField != null )
textField.setOpaque( false );
updateEditorPadding();
updateEditorColors();
return editor;
}
@@ -194,6 +193,8 @@ public class FlatSpinnerUI
removeEditorFocusListener( oldEditor );
addEditorFocusListener( newEditor );
updateEditorPadding();
updateEditorColors();
}
@@ -209,6 +210,12 @@ public class FlatSpinnerUI
textField.removeFocusListener( getHandler() );
}
private void updateEditorPadding() {
JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null )
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
private void updateEditorColors() {
JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null ) {
@@ -373,6 +380,7 @@ public class FlatSpinnerUI
@Override
public Dimension preferredLayoutSize( Container parent ) {
Insets insets = parent.getInsets();
Insets padding = scale( FlatSpinnerUI.this.padding );
Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 );
// the arrows width is the same as the inner height so that the arrows area is square
@@ -397,15 +405,19 @@ public class FlatSpinnerUI
if( nextButton == null && previousButton == null ) {
if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( r, padding ) );
editor.setBounds( r );
return;
}
Rectangle editorRect = new Rectangle( r );
Rectangle buttonsRect = new Rectangle( r );
// limit buttons width to height of a raw spinner (without insets)
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
// make button area square (if spinner has preferred height)
int buttonsWidth = parent.getPreferredSize().height - insets.top - insets.bottom;
int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
buttonsRect.width = buttonsWidth;
if( parent.getComponentOrientation().isLeftToRight() ) {
@@ -417,7 +429,7 @@ public class FlatSpinnerUI
}
if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( editorRect, padding ) );
editor.setBounds( editorRect );
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
if( nextButton != null )

View File

@@ -842,6 +842,17 @@ public class FlatTabbedPaneUI
paintTabArea( g, tabPlacement, selectedIndex );
}
@Override
protected void paintTabArea( Graphics g, int tabPlacement, int selectedIndex ) {
// need to set rendering hints here too because this method is also invoked
// from BasicTabbedPaneUI.ScrollableTabPanel.paintComponent()
Object[] oldHints = FlatUIUtils.setRenderingHints( g );
super.paintTabArea( g, tabPlacement, selectedIndex );
FlatUIUtils.resetRenderingHints( g, oldHints );
}
@Override
protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect )

View File

@@ -94,6 +94,12 @@ public class FlatTableHeaderUI
bottomSeparatorColor = null;
}
// overridden and made public to allow usage in custom renderers
@Override
public int getRolloverColumn() {
return super.getRolloverColumn();
}
@Override
public void paint( Graphics g, JComponent c ) {
TableColumnModel columnModel = header.getColumnModel();

View File

@@ -240,7 +240,7 @@ public class FlatTableUI
if( isDragging &&
SystemInfo.isJava_9_orLater &&
((horizontalLines && y1 == y2) || (verticalLines && x1 == x2)) &&
wasInvokedFromPaintDraggedArea() )
wasInvokedFromMethod( "paintDraggedArea" ) )
{
if( y1 == y2 ) {
// horizontal grid line
@@ -282,22 +282,8 @@ public class FlatTableUI
return wasInvokedFromMethod( "paintGrid" );
}
private boolean wasInvokedFromPaintDraggedArea() {
return wasInvokedFromMethod( "paintDraggedArea" );
}
private boolean wasInvokedFromMethod( String methodName ) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for( int i = 0; i < 10 || i < stackTrace.length; i++ ) {
if( "javax.swing.plaf.basic.BasicTableUI".equals( stackTrace[i].getClassName() ) ) {
String methodName2 = stackTrace[i].getMethodName();
if( "paintCell".equals( methodName2 ) )
return false;
if( methodName.equals( methodName2 ) )
return true;
}
}
return false;
return StackUtils.wasInvokedFrom( BasicTableUI.class.getName(), methodName, 8 );
}
};
}

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
@@ -67,6 +68,8 @@ public class FlatTextAreaUI
protected Color inactiveBackground;
protected Color focusedBackground;
private Insets defaultMargin;
private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) {
@@ -90,6 +93,8 @@ public class FlatTextAreaUI
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
focusedBackground = UIManager.getColor( "TextArea.focusedBackground" );
defaultMargin = UIManager.getInsets( "TextArea.margin" );
}
@Override
@@ -170,7 +175,7 @@ public class FlatTextAreaUI
if( c instanceof JTextArea && ((JTextArea)c).getColumns() > 0 )
return size;
return FlatEditorPaneUI.applyMinimumWidth( c, size, minimumWidth );
return FlatEditorPaneUI.applyMinimumWidth( c, size, minimumWidth, defaultMargin );
}
@Override

View File

@@ -24,8 +24,10 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.util.Objects;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JSpinner;
@@ -40,6 +42,7 @@ import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.JavaCompatibility;
import com.formdev.flatlaf.util.UIScale;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}.
@@ -78,6 +81,8 @@ public class FlatTextFieldUI
protected Color placeholderForeground;
protected Color focusedBackground;
private Insets defaultMargin;
private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) {
@@ -94,6 +99,8 @@ public class FlatTextFieldUI
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
LookAndFeel.installProperty( getComponent(), "opaque", false );
MigLayoutVisualPadding.install( getComponent() );
@@ -142,6 +149,7 @@ public class FlatTextFieldUI
switch( e.getPropertyName() ) {
case FlatClientProperties.PLACEHOLDER_TEXT:
case FlatClientProperties.COMPONENT_ROUND_RECT:
case FlatClientProperties.TEXT_FIELD_PADDING:
c.repaint();
break;
@@ -154,7 +162,7 @@ public class FlatTextFieldUI
@Override
protected void paintSafely( Graphics g ) {
paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
paintPlaceholder( g, getComponent(), placeholderForeground );
paintPlaceholder( g );
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
}
@@ -210,7 +218,9 @@ public class FlatTextFieldUI
return background;
}
static void paintPlaceholder( Graphics g, JTextComponent c, Color placeholderForeground ) {
protected void paintPlaceholder( Graphics g ) {
JTextComponent c = getComponent();
// check whether text component is empty
if( c.getDocument().getLength() > 0 )
return;
@@ -225,16 +235,14 @@ public class FlatTextFieldUI
return;
// compute placeholder location
Insets insets = c.getInsets();
Rectangle r = getVisibleEditorRect();
FontMetrics fm = c.getFontMetrics( c.getFont() );
int x = insets.left;
int y = insets.top + fm.getAscent() + ((c.getHeight() - insets.top - insets.bottom - fm.getHeight()) / 2);
int y = r.y + fm.getAscent() + ((r.height - fm.getHeight()) / 2);
// paint placeholder
g.setColor( placeholderForeground );
String clippedPlaceholder = JavaCompatibility.getClippedString( jc, fm,
(String) placeholder, c.getWidth() - insets.left - insets.right );
FlatUIUtils.drawString( c, g, clippedPlaceholder, x, y );
String clippedPlaceholder = JavaCompatibility.getClippedString( c, fm, (String) placeholder, r.width );
FlatUIUtils.drawString( c, g, clippedPlaceholder, r.x, y );
}
@Override
@@ -247,11 +255,15 @@ public class FlatTextFieldUI
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
}
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) {
private Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) {
// do not apply minimum width if JTextField.columns is set
if( c instanceof JTextField && ((JTextField)c).getColumns() > 0 )
return size;
// do not apply minimum width if JTextComponent.margin is set
if( !hasDefaultMargins( c, defaultMargin ) )
return size;
// do not apply minimum width if used in combobox or spinner
Container parent = c.getParent();
if( parent instanceof JComboBox ||
@@ -264,4 +276,41 @@ public class FlatTextFieldUI
size.width = Math.max( size.width, scale( minimumWidth ) + Math.round( focusWidth * 2 ) );
return size;
}
static boolean hasDefaultMargins( JComponent c, Insets defaultMargin ) {
Insets margin = ((JTextComponent)c).getMargin();
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
}
@Override
protected Rectangle getVisibleEditorRect() {
Rectangle r = super.getVisibleEditorRect();
if( r != null ) {
// remove padding
Insets padding = getPadding();
if( padding != null ) {
r = FlatUIUtils.subtractInsets( r, padding );
r.width = Math.max( r.width, 0 );
r.height = Math.max( r.height, 0 );
}
}
return r;
}
/**
* @since 1.4
*/
protected Insets getPadding() {
Object padding = getComponent().getClientProperty( FlatClientProperties.TEXT_FIELD_PADDING );
return (padding instanceof Insets) ? UIScale.scale( (Insets) padding ) : null;
}
/**
* @since 1.4
*/
protected void scrollCaretToVisible() {
Caret caret = getComponent().getCaret();
if( caret instanceof FlatCaret )
((FlatCaret)caret).scrollCaretToVisible();
}
}

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
@@ -62,6 +63,8 @@ public class FlatTextPaneUI
protected boolean isIntelliJTheme;
protected Color focusedBackground;
private Insets defaultMargin;
private Object oldHonorDisplayProperties;
private FocusListener focusListener;
@@ -78,6 +81,8 @@ public class FlatTextPaneUI
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
// use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true );
@@ -117,12 +122,12 @@ public class FlatTextPaneUI
@Override
public Dimension getPreferredSize( JComponent c ) {
return FlatEditorPaneUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth );
return FlatEditorPaneUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth, defaultMargin );
}
@Override
public Dimension getMinimumSize( JComponent c ) {
return FlatEditorPaneUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
return FlatEditorPaneUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth, defaultMargin );
}
@Override

View File

@@ -22,6 +22,7 @@ import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI;
@@ -41,15 +42,47 @@ import javax.swing.plaf.basic.BasicToolBarUI;
* @uiDefault ToolBar.floatingForeground Color
* @uiDefault ToolBar.isRollover boolean
*
* <!-- FlatToolBarUI -->
*
* @uiDefault ToolBar.focusableButtons boolean
*
* @author Karl Tauber
*/
public class FlatToolBarUI
extends BasicToolBarUI
{
/** @since 1.4 */
protected boolean focusableButtons;
public static ComponentUI createUI( JComponent c ) {
return new FlatToolBarUI();
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
// disable focusable state of buttons (when switching from another Laf)
if( !focusableButtons )
setButtonsFocusable( false );
}
@Override
public void uninstallUI( JComponent c ) {
super.uninstallUI( c );
// re-enable focusable state of buttons (when switching to another Laf)
if( !focusableButtons )
setButtonsFocusable( true );
}
@Override
protected void installDefaults() {
super.installDefaults();
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
}
@Override
protected ContainerListener createToolBarContListener() {
return new ToolBarContListener() {
@@ -57,22 +90,36 @@ public class FlatToolBarUI
public void componentAdded( ContainerEvent e ) {
super.componentAdded( e );
Component c = e.getChild();
if( c instanceof AbstractButton )
c.setFocusable( false );
if( !focusableButtons ) {
Component c = e.getChild();
if( c instanceof AbstractButton )
c.setFocusable( false );
}
}
@Override
public void componentRemoved( ContainerEvent e ) {
super.componentRemoved( e );
Component c = e.getChild();
if( c instanceof AbstractButton )
c.setFocusable( true );
if( !focusableButtons ) {
Component c = e.getChild();
if( c instanceof AbstractButton )
c.setFocusable( true );
}
}
};
}
/**
* @since 1.4
*/
protected void setButtonsFocusable( boolean focusable ) {
for( Component c : toolBar.getComponents() ) {
if( c instanceof AbstractButton )
c.setFocusable( focusable );
}
}
// disable rollover border
@Override protected void setBorderToRollover( Component c ) {}
@Override protected void setBorderToNonRollover( Component c ) {}

View File

@@ -94,6 +94,11 @@ public class FlatUIUtils
}
public static Insets addInsets( Insets insets1, Insets insets2 ) {
if( insets1 == null )
return insets2;
if( insets2 == null )
return insets1;
return new Insets(
insets1.top + insets2.top,
insets1.left + insets2.left,

View File

@@ -181,8 +181,12 @@ public abstract class FlatWindowResizer
protected abstract boolean isWindowResizable();
protected abstract Rectangle getWindowBounds();
protected abstract void setWindowBounds( Rectangle r );
protected abstract boolean limitToParentBounds();
protected abstract Rectangle getParentBounds();
protected abstract boolean honorMinimumSizeOnResize();
protected abstract boolean honorMaximumSizeOnResize();
protected abstract Dimension getWindowMinimumSize();
protected abstract Dimension getWindowMaximumSize();
protected void beginResizing( int direction ) {}
protected void endResizing() {}
@@ -283,6 +287,16 @@ public abstract class FlatWindowResizer
}
}
@Override
protected boolean limitToParentBounds() {
return false;
}
@Override
protected Rectangle getParentBounds() {
return null;
}
@Override
protected boolean honorMinimumSizeOnResize() {
return
@@ -290,11 +304,21 @@ public abstract class FlatWindowResizer
(honorDialogMinimumSizeOnResize && window instanceof Dialog);
}
@Override
protected boolean honorMaximumSizeOnResize() {
return false;
}
@Override
protected Dimension getWindowMinimumSize() {
return window.getMinimumSize();
}
@Override
protected Dimension getWindowMaximumSize() {
return window.getMaximumSize();
}
@Override
boolean isDialog() {
return window instanceof Dialog;
@@ -354,16 +378,36 @@ public abstract class FlatWindowResizer
desktopManager.get().resizeFrame( getFrame(), r.x, r.y, r.width, r.height );
}
@Override
protected boolean limitToParentBounds() {
return true;
}
@Override
protected Rectangle getParentBounds() {
return getFrame().getParent().getBounds();
}
@Override
protected boolean honorMinimumSizeOnResize() {
return true;
}
@Override
protected boolean honorMaximumSizeOnResize() {
return true;
}
@Override
protected Dimension getWindowMinimumSize() {
return getFrame().getMinimumSize();
}
@Override
protected Dimension getWindowMaximumSize() {
return getFrame().getMaximumSize();
}
@Override
protected void beginResizing( int direction ) {
desktopManager.get().beginResizingFrame( getFrame(), direction );
@@ -521,7 +565,7 @@ debug*/
int xOnScreen = e.getXOnScreen();
int yOnScreen = e.getYOnScreen();
// Get current window bounds and compute new bounds based them.
// Get current window bounds and compute new bounds based on them.
// This is necessary because window manager may alter window bounds while resizing.
// E.g. when having two monitors with different scale factors and resizing
// a window on first screen to the second screen, then the window manager may
@@ -535,41 +579,72 @@ debug*/
// top
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
newBounds.y = yOnScreen - dragTopOffset;
if( limitToParentBounds() && newBounds.y < 0 )
newBounds.y = 0;
newBounds.height += (oldBounds.y - newBounds.y);
}
// bottom
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y;
if( limitToParentBounds() ) {
int parentHeight = getParentBounds().height;
if( newBounds.y + newBounds.height > parentHeight )
newBounds.height = parentHeight - newBounds.y;
}
}
// left
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
newBounds.x = xOnScreen - dragLeftOffset;
if( limitToParentBounds() && newBounds.x < 0 )
newBounds.x = 0;
newBounds.width += (oldBounds.x - newBounds.x);
}
// right
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x;
if( limitToParentBounds() ) {
int parentWidth = getParentBounds().width;
if( newBounds.x + newBounds.width > parentWidth )
newBounds.width = parentWidth - newBounds.x;
}
}
// apply minimum window size
Dimension minimumSize = honorMinimumSizeOnResize() ? getWindowMinimumSize() : null;
if( minimumSize == null )
minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
if( newBounds.width < minimumSize.width ) {
if( newBounds.x != oldBounds.x )
newBounds.x -= (minimumSize.width - newBounds.width);
newBounds.width = minimumSize.width;
}
if( newBounds.height < minimumSize.height ) {
if( newBounds.y != oldBounds.y )
newBounds.y -= (minimumSize.height - newBounds.height);
newBounds.height = minimumSize.height;
if( newBounds.width < minimumSize.width )
changeWidth( oldBounds, newBounds, minimumSize.width );
if( newBounds.height < minimumSize.height )
changeHeight( oldBounds, newBounds, minimumSize.height );
// apply maximum window size
if( honorMaximumSizeOnResize() ) {
Dimension maximumSize = getWindowMaximumSize();
if( newBounds.width > maximumSize.width )
changeWidth( oldBounds, newBounds, maximumSize.width );
if( newBounds.height > maximumSize.height )
changeHeight( oldBounds, newBounds, maximumSize.height );
}
// set window bounds
if( !newBounds.equals( oldBounds ) )
setWindowBounds( newBounds );
}
private void changeWidth( Rectangle oldBounds, Rectangle newBounds, int width ) {
if( newBounds.x != oldBounds.x )
newBounds.x -= (width - newBounds.width);
newBounds.width = width;
}
private void changeHeight( Rectangle oldBounds, Rectangle newBounds, int height ) {
if( newBounds.y != oldBounds.y )
newBounds.y -= (height - newBounds.height);
newBounds.height = height;
}
}
}

View File

@@ -25,6 +25,8 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
@@ -289,6 +291,7 @@ class FlatWindowsNativeWindowBorder
//---- class WndProc ------------------------------------------------------
private class WndProc
implements PropertyChangeListener
{
// WM_NCHITTEST mouse position codes
private static final int
@@ -313,18 +316,36 @@ class FlatWindowsNativeWindowBorder
// remove the OS window title bar
updateFrame( hwnd, (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
// set window background (used when resizing window)
updateWindowBackground();
window.addPropertyChangeListener( "background", this );
}
void uninstall() {
window.removePropertyChangeListener( "background", this );
uninstallImpl( hwnd );
// cleanup
window = null;
}
@Override
public void propertyChange( PropertyChangeEvent e ) {
updateWindowBackground();
}
private void updateWindowBackground() {
Color bg = window.getBackground();
if( bg != null )
setWindowBackground( hwnd, bg.getRed(), bg.getGreen(), bg.getBlue() );
}
private native long installImpl( Window window );
private native void uninstallImpl( long hwnd );
private native void updateFrame( long hwnd, int state );
private native void setWindowBackground( long hwnd, int r, int g, int b );
private native void showWindow( long hwnd, int cmd );
// invoked from native code

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtils
{
private static final StackUtils INSTANCE = new StackUtilsImpl();
// hide from javadoc
StackUtils() {
}
/**
* Checks whether current method was invoked from the given class and method.
*/
public static boolean wasInvokedFrom( String className, String methodName, int limit ) {
return wasInvokedFrom( (c,m) -> c.equals( className ) && m.equals( methodName ), limit );
}
/**
* Checks whether current method was invoked from a class and method using the given predicate,
* which gets the class name of the stack frame as first parameter and the method name as second parameter.
*/
public static boolean wasInvokedFrom( BiPredicate<String, String> predicate, int limit ) {
return INSTANCE.wasInvokedFromImpl( predicate, limit );
}
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtilsImpl
extends StackUtils
{
@Override
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
int count = -2;
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for( StackTraceElement stackTraceElement : stackTrace ) {
if( predicate.test( stackTraceElement.getClassName(), stackTraceElement.getMethodName() ) )
return true;
count++;
if( limit > 0 && count > limit )
return false;
}
return false;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtilsImpl
extends StackUtils
{
@Override
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
return StackWalker.getInstance().walk( stream -> {
if( limit > 0 )
stream = stream.limit( limit + 2 );
return stream.anyMatch( f -> {
return predicate.test( f.getClassName(), f.getMethodName() );
} );
} );
}
}

View File

@@ -514,6 +514,17 @@ ScrollPane.fillUpperCorner = true
ScrollPane.smoothScrolling = true
#---- SearchField ----
SearchField.searchIconColor = fadeout(Actions.GreyInline,10%,lazy)
SearchField.searchIconHoverColor = fadeout(Actions.GreyInline,30%,lazy)
SearchField.searchIconPressedColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconHoverColor = $SearchField.clearIconColor
SearchField.clearIconPressedColor = fadeout(Actions.GreyInline,20%,lazy)
#---- Separator ----
Separator.height = 3
@@ -752,6 +763,7 @@ ToolBar.separatorWidth = 7
ToolBar.separatorColor = $Separator.foreground
ToolBar.spacingBorder = $Button.toolbar.spacingInsets
ToolBar.focusableButtons = false
#---- ToolTipManager ----

View File

@@ -0,0 +1,203 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import com.formdev.flatlaf.util.UIScale;
/**
* @author Karl Tauber
*/
public class TestFlatComponentSizes
{
@BeforeAll
static void setup() {
TestUtils.setup( false );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
}
static float[] factors() {
return TestUtils.FACTORS;
}
@ParameterizedTest
@MethodSource( "factors" )
void sizes( float factor ) {
TestUtils.scaleFont( factor );
// should have same default size (minimumWidth is 64)
JTextField textField = new JTextField();
JFormattedTextField formattedTextField = new JFormattedTextField();
JPasswordField passwordField = new JPasswordField();
JSpinner spinner = new JSpinner();
Dimension textFieldSize = textField.getPreferredSize();
assertEquals( textFieldSize, formattedTextField.getPreferredSize() );
assertEquals( textFieldSize, passwordField.getPreferredSize() );
assertEquals( textFieldSize, spinner.getPreferredSize() );
// should have same default size (minimumWidth is 72)
JButton button = new JButton( "text" );
JComboBox<String> comboBox = new JComboBox<>();
JComboBox<String> comboBoxEditable = new JComboBox<>();
comboBoxEditable.setEditable( true );
Dimension buttonSize = button.getPreferredSize();
assertEquals( buttonSize, comboBox.getPreferredSize() );
assertEquals( buttonSize, comboBoxEditable.getPreferredSize() );
// should have same height
JToggleButton toggleButton = new JToggleButton( "text" );
assertEquals( textFieldSize.height, button.getPreferredSize().height );
assertEquals( textFieldSize.height, toggleButton.getPreferredSize().height );
// should have same size
JCheckBox checkBox = new JCheckBox( "text" );
JRadioButton radioButton = new JRadioButton( "text" );
assertEquals( checkBox.getPreferredSize(), radioButton.getPreferredSize() );
// should have same size
JMenu menu = new JMenu( "text" );
JMenuItem menuItem = new JMenuItem( "text" );
JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem( "text" );
JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem( "text" );
Dimension menuSize = menu.getPreferredSize();
assertEquals( menuSize, menuItem.getPreferredSize() );
assertEquals( menuSize, checkBoxMenuItem.getPreferredSize() );
assertEquals( menuSize, radioButtonMenuItem.getPreferredSize() );
TestUtils.resetFont();
}
@ParameterizedTest
@MethodSource( "factors" )
void comboBox( float factor ) {
TestUtils.scaleFont( factor );
String[] items = { "t" };
JComboBox<String> comboBox = new JComboBox<>( items );
JComboBox<String> comboBox2 = new JComboBox<>( items );
JComboBox<String> comboBox3 = new JComboBox<>( items );
JComboBox<String> comboBox4 = new JComboBox<>( items );
applyCustomComboBoxRendererBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
applyCustomComboBoxRendererBorder( comboBox3, new BorderWithIcon() );
applyCustomComboBoxRendererBorder( comboBox4, null );
Dimension size = comboBox.getPreferredSize();
assertEquals( size.width, comboBox2.getPreferredSize().width );
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
assertEquals( size, comboBox3.getPreferredSize() );
assertEquals( size, comboBox4.getPreferredSize() );
TestUtils.resetFont();
}
@SuppressWarnings( "unchecked" )
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox, Border border ) {
BasicComboBoxRenderer customRenderer = new BasicComboBoxRenderer();
customRenderer.setBorder( border );
comboBox.setRenderer( customRenderer );
}
@ParameterizedTest
@MethodSource( "factors" )
void comboBoxEditable( float factor ) {
TestUtils.scaleFont( factor );
String[] items = { "t" };
JComboBox<String> comboBox = new JComboBox<>( items );
JComboBox<String> comboBox2 = new JComboBox<>( items );
JComboBox<String> comboBox3 = new JComboBox<>( items );
JComboBox<String> comboBox4 = new JComboBox<>( items );
comboBox.setEditable( true );
comboBox2.setEditable( true );
comboBox3.setEditable( true );
comboBox4.setEditable( true );
applyCustomComboBoxEditorBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
applyCustomComboBoxEditorBorder( comboBox3, new BorderWithIcon() );
applyCustomComboBoxEditorBorder( comboBox4, null );
Dimension size = comboBox.getPreferredSize();
assertEquals( size.width, comboBox2.getPreferredSize().width );
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
assertEquals( size, comboBox3.getPreferredSize() );
assertEquals( size, comboBox4.getPreferredSize() );
TestUtils.resetFont();
}
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox, Border border ) {
JTextField customTextField = new JTextField();
if( border != null )
customTextField.setBorder( border );
comboBox.setEditor( new BasicComboBoxEditor() {
@Override
protected JTextField createEditorComponent() {
return customTextField;
}
} );
}
//---- class BorderWithIcon -----------------------------------------------
private static class BorderWithIcon
implements Border
{
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
}
@Override
public boolean isBorderOpaque() {
return false;
}
@Override
public Insets getBorderInsets( Component c ) {
return new Insets( 0, 0, 0, UIScale.scale( 16 ) + 4 );
}
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import org.junit.jupiter.api.BeforeAll;
/**
* @author Karl Tauber
*/
public class TestFlatComponentSizesWithFocus
extends TestFlatComponentSizes
{
@BeforeAll
static void setup() {
TestUtils.setup( true );
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.ui;
import java.awt.Font;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatSystemProperties;
/**
* @author Karl Tauber
*/
public class TestUtils
{
public static final float[] FACTORS = new float[] { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f };
public static void setup( boolean withFocus ) {
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
if( withFocus )
FlatIntelliJLaf.setup();
else
FlatLightLaf.setup();
System.clearProperty( FlatSystemProperties.UI_SCALE );
}
public static void cleanup() {
UIManager.put( "defaultFont", null );
}
public static void scaleFont( float factor ) {
Font defaultFont = UIManager.getLookAndFeelDefaults().getFont( "defaultFont" );
UIManager.put( "defaultFont", defaultFont.deriveFont( (float) Math.round( defaultFont.getSize() * factor ) ) );
}
public static void resetFont() {
UIManager.put( "defaultFont", null );
}
}

View File

@@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
<rect width="6" height="2" x="5" y="12" fill="#FFF"/>
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 328 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" d="M8,1.75 C11.4517797,1.75 14.25,4.54822031 14.25,8 C14.25,11.4517797 11.4517797,14.25 8,14.25 C4.54822031,14.25 1.75,11.4517797 1.75,8 C1.75,4.54822031 4.54822031,1.75 8,1.75 Z M10.5,4.5 L8,7 L5.5,4.5 L4.5,5.5 L7,8 L4.5,10.5 L5.5,11.5 L8,9 L10.5,11.5 L11.5,10.5 L9,8 L11.5,5.5 L10.5,4.5 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 446 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="none" stroke="#7F8B91" stroke-linecap="square" stroke-opacity=".5" d="M5,5 L11,11 M5,11 L11,5"/>
</svg>

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="10.813 9.75 14 12.938 12.938 14 9.75 10.813"/>
<path fill="#7F8B91" d="M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z M7,3 C4.790861,3 3,4.790861 3,7 C3,9.209139 4.790861,11 7,11 C9.209139,11 11,9.209139 11,7 C11,4.790861 9.209139,3 7,3 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 526 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="8.813 9.75 12 12.938 10.938 14 7.75 10.813"/>
<path fill="#7F8B91" d="M5,2 C7.76142375,2 10,4.23857625 10,7 C10,9.76142375 7.76142375,12 5,12 C2.23857625,12 0,9.76142375 0,7 C0,4.23857625 2.23857625,2 5,2 Z M5,3 C2.790861,3 1,4.790861 1,7 C1,9.209139 2.790861,11 5,11 C7.209139,11 9,9.209139 9,7 C9,4.790861 7.209139,3 5,3 Z"/>
<polygon fill="#7F8B91" points="11 7 16 7 13.5 10"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 579 B

View File

@@ -28,6 +28,7 @@ import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.layout.ConstraintParser;
@@ -240,7 +241,7 @@ class ControlBar
frame.setSize( Math.max( prefSize.width, width ), Math.max( prefSize.height, height ) );
} catch( Exception ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
}
} );
}

View File

@@ -34,6 +34,7 @@ import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.extras.components.FlatButton;
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
import com.formdev.flatlaf.extras.FlatSVGUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.ui.JBRCustomDecorations;
import com.formdev.flatlaf.util.SystemInfo;
import net.miginfocom.layout.ConstraintParser;
@@ -185,6 +186,8 @@ class DemoFrame
Font font = UIManager.getFont( "defaultFont" );
Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() );
// StyleContext.getFont() may return a UIResource, which would cause loosing user scale factor on Windows
newFont = FlatUIUtils.nonUIResource( newFont );
UIManager.put( "defaultFont", newFont );
FlatLaf.updateUI();

View File

@@ -25,6 +25,7 @@ import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatPropertiesLaf;
import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
/**
@@ -83,7 +84,7 @@ public class DemoPrefs
UIManager.setLookAndFeel( lafClassName );
}
} catch( Throwable ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
// fallback
FlatLightLaf.setup();

View File

@@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import com.formdev.flatlaf.util.LoggingFacade;
/**
* This tool creates look and feel classes for all themes listed in themes.json.
@@ -120,7 +121,7 @@ public class IJThemesClassGenerator
Files.write( out, content.getBytes( StandardCharsets.ISO_8859_1 ),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING );
} catch( IOException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}

View File

@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.formdev.flatlaf.json.Json;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
/**
@@ -46,7 +47,7 @@ class IJThemesManager
try( Reader reader = new InputStreamReader( getClass().getResourceAsStream( "themes.json" ), StandardCharsets.UTF_8 ) ) {
json = (Map<String, Object>) Json.parse( reader );
} catch( IOException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
return;
}

View File

@@ -52,6 +52,7 @@ import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.demo.DemoPrefs;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
import net.miginfocom.swing.*;
@@ -259,7 +260,7 @@ public class IJThemesPanel
try {
UIManager.setLookAndFeel( themeInfo.lafClassName );
} catch( Exception ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
}
} else if( themeInfo.themeFile != null ) {
@@ -273,7 +274,7 @@ public class IJThemesPanel
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.FILE_PREFIX + themeInfo.themeFile );
} catch( Exception ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
}
} else {

View File

@@ -23,6 +23,7 @@ import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import com.formdev.flatlaf.util.LoggingFacade;
/**
* This tool updates all IntelliJ themes listed in themes.json by downloading
@@ -61,7 +62,7 @@ public class IJThemesUpdater
URLConnection con = url.openConnection();
Files.copy( con.getInputStream(), out, StandardCopyOption.REPLACE_EXISTING );
} catch( IOException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
}

View File

@@ -42,6 +42,7 @@ import com.formdev.flatlaf.FlatLaf.DisabledIconProvider;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.UIScale;
import com.kitfox.svg.SVGDiagram;
@@ -335,7 +336,7 @@ public class FlatSVGIcon
try {
diagram = svgUniverse.getDiagram( url.toURI() );
} catch( URISyntaxException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load SVG icon '" + url + "'.", ex );
}
}

View File

@@ -52,6 +52,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.HSLColor;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.formdev.flatlaf.util.UIScale;
@@ -377,11 +378,12 @@ public class FlatUIDefaultsInspector
}
private Properties loadDerivedColorKeys() {
String name = "/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties";
Properties properties = new Properties();
try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties" ) ) {
try( InputStream in = getClass().getResourceAsStream( name ) ) {
properties.load( in );
} catch( IOException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load '" + name + "'.", ex );
}
return properties;
}

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Insets;
import javax.swing.JComponent;
import javax.swing.UIManager;
import com.formdev.flatlaf.util.LoggingFacade;
/**
* Base interface for all FlatLaf component extensions.
@@ -87,7 +88,7 @@ public interface FlatComponentExtension
try {
return Enum.valueOf( enumType, (String) value );
} catch( IllegalArgumentException ex ) {
ex.printStackTrace();
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Unknown enum value '" + value + "' in enum '" + enumType.getName() + "'.", ex );
}
}
return defaultValue;

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color;
import java.awt.Insets;
import javax.swing.JFormattedTextField;
import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy;
@@ -61,6 +62,27 @@ public class FlatFormattedTextField
}
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/**
* Returns minimum width of a component.
*/

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color;
import java.awt.Insets;
import javax.swing.JPasswordField;
import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy;
@@ -61,6 +62,27 @@ public class FlatPasswordField
}
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/**
* Returns minimum width of a component.
*/

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color;
import java.awt.Insets;
import javax.swing.JTextField;
/**
@@ -63,6 +64,27 @@ public class FlatTextField
}
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/**
* Returns minimum width of a component.
*/

View File

@@ -28,6 +28,8 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
@@ -47,6 +49,7 @@ import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.Shell32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WTypes.LPWSTR;
@@ -282,11 +285,12 @@ public class FlatWindowsNativeWindowBorder
//---- class WndProc ------------------------------------------------------
private class WndProc
implements WindowProc
implements WindowProc, PropertyChangeListener
{
private static final int GWLP_WNDPROC = -4;
private static final int
WM_ERASEBKGND = 0x0014,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x0084,
WM_NCRBUTTONUP = 0x00A5,
@@ -326,6 +330,7 @@ public class FlatWindowsNativeWindowBorder
private final HWND hwnd;
private final BaseTSD.LONG_PTR defaultWndProc;
private int wmSizeWParam = -1;
private HBRUSH background;
private int titleBarHeight;
private Rectangle[] hitTestSpots;
@@ -345,9 +350,15 @@ public class FlatWindowsNativeWindowBorder
// remove the OS window title bar
updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
// set window background (used when resizing window)
updateWindowBackground();
window.addPropertyChangeListener( "background", this );
}
void uninstall() {
window.removePropertyChangeListener( "background", this );
// restore original window procedure
if( SystemInfo.isX86_64 )
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
@@ -358,6 +369,8 @@ public class FlatWindowsNativeWindowBorder
updateFrame( 0 );
// cleanup
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
window = null;
}
@@ -382,6 +395,26 @@ public class FlatWindowsNativeWindowBorder
wmSizeWParam = -1;
}
@Override
public void propertyChange( PropertyChangeEvent evt ) {
updateWindowBackground();
}
private void updateWindowBackground() {
Color bg = window.getBackground();
if( bg != null )
setWindowBackground( bg.getRed(), bg.getGreen(), bg.getBlue() );
}
private void setWindowBackground( int r, int g, int b ) {
// delete old background brush
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
// create new background brush
background = GDI32Ex.INSTANCE.CreateSolidBrush( RGB( r, g, b ) );
}
/**
* NOTE: This method is invoked on the AWT-Windows thread (not the AWT-EventQueue thread).
*/
@@ -408,6 +441,9 @@ public class FlatWindowsNativeWindowBorder
wParam = new WPARAM( wmSizeWParam );
break;
case WM_ERASEBKGND:
return WmEraseBkgnd( hwnd, uMsg, wParam, lParam );
case WM_DESTROY:
return WmDestroy( hwnd, uMsg, wParam, lParam );
}
@@ -432,11 +468,30 @@ public class FlatWindowsNativeWindowBorder
// cleanup
windowsMap.remove( window );
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
window = null;
return lResult;
}
/**
* Handle WM_ERASEBKGND
*
* https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd
*/
LRESULT WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ) {
if( background == null )
return new LRESULT( 0 );
// fill background
HDC hdc = new HDC( wParam.toPointer() );
RECT rect = new RECT();
User32.INSTANCE.GetClientRect( hwnd, rect );
User32Ex.INSTANCE.FillRect( hdc, rect, background );
return new LRESULT( 1 );
}
/**
* Handle WM_NCCALCSIZE
*
@@ -637,6 +692,13 @@ public class FlatWindowsNativeWindowBorder
return (short) ((lParam.longValue() >> 16) & 0xffff);
}
/**
* Same implementation as RGB(r,g,b) macro in wingdi.h.
*/
private DWORD RGB( int r, int g, int b ) {
return new DWORD( (r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16) );
}
/**
* Opens the window's system menu.
* The system menu is the menu that opens when the user presses Alt+Space or
@@ -690,6 +752,8 @@ public class FlatWindowsNativeWindowBorder
LONG_PTR SetWindowLong( HWND hWnd, int nIndex, LONG_PTR wndProc );
LRESULT CallWindowProc( LONG_PTR lpPrevWndFunc, HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam );
int FillRect( HDC hDC, RECT lprc, HBRUSH hbr );
int GetDpiForWindow( HWND hwnd );
int GetSystemMetricsForDpi( int nIndex, int dpi );
@@ -702,6 +766,16 @@ public class FlatWindowsNativeWindowBorder
BOOL TrackPopupMenu( HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, RECT prcRect );
}
//---- interface GDI32Ex --------------------------------------------------
private interface GDI32Ex
extends GDI32
{
GDI32Ex INSTANCE = Native.load( "gdi32", GDI32Ex.class, W32APIOptions.DEFAULT_OPTIONS );
HBRUSH CreateSolidBrush( DWORD color );
}
//---- class NCCALCSIZE_PARAMS --------------------------------------------
@FieldOrder( { "rgrc" } )

View File

@@ -73,8 +73,8 @@ library {
linkerArgs.addAll( toolChain.map {
when( it ) {
is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lshell32", "-lAdvAPI32", "-lKernel32" )
is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" )
is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lGdi32", "-lshell32", "-lAdvAPI32", "-lKernel32" )
is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "Gdi32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" )
else -> emptyList()
}
} )

View File

@@ -52,6 +52,13 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state );
}
extern "C"
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
( JNIEnv* env, jobject obj, jlong hwnd, jint r, jint g, jint b )
{
FlatWndProc::setWindowBackground( reinterpret_cast<HWND>( hwnd ), r, g, b );
}
extern "C"
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_showWindow
( JNIEnv* env, jobject obj, jlong hwnd, jint cmd )
@@ -80,6 +87,7 @@ FlatWndProc::FlatWndProc() {
hwnd = NULL;
defaultWndProc = NULL;
wmSizeWParam = -1;
background = NULL;
}
HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
@@ -128,6 +136,8 @@ void FlatWndProc::uninstall( JNIEnv *env, jobject obj, HWND hwnd ) {
// cleanup
env->DeleteGlobalRef( fwp->obj );
if( fwp->background != NULL )
::DeleteObject( fwp->background );
delete fwp;
}
@@ -174,8 +184,23 @@ void FlatWndProc::updateFrame( HWND hwnd, int state ) {
fwp->wmSizeWParam = -1;
}
void FlatWndProc::setWindowBackground( HWND hwnd, int r, int g, int b ) {
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
if( fwp == NULL )
return;
// delete old background brush
if( fwp->background != NULL )
::DeleteObject( fwp->background );
// create new background brush
fwp->background = ::CreateSolidBrush( RGB( r, g, b ) );
}
LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
if( fwp == NULL )
return 0;
return fwp->WindowProc( hwnd, uMsg, wParam, lParam );
}
@@ -204,12 +229,16 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
wParam = wmSizeWParam;
break;
case WM_ERASEBKGND:
return WmEraseBkgnd( hwnd, uMsg, wParam, lParam );
case WM_DESTROY:
return WmDestroy( hwnd, uMsg, wParam, lParam );
}
return ::CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam );
}
/**
* Handle WM_DESTROY
*
@@ -223,6 +252,8 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
// cleanup
getEnv()->DeleteGlobalRef( obj );
if( background != NULL )
::DeleteObject( background );
hwndMap->remove( hwnd );
delete this;
@@ -230,6 +261,23 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam );
}
/**
* Handle WM_ERASEBKGND
*
* https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd
*/
LRESULT FlatWndProc::WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ) {
if( background == NULL )
return FALSE;
// fill background
HDC hdc = (HDC) wParam;
RECT rect;
::GetClientRect( hwnd, &rect );
::FillRect( hdc, &rect, background );
return TRUE;
}
/**
* Handle WM_NCCALCSIZE
*

View File

@@ -26,6 +26,7 @@ public:
static HWND install( JNIEnv *env, jobject obj, jobject window );
static void uninstall( JNIEnv *env, jobject obj, HWND hwnd );
static void updateFrame( HWND hwnd, int state );
static void setWindowBackground( HWND hwnd, int r, int g, int b );
private:
static int initialized;
@@ -41,6 +42,7 @@ private:
HWND hwnd;
WNDPROC defaultWndProc;
int wmSizeWParam;
HBRUSH background;
FlatWndProc();
static void initIDs( JNIEnv *env, jobject obj );
@@ -48,6 +50,7 @@ private:
static LRESULT CALLBACK StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );

View File

@@ -39,6 +39,14 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
(JNIEnv *, jobject, jlong, jint);
/*
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
* Method: setWindowBackground
* Signature: (JIII)V
*/
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
(JNIEnv *, jobject, jlong, jint, jint, jint);
/*
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
* Method: showWindow

View File

@@ -42,3 +42,18 @@ JXTitledPanel.borderColor = $Button.borderColor
JXTitledPanel.titleBackground = $TaskPane.titleBackgroundGradientStart
JXTitledPanel.titleForeground = $TaskPane.titleForeground
JXTitledPanel.captionInsets = 4,10,4,10
#---- SearchField ----
SearchField.icon = com.formdev.flatlaf.icons.FlatSearchIcon
SearchField.rolloverIcon = lazy(SearchField.icon)
SearchField.pressedIcon = lazy(SearchField.icon)
SearchField.popupIcon = com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon
SearchField.popupRolloverIcon = lazy(SearchField.popupIcon)
SearchField.popupPressedIcon = lazy(SearchField.popupIcon)
SearchField.clearIcon = com.formdev.flatlaf.icons.FlatClearIcon
SearchField.clearRolloverIcon = lazy(SearchField.clearIcon)
SearchField.clearPressedIcon = lazy(SearchField.clearIcon)

View File

@@ -879,6 +879,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ----
Separator.background #3c3f41 javax.swing.plaf.ColorUIResource [UI]
@@ -1249,6 +1268,7 @@ ToolBar.dockingBackground #3c3f41 javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #3c3f41 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #888888 javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons false
ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #adadad javax.swing.plaf.ColorUIResource [UI]

View File

@@ -884,6 +884,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ----
Separator.background #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
@@ -1254,6 +1273,7 @@ ToolBar.dockingBackground #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #000000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons false
ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI]

View File

@@ -194,6 +194,7 @@ ComboBox.buttonBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonDarkShadow #696969 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonDisabledArrowColor #ababab javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonEditableBackground #cccccc javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonFocusedBackground #ffff00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonHighlight #ffffff javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonPressedArrowColor #0000ff javax.swing.plaf.ColorUIResource [UI]
@@ -202,6 +203,7 @@ ComboBox.buttonStyle auto
ComboBox.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
ComboBox.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI]
ComboBox.editorColumns 0
ComboBox.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
ComboBox.font [active] $defaultFont [UI]
ComboBox.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ComboBox.isEnterSelectablePopup false
@@ -209,6 +211,7 @@ ComboBox.maximumRowCount 15
ComboBox.minimumWidth 72
ComboBox.noActionOnKeyNavigation false
ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI]
ComboBox.popupBackground #ffffcc javax.swing.plaf.ColorUIResource [UI]
ComboBox.selectionBackground #00aa00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.selectionForeground #ffff00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.timeFactor 1000
@@ -265,6 +268,7 @@ EditorPane.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
EditorPane.caretBlinkRate 500
EditorPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
EditorPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
EditorPane.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
EditorPane.font [active] $defaultFont [UI]
EditorPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
EditorPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -304,6 +308,7 @@ FormattedTextField.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.F
FormattedTextField.caretBlinkRate 500
FormattedTextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.font [active] $defaultFont [UI]
FormattedTextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -700,6 +705,7 @@ PasswordField.caretBlinkRate 500
PasswordField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
PasswordField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
PasswordField.echoChar '\u2022'
PasswordField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
PasswordField.font [active] $defaultFont [UI]
PasswordField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
PasswordField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -877,6 +883,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ----
Separator.background #ccffcc javax.swing.plaf.ColorUIResource [UI]
@@ -935,6 +960,7 @@ Spinner.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
Spinner.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI]
Spinner.editorAlignment 11
Spinner.editorBorderPainted false
Spinner.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
Spinner.font [active] $defaultFont [UI]
Spinner.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
Spinner.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI]
@@ -1111,6 +1137,7 @@ TextArea.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
TextArea.caretBlinkRate 500
TextArea.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextArea.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextArea.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextArea.font [active] $defaultFont [UI]
TextArea.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextArea.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -1136,6 +1163,7 @@ TextField.caretBlinkRate 500
TextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextField.darkShadow #696969 javax.swing.plaf.ColorUIResource [UI]
TextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextField.font [active] $defaultFont [UI]
TextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextField.highlight #ffffff javax.swing.plaf.ColorUIResource [UI]
@@ -1157,6 +1185,7 @@ TextPane.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
TextPane.caretBlinkRate 500
TextPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextPane.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextPane.font [active] $defaultFont [UI]
TextPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -1253,6 +1282,7 @@ ToolBar.dockingBackground #ccffcc javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #ccffcc javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #000088 javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons true
ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI]

View File

@@ -51,6 +51,7 @@ public class FlatBaselineTest
JFormattedTextField formattedTextField1 = new JFormattedTextField();
JPasswordField passwordField1 = new JPasswordField();
JComboBox<String> comboBox1 = new JComboBox<>();
JComboBox<String> comboBox2 = new JComboBox<>();
JSpinner spinner1 = new JSpinner();
JLabel label6 = new JLabel();
JScrollPane scrollPane1 = new JScrollPane();
@@ -88,7 +89,7 @@ public class FlatBaselineTest
//======== this ========
setLayout(new MigLayout(
"insets dialog,hidemode 3,debug",
"insets dialog,hidemode 3",
// columns
"[fill]" +
"[fill]" +
@@ -96,6 +97,7 @@ public class FlatBaselineTest
"[fill]" +
"[fill]" +
"[fill]" +
"[fill]" +
"[fill]",
// rows
"[]" +
@@ -130,7 +132,7 @@ public class FlatBaselineTest
//---- textField4 ----
textField4.setText("Dext field");
add(textField4, "cell 6 0");
add(textField4, "cell 7 0");
//---- label2 ----
label2.setText("Dext");
@@ -147,8 +149,20 @@ public class FlatBaselineTest
//---- passwordField1 ----
passwordField1.setText("Dext");
add(passwordField1, "cell 3 1");
//---- comboBox1 ----
comboBox1.setModel(new DefaultComboBoxModel<>(new String[] {
"Dext"
}));
add(comboBox1, "cell 4 1");
add(spinner1, "cell 5 1");
//---- comboBox2 ----
comboBox2.setModel(new DefaultComboBoxModel<>(new String[] {
"Dext"
}));
comboBox2.setEditable(true);
add(comboBox2, "cell 5 1");
add(spinner1, "cell 6 1");
//---- label6 ----
label6.setText("Dext");
@@ -171,7 +185,7 @@ public class FlatBaselineTest
//---- textField2 ----
textField2.setText("Dext field");
add(textField2, "cell 6 2");
add(textField2, "cell 7 2");
//---- label7 ----
label7.setText("Dext");
@@ -230,18 +244,18 @@ public class FlatBaselineTest
//---- textField3 ----
textField3.setText("Dext field");
add(textField3, "cell 6 3");
add(textField3, "cell 7 3");
//---- label3 ----
label3.setText("Dext");
add(label3, "cell 0 4");
add(slider1, "cell 1 4 6 1");
add(slider1, "cell 1 4 7 1");
//---- slider6 ----
slider6.setPaintTicks(true);
slider6.setMajorTickSpacing(25);
slider6.setMinorTickSpacing(5);
add(slider6, "cell 1 4 6 1");
add(slider6, "cell 1 4 7 1");
//---- label8 ----
label8.setText("Dext");
@@ -251,14 +265,14 @@ public class FlatBaselineTest
slider7.setPaintLabels(true);
slider7.setMajorTickSpacing(25);
slider7.setMinorTickSpacing(5);
add(slider7, "cell 1 5 6 1");
add(slider7, "cell 1 5 7 1");
//---- slider8 ----
slider8.setPaintLabels(true);
slider8.setPaintTicks(true);
slider8.setMajorTickSpacing(25);
slider8.setMinorTickSpacing(5);
add(slider8, "cell 1 5 6 1");
add(slider8, "cell 1 5 7 1");
//---- label4 ----
label4.setText("Dext");
@@ -266,13 +280,13 @@ public class FlatBaselineTest
//---- progressBar1 ----
progressBar1.setValue(30);
add(progressBar1, "cell 1 6 6 1");
add(progressBar1, "cell 1 6 7 1");
//---- progressBar3 ----
progressBar3.setStringPainted(true);
progressBar3.setValue(30);
add(progressBar3, "cell 1 6 6 1");
add(separator1, "cell 1 6 6 1");
add(progressBar3, "cell 1 6 7 1");
add(separator1, "cell 1 6 7 1");
//---- label5 ----
label5.setText("Dext");
@@ -280,26 +294,26 @@ public class FlatBaselineTest
//---- slider2 ----
slider2.setOrientation(SwingConstants.VERTICAL);
add(slider2, "cell 1 7 6 1");
add(slider2, "cell 1 7 7 1");
//---- slider3 ----
slider3.setOrientation(SwingConstants.VERTICAL);
slider3.setPaintTicks(true);
slider3.setMajorTickSpacing(25);
slider3.setMinorTickSpacing(5);
add(slider3, "cell 1 7 6 1");
add(slider3, "cell 1 7 7 1");
//---- progressBar2 ----
progressBar2.setOrientation(SwingConstants.VERTICAL);
progressBar2.setValue(30);
add(progressBar2, "cell 1 7 6 1");
add(progressBar2, "cell 1 7 7 1");
//---- progressBar4 ----
progressBar4.setOrientation(SwingConstants.VERTICAL);
progressBar4.setStringPainted(true);
progressBar4.setValue(30);
add(progressBar4, "cell 1 7 6 1");
add(hSpacer1, "cell 1 7 6 1,growx");
add(progressBar4, "cell 1 7 7 1");
add(hSpacer1, "cell 1 7 7 1,growx");
//---- label9 ----
label9.setText("Dext");
@@ -310,7 +324,7 @@ public class FlatBaselineTest
slider4.setPaintLabels(true);
slider4.setMajorTickSpacing(25);
slider4.setMinorTickSpacing(5);
add(slider4, "cell 1 8 6 1");
add(slider4, "cell 1 8 7 1");
//---- slider5 ----
slider5.setOrientation(SwingConstants.VERTICAL);
@@ -318,8 +332,8 @@ public class FlatBaselineTest
slider5.setPaintTicks(true);
slider5.setMajorTickSpacing(25);
slider5.setMinorTickSpacing(5);
add(slider5, "cell 1 8 6 1");
add(hSpacer2, "cell 1 8 6 1,growx");
add(slider5, "cell 1 8 7 1");
add(hSpacer2, "cell 1 8 7 1,growx");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -7,8 +7,8 @@ new FormModel {
"JavaCodeGenerator.defaultVariableLocal": true
}
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3,debug"
"$columnConstraints": "[fill][fill][fill][fill][fill][fill][fill]"
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][fill][fill][fill][fill][fill][fill]"
"$rowConstraints": "[][][50][::80][][][][][]"
} ) {
name: "this"
@@ -46,7 +46,7 @@ new FormModel {
name: "textField4"
"text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 0"
"value": "cell 7 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
@@ -74,16 +74,33 @@ new FormModel {
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox1"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "Dext"
addElement( "Dext" )
}
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 1"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox2"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "Dext"
addElement( "Dext" )
}
"editable": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 1"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 1"
"value": "cell 6 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6"
@@ -112,7 +129,7 @@ new FormModel {
name: "textField2"
"text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 2"
"value": "cell 7 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label7"
@@ -184,7 +201,7 @@ new FormModel {
name: "textField3"
"text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3"
"value": "cell 7 3"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
@@ -195,7 +212,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 6 1"
"value": "cell 1 4 7 1"
} )
add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider6"
@@ -203,7 +220,7 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 6 1"
"value": "cell 1 4 7 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label8"
@@ -217,7 +234,7 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 6 1"
"value": "cell 1 5 7 1"
} )
add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider8"
@@ -226,7 +243,7 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 6 1"
"value": "cell 1 5 7 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
@@ -238,19 +255,19 @@ new FormModel {
name: "progressBar1"
"value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1"
"value": "cell 1 6 7 1"
} )
add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar3"
"stringPainted": true
"value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1"
"value": "cell 1 6 7 1"
} )
add( new FormComponent( "javax.swing.JSeparator" ) {
name: "separator1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1"
"value": "cell 1 6 7 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label5"
@@ -262,7 +279,7 @@ new FormModel {
name: "slider2"
"orientation": 1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1"
"value": "cell 1 7 7 1"
} )
add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider3"
@@ -271,14 +288,14 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1"
"value": "cell 1 7 7 1"
} )
add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar2"
"orientation": 1
"value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1"
"value": "cell 1 7 7 1"
} )
add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar4"
@@ -286,12 +303,12 @@ new FormModel {
"stringPainted": true
"value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1"
"value": "cell 1 7 7 1"
} )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1,growx"
"value": "cell 1 7 7 1,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label9"
@@ -306,7 +323,7 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1"
"value": "cell 1 8 7 1"
} )
add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider5"
@@ -316,12 +333,12 @@ new FormModel {
"majorTickSpacing": 25
"minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1"
"value": "cell 1 8 7 1"
} )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1,growx"
"value": "cell 1 8 7 1,growx"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )

View File

@@ -20,6 +20,7 @@ import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -42,9 +43,24 @@ public class FlatCustomBordersTest
} );
}
@SuppressWarnings( "unchecked" )
FlatCustomBordersTest() {
initComponents();
applyCustomBorders();
applySpecialComboBoxRenderers();
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>( new String[] {
"text",
"123",
"4567",
"abc",
"def"
} );
for( Component c : getComponents() ) {
if( c instanceof JComboBox )
((JComboBox<String>)c).setModel( model );
}
}
@Override
@@ -99,6 +115,40 @@ public class FlatCustomBordersTest
applyCustomComboBoxEditorBorderWithIcon( comboBox20 );
applyCustomComboBoxEditorBorder( comboBox21, null );
applyCustomComboBoxEditorBorder( comboBox22, null );
applyCustomComboBoxRendererBorder( comboBox23 );
applyCustomComboBoxRendererBorder( comboBox24 );
applyCustomComboBoxRendererBorderWithIcon( comboBox25 );
applyCustomComboBoxRendererBorderWithIcon( comboBox26 );
applyCustomComboBoxRendererBorder( comboBox27, null );
applyCustomComboBoxRendererBorder( comboBox28, null );
}
@SuppressWarnings( "unchecked" )
private void applySpecialComboBoxRenderers() {
BasicComboBoxRenderer sharedRenderer = new BasicComboBoxRenderer();
sharedRenderer.setBorder( new LineBorder( ORANGE, UIScale.scale( 2 ) ) );
comboBox29.setRenderer( sharedRenderer );
comboBox30.setRenderer( sharedRenderer );
comboBox31.setRenderer( new ListCellRenderer<String>() {
JLabel l1 = new JLabel();
JLabel l2 = new JLabel();
@Override
public Component getListCellRendererComponent( JList<? extends String> list,
String value, int index, boolean isSelected, boolean cellHasFocus )
{
JLabel l = (index % 2 == 0) ? l1 : l2;
l.setText( (value != null) ? value.toString() : "" );
l.setBorder( new LineBorder( (index % 2 == 0) ? GREEN : RED, UIScale.scale( 2 ) ) );
l.setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() );
l.setForeground( isSelected ? list.getSelectionForeground() : list.getForeground() );
l.setFont( list.getFont() );
l.setOpaque( true );
return l;
}
} );
}
private void applyCustomInsideBorder( JComponent c, String uiKey ) {
@@ -110,7 +160,7 @@ public class FlatCustomBordersTest
}
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 3 ) ) );
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
}
private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) {
@@ -129,6 +179,21 @@ public class FlatCustomBordersTest
} );
}
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
}
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new BorderWithIcon() );
}
@SuppressWarnings( "unchecked" )
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox, Border border ) {
BasicComboBoxRenderer customRenderer = new BasicComboBoxRenderer();
customRenderer.setBorder( border );
comboBox.setRenderer( customRenderer );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel();
@@ -152,10 +217,16 @@ public class FlatCustomBordersTest
comboBox2 = new JComboBox<>();
comboBox3 = new JComboBox<>();
comboBox4 = new JComboBox<>();
comboBox23 = new JComboBox<>();
comboBox25 = new JComboBox<>();
comboBox27 = new JComboBox<>();
comboBox5 = new JComboBox<>();
comboBox6 = new JComboBox<>();
comboBox7 = new JComboBox<>();
comboBox8 = new JComboBox<>();
comboBox24 = new JComboBox<>();
comboBox26 = new JComboBox<>();
comboBox28 = new JComboBox<>();
comboBox9 = new JComboBox<>();
comboBox10 = new JComboBox<>();
comboBox11 = new JComboBox<>();
@@ -188,6 +259,11 @@ public class FlatCustomBordersTest
textField6 = new JTextField();
textField7 = new JTextField();
textField8 = new JTextField();
label11 = new JLabel();
label12 = new JLabel();
comboBox29 = new JComboBox<>();
comboBox30 = new JComboBox<>();
comboBox31 = new JComboBox<>();
//======== this ========
setLayout(new MigLayout(
@@ -212,6 +288,8 @@ public class FlatCustomBordersTest
"[]" +
"[]" +
"[]" +
"[]para" +
"[]" +
"[]"));
//---- label1 ----
@@ -289,6 +367,9 @@ public class FlatCustomBordersTest
add(comboBox2, "cell 2 3");
add(comboBox3, "cell 3 3");
add(comboBox4, "cell 4 3");
add(comboBox23, "cell 5 3");
add(comboBox25, "cell 6 3");
add(comboBox27, "cell 7 3");
//---- comboBox5 ----
comboBox5.putClientProperty("JComponent.roundRect", true);
@@ -306,6 +387,18 @@ public class FlatCustomBordersTest
comboBox8.putClientProperty("JComponent.roundRect", true);
add(comboBox8, "cell 4 4");
//---- comboBox24 ----
comboBox24.putClientProperty("JComponent.roundRect", true);
add(comboBox24, "cell 5 4");
//---- comboBox26 ----
comboBox26.putClientProperty("JComponent.roundRect", true);
add(comboBox26, "cell 6 4");
//---- comboBox28 ----
comboBox28.putClientProperty("JComponent.roundRect", true);
add(comboBox28, "cell 7 4");
//---- comboBox9 ----
comboBox9.setEditable(true);
add(comboBox9, "cell 1 5");
@@ -435,6 +528,17 @@ public class FlatCustomBordersTest
textField8.putClientProperty("JComponent.roundRect", true);
textField8.setText("text");
add(textField8, "cell 4 10");
//---- label11 ----
label11.setText("JComboBox with shared renderer:");
add(label11, "cell 1 11 2 1");
//---- label12 ----
label12.setText("JComboBox with renderer that uses varying components:");
add(label12, "cell 3 11 3 1");
add(comboBox29, "cell 1 12");
add(comboBox30, "cell 2 12");
add(comboBox31, "cell 3 12");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
@@ -460,10 +564,16 @@ public class FlatCustomBordersTest
private JComboBox<String> comboBox2;
private JComboBox<String> comboBox3;
private JComboBox<String> comboBox4;
private JComboBox<String> comboBox23;
private JComboBox<String> comboBox25;
private JComboBox<String> comboBox27;
private JComboBox<String> comboBox5;
private JComboBox<String> comboBox6;
private JComboBox<String> comboBox7;
private JComboBox<String> comboBox8;
private JComboBox<String> comboBox24;
private JComboBox<String> comboBox26;
private JComboBox<String> comboBox28;
private JComboBox<String> comboBox9;
private JComboBox<String> comboBox10;
private JComboBox<String> comboBox11;
@@ -496,6 +606,11 @@ public class FlatCustomBordersTest
private JTextField textField6;
private JTextField textField7;
private JTextField textField8;
private JLabel label11;
private JLabel label12;
private JComboBox<String> comboBox29;
private JComboBox<String> comboBox30;
private JComboBox<String> comboBox31;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class BorderWithIcon -----------------------------------------------
@@ -508,6 +623,9 @@ public class FlatCustomBordersTest
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
icon.paintIcon( c, g, x + width - icon.getIconWidth() - 2, y + ((height - icon.getIconHeight()) / 2) );
g.setColor( RED );
g.drawRect( x, y, width - 1, height - 1 );
}
@Override

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -6,7 +6,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][fill][fill][fill][fill][fill][fill][fill]"
"$rowConstraints": "[][][][][][][][][][][]"
"$rowConstraints": "[][][][][][][][][][][]para[][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -147,6 +147,30 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox23"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox25"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox27"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox5"
"$client.JComponent.roundRect": true
@@ -183,6 +207,33 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox24"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox26"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox28"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox9"
"editable": true
@@ -427,6 +478,42 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 10"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JComboBox with shared renderer:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label12"
"text": "JComboBox with renderer that uses varying components:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 11 3 1"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox29"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 12"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox30"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 12"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox31"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 12"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 915, 715 )

View File

@@ -89,6 +89,15 @@ public class FlatInternalFrameTest
};
internalFrame.setContentPane( panel );
if( minSizeCheckBox.isSelected() ) {
internalFrame.setMinimumSize( new Dimension( 300, 150 ) );
panel.add( new JLabel( "min 300,150" ) );
}
if( maxSizeCheckBox.isSelected() ) {
internalFrame.setMaximumSize( new Dimension( 400, 200 ) );
panel.add( new JLabel( "max 400,200" ) );
}
if( !palette.getComponentOrientation().isLeftToRight() )
internalFrame.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
@@ -123,6 +132,8 @@ public class FlatInternalFrameTest
maximizableCheckBox = new JCheckBox();
iconCheckBox = new FlatTriStateCheckBox();
menuBarCheckBox = new JCheckBox();
minSizeCheckBox = new JCheckBox();
maxSizeCheckBox = new JCheckBox();
titleLabel = new JLabel();
titleField = new JTextField();
createFrameButton = new JButton();
@@ -158,6 +169,8 @@ public class FlatInternalFrameTest
"[fill]0" +
"[]0" +
"[]0" +
"[]0" +
"[]0" +
"[]unrel" +
"[]unrel"));
@@ -189,18 +202,26 @@ public class FlatInternalFrameTest
menuBarCheckBox.setText("Menu Bar");
paletteContentPane.add(menuBarCheckBox, "cell 1 2");
//---- minSizeCheckBox ----
minSizeCheckBox.setText("Minimum size 300,150");
paletteContentPane.add(minSizeCheckBox, "cell 0 3 2 1,alignx left,growx 0");
//---- maxSizeCheckBox ----
maxSizeCheckBox.setText("Maximum size 400,200");
paletteContentPane.add(maxSizeCheckBox, "cell 0 4 2 1,alignx left,growx 0");
//---- titleLabel ----
titleLabel.setText("Frame title:");
paletteContentPane.add(titleLabel, "cell 0 3");
paletteContentPane.add(titleField, "cell 1 3");
paletteContentPane.add(titleLabel, "cell 0 5");
paletteContentPane.add(titleField, "cell 1 5");
//---- createFrameButton ----
createFrameButton.setText("Create Frame");
createFrameButton.addActionListener(e -> createInternalFrame());
paletteContentPane.add(createFrameButton, "cell 1 4,alignx right,growx 0");
paletteContentPane.add(createFrameButton, "cell 1 6,alignx right,growx 0");
}
desktopPane.add(palette, JLayeredPane.PALETTE_LAYER);
palette.setBounds(15, 25, 275, 185);
palette.setBounds(15, 25, 275, 275);
}
add(desktopPane, "cell 0 0,width 600,height 600");
@@ -234,6 +255,8 @@ public class FlatInternalFrameTest
private JCheckBox maximizableCheckBox;
private FlatTriStateCheckBox iconCheckBox;
private JCheckBox menuBarCheckBox;
private JCheckBox minSizeCheckBox;
private JCheckBox maxSizeCheckBox;
private JLabel titleLabel;
private JTextField titleField;
private JButton createFrameButton;

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -14,7 +14,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JInternalFrame", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]"
"$rowConstraints": "[fill]0[]0[]0[]unrel[]unrel"
"$rowConstraints": "[fill]0[]0[]0[]0[]0[]unrel[]unrel"
} ) {
name: "palette"
"visible": true
@@ -62,29 +62,41 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "minSizeCheckBox"
"text": "Minimum size 300,150"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "maxSizeCheckBox"
"text": "Maximum size 400,200"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "titleLabel"
"text": "Frame title:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
"value": "cell 0 5"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "titleField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
"value": "cell 1 5"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "createFrameButton"
"text": "Create Frame"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "createInternalFrame", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4,alignx right,growx 0"
"value": "cell 1 6,alignx right,growx 0"
} )
}, new FormLayoutConstraints( null ) {
"x": 15
"y": 25
"width": 275
"height": 185
"height": 275
"layer": 100
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {

View File

@@ -89,6 +89,10 @@ public class FlatOptionPaneTest
JPanel panel6 = new JPanel();
customOptionPane = new JOptionPane();
FlatOptionPaneTest.ShowDialogLinkLabel customShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
JLabel rightToLeftLabel = new JLabel();
JPanel panel10 = new JPanel();
JOptionPane rightToLeftOptionPane = new JOptionPane();
rightToLeftShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
//======== this ========
setBorder(BorderFactory.createEmptyBorder());
@@ -109,6 +113,7 @@ public class FlatOptionPaneTest
"[top]" +
"[top]" +
"[top]" +
"[top]" +
"[top]"));
//---- plainLabel ----
@@ -283,6 +288,28 @@ public class FlatOptionPaneTest
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
panel9.add(customShowDialogLabel, "cell 2 7");
//---- rightToLeftLabel ----
rightToLeftLabel.setText("Right-to-left:");
panel9.add(rightToLeftLabel, "cell 0 8");
//======== panel10 ========
{
panel10.setBorder(LineBorder.createGrayLineBorder());
panel10.setLayout(new BorderLayout());
//---- rightToLeftOptionPane ----
rightToLeftOptionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
rightToLeftOptionPane.setMessage("\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.\n\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.\n\n\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \n\u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.");
rightToLeftOptionPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
panel10.add(rightToLeftOptionPane, BorderLayout.CENTER);
}
panel9.add(panel10, "cell 1 8");
//---- rightToLeftShowDialogLabel ----
rightToLeftShowDialogLabel.setOptionPane(rightToLeftOptionPane);
rightToLeftShowDialogLabel.setTitleLabel(rightToLeftLabel);
panel9.add(rightToLeftShowDialogLabel, "cell 2 8");
}
setViewportView(panel9);
// JFormDesigner - End of component initialization //GEN-END:initComponents
@@ -293,6 +320,7 @@ public class FlatOptionPaneTest
private FlatOptionPaneTest.ShowDialogLinkLabel errorShowDialogLabel;
private FlatOptionPaneTest.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
private FlatOptionPaneTest.ShowDialogLinkLabel rightToLeftShowDialogLabel;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class ShowDialogLinkLabel ------------------------------------------
@@ -315,9 +343,15 @@ public class FlatOptionPaneTest
}
private void showDialog() {
Component parent = SwingUtilities.windowForComponent( this );
// use optionPane as parent if component orientation is different
if( parent.getComponentOrientation().isLeftToRight() != optionPane.getComponentOrientation().isLeftToRight() )
parent = optionPane;
if( optionPane.getWantsInput() ) {
JOptionPane.showInputDialog(
getParent(),
parent,
optionPane.getMessage(),
titleLabel.getText() + " Title",
optionPane.getMessageType(),
@@ -326,7 +360,7 @@ public class FlatOptionPaneTest
null );
} else {
JOptionPane.showOptionDialog(
getParent(),
parent,
optionPane.getMessage(),
titleLabel.getText() + " Title",
optionPane.getOptionType(),

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -12,7 +12,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "flowy,ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top]"
"$rowConstraints": "[top][top][top][top][top][top][top][top][top]"
} ) {
name: "panel9"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -240,10 +240,40 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 7"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightToLeftLabel"
"text": "Right-to-left:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
name: "panel10"
"border": #LineBorder0
add( new FormComponent( "javax.swing.JOptionPane" ) {
name: "rightToLeftOptionPane"
"messageType": 1
"message": "المادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء.\nالمادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء.\n\nالمادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة \nوالحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء."
"componentOrientation": sfield java.awt.ComponentOrientation RIGHT_TO_LEFT
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatOptionPaneTest$ShowDialogLinkLabel" ) {
name: "rightToLeftShowDialogLabel"
"optionPane": new FormReference( "rightToLeftOptionPane" )
"titleLabel": new FormReference( "rightToLeftLabel" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 8"
} )
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 840, 900 )
"size": new java.awt.Dimension( 895, 1080 )
} )
}
}

View File

@@ -0,0 +1,361 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.*;
import java.awt.Point;
import javax.swing.*;
import com.formdev.flatlaf.util.Animator;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatPopupTest
extends FlatTestPanel
{
private Popup popup;
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatPopupTest" );
frame.showFrame( FlatPopupTest::new );
} );
}
FlatPopupTest() {
initComponents();
}
private void showPopupMenu() {
popupMenu1.show( showPopupMenuButton, 0, showPopupMenuButton.getHeight() );
}
private void showLargePopupMenu() {
popupMenu2.show( showLargePopupMenuButton, 0, showLargePopupMenuButton.getHeight() );
}
private void showPopup() {
showPopup( 0, 0 );
}
private void showPopup( int xoffset, int yoffset ) {
hidePopup();
Point pt = showPopupButton.getLocationOnScreen();
popup = PopupFactory.getSharedInstance().getPopup( showPopupButton, popupPanel,
pt.x + xoffset, pt.y + showPopupButton.getHeight() + yoffset );
popup.show();
}
private void hidePopup() {
if( popup == null )
return;
popup.hide();
popup = null;
}
private void movePopupDown() {
movePopup( 0, 600 );
}
private void movePopupRight() {
movePopup( 600, 0 );
}
private void movePopup( int xoffset, int yoffset ) {
showPopup();
Animator animator = new Animator( 1000, fraction -> {
System.out.println(fraction);
showPopup( (int) (fraction * xoffset), (int) (fraction * yoffset) );
} );
animator.start();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel();
label2 = new JLabel();
showPopupMenuButton = new JButton();
showLargePopupMenuButton = new JButton();
showPopupButton = new JButton();
hidePopupButton = new JButton();
movePopupDownButton = new JButton();
movePopuprightButton = new JButton();
label4 = new JLabel();
popupMenu1 = new JPopupMenu();
menuItem1 = new JMenuItem();
menuItem2 = new JMenuItem();
menu1 = new JMenu();
menuItem3 = new JMenuItem();
menuItem4 = new JMenuItem();
popupPanel = new JPanel();
label3 = new JLabel();
popupMenu2 = new JPopupMenu();
menuItem5 = new JMenuItem();
menuItem6 = new JMenuItem();
menuItem7 = new JMenuItem();
menuItem8 = new JMenuItem();
menuItem9 = new JMenuItem();
menuItem10 = new JMenuItem();
menuItem11 = new JMenuItem();
menuItem12 = new JMenuItem();
menuItem13 = new JMenuItem();
menuItem14 = new JMenuItem();
menuItem15 = new JMenuItem();
menuItem16 = new JMenuItem();
menuItem17 = new JMenuItem();
menuItem18 = new JMenuItem();
menuItem19 = new JMenuItem();
menuItem20 = new JMenuItem();
menuItem21 = new JMenuItem();
menu2 = new JMenu();
menuItem22 = new JMenuItem();
menuItem23 = new JMenuItem();
//======== this ========
setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
// columns
"[fill]" +
"[fill]" +
"[fill]" +
"[fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- label1 ----
label1.setText("Label with light-weight tooltip");
label1.setToolTipText("some tip");
add(label1, "cell 0 0");
//---- label2 ----
label2.setText("Label with heavy-weight tooltip");
label2.setToolTipText("some tip\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25");
add(label2, "cell 0 1");
//---- showPopupMenuButton ----
showPopupMenuButton.setText("show light-weight JPopupMenu");
showPopupMenuButton.addActionListener(e -> showPopupMenu());
add(showPopupMenuButton, "cell 0 2");
//---- showLargePopupMenuButton ----
showLargePopupMenuButton.setText("show heavy-weight JPopupMenu");
showLargePopupMenuButton.addActionListener(e -> showLargePopupMenu());
add(showLargePopupMenuButton, "cell 0 3");
//---- showPopupButton ----
showPopupButton.setText("show medium-weight popup");
showPopupButton.addActionListener(e -> showPopup());
add(showPopupButton, "cell 0 4");
//---- hidePopupButton ----
hidePopupButton.setText("hide");
hidePopupButton.addActionListener(e -> hidePopup());
add(hidePopupButton, "cell 1 4");
//---- movePopupDownButton ----
movePopupDownButton.setText("move down");
movePopupDownButton.addActionListener(e -> movePopupDown());
add(movePopupDownButton, "cell 2 4");
//---- movePopuprightButton ----
movePopuprightButton.setText("move right");
movePopuprightButton.addActionListener(e -> movePopupRight());
add(movePopuprightButton, "cell 3 4");
//---- label4 ----
label4.setText("(switches to heavy-weight when moving outside of window)");
add(label4, "cell 0 5 4 1,alignx right,growx 0");
//======== popupMenu1 ========
{
//---- menuItem1 ----
menuItem1.setText("text");
popupMenu1.add(menuItem1);
//---- menuItem2 ----
menuItem2.setText("text");
popupMenu1.add(menuItem2);
//======== menu1 ========
{
menu1.setText("text");
//---- menuItem3 ----
menuItem3.setText("text");
menu1.add(menuItem3);
//---- menuItem4 ----
menuItem4.setText("text");
menu1.add(menuItem4);
}
popupMenu1.add(menu1);
}
//======== popupPanel ========
{
popupPanel.setBackground(new Color(153, 255, 153));
popupPanel.setLayout(new MigLayout(
"hidemode 3",
// columns
"[fill]",
// rows
"[]"));
//---- label3 ----
label3.setText("popup");
popupPanel.add(label3, "cell 0 0");
}
//======== popupMenu2 ========
{
//---- menuItem5 ----
menuItem5.setText("text");
popupMenu2.add(menuItem5);
//---- menuItem6 ----
menuItem6.setText("text");
popupMenu2.add(menuItem6);
//---- menuItem7 ----
menuItem7.setText("text");
popupMenu2.add(menuItem7);
//---- menuItem8 ----
menuItem8.setText("text");
popupMenu2.add(menuItem8);
//---- menuItem9 ----
menuItem9.setText("text");
popupMenu2.add(menuItem9);
//---- menuItem10 ----
menuItem10.setText("text");
popupMenu2.add(menuItem10);
//---- menuItem11 ----
menuItem11.setText("text");
popupMenu2.add(menuItem11);
//---- menuItem12 ----
menuItem12.setText("text");
popupMenu2.add(menuItem12);
//---- menuItem13 ----
menuItem13.setText("text");
popupMenu2.add(menuItem13);
//---- menuItem14 ----
menuItem14.setText("text");
popupMenu2.add(menuItem14);
//---- menuItem15 ----
menuItem15.setText("text");
popupMenu2.add(menuItem15);
//---- menuItem16 ----
menuItem16.setText("text");
popupMenu2.add(menuItem16);
//---- menuItem17 ----
menuItem17.setText("text");
popupMenu2.add(menuItem17);
//---- menuItem18 ----
menuItem18.setText("text");
popupMenu2.add(menuItem18);
//---- menuItem19 ----
menuItem19.setText("text");
popupMenu2.add(menuItem19);
//---- menuItem20 ----
menuItem20.setText("text");
popupMenu2.add(menuItem20);
//---- menuItem21 ----
menuItem21.setText("text");
popupMenu2.add(menuItem21);
//======== menu2 ========
{
menu2.setText("text");
//---- menuItem22 ----
menuItem22.setText("text");
menu2.add(menuItem22);
//---- menuItem23 ----
menuItem23.setText("text");
menu2.add(menuItem23);
}
popupMenu2.add(menu2);
}
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel label1;
private JLabel label2;
private JButton showPopupMenuButton;
private JButton showLargePopupMenuButton;
private JButton showPopupButton;
private JButton hidePopupButton;
private JButton movePopupDownButton;
private JButton movePopuprightButton;
private JLabel label4;
private JPopupMenu popupMenu1;
private JMenuItem menuItem1;
private JMenuItem menuItem2;
private JMenu menu1;
private JMenuItem menuItem3;
private JMenuItem menuItem4;
private JPanel popupPanel;
private JLabel label3;
private JPopupMenu popupMenu2;
private JMenuItem menuItem5;
private JMenuItem menuItem6;
private JMenuItem menuItem7;
private JMenuItem menuItem8;
private JMenuItem menuItem9;
private JMenuItem menuItem10;
private JMenuItem menuItem11;
private JMenuItem menuItem12;
private JMenuItem menuItem13;
private JMenuItem menuItem14;
private JMenuItem menuItem15;
private JMenuItem menuItem16;
private JMenuItem menuItem17;
private JMenuItem menuItem18;
private JMenuItem menuItem19;
private JMenuItem menuItem20;
private JMenuItem menuItem21;
private JMenu menu2;
private JMenuItem menuItem22;
private JMenuItem menuItem23;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -0,0 +1,206 @@
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][fill][fill]"
"$rowConstraints": "[][][][][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Label with light-weight tooltip"
"toolTipText": "some tip"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
"text": "Label with heavy-weight tooltip"
"toolTipText": "some tip\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showPopupMenuButton"
"text": "show light-weight JPopupMenu"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showPopupMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showLargePopupMenuButton"
"text": "show heavy-weight JPopupMenu"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showLargePopupMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showPopupButton"
"text": "show medium-weight popup"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showPopup", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "hidePopupButton"
"text": "hide"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hidePopup", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "movePopupDownButton"
"text": "move down"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopupDown", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "movePopuprightButton"
"text": "move right"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopupRight", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "(switches to heavy-weight when moving outside of window)"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5 4 1,alignx right,growx 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 490, 350 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem1"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem2"
"text": "text"
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu1"
"text": "text"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem3"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem4"
"text": "text"
} )
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 395 )
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill]"
"$rowConstraints": "[]"
} ) {
name: "popupPanel"
"background": new java.awt.Color( 153, 255, 153, 255 )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "popup"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 225, 395 )
"size": new java.awt.Dimension( 200, 200 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu2"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem5"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem6"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem7"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem8"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem9"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem10"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem11"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem12"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem13"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem14"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem15"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem16"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem17"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem18"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem19"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem20"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem21"
"text": "text"
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu2"
"text": "text"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem22"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem23"
"text": "text"
} )
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 505 )
} )
}
}

View File

@@ -0,0 +1,236 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.demo.DemoPrefs;
import com.formdev.flatlaf.extras.FlatInspector;
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.MigLayout;
/**
* @author Karl Tauber
*/
public class FlatSingleComponentTest
extends JFrame
{
private static final String PREFS_ROOT_PATH = "/flatlaf-test-single";
private static final String KEY_SCALE_FACTOR = "scaleFactor";
private final JLabel infoLabel;
private JComponent createSingleComponent() {
return new JButton( "hello" );
}
public static void main( String[] args ) {
DemoPrefs.init( PREFS_ROOT_PATH );
// set scale factor
if( System.getProperty( FlatSystemProperties.UI_SCALE ) == null ) {
String scaleFactor = DemoPrefs.getState().get( KEY_SCALE_FACTOR, null );
if( scaleFactor != null )
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
}
// install inspectors
FlatInspector.install( "ctrl shift alt X" );
FlatUIDefaultsInspector.install( "ctrl shift alt Y" );
// disable animated Laf change
System.setProperty( "flatlaf.animatedLafChange", "false" );
// test loading custom defaults from package
FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.customdefaults" );
// set look and feel
DemoPrefs.setupLaf( args );
// create and show frame
new FlatSingleComponentTest();
}
private FlatSingleComponentTest() {
super( "FlatSingleComponentTest" );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JComponent c = createSingleComponent();
Container contentPane = getContentPane();
contentPane.setLayout( new MigLayout( null, null, "[][grow]") );
contentPane.add( c );
infoLabel = new JLabel();
infoLabel.setEnabled( false );
contentPane.add( infoLabel, "newline, aligny bottom,growy 0" );
// register F1, F2, ... keys to switch to Light, Dark or other LaFs
registerSwitchToLookAndFeel( "F1", FlatLightLaf.class.getName() );
registerSwitchToLookAndFeel( "F2", FlatDarkLaf.class.getName() );
registerSwitchToLookAndFeel( "F3", FlatIntelliJLaf.class.getName() );
registerSwitchToLookAndFeel( "F4", FlatDarculaLaf.class.getName() );
registerSwitchToLookAndFeel( "F8", FlatTestLaf.class.getName() );
if( SystemInfo.isWindows )
registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
else if( SystemInfo.isMacOS )
registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" );
else if( SystemInfo.isLinux )
registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" );
registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() );
registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() );
// register Alt+F1, F2, ... keys to change scale factor
registerScaleFactor( "alt F1", "1" );
registerScaleFactor( "alt F2", "1.25" );
registerScaleFactor( "alt F3", "1.5" );
registerScaleFactor( "alt F4", "1.75" );
registerScaleFactor( "alt F5", "2" );
registerScaleFactor( "alt F6", "2.5" );
registerScaleFactor( "alt F7", "3" );
registerScaleFactor( "alt F8", "3.5" );
registerScaleFactor( "alt F9", "4" );
registerScaleFactor( "alt F10", "5" );
registerScaleFactor( "alt F11", "6" );
registerScaleFactor( "alt F12", null );
// register ESC key to close frame
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
dispose();
},
KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
// update info
addWindowListener( new WindowAdapter() {
@Override
public void windowOpened( WindowEvent e ) {
updateInfo();
}
} );
// update info when moved to another screen
addComponentListener( new ComponentAdapter() {
@Override
public void componentMoved( ComponentEvent e ) {
updateInfo();
}
} );
UIManager.addPropertyChangeListener( e -> {
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
EventQueue.invokeLater( () -> {
// update info because user scale factor may change
updateInfo();
} );
}
} );
UIScale.addPropertyChangeListener( e -> {
// update info because user scale factor may change
updateInfo();
} );
setMinimumSize( UIScale.scale( new Dimension( 300, 150 ) ) );
pack();
setLocationRelativeTo( null );
setVisible( true );
}
private void updateInfo() {
double systemScaleFactor = UIScale.getSystemScaleFactor( getGraphicsConfiguration() );
float userScaleFactor = UIScale.getUserScaleFactor();
infoLabel.setText( " (Java " + System.getProperty( "java.version" )
+ (systemScaleFactor != 1 ? ("; system scale factor " + systemScaleFactor) : "")
+ (userScaleFactor != 1 ? ("; user scale factor " + userScaleFactor) : "")
+ (systemScaleFactor == 1 && userScaleFactor == 1 ? "; no scaling" : "")
+ ")" );
}
private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) {
KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr );
if( keyStroke == null )
throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" );
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
applyLookAndFeel( lafClassName );
},
keyStroke,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
}
private void applyLookAndFeel( String lafClassName ) {
try {
UIManager.setLookAndFeel( lafClassName );
FlatLaf.updateUI();
} catch( Exception ex ) {
ex.printStackTrace();
}
}
private void registerScaleFactor( String keyStrokeStr, String scaleFactor ) {
KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr );
if( keyStroke == null )
throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" );
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
applyScaleFactor( scaleFactor );
},
keyStroke,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
}
private void applyScaleFactor( String scaleFactor ) {
if( scaleFactor != null ) {
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
DemoPrefs.getState().put( KEY_SCALE_FACTOR, scaleFactor );
} else {
System.clearProperty( FlatSystemProperties.UI_SCALE );
DemoPrefs.getState().remove( KEY_SCALE_FACTOR );
}
applyLookAndFeel( UIManager.getLookAndFeel().getClass().getName() );
pack();
}
}

View File

@@ -16,8 +16,13 @@
package com.formdev.flatlaf.testing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.DefaultEditorKit;
import com.formdev.flatlaf.FlatClientProperties;
import net.miginfocom.swing.*;
/**
@@ -41,16 +46,40 @@ public class FlatTextComponentsTest
textField1.setText( "new text" );
}
private void paddingChanged() {
Insets padding = new Insets(
(int) topPaddingField.getValue(),
(int) leftPaddingField.getValue(),
(int) bottomPaddingField.getValue(),
(int) rightPaddingField.getValue() );
if( padding.equals( new Insets( 0, 0, 0, 0 ) ) )
padding = null;
for( Component c : getComponents() ) {
if( c instanceof JTextField )
((JTextField)c).putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JLabel textFieldLabel = new JLabel();
textField1 = new JTextField();
JTextField textField3 = new JTextField();
JTextField textField2 = new JTextField();
JButton button1 = new JButton();
JLabel formattedTextFieldLabel = new JLabel();
JFormattedTextField formattedTextField1 = new JFormattedTextField();
JFormattedTextField formattedTextField3 = new JFormattedTextField();
JPanel panel1 = new JPanel();
JButton button1 = new JButton();
JLabel leftPaddingLabel = new JLabel();
leftPaddingField = new JSpinner();
JLabel rightPaddingLabel = new JLabel();
rightPaddingField = new JSpinner();
JLabel topPaddingLabel = new JLabel();
topPaddingField = new JSpinner();
JLabel bottomPaddingLabel = new JLabel();
bottomPaddingField = new JSpinner();
JLabel passwordFieldLabel = new JLabel();
JPasswordField passwordField1 = new JPasswordField();
JPasswordField passwordField3 = new JPasswordField();
@@ -74,10 +103,18 @@ public class FlatTextComponentsTest
JComboBox<String> comboBox3 = new JComboBox<>();
JLabel spinnerLabel = new JLabel();
JSpinner spinner1 = new JSpinner();
JSpinner spinner2 = new JSpinner();
JSpinner spinner3 = new JSpinner();
JLabel label2 = new JLabel();
JComboBox<String> comboBox2 = new JComboBox<>();
JSpinner spinner2 = new JSpinner();
JLabel label1 = new JLabel();
JComboBox<String> comboBox5 = new JComboBox<>();
JSpinner spinner4 = new JSpinner();
JLabel label3 = new JLabel();
JComboBox<String> comboBox4 = new JComboBox<>();
JSpinner spinner3 = new JSpinner();
JLabel label4 = new JLabel();
JComboBox<String> comboBox6 = new JComboBox<>();
JSpinner spinner5 = new JSpinner();
JPopupMenu popupMenu1 = new JPopupMenu();
JMenuItem cutMenuItem = new JMenuItem();
JMenuItem copyMenuItem = new JMenuItem();
@@ -102,8 +139,12 @@ public class FlatTextComponentsTest
"[50,fill]" +
"[]" +
"[]para" +
"[40]" +
"[40]" +
"[]" +
"[]" +
"[::14]" +
"[::14]" +
"[]" +
"[]"));
@@ -134,12 +175,6 @@ public class FlatTextComponentsTest
textField2.setName("textField2");
add(textField2, "cell 3 0");
//---- button1 ----
button1.setText("change text");
button1.setName("button1");
button1.addActionListener(e -> changeText());
add(button1, "cell 4 0");
//---- formattedTextFieldLabel ----
formattedTextFieldLabel.setText("JFormattedTextField:");
formattedTextFieldLabel.setDisplayedMnemonic('F');
@@ -159,6 +194,70 @@ public class FlatTextComponentsTest
formattedTextField3.setName("formattedTextField3");
add(formattedTextField3, "cell 2 1,growx");
//======== panel1 ========
{
panel1.setBorder(new TitledBorder("Control"));
panel1.setName("panel1");
panel1.setLayout(new MigLayout(
"hidemode 3",
// columns
"[fill]" +
"[fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- button1 ----
button1.setText("change text");
button1.setName("button1");
button1.addActionListener(e -> changeText());
panel1.add(button1, "cell 0 0 2 1,alignx left,growx 0");
//---- leftPaddingLabel ----
leftPaddingLabel.setText("Left padding:");
leftPaddingLabel.setName("leftPaddingLabel");
panel1.add(leftPaddingLabel, "cell 0 1");
//---- leftPaddingField ----
leftPaddingField.setName("leftPaddingField");
leftPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(leftPaddingField, "cell 1 1");
//---- rightPaddingLabel ----
rightPaddingLabel.setText("Right padding:");
rightPaddingLabel.setName("rightPaddingLabel");
panel1.add(rightPaddingLabel, "cell 0 2");
//---- rightPaddingField ----
rightPaddingField.setName("rightPaddingField");
rightPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(rightPaddingField, "cell 1 2");
//---- topPaddingLabel ----
topPaddingLabel.setText("Top padding:");
topPaddingLabel.setName("topPaddingLabel");
panel1.add(topPaddingLabel, "cell 0 3");
//---- topPaddingField ----
topPaddingField.setName("topPaddingField");
topPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(topPaddingField, "cell 1 3");
//---- bottomPaddingLabel ----
bottomPaddingLabel.setText("Bottom padding:");
bottomPaddingLabel.setName("bottomPaddingLabel");
panel1.add(bottomPaddingLabel, "cell 0 4");
//---- bottomPaddingField ----
bottomPaddingField.setName("bottomPaddingField");
bottomPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(bottomPaddingField, "cell 1 4");
}
add(panel1, "cell 4 0 1 6,aligny top,growy 0");
//---- passwordFieldLabel ----
passwordFieldLabel.setText("JPasswordField:");
passwordFieldLabel.setDisplayedMnemonic('P');
@@ -301,7 +400,7 @@ public class FlatTextComponentsTest
comboBox3.setPrototypeDisplayValue("12345");
comboBox3.setComponentPopupMenu(popupMenu1);
comboBox3.setName("comboBox3");
add(comboBox3, "cell 2 6,growx");
add(comboBox3, "cell 2 6,growx,wmin 50");
//---- spinnerLabel ----
spinnerLabel.setText("JSpinner:");
@@ -315,23 +414,67 @@ public class FlatTextComponentsTest
spinner1.setName("spinner1");
add(spinner1, "cell 1 7,growx");
//---- spinner2 ----
spinner2.setName("spinner2");
add(spinner2, "cell 1 8,growx,height 40");
//---- spinner3 ----
spinner3.setName("spinner3");
add(spinner3, "cell 1 9,growx,hmax 14");
//---- label2 ----
label2.setText("<html>Large row height:<br>(default pref height)</html>");
label2.setName("label2");
add(label2, "cell 0 8,aligny top,growy 0");
//---- comboBox2 ----
comboBox2.setEditable(true);
comboBox2.setName("comboBox2");
add(comboBox2, "cell 1 10,growx,height 40");
add(comboBox2, "cell 1 8,grow");
//---- spinner2 ----
spinner2.setName("spinner2");
add(spinner2, "cell 1 9,grow");
//---- label1 ----
label1.setText("Large pref height:");
label1.setName("label1");
add(label1, "cell 0 10,aligny top,growy 0");
//---- comboBox5 ----
comboBox5.setPreferredSize(new Dimension(60, 40));
comboBox5.setEditable(true);
comboBox5.setName("comboBox5");
add(comboBox5, "cell 1 10,growx");
//---- spinner4 ----
spinner4.setPreferredSize(new Dimension(60, 40));
spinner4.setName("spinner4");
add(spinner4, "cell 1 11,growx");
//---- label3 ----
label3.setText("<html>Small row height:<br>(default pref height)</html>");
label3.setName("label3");
add(label3, "cell 0 12 1 2,aligny top,growy 0");
//---- comboBox4 ----
comboBox4.setEditable(true);
comboBox4.setName("comboBox4");
add(comboBox4, "cell 1 11,growx,hmax 14");
add(comboBox4, "cell 1 12,growx");
//---- spinner3 ----
spinner3.setName("spinner3");
add(spinner3, "cell 1 13,growx");
//---- label4 ----
label4.setText("Small pref height:");
label4.setName("label4");
add(label4, "cell 0 14 1 2,aligny top,growy 0");
//---- comboBox6 ----
comboBox6.setEditable(true);
comboBox6.setPreferredSize(new Dimension(60, 14));
comboBox6.setMinimumSize(new Dimension(60, 14));
comboBox6.setName("comboBox6");
add(comboBox6, "cell 1 14,growx");
//---- spinner5 ----
spinner5.setMinimumSize(new Dimension(60, 14));
spinner5.setPreferredSize(new Dimension(60, 14));
spinner5.setName("spinner5");
add(spinner5, "cell 1 15,growx,hmax 14");
//======== popupMenu1 ========
{
@@ -361,5 +504,9 @@ public class FlatTextComponentsTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField textField1;
private JSpinner leftPaddingField;
private JSpinner rightPaddingField;
private JSpinner topPaddingField;
private JSpinner bottomPaddingField;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -10,7 +10,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][::100][100,fill][fill]"
"$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[][][][]"
"$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[40][40][][][::14][::14][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -47,13 +47,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 0"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button1"
"text": "change text"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "formattedTextFieldLabel"
"text": "JFormattedTextField:"
@@ -76,6 +69,83 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1,growx"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][][][]"
} ) {
name: "panel1"
"border": new javax.swing.border.TitledBorder( "Control" )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button1"
"text": "change text"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "leftPaddingLabel"
"text": "Left padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "leftPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightPaddingLabel"
"text": "Right padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "rightPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "topPaddingLabel"
"text": "Top padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "topPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "bottomPaddingLabel"
"text": "Bottom padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "bottomPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0 1 6,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "passwordFieldLabel"
"text": "JPasswordField:"
@@ -217,7 +287,7 @@ new FormModel {
"prototypeDisplayValue": "12345"
"componentPopupMenu": #FormReference0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 6,growx"
"value": "cell 2 6,growx,wmin 50"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "spinnerLabel"
@@ -233,15 +303,11 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner2"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
"text": "<html>Large row height:<br>(default pref height)</html>"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8,growx,height 40"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,growx,hmax 14"
"value": "cell 0 8,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox2"
@@ -250,7 +316,40 @@ new FormModel {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx,height 40"
"value": "cell 1 8,grow"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,grow"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Large pref height:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox5"
"preferredSize": new java.awt.Dimension( 60, 40 )
"editable": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner4"
"preferredSize": new java.awt.Dimension( 60, 40 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "<html>Small row height:<br>(default pref height)</html>"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 12 1 2,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox4"
@@ -259,11 +358,40 @@ new FormModel {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,growx,hmax 14"
"value": "cell 1 12,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 13,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "Small pref height:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 14 1 2,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox6"
"editable": true
"preferredSize": new java.awt.Dimension( 60, 14 )
"minimumSize": new java.awt.Dimension( 60, 14 )
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 14,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner5"
"minimumSize": new java.awt.Dimension( 60, 14 )
"preferredSize": new java.awt.Dimension( 60, 14 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15,growx,hmax 14"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 530, 580 )
"size": new java.awt.Dimension( 530, 660 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1"
@@ -280,7 +408,7 @@ new FormModel {
"text": "Paste"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 680 )
"location": new java.awt.Point( 0, 705 )
"size": new java.awt.Dimension( 91, 87 )
} )
}

View File

@@ -124,6 +124,11 @@ public class FlatSwingXTest
JTextField textField3 = new JTextField();
JLabel label10 = new JLabel();
JTextField textField4 = new JTextField();
JLabel label11 = new JLabel();
JXSearchField xSearchField1 = new JXSearchField();
JXSearchField xSearchField2 = new JXSearchField();
JXSearchField xSearchField3 = new JXSearchField();
JXSearchField xSearchField4 = new JXSearchField();
JButton button1 = new JButton();
JButton button2 = new JButton();
@@ -146,6 +151,8 @@ public class FlatSwingXTest
"[]" +
"[]" +
"[]" +
"[]" +
"[]" +
"[37]"));
//---- label1 ----
@@ -425,6 +432,30 @@ public class FlatSwingXTest
}
add(xTitledPanel2, "cell 3 8,grow");
//---- label11 ----
label11.setText("JXSearchField:");
add(label11, "cell 0 9");
//---- xSearchField1 ----
xSearchField1.setText("abc");
add(xSearchField1, "cell 1 9,growx");
//---- xSearchField2 ----
xSearchField2.setEnabled(false);
xSearchField2.setText("abc");
add(xSearchField2, "cell 2 9,growx");
//---- xSearchField3 ----
xSearchField3.setRecentSearchesSaveKey("flatlaf.swingx.search.recent");
xSearchField3.setText("abc");
add(xSearchField3, "cell 1 10,growx");
//---- xSearchField4 ----
xSearchField4.setRecentSearchesSaveKey("flatlaf.swingx.search.recent");
xSearchField4.setEnabled(false);
xSearchField4.setText("abc");
add(xSearchField4, "cell 2 10,growx");
//---- button1 ----
button1.setText("<");

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[left][][][][fill]"
"$rowConstraints": "[]0[][]0[top][][][][][][37]"
"$rowConstraints": "[]0[][]0[top][][][][][][][][37]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -354,6 +354,40 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 8,grow"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JXSearchField:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField1"
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField2"
"enabled": false
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 9,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField3"
"recentSearchesSaveKey": "flatlaf.swingx.search.recent"
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField4"
"recentSearchesSaveKey": "flatlaf.swingx.search.recent"
"enabled": false
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 10,growx"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 700, 600 )

View File

@@ -29,6 +29,7 @@ import java.util.Locale;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.testing.FlatTestLaf;
/**
* Collects all FlatLaf UI defaults keys and dumps them to a file.
@@ -60,6 +61,7 @@ public class UIDefaultsKeysDump
collectKeys( FlatDarkLaf.class.getName(), keys );
collectKeys( FlatIntelliJLaf.class.getName(), keys );
collectKeys( FlatDarculaLaf.class.getName(), keys );
collectKeys( FlatTestLaf.class.getName(), keys );
// write key file
try( Writer fileWriter = new BufferedWriter( new FileWriter( keysFile ) ) ) {

View File

@@ -400,6 +400,11 @@ ToggleButton.pressedBackground = #FFC800
ToggleButton.toolbar.selectedBackground = #ddd
#---- ToolBar ----
ToolBar.focusableButtons = true
#---- ToolTip ----
ToolTip.background = #eef

View File

@@ -18,6 +18,8 @@ Button.default.background
Button.default.boldText
Button.default.borderColor
Button.default.borderWidth
Button.default.endBackground
Button.default.endBorderColor
Button.default.focusColor
Button.default.focusedBackground
Button.default.focusedBorderColor
@@ -25,12 +27,16 @@ Button.default.foreground
Button.default.hoverBackground
Button.default.hoverBorderColor
Button.default.pressedBackground
Button.default.startBackground
Button.default.startBorderColor
Button.defaultButtonFollowsFocus
Button.disabledBackground
Button.disabledBorderColor
Button.disabledForeground
Button.disabledSelectedBackground
Button.disabledText
Button.endBackground
Button.endBorderColor
Button.focusInputMap
Button.focusedBackground
Button.focusedBorderColor
@@ -49,6 +55,8 @@ Button.rollover
Button.selectedBackground
Button.selectedForeground
Button.shadow
Button.startBackground
Button.startBorderColor
Button.textIconGap
Button.textShiftOffset
Button.toolbar.hoverBackground
@@ -142,6 +150,7 @@ ComboBox.buttonBackground
ComboBox.buttonDarkShadow
ComboBox.buttonDisabledArrowColor
ComboBox.buttonEditableBackground
ComboBox.buttonFocusedBackground
ComboBox.buttonHighlight
ComboBox.buttonHoverArrowColor
ComboBox.buttonPressedArrowColor
@@ -150,6 +159,7 @@ ComboBox.buttonStyle
ComboBox.disabledBackground
ComboBox.disabledForeground
ComboBox.editorColumns
ComboBox.focusedBackground
ComboBox.font
ComboBox.foreground
ComboBox.isEnterSelectablePopup
@@ -157,6 +167,7 @@ ComboBox.maximumRowCount
ComboBox.minimumWidth
ComboBox.noActionOnKeyNavigation
ComboBox.padding
ComboBox.popupBackground
ComboBox.selectionBackground
ComboBox.selectionForeground
ComboBox.timeFactor
@@ -197,6 +208,7 @@ EditorPane.caretBlinkRate
EditorPane.caretForeground
EditorPane.disabledBackground
EditorPane.focusInputMap
EditorPane.focusedBackground
EditorPane.font
EditorPane.foreground
EditorPane.inactiveBackground
@@ -226,6 +238,7 @@ FormattedTextField.caretBlinkRate
FormattedTextField.caretForeground
FormattedTextField.disabledBackground
FormattedTextField.focusInputMap
FormattedTextField.focusedBackground
FormattedTextField.font
FormattedTextField.foreground
FormattedTextField.inactiveBackground
@@ -295,7 +308,9 @@ JXBusyLabel.baseColor
JXBusyLabel.highlightColor
JXDatePicker.border
JXHeader.background
JXHeader.descriptionForeground
JXHeader.startBackground
JXHeader.titleForeground
JXMonthView.arrowColor
JXMonthView.background
JXMonthView.daysOfTheWeekForeground
@@ -475,6 +490,11 @@ OptionPane.buttonPadding
OptionPane.errorIcon
OptionPane.font
OptionPane.foreground
OptionPane.icon.errorColor
OptionPane.icon.foreground
OptionPane.icon.informationColor
OptionPane.icon.questionColor
OptionPane.icon.warningColor
OptionPane.iconMessageGap
OptionPane.informationIcon
OptionPane.maxCharactersPerLine
@@ -500,6 +520,7 @@ PasswordField.caretForeground
PasswordField.disabledBackground
PasswordField.echoChar
PasswordField.focusInputMap
PasswordField.focusedBackground
PasswordField.font
PasswordField.foreground
PasswordField.inactiveBackground
@@ -629,6 +650,21 @@ ScrollPane.font
ScrollPane.foreground
ScrollPane.smoothScrolling
ScrollPaneUI
SearchField.clearIcon
SearchField.clearIconColor
SearchField.clearIconHoverColor
SearchField.clearIconPressedColor
SearchField.clearPressedIcon
SearchField.clearRolloverIcon
SearchField.icon
SearchField.popupIcon
SearchField.popupPressedIcon
SearchField.popupRolloverIcon
SearchField.pressedIcon
SearchField.rolloverIcon
SearchField.searchIconColor
SearchField.searchIconHoverColor
SearchField.searchIconPressedColor
Separator.background
Separator.foreground
Separator.height
@@ -651,11 +687,14 @@ Slider.foreground
Slider.highlight
Slider.horizontalSize
Slider.hoverThumbColor
Slider.hoverTrackColor
Slider.minimumHorizontalSize
Slider.minimumVerticalSize
Slider.onlyLeftMouseButtonDrag
Slider.pressedThumbColor
Slider.pressedTrackColor
Slider.shadow
Slider.thumbBorderColor
Slider.thumbColor
Slider.thumbSize
Slider.tickColor
@@ -678,6 +717,7 @@ Spinner.disabledBackground
Spinner.disabledForeground
Spinner.editorAlignment
Spinner.editorBorderPainted
Spinner.focusedBackground
Spinner.font
Spinner.foreground
Spinner.padding
@@ -753,6 +793,7 @@ TabbedPane.tabHeight
TabbedPane.tabInsets
TabbedPane.tabRunOverlay
TabbedPane.tabSelectionHeight
TabbedPane.tabSeparatorColor
TabbedPane.tabSeparatorsFullHeight
TabbedPane.tabWidthMode
TabbedPane.tabsOpaque
@@ -820,6 +861,7 @@ TextArea.caretBlinkRate
TextArea.caretForeground
TextArea.disabledBackground
TextArea.focusInputMap
TextArea.focusedBackground
TextArea.font
TextArea.foreground
TextArea.inactiveBackground
@@ -838,6 +880,7 @@ TextField.caretForeground
TextField.darkShadow
TextField.disabledBackground
TextField.focusInputMap
TextField.focusedBackground
TextField.font
TextField.foreground
TextField.highlight
@@ -856,6 +899,7 @@ TextPane.caretBlinkRate
TextPane.caretForeground
TextPane.disabledBackground
TextPane.focusInputMap
TextPane.focusedBackground
TextPane.font
TextPane.foreground
TextPane.inactiveBackground
@@ -865,6 +909,7 @@ TextPane.selectionBackground
TextPane.selectionForeground
TextPaneUI
TitlePane.background
TitlePane.borderColor
TitlePane.buttonHoverBackground
TitlePane.buttonMaximizedHeight
TitlePane.buttonPressedBackground
@@ -902,9 +947,11 @@ ToggleButton.disabledBackground
ToggleButton.disabledSelectedBackground
ToggleButton.disabledText
ToggleButton.focusInputMap
ToggleButton.focusedBackground
ToggleButton.font
ToggleButton.foreground
ToggleButton.highlight
ToggleButton.hoverBackground
ToggleButton.iconTextGap
ToggleButton.light
ToggleButton.margin
@@ -916,6 +963,7 @@ ToggleButton.shadow
ToggleButton.tab.disabledUnderlineColor
ToggleButton.tab.focusBackground
ToggleButton.tab.hoverBackground
ToggleButton.tab.selectedBackground
ToggleButton.tab.underlineColor
ToggleButton.tab.underlineHeight
ToggleButton.textIconGap
@@ -933,6 +981,7 @@ ToolBar.dockingBackground
ToolBar.dockingForeground
ToolBar.floatingBackground
ToolBar.floatingForeground
ToolBar.focusableButtons
ToolBar.font
ToolBar.foreground
ToolBar.gripColor
@@ -962,6 +1011,7 @@ Tree.dropCellBackground
Tree.dropCellForeground
Tree.dropLineColor
Tree.editorBorder
Tree.editorBorderSelectionColor
Tree.expandedIcon
Tree.focusInputMap
Tree.focusInputMap.RightToLeft