mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 22:47:13 -06:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4487c9985c | ||
|
|
a53ce99977 | ||
|
|
5444719895 | ||
|
|
b66139281d | ||
|
|
8925c27eb9 | ||
|
|
99be346387 | ||
|
|
81d46ba8ee | ||
|
|
ef4c467b20 | ||
|
|
44d196fb8c | ||
|
|
867c4fff58 | ||
|
|
5643546117 | ||
|
|
549832ba96 | ||
|
|
a8744b2bb4 | ||
|
|
e292d3444c | ||
|
|
ee6a1da709 | ||
|
|
8c15bc746b | ||
|
|
aebb083180 | ||
|
|
5438549b6d | ||
|
|
0077708235 | ||
|
|
2fd99ec9f3 | ||
|
|
0d266c4990 | ||
|
|
0982675b5f | ||
|
|
3bac5d3c80 | ||
|
|
58338f4848 | ||
|
|
9c261d3a3f | ||
|
|
5441ac6640 | ||
|
|
015b04a29a | ||
|
|
12ec0abf54 | ||
|
|
c8d461cdee | ||
|
|
faecffeadd | ||
|
|
b3c76c21b4 | ||
|
|
1697735162 | ||
|
|
ecb94bac6d | ||
|
|
7ebeacf16e | ||
|
|
d0079ab66b | ||
|
|
147e400bd6 | ||
|
|
c44905ea5e | ||
|
|
98b9df06fe | ||
|
|
02473080a5 | ||
|
|
c6beb9dc0a | ||
|
|
dcce14b122 | ||
|
|
a2ac24ac74 | ||
|
|
600f812f45 | ||
|
|
e945f46f25 | ||
|
|
c78c653b0a | ||
|
|
e0b3663239 | ||
|
|
3cc9c98040 | ||
|
|
ec8213b891 | ||
|
|
ae61383742 | ||
|
|
cc90a2ad75 | ||
|
|
28634cda56 | ||
|
|
3b71fcd690 | ||
|
|
5923ac65df | ||
|
|
faffc9393d | ||
|
|
6da220f36c | ||
|
|
21d78671d6 | ||
|
|
af5a0ec0b7 | ||
|
|
ff214455a3 | ||
|
|
3e941e3e42 | ||
|
|
2f876d553f | ||
|
|
b208017117 | ||
|
|
a1dab94a61 | ||
|
|
e55b2afd60 | ||
|
|
535c3ddf6c | ||
|
|
3008d99fcd | ||
|
|
fd37339e2f | ||
|
|
e29eca203c | ||
|
|
f1fd6dcdd2 | ||
|
|
2975ed2eae | ||
|
|
5a27d03faa | ||
|
|
8bcf9dbcaf | ||
|
|
56ebd26361 | ||
|
|
b0426b81a7 | ||
|
|
368fbcdeb0 | ||
|
|
30747b7776 | ||
|
|
4eb4ddf5d8 | ||
|
|
b1d24680b2 | ||
|
|
ef38f3805e | ||
|
|
2f5ca20ca4 | ||
|
|
f29d3d84d4 | ||
|
|
02132c5fcd | ||
|
|
7057e3c6ad | ||
|
|
a8f4c8e843 | ||
|
|
a2b6e66a13 | ||
|
|
e3b3cc2896 | ||
|
|
a5b2c50f24 | ||
|
|
5ebdf64d30 | ||
|
|
2640ab2e8b | ||
|
|
e29436da04 | ||
|
|
7b35325f9a | ||
|
|
f2ab7fafcf | ||
|
|
e3cda9905a | ||
|
|
a8423f7741 | ||
|
|
5a9e620c17 | ||
|
|
9f41ec3986 | ||
|
|
5a2c0672d4 | ||
|
|
38d853b5b2 | ||
|
|
5166d4bb0f | ||
|
|
2ffd5437a9 | ||
|
|
797830ff96 | ||
|
|
008ecabd21 | ||
|
|
2cdcde8a5e | ||
|
|
e7ec3988e2 | ||
|
|
093dd9f3ef | ||
|
|
b491202ec7 | ||
|
|
8603ca827e | ||
|
|
6b148a59da | ||
|
|
de6d45fee6 | ||
|
|
65e2071937 | ||
|
|
8a6242d9ea | ||
|
|
82294b68eb | ||
|
|
c232de1996 | ||
|
|
dc18c8178d | ||
|
|
6662714277 | ||
|
|
c404a0d1a9 | ||
|
|
990da2b412 | ||
|
|
1b974379c8 | ||
|
|
835faf9773 | ||
|
|
80deecb73e | ||
|
|
64328ab9cc | ||
|
|
eafad942e7 | ||
|
|
eb5a3168b9 | ||
|
|
ac8225d8fb | ||
|
|
6f71e4ada0 | ||
|
|
7ed90cddf8 | ||
|
|
283ba83cef | ||
|
|
468c66e842 | ||
|
|
f22862b0a4 | ||
|
|
9e731cb67a | ||
|
|
7f911b61a2 | ||
|
|
cace4a9bfd | ||
|
|
0992e97a1a | ||
|
|
eee101f279 | ||
|
|
4b9f204951 | ||
|
|
019804407b | ||
|
|
65b54ced7a | ||
|
|
a308114b2f | ||
|
|
41da023bdd | ||
|
|
19fcb6a82c | ||
|
|
221a18c119 |
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,6 +1,136 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 0.42
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
- Demo: Improved "SplitPane & Tabs" and "Data Components" tabs.
|
||||
- Demo: Menu items "File > Open" and "File > Save As" now show file choosers.
|
||||
- InternalFrame: Support draggable border for resizing frame inside of the
|
||||
visible frame border. (issue #121)
|
||||
- `FlatUIDefaultsInspector` added (see [FlatLaf Extras](flatlaf-extras)). A
|
||||
simple UI defaults inspector that shows a window with all UI defaults used in
|
||||
current theme (look and feel).
|
||||
- Made disabled text color slightly lighter in dark themes for better
|
||||
readability. (issue #174)
|
||||
- PasswordField: Support disabling Caps Lock warning icon. (issue #172)
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- TextComponents: Fixed text color of disabled text components in dark themes.
|
||||
- Custom window decorations: Fixed wrong window placement when moving window to
|
||||
another screen with different scaling factor. (issue #166)
|
||||
- Custom window decorations: Fixed wrong window bounds when resizing window to
|
||||
another screen with different scaling factor. (issue #166)
|
||||
- Fixed occasional wrong positioning of heavy weight popups when using multiple
|
||||
screens with different scaling factors. (issue #166)
|
||||
- ToolTip: Avoid that tooltip hides owner component. (issue #164)
|
||||
|
||||
|
||||
## 0.41
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
- Added API to register packages or folders where FlatLaf searches for
|
||||
application specific properties files with custom UI defaults (see
|
||||
`FlatLaf.registerCustomDefaultsSource(...)` methods).
|
||||
- Demo: Show hint popups to guide users to some features of the FlatLaf Demo
|
||||
application.
|
||||
- Extras: `FlatSVGIcon` now allows specifying `ClassLoader` that is used to load
|
||||
SVG file. (issue #163)
|
||||
- Smoother transition from old to new theme, independent of UI complexity, when
|
||||
using animated theme change (see [FlatLaf Extras](flatlaf-extras)).
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- Button: "selected" state was not shown. (issue #161)
|
||||
- TextArea: Update background color property if enabled or editable state
|
||||
changes in the same way as Swing does it for all other text components. (issue
|
||||
#147)
|
||||
- Demo: Fixed restoring last used theme on startup. (regression in 0.39)
|
||||
- Custom window decorations: Fixed iconify, maximize and close icon colors if
|
||||
window is inactive.
|
||||
- Custom window decorations: Fixed title pane background color in IntelliJ
|
||||
themes if window is inactive.
|
||||
- Fixed sub-pixel text rendering in animated theme change (see
|
||||
[FlatLaf Extras](flatlaf-extras)).
|
||||
|
||||
#### Other Changes
|
||||
|
||||
- Extras: Updated dependency
|
||||
[svgSalamander](https://github.com/JFormDesigner/svgSalamander) to version
|
||||
1.1.2.3.
|
||||
|
||||
|
||||
## 0.40
|
||||
|
||||
#### New features
|
||||
|
||||
- Table: Detect whether component is used in cell editor and automatically
|
||||
disable round border style and reduce cell editor outer border width (used for
|
||||
focus indicator) to zero. (issue #148)
|
||||
- ComboBox, Spinner and TextField: Support disabling round border style per
|
||||
component, if globally enabled (set client property `JComponent.roundRect` to
|
||||
`false`). (issue #148)
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- Custom window decorations: Embedded menu bar did not always respond to mouse
|
||||
events after adding menus and when running in JetBrains Runtime. (issue #151)
|
||||
- IntelliJ Themes: Fixed NPE in Solarized themes on scroll bar hover.
|
||||
|
||||
|
||||
## 0.39
|
||||
|
||||
#### New features
|
||||
|
||||
- Animated theme change (see [FlatLaf Extras](flatlaf-extras)). Used in Demo.
|
||||
- Demo: Added combo box above themes list to show only light or dark themes.
|
||||
- IntelliJ Themes:
|
||||
- Added "Arc Dark", "Arc Dark - Orange", "Carbon" and "Cobalt 2" themes.
|
||||
- Replaced "Solarized" themes with much better ones from 4lex4.
|
||||
- Updated "Arc", "One Dark" and "Vuesion" themes.
|
||||
- ScrollPane: Enable/disable smooth scrolling per component if client property
|
||||
"JScrollPane.smoothScrolling" is set to a `Boolean` on `JScrollPane`.
|
||||
- ScrollBar: Increased minimum thumb size on macOS and Linux from 8 to 18
|
||||
pixels. On Windows, it is now 10 pixels. (issue #131)
|
||||
- Button: Support specifying button border width.
|
||||
- ComboBox: Changed maximum row count of popup list to 15 (was 20). Set UI value
|
||||
`ComboBox.maximumRowCount` to any integer to use a different value.
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- Custom window decorations: Fixed maximized window bounds when programmatically
|
||||
maximizing window. E.g. restoring window state at startup. (issue #129)
|
||||
- InternalFrame: Title pane height was too small when iconify, maximize and
|
||||
close buttons are hidden. (issue #132)
|
||||
- ToolTip: Do not show empty tooltip component if tooltip text is an empty
|
||||
string. (issue #134)
|
||||
- ToolTip: Fixed truncated text in HTML formatted tooltip on HiDPI displays.
|
||||
(issue #142)
|
||||
- ComboBox: Fixed width of popup, which was too small if popup is wider than
|
||||
combo box and vertical scroll bar is visible. (issue #137)
|
||||
- MenuItem on macOS: Removed plus characters from accelerator text and made
|
||||
modifier key order conform with macOS standard. (issue #141)
|
||||
- FileChooser: Fixed too small text field when renaming a file/directory in Flat
|
||||
IntelliJ/Darcula themes. (issue #143)
|
||||
- IntelliJ Themes: Fixed text colors in ProgressBar. (issue #138)
|
||||
|
||||
|
||||
## 0.38
|
||||
|
||||
- Hide focus indicator when window is inactive.
|
||||
- Custom window decorations: Improved/fixed window border color in dark themes.
|
||||
- Custom window decorations: Hide window border if window is maximized.
|
||||
- Custom window decorations: Center title if menu bar is embedded.
|
||||
- Custom window decorations: Cursor of components (e.g. TextField) was not
|
||||
changed. (issue #125)
|
||||
- CheckBox: Fixed colors in light IntelliJ themes. (issue #126; regression in
|
||||
0.37)
|
||||
- InternalFrame: Use default icon in internal frames. (issue #122)
|
||||
|
||||
|
||||
## 0.37
|
||||
|
||||
- Custom window decorations (Windows 10 only; PR #108; issues #47 and #82)
|
||||
|
||||
18
README.md
18
README.md
@@ -11,9 +11,9 @@ scales on **HiDPI** displays and runs on Java 8 or newer.
|
||||
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
|
||||
IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
IntelliJ Platform Themes
|
||||
@@ -22,9 +22,7 @@ IntelliJ Platform Themes
|
||||
FlatLaf can use 3rd party themes created for IntelliJ Platform (see
|
||||
[IntelliJ Themes Pack](flatlaf-intellij-themes)):
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
Demo
|
||||
@@ -82,6 +80,7 @@ Projects using FlatLaf
|
||||
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
|
||||
- [KeyStore Explorer](https://keystore-explorer.org/) 5.4.3
|
||||
- [OWASP Zed Attack Proxy (ZAP)](https://www.zaproxy.org/) (in weekly releases)
|
||||
-  [jAlbum](https://jalbum.net/) 21 (commercial)
|
||||
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (commercial)
|
||||
- [Total Validator](https://www.totalvalidator.com/) 15 (commercial)
|
||||
- [j-lawyer](https://github.com/jlawyerorg/j-lawyer-org)
|
||||
@@ -98,8 +97,15 @@ Projects using FlatLaf
|
||||
[mendelson AS2](https://mendelson-e-c.com/as2/),
|
||||
[AS4](https://mendelson-e-c.com/as4/) and
|
||||
[OFTP2](https://mendelson-e-c.com/oftp2) (commercial)
|
||||
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.1.6
|
||||
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2
|
||||
- [lsfusion platform](https://github.com/lsfusion/platform)
|
||||
- [Jes - Die Java-EÜR](https://www.jes-eur.de)
|
||||
- [Mapton](https://mapton.org/) 2.0
|
||||
([source code](https://github.com/trixon/mapton)) based on NetBeans platform
|
||||
- [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE)
|
||||
- [Sound Analysis](https://github.com/tomasz-herman/SoundAnalysis)
|
||||
- [RemoteLight](https://github.com/Drumber/RemoteLight) - Multifunctional LED
|
||||
Control Software
|
||||
- and more...
|
||||
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
val releaseVersion = "0.37"
|
||||
val developmentVersion = "0.38-SNAPSHOT"
|
||||
val releaseVersion = "0.42"
|
||||
val developmentVersion = "0.43-SNAPSHOT"
|
||||
|
||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||
|
||||
|
||||
@@ -200,6 +200,14 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String SCROLL_BAR_SHOW_BUTTONS = "JScrollBar.showButtons";
|
||||
|
||||
/**
|
||||
* Specifies whether the scroll pane uses smooth scrolling.
|
||||
* <p>
|
||||
* <strong>Component</strong> {{@link javax.swing.JScrollPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling";
|
||||
|
||||
/**
|
||||
* Specifies whether separators are shown between tabs.
|
||||
* <p>
|
||||
@@ -306,6 +314,15 @@ public interface FlatClientProperties
|
||||
return (value instanceof Boolean) ? (boolean) value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a client property of a component is a {@link Boolean} and returns its value.
|
||||
* If the client property is not set, or not a {@link Boolean}, defaultValue is returned.
|
||||
*/
|
||||
static Boolean clientPropertyBooleanStrict( JComponent c, String key, Boolean defaultValue ) {
|
||||
Object value = c.getClientProperty( key );
|
||||
return (value instanceof Boolean) ? (Boolean) value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a client property of a component is an integer and returns its value.
|
||||
* If the client property is not set, or not an integer, defaultValue is returned.
|
||||
|
||||
@@ -22,9 +22,11 @@ import javax.swing.KeyStroke;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIDefaults.LazyValue;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.InputMapUIResource;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import static javax.swing.text.DefaultEditorKit.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -35,7 +37,7 @@ class FlatInputMaps
|
||||
initBasicInputMaps( defaults );
|
||||
initTextComponentInputMaps( defaults );
|
||||
|
||||
if( SystemInfo.IS_MAC )
|
||||
if( SystemInfo.isMacOS )
|
||||
initMacInputMaps( defaults );
|
||||
}
|
||||
|
||||
@@ -59,7 +61,7 @@ class FlatInputMaps
|
||||
mac( "alt KP_DOWN", null ), "togglePopup"
|
||||
);
|
||||
|
||||
if( !SystemInfo.IS_MAC ) {
|
||||
if( !SystemInfo.isMacOS ) {
|
||||
modifyInputMap( defaults, "FileChooser.ancestorInputMap",
|
||||
"F2", "editFileName",
|
||||
"BACK_SPACE", "Go Up"
|
||||
@@ -81,8 +83,11 @@ class FlatInputMaps
|
||||
"shift ctrl TAB", "navigatePrevious"
|
||||
);
|
||||
|
||||
modifyInputMap( defaults, "Table.ancestorInputMap",
|
||||
// swap to make it consistent with List and Tree
|
||||
// swap Home/End with Ctrl+Home/End to make it consistent with List and Tree
|
||||
modifyInputMap( () -> {
|
||||
return UIManager.getBoolean( "Table.consistentHomeEndKeyBehavior" );
|
||||
},
|
||||
defaults, "Table.ancestorInputMap",
|
||||
"HOME", "selectFirstRow",
|
||||
"END", "selectLastRow",
|
||||
"shift HOME", "selectFirstRowExtendSelection",
|
||||
@@ -93,7 +98,7 @@ class FlatInputMaps
|
||||
mac( "shift ctrl END", null ), "selectLastColumnExtendSelection"
|
||||
);
|
||||
|
||||
if( !SystemInfo.IS_MAC ) {
|
||||
if( !SystemInfo.isMacOS ) {
|
||||
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||
"ADD", "expand",
|
||||
"SUBTRACT", "collapse"
|
||||
@@ -164,7 +169,7 @@ class FlatInputMaps
|
||||
"control shift O", "toggle-componentOrientation", // DefaultEditorKit.toggleComponentOrientation
|
||||
};
|
||||
|
||||
Object[] macCommonTextComponentBindings = SystemInfo.IS_MAC ? new Object[] {
|
||||
Object[] macCommonTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret one character (without selecting text)
|
||||
"ctrl B", backwardAction,
|
||||
"ctrl F", forwardAction,
|
||||
@@ -211,7 +216,7 @@ class FlatInputMaps
|
||||
"ENTER", JTextField.notifyAction,
|
||||
};
|
||||
|
||||
Object[] macSingleLineTextComponentBindings = SystemInfo.IS_MAC ? new Object[] {
|
||||
Object[] macSingleLineTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret to line begin/end (without selecting text)
|
||||
"UP", beginLineAction,
|
||||
"DOWN", endLineAction,
|
||||
@@ -289,7 +294,7 @@ class FlatInputMaps
|
||||
mac( "ctrl SPACE", "meta SPACE" ), "activate-link-action",
|
||||
};
|
||||
|
||||
Object[] macMultiLineTextComponentBindings = SystemInfo.IS_MAC ? new Object[] {
|
||||
Object[] macMultiLineTextComponentBindings = SystemInfo.isMacOS ? new Object[] {
|
||||
// move caret one line (without selecting text)
|
||||
"ctrl N", downAction,
|
||||
"ctrl P", upAction,
|
||||
@@ -574,12 +579,16 @@ class FlatInputMaps
|
||||
}
|
||||
|
||||
private static void modifyInputMap( UIDefaults defaults, String key, Object... bindings ) {
|
||||
// Note: not using `defaults.get(key)` here because this would resolve the lazy value
|
||||
defaults.put( key, new LazyModifyInputMap( defaults.remove( key ), bindings ) );
|
||||
modifyInputMap( null, defaults, key, bindings );
|
||||
}
|
||||
|
||||
private static void modifyInputMap( BooleanSupplier condition, UIDefaults defaults, String key, Object... bindings ) {
|
||||
// Note: not using `defaults.get(key)` here because this would resolve a lazy value
|
||||
defaults.put( key, new LazyModifyInputMap( condition, defaults.remove( key ), bindings ) );
|
||||
}
|
||||
|
||||
private static <T> T mac( T value, T macValue ) {
|
||||
return SystemInfo.IS_MAC ? macValue : value;
|
||||
return SystemInfo.isMacOS ? macValue : value;
|
||||
}
|
||||
|
||||
//---- class LazyInputMapEx -----------------------------------------------
|
||||
@@ -614,10 +623,12 @@ class FlatInputMaps
|
||||
private static class LazyModifyInputMap
|
||||
implements LazyValue
|
||||
{
|
||||
private final BooleanSupplier condition;
|
||||
private final Object baseInputMap;
|
||||
private final Object[] bindings;
|
||||
|
||||
LazyModifyInputMap( Object baseInputMap, Object[] bindings ) {
|
||||
LazyModifyInputMap( BooleanSupplier condition, Object baseInputMap, Object[] bindings ) {
|
||||
this.condition = condition;
|
||||
this.baseInputMap = baseInputMap;
|
||||
this.bindings = bindings;
|
||||
}
|
||||
@@ -629,6 +640,9 @@ class FlatInputMaps
|
||||
? (InputMap) ((LazyValue)baseInputMap).createValue( table )
|
||||
: (InputMap) baseInputMap;
|
||||
|
||||
if( condition != null && !condition.getAsBoolean() )
|
||||
return inputMap;
|
||||
|
||||
// modify input map (replace or remove)
|
||||
for( int i = 0; i < bindings.length; i += 2 ) {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( (String) bindings[i] );
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.awt.image.ImageFilter;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -76,6 +77,8 @@ public abstract class FlatLaf
|
||||
static final Logger LOG = Logger.getLogger( FlatLaf.class.getName() );
|
||||
private static final String DESKTOPFONTHINTS = "awt.font.desktophints";
|
||||
|
||||
private static List<Object> customDefaultsSources;
|
||||
|
||||
private String desktopPropertyName;
|
||||
private String desktopPropertyName2;
|
||||
private PropertyChangeListener desktopPropertyListener;
|
||||
@@ -147,12 +150,12 @@ public abstract class FlatLaf
|
||||
*/
|
||||
@Override
|
||||
public boolean getSupportsWindowDecorations() {
|
||||
if( SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER &&
|
||||
SystemInfo.IS_WINDOWS_10_OR_LATER &&
|
||||
if( SystemInfo.isJetBrainsJVM_11_orLater &&
|
||||
SystemInfo.isWindows_10_orLater &&
|
||||
JBRCustomDecorations.isSupported() )
|
||||
return false;
|
||||
|
||||
return SystemInfo.IS_WINDOWS_10_OR_LATER;
|
||||
return SystemInfo.isWindows_10_orLater;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,7 +190,7 @@ public abstract class FlatLaf
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if( SystemInfo.IS_MAC )
|
||||
if( SystemInfo.isMacOS )
|
||||
initializeAqua();
|
||||
|
||||
super.initialize();
|
||||
@@ -201,11 +204,11 @@ public abstract class FlatLaf
|
||||
mnemonicHandler.install();
|
||||
|
||||
// listen to desktop property changes to update UI if system font or scaling changes
|
||||
if( SystemInfo.IS_WINDOWS ) {
|
||||
if( SystemInfo.isWindows ) {
|
||||
// Windows 10 allows increasing font size independent of scaling:
|
||||
// Settings > Ease of Access > Display > Make text bigger (100% - 225%)
|
||||
desktopPropertyName = "win.messagebox.font";
|
||||
} else if( SystemInfo.IS_LINUX ) {
|
||||
} else if( SystemInfo.isLinux ) {
|
||||
// Linux/Gnome allows changing font in "Tweaks" app
|
||||
desktopPropertyName = "gnome.Gtk/FontName";
|
||||
|
||||
@@ -315,7 +318,7 @@ public abstract class FlatLaf
|
||||
String aquaLafClassName = "com.apple.laf.AquaLookAndFeel";
|
||||
BasicLookAndFeel aquaLaf;
|
||||
try {
|
||||
if( SystemInfo.IS_JAVA_9_OR_LATER ) {
|
||||
if( SystemInfo.isJava_9_orLater ) {
|
||||
Method m = UIManager.class.getMethod( "createLookAndFeel", String.class );
|
||||
aquaLaf = (BasicLookAndFeel) m.invoke( null, "Mac OS X" );
|
||||
} else
|
||||
@@ -391,7 +394,7 @@ public abstract class FlatLaf
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults );
|
||||
|
||||
// use Aqua MenuBarUI if Mac screen menubar is enabled
|
||||
if( SystemInfo.IS_MAC && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) {
|
||||
if( SystemInfo.isMacOS && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) {
|
||||
defaults.put( "MenuBarUI", "com.apple.laf.AquaMenuBarUI" );
|
||||
|
||||
// add defaults necessary for AquaMenuBarUI
|
||||
@@ -435,17 +438,17 @@ public abstract class FlatLaf
|
||||
private void initFonts( UIDefaults defaults ) {
|
||||
FontUIResource uiFont = null;
|
||||
|
||||
if( SystemInfo.IS_WINDOWS ) {
|
||||
if( SystemInfo.isWindows ) {
|
||||
Font winFont = (Font) Toolkit.getDefaultToolkit().getDesktopProperty( "win.messagebox.font" );
|
||||
if( winFont != null )
|
||||
uiFont = createCompositeFont( winFont.getFamily(), winFont.getStyle(), winFont.getSize() );
|
||||
|
||||
} else if( SystemInfo.IS_MAC ) {
|
||||
} else if( SystemInfo.isMacOS ) {
|
||||
String fontName;
|
||||
if( SystemInfo.IS_MAC_OS_10_15_CATALINA_OR_LATER ) {
|
||||
if( SystemInfo.isMacOS_10_15_Catalina_orLater ) {
|
||||
// use Helvetica Neue font
|
||||
fontName = "Helvetica Neue";
|
||||
} else if( SystemInfo.IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER ) {
|
||||
} else if( SystemInfo.isMacOS_10_11_ElCapitan_orLater ) {
|
||||
// use San Francisco Text font
|
||||
fontName = ".SF NS Text";
|
||||
} else {
|
||||
@@ -455,7 +458,7 @@ public abstract class FlatLaf
|
||||
|
||||
uiFont = createCompositeFont( fontName, Font.PLAIN, 13 );
|
||||
|
||||
} else if( SystemInfo.IS_LINUX ) {
|
||||
} else if( SystemInfo.isLinux ) {
|
||||
Font font = LinuxFontPolicy.getFont();
|
||||
uiFont = (font instanceof FontUIResource) ? (FontUIResource) font : new FontUIResource( font );
|
||||
}
|
||||
@@ -515,7 +518,7 @@ public abstract class FlatLaf
|
||||
}
|
||||
|
||||
private void putAATextInfo( UIDefaults defaults ) {
|
||||
if( SystemInfo.IS_JAVA_9_OR_LATER ) {
|
||||
if( SystemInfo.isJava_9_orLater ) {
|
||||
Object desktopHints = Toolkit.getDefaultToolkit().getDesktopProperty( DESKTOPFONTHINTS );
|
||||
if( desktopHints instanceof Map ) {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
@@ -552,6 +555,87 @@ public abstract class FlatLaf
|
||||
defaults.put( key, value );
|
||||
}
|
||||
|
||||
static List<Object> getCustomDefaultsSources() {
|
||||
return customDefaultsSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a package where FlatLaf searches for properties files with custom UI defaults.
|
||||
* <p>
|
||||
* This can be used to specify application specific UI defaults that override UI values
|
||||
* of existing themes or to define own UI values used in custom controls.
|
||||
* <p>
|
||||
* There may be multiple properties files in that package for multiple themes.
|
||||
* The properties file name must match the used theme class names.
|
||||
* E.g. {@code FlatLightLaf.properties} for class {@link FlatLightLaf}
|
||||
* or {@code FlatDarkLaf.properties} for class {@link FlatDarkLaf}.
|
||||
* {@code FlatLaf.properties} is loaded first for all themes.
|
||||
* <p>
|
||||
* These properties files are loaded after theme and addon properties files
|
||||
* and can therefore override all UI defaults.
|
||||
* <p>
|
||||
* Invoke this method before setting the look and feel.
|
||||
*
|
||||
* @param packageName a package name (e.g. "com.myapp.resources")
|
||||
*/
|
||||
public static void registerCustomDefaultsSource( String packageName ) {
|
||||
registerCustomDefaultsSource( packageName, null );
|
||||
}
|
||||
|
||||
public static void unregisterCustomDefaultsSource( String packageName ) {
|
||||
unregisterCustomDefaultsSource( packageName, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a package where FlatLaf searches for properties files with custom UI defaults.
|
||||
* <p>
|
||||
* See {@link #registerCustomDefaultsSource(String)} for details.
|
||||
*
|
||||
* @param packageName a package name (e.g. "com.myapp.resources")
|
||||
* @param classLoader a class loader used to find resources, or {@code null}
|
||||
*/
|
||||
public static void registerCustomDefaultsSource( String packageName, ClassLoader classLoader ) {
|
||||
if( customDefaultsSources == null )
|
||||
customDefaultsSources = new ArrayList<>();
|
||||
customDefaultsSources.add( packageName );
|
||||
customDefaultsSources.add( classLoader );
|
||||
}
|
||||
|
||||
public static void unregisterCustomDefaultsSource( String packageName, ClassLoader classLoader ) {
|
||||
if( customDefaultsSources == null )
|
||||
return;
|
||||
|
||||
int size = customDefaultsSources.size();
|
||||
for( int i = 0; i < size - 1; i++ ) {
|
||||
Object source = customDefaultsSources.get( i );
|
||||
if( packageName.equals( source ) && customDefaultsSources.get( i + 1 ) == classLoader ) {
|
||||
customDefaultsSources.remove( i + 1 );
|
||||
customDefaultsSources.remove( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a folder where FlatLaf searches for properties files with custom UI defaults.
|
||||
* <p>
|
||||
* See {@link #registerCustomDefaultsSource(String)} for details.
|
||||
*
|
||||
* @param folder a folder
|
||||
*/
|
||||
public static void registerCustomDefaultsSource( File folder ) {
|
||||
if( customDefaultsSources == null )
|
||||
customDefaultsSources = new ArrayList<>();
|
||||
customDefaultsSources.add( folder );
|
||||
}
|
||||
|
||||
public static void unregisterCustomDefaultsSource( File folder ) {
|
||||
if( customDefaultsSources == null )
|
||||
return;
|
||||
|
||||
customDefaultsSources.remove( folder );
|
||||
}
|
||||
|
||||
private static void reSetLookAndFeel() {
|
||||
EventQueue.invokeLater( () -> {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
|
||||
@@ -39,6 +39,14 @@ public interface FlatSystemProperties
|
||||
*/
|
||||
String UI_SCALE = "flatlaf.uiScale";
|
||||
|
||||
/**
|
||||
* Specifies whether user scaling mode is enabled.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled";
|
||||
|
||||
/**
|
||||
* Specifies whether Ubuntu font should be used on Ubuntu Linux.
|
||||
* By default, if not running in a JetBrains Runtime, the Liberation Sans font
|
||||
|
||||
@@ -147,6 +147,10 @@ public class IntelliJTheme
|
||||
applyColorPalette( defaults );
|
||||
applyCheckBoxColors( defaults );
|
||||
|
||||
// copy values
|
||||
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() )
|
||||
defaults.put( e.getKey(), defaults.get( e.getValue() ) );
|
||||
|
||||
// IDEA does not paint button background if disabled, but FlatLaf does
|
||||
Object panelBackground = defaults.get( "Panel.background" );
|
||||
defaults.put( "Button.disabledBackground", panelBackground );
|
||||
@@ -259,6 +263,9 @@ public class IntelliJTheme
|
||||
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
||||
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
} else {
|
||||
if( "".equals( value ) )
|
||||
return; // ignore empty value
|
||||
|
||||
uiKeys.add( key );
|
||||
|
||||
// fix ComboBox size and Spinner border in all Material UI Lite themes
|
||||
@@ -412,6 +419,10 @@ public class IntelliJTheme
|
||||
|
||||
String newKey = checkboxKeyMapping.get( key );
|
||||
if( newKey != null ) {
|
||||
String checkBoxIconPrefix = "CheckBox.icon.";
|
||||
if( !dark && newKey.startsWith( checkBoxIconPrefix ) )
|
||||
newKey = "CheckBox.icon[filled].".concat( newKey.substring( checkBoxIconPrefix.length() ) );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
if( color != null ) {
|
||||
defaults.put( newKey, color );
|
||||
@@ -444,17 +455,24 @@ public class IntelliJTheme
|
||||
|
||||
// remove hover and pressed colors
|
||||
if( checkboxModified ) {
|
||||
defaults.remove( "CheckBox.icon.focusWidth" );
|
||||
defaults.remove( "CheckBox.icon.hoverBorderColor" );
|
||||
defaults.remove( "CheckBox.icon.focusedBackground" );
|
||||
defaults.remove( "CheckBox.icon.hoverBackground" );
|
||||
defaults.remove( "CheckBox.icon.pressedBackground" );
|
||||
defaults.remove( "CheckBox.icon.selectedFocusedBackground" );
|
||||
defaults.remove( "CheckBox.icon.selectedHoverBackground" );
|
||||
defaults.remove( "CheckBox.icon.selectedPressedBackground" );
|
||||
}
|
||||
|
||||
// copy values
|
||||
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() )
|
||||
defaults.put( e.getKey(), defaults.get( e.getValue() ) );
|
||||
defaults.remove( "CheckBox.icon[filled].focusWidth" );
|
||||
defaults.remove( "CheckBox.icon[filled].hoverBorderColor" );
|
||||
defaults.remove( "CheckBox.icon[filled].focusedBackground" );
|
||||
defaults.remove( "CheckBox.icon[filled].hoverBackground" );
|
||||
defaults.remove( "CheckBox.icon[filled].pressedBackground" );
|
||||
defaults.remove( "CheckBox.icon[filled].selectedFocusedBackground" );
|
||||
defaults.remove( "CheckBox.icon[filled].selectedHoverBackground" );
|
||||
defaults.remove( "CheckBox.icon[filled].selectedPressedBackground" );
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> uiKeyMapping = new HashMap<>();
|
||||
@@ -499,6 +517,8 @@ public class IntelliJTheme
|
||||
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
|
||||
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionForeground", "ProgressBar.background" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionBackground", "ProgressBar.foreground" );
|
||||
|
||||
// ScrollBar
|
||||
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
|
||||
@@ -511,6 +531,7 @@ public class IntelliJTheme
|
||||
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// TitlePane
|
||||
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
|
||||
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
||||
uiKeyMapping.put( "TitlePane.inactiveInfoForeground", "TitlePane.inactiveForeground" );
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
class LinuxFontPolicy
|
||||
{
|
||||
static Font getFont() {
|
||||
return SystemInfo.IS_KDE ? getKDEFont() : getGnomeFont();
|
||||
return SystemInfo.isKDE ? getKDEFont() : getGnomeFont();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ class LinuxFontPolicy
|
||||
// Ubuntu font is rendered poorly (except if running in JetBrains VM)
|
||||
// --> use Liberation Sans font
|
||||
if( family.startsWith( "Ubuntu" ) &&
|
||||
!SystemInfo.IS_JETBRAINS_JVM &&
|
||||
!SystemInfo.isJetBrainsJVM &&
|
||||
!FlatSystemProperties.getBoolean( FlatSystemProperties.USE_UBUNTU_FONT, false ) )
|
||||
family = "Liberation Sans";
|
||||
|
||||
|
||||
@@ -71,13 +71,13 @@ class MnemonicHandler
|
||||
@Override
|
||||
public boolean postProcessKeyEvent( KeyEvent e ) {
|
||||
int keyCode = e.getKeyCode();
|
||||
if( SystemInfo.IS_MAC ) {
|
||||
if( SystemInfo.isMacOS ) {
|
||||
// Ctrl+Alt keys must be pressed on Mac
|
||||
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_ALT )
|
||||
showMnemonics( shouldShowMnemonics( e ) && e.isControlDown() && e.isAltDown(), e.getComponent() );
|
||||
} else {
|
||||
// Alt key must be pressed on Windows and Linux
|
||||
if( SystemInfo.IS_WINDOWS )
|
||||
if( SystemInfo.isWindows )
|
||||
return processKeyEventOnWindows( e );
|
||||
|
||||
if( keyCode == KeyEvent.VK_ALT )
|
||||
|
||||
@@ -19,14 +19,18 @@ package com.formdev.flatlaf;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
@@ -115,6 +119,46 @@ class UIDefaultsLoader
|
||||
addonClassLoaders.add( addonClassLoader );
|
||||
}
|
||||
|
||||
// load custom properties files (usually provides by applications)
|
||||
List<Object> customDefaultsSources = FlatLaf.getCustomDefaultsSources();
|
||||
int size = (customDefaultsSources != null) ? customDefaultsSources.size() : 0;
|
||||
for( int i = 0; i < size; i++ ) {
|
||||
Object source = customDefaultsSources.get( i );
|
||||
if( source instanceof String && i + 1 < size ) {
|
||||
// load from package in classloader
|
||||
String packageName = (String) source;
|
||||
ClassLoader classLoader = (ClassLoader) customDefaultsSources.get( ++i );
|
||||
|
||||
// use class loader also for instantiating classes specified in values
|
||||
if( classLoader != null && !addonClassLoaders.contains( classLoader ) )
|
||||
addonClassLoaders.add( classLoader );
|
||||
|
||||
packageName = packageName.replace( '.', '/' );
|
||||
if( classLoader == null )
|
||||
classLoader = FlatLaf.class.getClassLoader();
|
||||
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
String propertiesName = packageName + '/' + lafClass.getSimpleName() + ".properties";
|
||||
try( InputStream in = classLoader.getResourceAsStream( propertiesName ) ) {
|
||||
if( in != null )
|
||||
properties.load( in );
|
||||
}
|
||||
}
|
||||
} else if( source instanceof File ) {
|
||||
// load from folder
|
||||
File folder = (File) source;
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
File propertiesFile = new File( folder, lafClass.getSimpleName() + ".properties" );
|
||||
if( !propertiesFile.isFile() )
|
||||
continue;
|
||||
|
||||
try( InputStream in = new FileInputStream( propertiesFile ) ) {
|
||||
properties.load( in );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add additional defaults
|
||||
if( additionalDefaults != null )
|
||||
properties.putAll( additionalDefaults );
|
||||
@@ -144,9 +188,9 @@ class UIDefaultsLoader
|
||||
|
||||
// handle platform specific properties
|
||||
String platformPrefix =
|
||||
SystemInfo.IS_WINDOWS ? "[win]" :
|
||||
SystemInfo.IS_MAC ? "[mac]" :
|
||||
SystemInfo.IS_LINUX ? "[linux]" : "[unknown]";
|
||||
SystemInfo.isWindows ? "[win]" :
|
||||
SystemInfo.isMacOS ? "[mac]" :
|
||||
SystemInfo.isLinux ? "[linux]" : "[unknown]";
|
||||
for( String key : platformSpecificKeys ) {
|
||||
Object value = properties.remove( key );
|
||||
if( key.startsWith( platformPrefix ) )
|
||||
@@ -154,45 +198,45 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
Function<String, String> resolver = value -> {
|
||||
return resolveValue( properties, value );
|
||||
};
|
||||
|
||||
// get globals, which override all other defaults that end with same suffix
|
||||
HashMap<String, Object> globals = new HashMap<>();
|
||||
for( Map.Entry<Object, Object> e : properties.entrySet() ) {
|
||||
// get (and remove) globals, which override all other defaults that end with same suffix
|
||||
HashMap<String, String> globals = new HashMap<>();
|
||||
Iterator<Entry<Object, Object>> it = properties.entrySet().iterator();
|
||||
while( it.hasNext() ) {
|
||||
Entry<Object, Object> e = it.next();
|
||||
String key = (String) e.getKey();
|
||||
if( !key.startsWith( GLOBAL_PREFIX ) )
|
||||
continue;
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
try {
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( Level.SEVERE, key, value, ex );
|
||||
if( key.startsWith( GLOBAL_PREFIX ) ) {
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), (String) e.getValue() );
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// override UI defaults with globals
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && ((String)key).contains( "." ) ) {
|
||||
String skey = (String) key;
|
||||
String globalKey = skey.substring( skey.lastIndexOf( '.' ) + 1 );
|
||||
Object globalValue = globals.get( globalKey );
|
||||
if( globalValue != null )
|
||||
defaults.put( key, globalValue );
|
||||
for( Object okey : defaults.keySet() ) {
|
||||
if( okey instanceof String && ((String)okey).contains( "." ) ) {
|
||||
String key = (String) okey;
|
||||
String globalKey = key.substring( key.lastIndexOf( '.' ) + 1 );
|
||||
String globalValue = globals.get( globalKey );
|
||||
if( globalValue != null && !properties.containsKey( key ) )
|
||||
properties.put( key, globalValue );
|
||||
}
|
||||
}
|
||||
|
||||
// add non-global properties to UI defaults
|
||||
Function<String, String> propertiesGetter = key -> {
|
||||
return properties.getProperty( key );
|
||||
};
|
||||
Function<String, String> resolver = value -> {
|
||||
return resolveValue( value, propertiesGetter );
|
||||
};
|
||||
|
||||
// parse and add properties to UI defaults
|
||||
for( Map.Entry<Object, Object> e : properties.entrySet() ) {
|
||||
String key = (String) e.getKey();
|
||||
if( key.startsWith( VARIABLE_PREFIX ) || key.startsWith( GLOBAL_PREFIX ) )
|
||||
if( key.startsWith( VARIABLE_PREFIX ) )
|
||||
continue;
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
String value = resolveValue( (String) e.getValue(), propertiesGetter );
|
||||
try {
|
||||
defaults.put( key, parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
defaults.put( key, parseValue( key, value, null, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( Level.SEVERE, key, value, ex );
|
||||
}
|
||||
@@ -206,7 +250,10 @@ class UIDefaultsLoader
|
||||
FlatLaf.LOG.log( level, "FlatLaf: Failed to parse: '" + key + '=' + value + '\'', ex );
|
||||
}
|
||||
|
||||
private static String resolveValue( Properties properties, String value ) {
|
||||
static String resolveValue( String value, Function<String, String> propertiesGetter ) {
|
||||
value = value.trim();
|
||||
String value0 = value;
|
||||
|
||||
if( value.startsWith( PROPERTY_PREFIX ) )
|
||||
value = value.substring( PROPERTY_PREFIX.length() );
|
||||
else if( !value.startsWith( VARIABLE_PREFIX ) )
|
||||
@@ -218,7 +265,7 @@ class UIDefaultsLoader
|
||||
optional = true;
|
||||
}
|
||||
|
||||
String newValue = properties.getProperty( value );
|
||||
String newValue = propertiesGetter.apply( value );
|
||||
if( newValue == null ) {
|
||||
if( optional )
|
||||
return "null";
|
||||
@@ -226,29 +273,40 @@ class UIDefaultsLoader
|
||||
throw new IllegalArgumentException( "variable or property '" + value + "' not found" );
|
||||
}
|
||||
|
||||
return resolveValue( properties, newValue );
|
||||
if( newValue.equals( value0 ) )
|
||||
throw new IllegalArgumentException( "endless recursion in variable or property '" + value + "'" );
|
||||
|
||||
return resolveValue( newValue, propertiesGetter );
|
||||
}
|
||||
|
||||
private enum ValueType { UNKNOWN, STRING, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
|
||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER }
|
||||
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
|
||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
||||
|
||||
private static ValueType[] tempResultValueType = new ValueType[1];
|
||||
|
||||
static Object parseValue( String key, String value ) {
|
||||
return parseValue( key, value, v -> v, Collections.emptyList() );
|
||||
return parseValue( key, value, null, v -> v, Collections.emptyList() );
|
||||
}
|
||||
|
||||
private static Object parseValue( String key, String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
static Object parseValue( String key, String value, ValueType[] resultValueType,
|
||||
Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
|
||||
{
|
||||
if( resultValueType == null )
|
||||
resultValueType = tempResultValueType;
|
||||
|
||||
value = value.trim();
|
||||
|
||||
// null, false, true
|
||||
switch( value ) {
|
||||
case "null": return null;
|
||||
case "false": return false;
|
||||
case "true": return true;
|
||||
case "null": resultValueType[0] = ValueType.NULL; return null;
|
||||
case "false": resultValueType[0] = ValueType.BOOLEAN; return false;
|
||||
case "true": resultValueType[0] = ValueType.BOOLEAN; return true;
|
||||
}
|
||||
|
||||
// check for function "lazy"
|
||||
// Syntax: lazy(uiKey)
|
||||
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
|
||||
resultValueType[0] = ValueType.LAZY;
|
||||
String uiKey = value.substring( 5, value.length() - 1 ).trim();
|
||||
return (LazyValue) t -> {
|
||||
return lazyUIManagerGet( uiKey );
|
||||
@@ -301,6 +359,8 @@ class UIDefaultsLoader
|
||||
valueType = ValueType.GRAYFILTER;
|
||||
}
|
||||
|
||||
resultValueType[0] = valueType;
|
||||
|
||||
// parse value
|
||||
switch( valueType ) {
|
||||
case STRING: return value;
|
||||
@@ -323,20 +383,27 @@ class UIDefaultsLoader
|
||||
default:
|
||||
// colors
|
||||
Object color = parseColorOrFunction( value, resolver, false );
|
||||
if( color != null )
|
||||
if( color != null ) {
|
||||
resultValueType[0] = ValueType.COLOR;
|
||||
return color;
|
||||
}
|
||||
|
||||
// integer
|
||||
Integer integer = parseInteger( value, false );
|
||||
if( integer != null )
|
||||
if( integer != null ) {
|
||||
resultValueType[0] = ValueType.INTEGER;
|
||||
return integer;
|
||||
}
|
||||
|
||||
// float
|
||||
Float f = parseFloat( value, false );
|
||||
if( f != null )
|
||||
if( f != null ) {
|
||||
resultValueType[0] = ValueType.FLOAT;
|
||||
return f;
|
||||
}
|
||||
|
||||
// string
|
||||
resultValueType[0] = ValueType.STRING;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -612,6 +679,8 @@ class UIDefaultsLoader
|
||||
// parse base color
|
||||
String resolvedColorStr = resolver.apply( colorStr );
|
||||
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver, reportError );
|
||||
if( baseColor == null )
|
||||
return null;
|
||||
|
||||
// apply this function to base color
|
||||
Color newColor = ColorFunctions.applyFunctions( baseColor, function );
|
||||
|
||||
@@ -43,24 +43,24 @@ import com.formdev.flatlaf.util.DerivedColor;
|
||||
* Border for various components (e.g. {@link javax.swing.JTextField}).
|
||||
*
|
||||
* There is empty space around the component border, if Component.focusWidth is greater than zero,
|
||||
* which is used to paint focus border.
|
||||
* which is used to paint outer focus border.
|
||||
*
|
||||
* Because there is empty space (if focus border is not painted),
|
||||
* Because there is empty space (if outer focus border is not painted),
|
||||
* UI delegates that use this border (or subclasses) must invoke
|
||||
* {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly.
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.innerFocusWidth int or float
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Component.focusedBorderColor Color
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.innerFocusWidth int or float
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Component.focusedBorderColor Color
|
||||
*
|
||||
* @uiDefault Component.error.borderColor Color
|
||||
* @uiDefault Component.error.focusedBorderColor Color
|
||||
* @uiDefault Component.warning.borderColor Color
|
||||
* @uiDefault Component.warning.focusedBorderColor Color
|
||||
* @uiDefault Component.custom.borderColor Color
|
||||
* @uiDefault Component.error.borderColor Color
|
||||
* @uiDefault Component.error.focusedBorderColor Color
|
||||
* @uiDefault Component.warning.borderColor Color
|
||||
* @uiDefault Component.warning.focusedBorderColor Color
|
||||
* @uiDefault Component.custom.borderColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -87,22 +87,23 @@ public class FlatBorder
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
boolean isCellEditor = isTableCellEditor( c );
|
||||
float focusWidth = isCellEditor ? 0 : scale( (float) getFocusWidth( c ) );
|
||||
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||
float borderWidth = scale( (float) getBorderWidth( c ) );
|
||||
float arc = isCellEditor ? 0 : scale( (float) getArc( c ) );
|
||||
float arc = scale( (float) getArc( c ) );
|
||||
Color outlineColor = getOutlineColor( c );
|
||||
|
||||
// paint outer border
|
||||
if( outlineColor != null || isFocused( c ) ) {
|
||||
float innerFocusWidth = !(c instanceof JScrollPane)
|
||||
? (outlineColor != null ? innerOutlineWidth : this.innerFocusWidth)
|
||||
float innerWidth = !isCellEditor( c ) && !(c instanceof JScrollPane)
|
||||
? (outlineColor != null ? innerOutlineWidth : innerFocusWidth)
|
||||
: 0;
|
||||
|
||||
g2.setColor( (outlineColor != null) ? outlineColor : getFocusColor( c ) );
|
||||
FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height, focusWidth,
|
||||
scale( (float) getLineWidth( c ) ) + scale( innerFocusWidth ), arc );
|
||||
FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height,
|
||||
focusWidth, borderWidth + scale( innerWidth ), arc );
|
||||
}
|
||||
|
||||
// paint border
|
||||
g2.setPaint( (outlineColor != null) ? outlineColor : getBorderColor( c ) );
|
||||
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
||||
} finally {
|
||||
@@ -110,6 +111,10 @@ public class FlatBorder
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the outline color of the component border specified in client property
|
||||
* {@link FlatClientProperties#OUTLINE}.
|
||||
*/
|
||||
protected Color getOutlineColor( Component c ) {
|
||||
if( !(c instanceof JComponent) )
|
||||
return null;
|
||||
@@ -192,14 +197,13 @@ public class FlatBorder
|
||||
return FlatUIUtils.isPermanentFocusOwner( c );
|
||||
}
|
||||
|
||||
protected boolean isTableCellEditor( Component c ) {
|
||||
return FlatUIUtils.isTableCellEditor( c );
|
||||
protected boolean isCellEditor( Component c ) {
|
||||
return FlatUIUtils.isCellEditor( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
boolean isCellEditor = isTableCellEditor( c );
|
||||
float focusWidth = isCellEditor ? 0 : scale( (float) getFocusWidth( c ) );
|
||||
float focusWidth = scale( (float) getFocusWidth( c ) );
|
||||
float ow = focusWidth + scale( (float) getLineWidth( c ) );
|
||||
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
@@ -207,6 +211,18 @@ public class FlatBorder
|
||||
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 );
|
||||
|
||||
if( isCellEditor( c ) ) {
|
||||
// remove top and bottom insets if used as cell editor
|
||||
insets.top = insets.bottom = 0;
|
||||
|
||||
// remove right/left insets to avoid that text is truncated (e.g. in file chooser)
|
||||
if( c.getComponentOrientation().isLeftToRight() )
|
||||
insets.right = 0;
|
||||
else
|
||||
insets.left = 0;
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@@ -214,6 +230,9 @@ public class FlatBorder
|
||||
* Returns the (unscaled) thickness of the outer focus border.
|
||||
*/
|
||||
protected int getFocusWidth( Component c ) {
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
return focusWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||
* @uiDefault Button.default.focusedBorderColor Color
|
||||
* @uiDefault Button.default.focusColor Color
|
||||
* @uiDefault Button.borderWidth int
|
||||
* @uiDefault Button.default.borderWidth int
|
||||
* @uiDefault Button.toolbar.margin Insets
|
||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||
@@ -62,6 +63,7 @@ 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" );
|
||||
protected final int borderWidth = UIManager.getInt( "Button.borderWidth" );
|
||||
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
|
||||
protected final Insets toolbarMargin = UIManager.getInsets( "Button.toolbar.margin" );
|
||||
protected final Insets toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" );
|
||||
@@ -134,11 +136,14 @@ public class FlatButtonBorder
|
||||
|
||||
@Override
|
||||
protected int getBorderWidth( Component c ) {
|
||||
return FlatButtonUI.isDefaultButton( c ) ? defaultBorderWidth : super.getBorderWidth( c );
|
||||
return FlatButtonUI.isDefaultButton( c ) ? defaultBorderWidth : borderWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getArc( Component c ) {
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
switch( FlatButtonUI.getButtonType( c ) ) {
|
||||
case FlatButtonUI.TYPE_SQUARE: return 0;
|
||||
case FlatButtonUI.TYPE_ROUND_RECT: return Short.MAX_VALUE;
|
||||
|
||||
@@ -67,8 +67,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Button.focusedBackground Color optional
|
||||
* @uiDefault Button.hoverBackground Color optional
|
||||
* @uiDefault Button.pressedBackground Color optional
|
||||
* @uiDefault Button.selectedBackground Color
|
||||
* @uiDefault Button.selectedForeground Color
|
||||
* @uiDefault Button.disabledBackground Color optional
|
||||
* @uiDefault Button.disabledText Color
|
||||
* @uiDefault Button.disabledSelectedBackground Color
|
||||
* @uiDefault Button.default.background Color
|
||||
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
||||
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
||||
@@ -84,6 +87,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||
* @uiDefault Button.toolbar.hoverBackground Color
|
||||
* @uiDefault Button.toolbar.pressedBackground Color
|
||||
* @uiDefault Button.toolbar.selectedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -101,8 +105,11 @@ public class FlatButtonUI
|
||||
protected Color focusedBackground;
|
||||
protected Color hoverBackground;
|
||||
protected Color pressedBackground;
|
||||
protected Color selectedBackground;
|
||||
protected Color selectedForeground;
|
||||
protected Color disabledBackground;
|
||||
protected Color disabledText;
|
||||
protected Color disabledSelectedBackground;
|
||||
|
||||
protected Color defaultBackground;
|
||||
protected Color defaultEndBackground;
|
||||
@@ -119,6 +126,7 @@ public class FlatButtonUI
|
||||
protected Insets toolbarSpacingInsets;
|
||||
protected Color toolbarHoverBackground;
|
||||
protected Color toolbarPressedBackground;
|
||||
protected Color toolbarSelectedBackground;
|
||||
|
||||
private Icon helpButtonIcon;
|
||||
|
||||
@@ -150,8 +158,11 @@ public class FlatButtonUI
|
||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
||||
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
||||
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
||||
|
||||
if( UIManager.getBoolean( "Button.paintShadow" ) ) {
|
||||
shadowWidth = FlatUIUtils.getUIInt( "Button.shadowWidth", 2 );
|
||||
@@ -174,6 +185,7 @@ public class FlatButtonUI
|
||||
toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" );
|
||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||
|
||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||
|
||||
@@ -202,13 +214,7 @@ public class FlatButtonUI
|
||||
|
||||
@Override
|
||||
protected BasicButtonListener createButtonListener( AbstractButton b ) {
|
||||
return new BasicButtonListener( b ) {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
FlatButtonUI.this.propertyChange( b, e );
|
||||
}
|
||||
};
|
||||
return new FlatButtonListener( b );
|
||||
}
|
||||
|
||||
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
|
||||
@@ -375,6 +381,17 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
protected Color getBackground( JComponent c ) {
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
// in toolbar use same colors for disabled and enabled because
|
||||
// we assume that toolbar icon is shown disabled
|
||||
boolean toolBarButton = isToolBarButton( c );
|
||||
return buttonStateColor( c,
|
||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
||||
null, null,
|
||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||
}
|
||||
|
||||
if( !c.isEnabled() )
|
||||
return disabledBackground;
|
||||
|
||||
@@ -436,6 +453,9 @@ public class FlatButtonUI
|
||||
if( !c.isEnabled() )
|
||||
return disabledText;
|
||||
|
||||
if( ((AbstractButton)c).isSelected() && !isToolBarButton( c ) )
|
||||
return selectedForeground;
|
||||
|
||||
// use component foreground if explicitly set
|
||||
Color fg = c.getForeground();
|
||||
if( isCustomForeground( fg ) )
|
||||
@@ -475,4 +495,23 @@ public class FlatButtonUI
|
||||
|
||||
return prefSize;
|
||||
}
|
||||
|
||||
//---- class FlatButtonListener -------------------------------------------
|
||||
|
||||
protected class FlatButtonListener
|
||||
extends BasicButtonListener
|
||||
{
|
||||
private final AbstractButton b;
|
||||
|
||||
protected FlatButtonListener( AbstractButton b ) {
|
||||
super( b );
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
FlatButtonUI.this.propertyChange( b, e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListCellRenderer;
|
||||
@@ -119,7 +120,7 @@ public class FlatComboBoxUI
|
||||
protected Color buttonHoverArrowColor;
|
||||
|
||||
private MouseListener hoverListener;
|
||||
private boolean hover;
|
||||
protected boolean hover;
|
||||
|
||||
private WeakReference<Component> lastRendererComponent;
|
||||
|
||||
@@ -306,7 +307,7 @@ public class FlatComboBoxUI
|
||||
updateEditorColors();
|
||||
|
||||
// macOS
|
||||
if( SystemInfo.IS_MAC && editor instanceof JTextComponent ) {
|
||||
if( SystemInfo.isMacOS && editor instanceof JTextComponent ) {
|
||||
// delegate actions from editor text field to combobox, which is necessary
|
||||
// because text field on macOS already handle those keys
|
||||
InputMap inputMap = ((JTextComponent)editor).getInputMap();
|
||||
@@ -332,14 +333,7 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
return new FlatArrowButton( SwingConstants.SOUTH, arrowType, buttonArrowColor,
|
||||
buttonDisabledArrowColor, buttonHoverArrowColor, null )
|
||||
{
|
||||
@Override
|
||||
protected boolean isHover() {
|
||||
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
||||
}
|
||||
};
|
||||
return new FlatComboBoxButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -507,6 +501,27 @@ public class FlatComboBoxUI
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatComboBoxButton -------------------------------------------
|
||||
|
||||
protected class FlatComboBoxButton
|
||||
extends FlatArrowButton
|
||||
{
|
||||
protected FlatComboBoxButton() {
|
||||
this( SwingConstants.SOUTH, arrowType, buttonArrowColor, buttonDisabledArrowColor, buttonHoverArrowColor, null, null );
|
||||
}
|
||||
|
||||
protected FlatComboBoxButton( int direction, String type, Color foreground, Color disabledForeground,
|
||||
Color hoverForeground, Color hoverBackground, Color pressedBackground )
|
||||
{
|
||||
super( direction, type, foreground, disabledForeground, hoverForeground, hoverBackground, pressedBackground );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isHover() {
|
||||
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatComboPopup -----------------------------------------------
|
||||
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
@@ -530,13 +545,26 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
protected Rectangle computePopupBounds( int px, int py, int pw, int ph ) {
|
||||
// get maximum display size of all items
|
||||
Dimension displaySize = getDisplaySize();
|
||||
// get maximum display width of all items
|
||||
int displayWidth = getDisplaySize().width;
|
||||
|
||||
// add border insets
|
||||
for( Border border : new Border[] { scroller.getViewportBorder(), scroller.getBorder() } ) {
|
||||
if( border != null ) {
|
||||
Insets borderInsets = border.getBorderInsets( null );
|
||||
displayWidth += borderInsets.left + borderInsets.right;
|
||||
}
|
||||
}
|
||||
|
||||
// add width of vertical scroll bar
|
||||
JScrollBar verticalScrollBar = scroller.getVerticalScrollBar();
|
||||
if( verticalScrollBar != null )
|
||||
displayWidth += verticalScrollBar.getPreferredSize().width;
|
||||
|
||||
// make popup wider if necessary
|
||||
if( displaySize.width > pw ) {
|
||||
int diff = displaySize.width - pw;
|
||||
pw = displaySize.width;
|
||||
if( displayWidth > pw ) {
|
||||
int diff = displayWidth - pw;
|
||||
pw = displayWidth;
|
||||
|
||||
if( !comboBox.getComponentOrientation().isLeftToRight() )
|
||||
px -= diff;
|
||||
|
||||
@@ -57,4 +57,8 @@ public class FlatEmptyBorder
|
||||
insets.bottom = scale( bottom );
|
||||
return insets;
|
||||
}
|
||||
|
||||
public Insets getUnscaledBorderInsets() {
|
||||
return super.getBorderInsets();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,14 @@ import java.beans.PropertyChangeListener;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
|
||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -91,7 +92,21 @@ public class FlatInternalFrameTitlePane
|
||||
updateFrameIcon();
|
||||
updateColors();
|
||||
|
||||
buttonPanel = new JPanel();
|
||||
buttonPanel = new JPanel() {
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
int height = size.height;
|
||||
// use height of invisible buttons to always have same title pane height
|
||||
if( !iconButton.isVisible() )
|
||||
height = Math.max( height, iconButton.getPreferredSize().height );
|
||||
if( !maxButton.isVisible() )
|
||||
height = Math.max( height, maxButton.getPreferredSize().height );
|
||||
if( !closeButton.isVisible() )
|
||||
height = Math.max( height, closeButton.getPreferredSize().height );
|
||||
return new Dimension( size.width, height );
|
||||
}
|
||||
};
|
||||
buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) );
|
||||
buttonPanel.setOpaque( false );
|
||||
|
||||
@@ -103,14 +118,16 @@ public class FlatInternalFrameTitlePane
|
||||
add( buttonPanel, BorderLayout.LINE_END );
|
||||
}
|
||||
|
||||
private void updateFrameIcon() {
|
||||
protected void updateFrameIcon() {
|
||||
Icon frameIcon = frame.getFrameIcon();
|
||||
if( frameIcon == UIManager.getIcon( "InternalFrame.icon" ) )
|
||||
if( frameIcon != null && (frameIcon.getIconWidth() == 0 || frameIcon.getIconHeight() == 0) )
|
||||
frameIcon = null;
|
||||
else if( frameIcon instanceof ImageIcon )
|
||||
frameIcon = new ScaledImageIcon( (ImageIcon) frameIcon );
|
||||
titleLabel.setIcon( frameIcon );
|
||||
}
|
||||
|
||||
private void updateColors() {
|
||||
protected void updateColors() {
|
||||
Color background = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTitleColor : notSelectedTitleColor );
|
||||
Color foreground = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTextColor : notSelectedTextColor );
|
||||
|
||||
@@ -123,7 +140,7 @@ public class FlatInternalFrameTitlePane
|
||||
closeButton.setForeground( foreground );
|
||||
}
|
||||
|
||||
private void updateButtonsVisibility() {
|
||||
protected void updateButtonsVisibility() {
|
||||
iconButton.setVisible( frame.isIconifiable() );
|
||||
maxButton.setVisible( frame.isMaximizable() );
|
||||
closeButton.setVisible( frame.isClosable() );
|
||||
@@ -150,7 +167,7 @@ public class FlatInternalFrameTitlePane
|
||||
|
||||
//---- class FlatPropertyChangeHandler ------------------------------------
|
||||
|
||||
private class FlatPropertyChangeHandler
|
||||
protected class FlatPropertyChangeHandler
|
||||
extends PropertyChangeHandler
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -84,6 +84,8 @@ import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
public class FlatInternalFrameUI
|
||||
extends BasicInternalFrameUI
|
||||
{
|
||||
protected FlatWindowResizer windowResizer;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatInternalFrameUI( (JInternalFrame) c );
|
||||
}
|
||||
@@ -97,6 +99,18 @@ public class FlatInternalFrameUI
|
||||
super.installUI( c );
|
||||
|
||||
LookAndFeel.installProperty( frame, "opaque", false );
|
||||
|
||||
windowResizer = createWindowResizer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI( JComponent c ) {
|
||||
super.uninstallUI( c );
|
||||
|
||||
if( windowResizer != null ) {
|
||||
windowResizer.uninstall();
|
||||
windowResizer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,6 +118,10 @@ public class FlatInternalFrameUI
|
||||
return new FlatInternalFrameTitlePane( w );
|
||||
}
|
||||
|
||||
protected FlatWindowResizer createWindowResizer() {
|
||||
return new FlatWindowResizer.InternalFrameResizer( frame, this::getDesktopManager );
|
||||
}
|
||||
|
||||
//---- class FlatInternalFrameBorder --------------------------------------
|
||||
|
||||
public static class FlatInternalFrameBorder
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import javax.swing.JComponent;
|
||||
@@ -106,7 +107,11 @@ public class FlatListUI
|
||||
@Override
|
||||
public void focusLost( FocusEvent e ) {
|
||||
super.focusLost( e );
|
||||
toggleSelectionColors();
|
||||
|
||||
// use invokeLater for the case that the window is deactivated
|
||||
EventQueue.invokeLater( () -> {
|
||||
toggleSelectionColors();
|
||||
} );
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -121,6 +126,9 @@ public class FlatListUI
|
||||
* or the application has to be changed to extend a FlatLaf renderer.
|
||||
*/
|
||||
private void toggleSelectionColors() {
|
||||
if( list == null )
|
||||
return;
|
||||
|
||||
if( FlatUIUtils.isPermanentFocusOwner( list ) ) {
|
||||
if( list.getSelectionBackground() == selectionInactiveBackground )
|
||||
list.setSelectionBackground( selectionBackground );
|
||||
|
||||
@@ -82,7 +82,7 @@ public class FlatMenuBarUI
|
||||
JMenuBar menuBar = (JMenuBar) e.getSource();
|
||||
JMenu menu = menuBar.getMenu( 0 );
|
||||
if( menu != null ) {
|
||||
MenuSelectionManager.defaultManager().setSelectedPath( SystemInfo.IS_WINDOWS
|
||||
MenuSelectionManager.defaultManager().setSelectedPath( SystemInfo.isWindows
|
||||
? new MenuElement[] { menuBar, menu }
|
||||
: new MenuElement[] { menuBar, menu, menu.getPopupMenu() } );
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import javax.swing.text.View;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Renderer for menu items.
|
||||
@@ -418,36 +419,78 @@ debug*/
|
||||
|
||||
private KeyStroke cachedAccelerator;
|
||||
private String cachedAcceleratorText;
|
||||
private boolean cachedAcceleratorLeftToRight;
|
||||
|
||||
private String getAcceleratorText() {
|
||||
KeyStroke accelerator = menuItem.getAccelerator();
|
||||
if( accelerator == null )
|
||||
return null;
|
||||
|
||||
if( accelerator == cachedAccelerator )
|
||||
boolean leftToRight = menuItem.getComponentOrientation().isLeftToRight();
|
||||
|
||||
if( accelerator == cachedAccelerator && leftToRight == cachedAcceleratorLeftToRight )
|
||||
return cachedAcceleratorText;
|
||||
|
||||
cachedAccelerator = accelerator;
|
||||
cachedAcceleratorText = getTextForAccelerator( accelerator );
|
||||
cachedAcceleratorLeftToRight = leftToRight;
|
||||
|
||||
return cachedAcceleratorText;
|
||||
}
|
||||
|
||||
protected String getTextForAccelerator( KeyStroke accelerator ) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
int modifiers = accelerator.getModifiers();
|
||||
if( modifiers != 0 )
|
||||
buf.append( InputEvent.getModifiersExText( modifiers ) ).append( acceleratorDelimiter );
|
||||
boolean leftToRight = menuItem.getComponentOrientation().isLeftToRight();
|
||||
|
||||
// modifiers
|
||||
int modifiers = accelerator.getModifiers();
|
||||
if( modifiers != 0 ) {
|
||||
if( SystemInfo.isMacOS ) {
|
||||
if( leftToRight )
|
||||
buf.append( getMacOSModifiersExText( modifiers, leftToRight ) );
|
||||
} else
|
||||
buf.append( InputEvent.getModifiersExText( modifiers ) ).append( acceleratorDelimiter );
|
||||
}
|
||||
|
||||
// key
|
||||
int keyCode = accelerator.getKeyCode();
|
||||
if( keyCode != 0 )
|
||||
buf.append( KeyEvent.getKeyText( keyCode ) );
|
||||
else
|
||||
buf.append( accelerator.getKeyChar() );
|
||||
|
||||
// modifiers if right-to-left on macOS
|
||||
if( modifiers != 0 && !leftToRight && SystemInfo.isMacOS )
|
||||
buf.append( getMacOSModifiersExText( modifiers, leftToRight ) );
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String getMacOSModifiersExText( int modifiers, boolean leftToRight ) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
if( (modifiers & InputEvent.CTRL_DOWN_MASK) != 0 )
|
||||
buf.append( controlGlyph );
|
||||
if( (modifiers & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK)) != 0 )
|
||||
buf.append( optionGlyph );
|
||||
if( (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 )
|
||||
buf.append( shiftGlyph );
|
||||
if( (modifiers & InputEvent.META_DOWN_MASK) != 0 )
|
||||
buf.append( commandGlyph );
|
||||
|
||||
// reverse order for right-to-left
|
||||
if( !leftToRight )
|
||||
buf.reverse();
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static final char
|
||||
controlGlyph = 0x2303,
|
||||
optionGlyph = 0x2325,
|
||||
shiftGlyph = 0x21E7,
|
||||
commandGlyph = 0x2318;
|
||||
|
||||
//---- class MinSizeIcon --------------------------------------------------
|
||||
|
||||
private class MinSizeIcon
|
||||
|
||||
@@ -123,6 +123,14 @@ public class FlatMenuUI
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
// avoid that top-level menus (in menu bar) are made smaller if horizontal space is rare
|
||||
// same code is in BasicMenuUI since Java 10
|
||||
// see https://bugs.openjdk.java.net/browse/JDK-8178430
|
||||
return ((JMenu)menuItem).isTopLevelMenu() ? c.getPreferredSize() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||
return renderer.getPreferredMenuItemSize();
|
||||
|
||||
@@ -60,6 +60,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault PasswordField.placeholderForeground Color
|
||||
* @uiDefault PasswordField.showCapsLock boolean
|
||||
* @uiDefault PasswordField.capsLockIcon Icon
|
||||
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
|
||||
*
|
||||
@@ -71,6 +72,7 @@ public class FlatPasswordFieldUI
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
protected Color placeholderForeground;
|
||||
protected boolean showCapsLock;
|
||||
protected Icon capsLockIcon;
|
||||
|
||||
private FocusListener focusListener;
|
||||
@@ -88,6 +90,7 @@ public class FlatPasswordFieldUI
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
|
||||
showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
|
||||
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );
|
||||
|
||||
LookAndFeel.installProperty( getComponent(), "opaque", false );
|
||||
@@ -160,6 +163,9 @@ public class FlatPasswordFieldUI
|
||||
}
|
||||
|
||||
protected void paintCapsLock( Graphics g ) {
|
||||
if( !showCapsLock )
|
||||
return;
|
||||
|
||||
JTextComponent c = getComponent();
|
||||
if( !FlatUIUtils.isPermanentFocusOwner( c ) ||
|
||||
!Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK ) )
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
@@ -32,6 +33,8 @@ import java.lang.reflect.Method;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.RootPaneContainer;
|
||||
@@ -40,6 +43,7 @@ import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* A popup factory that adds drop shadows to popups on Windows.
|
||||
@@ -58,19 +62,97 @@ public class FlatPopupFactory
|
||||
public Popup getPopup( Component owner, Component contents, int x, int y )
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
Point pt = fixToolTipLocation( owner, contents, x, y );
|
||||
if( pt != null ) {
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
if( !isDropShadowPainted( owner, contents ) )
|
||||
return new NonFlashingPopup( super.getPopup( owner, contents, x, y ), contents );
|
||||
return new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, false ), contents );
|
||||
|
||||
// macOS and Linux adds drop shadow to heavy weight popups
|
||||
if( SystemInfo.IS_MAC || SystemInfo.IS_LINUX ) {
|
||||
Popup popup = getHeavyWeightPopup( owner, contents, x, y );
|
||||
if( SystemInfo.isMacOS || SystemInfo.isLinux ) {
|
||||
Popup popup = getPopupForScreenOfOwner( owner, contents, x, y, true );
|
||||
if( popup == null )
|
||||
popup = super.getPopup( owner, contents, x, y );
|
||||
popup = getPopupForScreenOfOwner( owner, contents, x, y, false );
|
||||
return new NonFlashingPopup( popup, contents );
|
||||
}
|
||||
|
||||
// create drop shadow popup
|
||||
return new DropShadowPopup( super.getPopup( owner, contents, x, y ), owner, contents );
|
||||
return new DropShadowPopup( getPopupForScreenOfOwner( owner, contents, x, y, false ), owner, contents );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a popup for the screen that the owner component is on.
|
||||
* <p>
|
||||
* PopupFactory caches heavy weight popup windows and reuses them.
|
||||
* On a dual screen setup, if the popup owner has moved from one screen to the other one,
|
||||
* then the cached heavy weight popup window may be connected to the wrong screen.
|
||||
* If the two screens use different scaling factors, then the popup location and size
|
||||
* is scaled when the popup becomes visible, which shows the popup in the wrong location
|
||||
* (or on wrong screen). The re-scaling is done in WWindowPeer.setBounds() (Java 9+).
|
||||
* <p>
|
||||
* To fix this, dispose popup windows that are on wrong screen and get new popup.
|
||||
* <p>
|
||||
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
||||
*/
|
||||
private Popup getPopupForScreenOfOwner( Component owner, Component contents, int x, int y, boolean forceHeavyWeight )
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for(;;) {
|
||||
// create new or get cached popup
|
||||
Popup popup = forceHeavyWeight
|
||||
? getHeavyWeightPopup( owner, contents, x, y )
|
||||
: super.getPopup( owner, contents, x, y );
|
||||
|
||||
// get heavy weight popup window; is null for non-heavy weight popup
|
||||
Window popupWindow = SwingUtilities.windowForComponent( contents );
|
||||
|
||||
// check whether heavy weight popup window is on same screen as owner component
|
||||
if( popupWindow == null ||
|
||||
popupWindow.getGraphicsConfiguration() == owner.getGraphicsConfiguration() )
|
||||
return popup;
|
||||
|
||||
// remove contents component from popup window
|
||||
if( popupWindow instanceof JWindow )
|
||||
((JWindow)popupWindow).getContentPane().removeAll();
|
||||
|
||||
// dispose unused popup
|
||||
// (do not invoke popup.hide() because this would cache the popup window)
|
||||
popupWindow.dispose();
|
||||
|
||||
// avoid endless loop (should newer happen; PopupFactory cache size is 5)
|
||||
if( ++count > 10 )
|
||||
return popup;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the given popup and, if necessary, fixes the location of a heavy weight popup window.
|
||||
* <p>
|
||||
* On a dual screen setup, where screens use different scale factors, it may happen
|
||||
* that the window location changes when showing a heavy weight popup window.
|
||||
* E.g. when opening an dialog on the secondary screen and making combobox popup visible.
|
||||
* <p>
|
||||
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
||||
*/
|
||||
private static void showPopupAndFixLocation( Popup popup, Window popupWindow ) {
|
||||
if( popupWindow != null ) {
|
||||
// remember location of heavy weight popup window
|
||||
int x = popupWindow.getX();
|
||||
int y = popupWindow.getY();
|
||||
|
||||
popup.show();
|
||||
|
||||
// restore popup window location if it has changed
|
||||
// (probably scaled when screens use different scale factors)
|
||||
if( popupWindow.getX() != x || popupWindow.getY() != y )
|
||||
popupWindow.setLocation( x, y );
|
||||
} else
|
||||
popup.show();
|
||||
}
|
||||
|
||||
private boolean isDropShadowPainted( Component owner, Component contents ) {
|
||||
@@ -105,7 +187,7 @@ public class FlatPopupFactory
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
try {
|
||||
if( SystemInfo.IS_JAVA_9_OR_LATER ) {
|
||||
if( SystemInfo.isJava_9_orLater ) {
|
||||
if( java9getPopupMethod == null ) {
|
||||
java9getPopupMethod = PopupFactory.class.getDeclaredMethod(
|
||||
"getPopup", Component.class, Component.class, int.class, int.class, boolean.class );
|
||||
@@ -126,12 +208,38 @@ public class FlatPopupFactory
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).
|
||||
* In case that the tooltip would be partly outside of the screen,
|
||||
* ToolTipManagerthe changes the location so that the entire tooltip fits on screen.
|
||||
* But this can place the tooltip under the mouse location and hide the owner component.
|
||||
* <p>
|
||||
* This method checks whether the current mouse location is within tooltip bounds
|
||||
* and corrects the y-location so that the tooltip is placed above the mouse location.
|
||||
*/
|
||||
private Point fixToolTipLocation( Component owner, Component contents, int x, int y ) {
|
||||
if( !(contents instanceof JToolTip) )
|
||||
return null;
|
||||
|
||||
Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
|
||||
Dimension tipSize = contents.getPreferredSize();
|
||||
|
||||
// check whether mouse location is within tooltip bounds
|
||||
Rectangle tipBounds = new Rectangle( x, y, tipSize.width, tipSize.height );
|
||||
if( !tipBounds.contains( mouseLocation ) )
|
||||
return null;
|
||||
|
||||
// place tooltip above mouse location
|
||||
return new Point( x, mouseLocation.y - tipSize.height - UIScale.scale( 20 ) );
|
||||
}
|
||||
|
||||
//---- class NonFlashingPopup ---------------------------------------------
|
||||
|
||||
private class NonFlashingPopup
|
||||
extends Popup
|
||||
{
|
||||
private Popup delegate;
|
||||
private Component contents;
|
||||
|
||||
// heavy weight
|
||||
protected Window popupWindow;
|
||||
@@ -139,6 +247,7 @@ public class FlatPopupFactory
|
||||
|
||||
NonFlashingPopup( Popup delegate, Component contents ) {
|
||||
this.delegate = delegate;
|
||||
this.contents = contents;
|
||||
|
||||
popupWindow = SwingUtilities.windowForComponent( contents );
|
||||
if( popupWindow != null ) {
|
||||
@@ -153,8 +262,25 @@ public class FlatPopupFactory
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if( delegate != null )
|
||||
delegate.show();
|
||||
if( delegate != null ) {
|
||||
showPopupAndFixLocation( delegate, popupWindow );
|
||||
|
||||
// increase tooltip size if necessary because it may be too small on HiDPI screens
|
||||
// https://bugs.openjdk.java.net/browse/JDK-8213535
|
||||
if( contents instanceof JToolTip ) {
|
||||
Container parent = contents.getParent();
|
||||
if( parent instanceof JPanel ) {
|
||||
Dimension prefSize = parent.getPreferredSize();
|
||||
if( !prefSize.equals( parent.getSize() ) ) {
|
||||
Container panel = SwingUtilities.getAncestorOfClass( Panel.class, parent );
|
||||
if( panel != null )
|
||||
panel.setSize( prefSize ); // for medium weight popup
|
||||
else
|
||||
parent.setSize( prefSize ); // for light weight popup
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,6 +288,7 @@ public class FlatPopupFactory
|
||||
if( delegate != null ) {
|
||||
delegate.hide();
|
||||
delegate = null;
|
||||
contents = null;
|
||||
}
|
||||
|
||||
if( popupWindow != null ) {
|
||||
@@ -228,7 +355,7 @@ public class FlatPopupFactory
|
||||
// create heavy weight popup for drop shadow
|
||||
int x = popupWindow.getX() - insets.left;
|
||||
int y = popupWindow.getY() - insets.top;
|
||||
dropShadowDelegate = getHeavyWeightPopup( owner, dropShadowPanel, x, y );
|
||||
dropShadowDelegate = getPopupForScreenOfOwner( owner, dropShadowPanel, x, y, true );
|
||||
|
||||
// make drop shadow popup window translucent
|
||||
dropShadowWindow = SwingUtilities.windowForComponent( dropShadowPanel );
|
||||
@@ -270,7 +397,7 @@ public class FlatPopupFactory
|
||||
@Override
|
||||
public void show() {
|
||||
if( dropShadowDelegate != null )
|
||||
dropShadowDelegate.show();
|
||||
showPopupAndFixLocation( dropShadowDelegate, dropShadowWindow );
|
||||
|
||||
if( mediumWeightPanel != null )
|
||||
showMediumWeightDropShadow();
|
||||
|
||||
@@ -20,12 +20,13 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.LayoutManager2;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JComponent;
|
||||
@@ -51,12 +52,15 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
* <!-- FlatRootPaneUI -->
|
||||
*
|
||||
* @uiDefault RootPane.border Border
|
||||
* @uiDefault RootPane.activeBorderColor Color
|
||||
* @uiDefault RootPane.inactiveBorderColor Color
|
||||
*
|
||||
* <!-- FlatWindowResizer -->
|
||||
*
|
||||
* @uiDefault RootPane.borderDragThickness int
|
||||
* @uiDefault RootPane.cornerDragWidth int
|
||||
* @uiDefault RootPane.honorMinimumSizeOnResize boolean
|
||||
* @uiDefault RootPane.honorFrameMinimumSizeOnResize boolean
|
||||
* @uiDefault RootPane.honorDialogMinimumSizeOnResize boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -65,12 +69,13 @@ public class FlatRootPaneUI
|
||||
{
|
||||
// check this field before using class JBRCustomDecorations to avoid unnecessary loading of that class
|
||||
static final boolean canUseJBRCustomDecorations
|
||||
= SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER && SystemInfo.IS_WINDOWS_10_OR_LATER;
|
||||
= SystemInfo.isJetBrainsJVM_11_orLater && SystemInfo.isWindows_10_orLater;
|
||||
|
||||
protected JRootPane rootPane;
|
||||
protected FlatTitlePane titlePane;
|
||||
protected FlatWindowResizer windowResizer;
|
||||
|
||||
private JRootPane rootPane;
|
||||
private FlatTitlePane titlePane;
|
||||
private LayoutManager oldLayout;
|
||||
private FlatWindowResizer windowResizer;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatRootPaneUI();
|
||||
@@ -114,7 +119,7 @@ public class FlatRootPaneUI
|
||||
}
|
||||
|
||||
// enable dark window appearance on macOS when running in JetBrains Runtime
|
||||
if( SystemInfo.IS_JETBRAINS_JVM && SystemInfo.IS_MAC_OS_10_14_MOJAVE ) {
|
||||
if( SystemInfo.isJetBrainsJVM && SystemInfo.isMacOS_10_14_Mojave_orLater ) {
|
||||
LookAndFeel laf = UIManager.getLookAndFeel();
|
||||
boolean isDark = laf instanceof FlatLaf && ((FlatLaf)laf).isDark();
|
||||
c.putClientProperty( "jetbrains.awt.windowDarkAppearance", isDark );
|
||||
@@ -167,7 +172,7 @@ public class FlatRootPaneUI
|
||||
}
|
||||
|
||||
protected FlatWindowResizer createWindowResizer() {
|
||||
return new FlatWindowResizer( rootPane );
|
||||
return new FlatWindowResizer.WindowResizer( rootPane );
|
||||
}
|
||||
|
||||
protected FlatTitlePane createTitlePane() {
|
||||
@@ -299,6 +304,9 @@ public class FlatRootPaneUI
|
||||
Container contentPane = rootPane.getContentPane();
|
||||
if( contentPane != null )
|
||||
contentPane.setBounds( 0, nextY, width, Math.max( height - nextY, 0 ) );
|
||||
|
||||
if( titlePane != null )
|
||||
titlePane.menuBarLayouted();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -323,24 +331,45 @@ public class FlatRootPaneUI
|
||||
public static class FlatWindowBorder
|
||||
extends BorderUIResource.EmptyBorderUIResource
|
||||
{
|
||||
protected final Color activeBorderColor = UIManager.getColor( "RootPane.activeBorderColor" );
|
||||
protected final Color inactiveBorderColor = UIManager.getColor( "RootPane.inactiveBorderColor" );
|
||||
protected final Color baseBorderColor = UIManager.getColor( "Panel.background" );
|
||||
|
||||
public FlatWindowBorder() {
|
||||
super( 1, 1, 1, 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
Object borderColorObj = Toolkit.getDefaultToolkit().getDesktopProperty(
|
||||
"win.frame.activeBorderColor" );
|
||||
Color borderColor = (borderColorObj instanceof Color)
|
||||
? (Color) borderColorObj
|
||||
: UIManager.getColor( "windowBorder" );
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
if( isWindowMaximized( c ) ) {
|
||||
// hide border if window is maximized
|
||||
insets.top = insets.left = insets.bottom = insets.right = 0;
|
||||
return insets;
|
||||
} else
|
||||
return super.getBorderInsets( c, insets );
|
||||
}
|
||||
|
||||
g.setColor( borderColor );
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( isWindowMaximized( c ) )
|
||||
return;
|
||||
|
||||
Container parent = c.getParent();
|
||||
boolean active = parent instanceof Window ? ((Window)parent).isActive() : false;
|
||||
|
||||
g.setColor( FlatUIUtils.deriveColor( active ? activeBorderColor : inactiveBorderColor, baseBorderColor ) );
|
||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||
}
|
||||
|
||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
g.drawRect( x, y, width - 1, height - 1 );
|
||||
}
|
||||
|
||||
protected boolean isWindowMaximized( Component c ) {
|
||||
Container parent = c.getParent();
|
||||
return parent instanceof Frame
|
||||
? (((Frame)parent).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0
|
||||
: false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ public class FlatRoundBorder
|
||||
|
||||
@Override
|
||||
protected int getArc( Component c ) {
|
||||
return FlatUIUtils.isRoundRect( c ) ? Short.MAX_VALUE : arc;
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
Boolean roundRect = FlatUIUtils.isRoundRect( c );
|
||||
return roundRect != null ? (roundRect ? Short.MAX_VALUE : 0) : arc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,46 +198,12 @@ public class FlatScrollBarUI
|
||||
|
||||
@Override
|
||||
protected JButton createDecreaseButton( int orientation ) {
|
||||
return createArrowButton( orientation );
|
||||
return new FlatScrollBarButton( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JButton createIncreaseButton( int orientation ) {
|
||||
return createArrowButton( orientation );
|
||||
}
|
||||
|
||||
private JButton createArrowButton( int orientation ) {
|
||||
FlatArrowButton button = new FlatArrowButton( orientation, arrowType, buttonArrowColor,
|
||||
buttonDisabledArrowColor, null, hoverButtonBackground, pressedButtonBackground )
|
||||
{
|
||||
@Override
|
||||
protected Color deriveBackground( Color background ) {
|
||||
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
if( isShowButtons() ) {
|
||||
int w = UIScale.scale( scrollBarWidth );
|
||||
return new Dimension( w, w );
|
||||
} else
|
||||
return new Dimension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return isShowButtons() ? super.getMinimumSize() : new Dimension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return isShowButtons() ? super.getMaximumSize() : new Dimension();
|
||||
}
|
||||
};
|
||||
button.setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
|
||||
button.setFocusable( false );
|
||||
button.setRequestFocusEnabled( false );
|
||||
return button;
|
||||
return new FlatScrollBarButton( orientation );
|
||||
}
|
||||
|
||||
protected boolean isShowButtons() {
|
||||
@@ -318,12 +284,12 @@ public class FlatScrollBarUI
|
||||
|
||||
@Override
|
||||
protected Dimension getMinimumThumbSize() {
|
||||
return UIScale.scale( super.getMinimumThumbSize() );
|
||||
return UIScale.scale( FlatUIUtils.addInsets( super.getMinimumThumbSize(), thumbInsets ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getMaximumThumbSize() {
|
||||
return UIScale.scale( super.getMaximumThumbSize() );
|
||||
return UIScale.scale( FlatUIUtils.addInsets( super.getMaximumThumbSize(), thumbInsets ) );
|
||||
}
|
||||
|
||||
//---- class ScrollBarHoverListener ---------------------------------------
|
||||
@@ -377,4 +343,49 @@ public class FlatScrollBarUI
|
||||
scrollbar.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatScrollBarButton ------------------------------------------
|
||||
|
||||
protected class FlatScrollBarButton
|
||||
extends FlatArrowButton
|
||||
{
|
||||
protected FlatScrollBarButton( int direction ) {
|
||||
this( direction, arrowType, buttonArrowColor, buttonDisabledArrowColor,
|
||||
null, hoverButtonBackground, pressedButtonBackground );
|
||||
}
|
||||
|
||||
protected FlatScrollBarButton( int direction, String type, Color foreground, Color disabledForeground,
|
||||
Color hoverForeground, Color hoverBackground, Color pressedBackground )
|
||||
{
|
||||
super( direction, type, foreground, disabledForeground, hoverForeground, hoverBackground, pressedBackground );
|
||||
|
||||
setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
|
||||
setFocusable( false );
|
||||
setRequestFocusEnabled( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color deriveBackground( Color background ) {
|
||||
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
if( isShowButtons() ) {
|
||||
int w = UIScale.scale( scrollBarWidth );
|
||||
return new Dimension( w, w );
|
||||
} else
|
||||
return new Dimension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return isShowButtons() ? super.getMinimumSize() : new Dimension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return isShowButtons() ? super.getMaximumSize() : new Dimension();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,10 +114,7 @@ public class FlatScrollPaneUI
|
||||
return new BasicScrollPaneUI.MouseWheelHandler() {
|
||||
@Override
|
||||
public void mouseWheelMoved( MouseWheelEvent e ) {
|
||||
// Note: Getting UI value "ScrollPane.smoothScrolling" here to allow
|
||||
// applications to turn smooth scrolling on or off at any time
|
||||
// (e.g. in application options dialog).
|
||||
if( UIManager.getBoolean( "ScrollPane.smoothScrolling" ) &&
|
||||
if( isSmoothScrollingEnabled() &&
|
||||
scrollpane.isWheelScrollingEnabled() &&
|
||||
e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL &&
|
||||
e.getPreciseWheelRotation() != 0 &&
|
||||
@@ -130,6 +127,17 @@ public class FlatScrollPaneUI
|
||||
};
|
||||
}
|
||||
|
||||
protected boolean isSmoothScrollingEnabled() {
|
||||
Object smoothScrolling = scrollpane.getClientProperty( FlatClientProperties.SCROLL_PANE_SMOOTH_SCROLLING );
|
||||
if( smoothScrolling instanceof Boolean )
|
||||
return (Boolean) smoothScrolling;
|
||||
|
||||
// Note: Getting UI value "ScrollPane.smoothScrolling" here to allow
|
||||
// applications to turn smooth scrolling on or off at any time
|
||||
// (e.g. in application options dialog).
|
||||
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
||||
}
|
||||
|
||||
private static final double EPSILON = 1e-5d;
|
||||
|
||||
private void mouseWheelMovedSmooth( MouseWheelEvent e ) {
|
||||
|
||||
@@ -87,10 +87,10 @@ public class FlatSplitPaneUI
|
||||
|
||||
//---- class FlatSplitPaneDivider -----------------------------------------
|
||||
|
||||
private class FlatSplitPaneDivider
|
||||
protected class FlatSplitPaneDivider
|
||||
extends BasicSplitPaneDivider
|
||||
{
|
||||
public FlatSplitPaneDivider( BasicSplitPaneUI ui ) {
|
||||
protected FlatSplitPaneDivider( BasicSplitPaneUI ui ) {
|
||||
super( ui );
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ public class FlatTableHeaderUI
|
||||
g2.setColor( separatorColor );
|
||||
|
||||
int sepCount = columnCount;
|
||||
if( header.getTable().getAutoResizeMode() != JTable.AUTO_RESIZE_OFF && !isVerticalScrollBarVisible() )
|
||||
if( header.getTable() != null && header.getTable().getAutoResizeMode() != JTable.AUTO_RESIZE_OFF && !isVerticalScrollBarVisible() )
|
||||
sepCount--;
|
||||
|
||||
if( header.getComponentOrientation().isLeftToRight() ) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import javax.swing.JCheckBox;
|
||||
@@ -70,6 +71,10 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Table.cellFocusColor Color
|
||||
* @uiDefault Table.showCellFocusIndicator boolean
|
||||
*
|
||||
* <!-- FlatInputMaps -->
|
||||
*
|
||||
* @uiDefault Table.consistentHomeEndKeyBehavior boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatTableUI
|
||||
@@ -92,16 +97,6 @@ public class FlatTableUI
|
||||
return new FlatTableUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI( JComponent c ) {
|
||||
super.uninstallUI( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
@@ -174,7 +169,11 @@ public class FlatTableUI
|
||||
@Override
|
||||
public void focusLost( FocusEvent e ) {
|
||||
super.focusLost( e );
|
||||
toggleSelectionColors();
|
||||
|
||||
// use invokeLater for the case that the window is deactivated
|
||||
EventQueue.invokeLater( () -> {
|
||||
toggleSelectionColors();
|
||||
} );
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -189,6 +188,9 @@ public class FlatTableUI
|
||||
* or the application has to be changed to extend a FlatLaf renderer.
|
||||
*/
|
||||
private void toggleSelectionColors() {
|
||||
if( table == null )
|
||||
return;
|
||||
|
||||
if( FlatUIUtils.isPermanentFocusOwner( table ) ) {
|
||||
if( table.getSelectionBackground() == selectionInactiveBackground )
|
||||
table.setSelectionBackground( selectionBackground );
|
||||
|
||||
@@ -60,6 +60,7 @@ public class FlatTextAreaUI
|
||||
{
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
protected Color background;
|
||||
protected Color disabledBackground;
|
||||
protected Color inactiveBackground;
|
||||
|
||||
@@ -67,12 +68,20 @@ public class FlatTextAreaUI
|
||||
return new FlatTextAreaUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
updateBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
background = UIManager.getColor( "TextArea.background" );
|
||||
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
|
||||
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
|
||||
}
|
||||
@@ -81,6 +90,7 @@ public class FlatTextAreaUI
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
background = null;
|
||||
disabledBackground = null;
|
||||
inactiveBackground = null;
|
||||
}
|
||||
@@ -89,26 +99,36 @@ public class FlatTextAreaUI
|
||||
protected void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
FlatEditorPaneUI.propertyChange( getComponent(), e );
|
||||
|
||||
switch( e.getPropertyName() ) {
|
||||
case "editable":
|
||||
case "enabled":
|
||||
updateBackground();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintSafely( Graphics g ) {
|
||||
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground( Graphics g ) {
|
||||
private void updateBackground() {
|
||||
JTextComponent c = getComponent();
|
||||
|
||||
Color background = c.getBackground();
|
||||
g.setColor( !(background instanceof UIResource)
|
||||
? background
|
||||
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
|
||||
? FlatUIUtils.getParentBackground( c )
|
||||
: (!c.isEnabled()
|
||||
? disabledBackground
|
||||
: (!c.isEditable() ? inactiveBackground : background))) );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
if( !(background instanceof UIResource) )
|
||||
return;
|
||||
|
||||
// do not update background if it currently has a unknown color (assigned from outside)
|
||||
if( background != this.background &&
|
||||
background != disabledBackground &&
|
||||
background != inactiveBackground )
|
||||
return;
|
||||
|
||||
Color newBackground = !c.isEnabled()
|
||||
? disabledBackground
|
||||
: (!c.isEditable()
|
||||
? inactiveBackground
|
||||
: this.background);
|
||||
|
||||
if( newBackground != background )
|
||||
c.setBackground( newBackground );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,4 +148,22 @@ public class FlatTextAreaUI
|
||||
|
||||
return FlatEditorPaneUI.applyMinimumWidth( c, size, minimumWidth );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintSafely( Graphics g ) {
|
||||
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground( Graphics g ) {
|
||||
JTextComponent c = getComponent();
|
||||
|
||||
// for compatibility with IntelliJ themes
|
||||
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
|
||||
FlatUIUtils.paintParentBackground( g, c );
|
||||
return;
|
||||
}
|
||||
|
||||
super.paintBackground( g );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ public class FlatTextBorder
|
||||
|
||||
@Override
|
||||
protected int getArc( Component c ) {
|
||||
return FlatUIUtils.isRoundRect( c ) ? Short.MAX_VALUE : arc;
|
||||
if( isCellEditor( c ) )
|
||||
return 0;
|
||||
|
||||
Boolean roundRect = FlatUIUtils.isRoundRect( c );
|
||||
return roundRect != null ? (roundRect ? Short.MAX_VALUE : 0) : arc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
@@ -55,6 +56,7 @@ import javax.swing.JLabel;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
@@ -90,30 +92,31 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public class FlatTitlePane
|
||||
extends JComponent
|
||||
{
|
||||
private final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||
private final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||
private final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
|
||||
private final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" );
|
||||
private final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
|
||||
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
|
||||
protected final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" );
|
||||
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
|
||||
|
||||
private final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" );
|
||||
private final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||
private final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
||||
protected final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" );
|
||||
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
||||
|
||||
private final JRootPane rootPane;
|
||||
protected final JRootPane rootPane;
|
||||
|
||||
private JPanel leftPanel;
|
||||
private JLabel iconLabel;
|
||||
private JComponent menuBarPlaceholder;
|
||||
private JLabel titleLabel;
|
||||
private JPanel buttonPanel;
|
||||
private JButton iconifyButton;
|
||||
private JButton maximizeButton;
|
||||
private JButton restoreButton;
|
||||
private JButton closeButton;
|
||||
protected JPanel leftPanel;
|
||||
protected JLabel iconLabel;
|
||||
protected JComponent menuBarPlaceholder;
|
||||
protected JLabel titleLabel;
|
||||
protected JPanel buttonPanel;
|
||||
protected JButton iconifyButton;
|
||||
protected JButton maximizeButton;
|
||||
protected JButton restoreButton;
|
||||
protected JButton closeButton;
|
||||
|
||||
protected Window window;
|
||||
|
||||
private final Handler handler;
|
||||
private Window window;
|
||||
|
||||
public FlatTitlePane( JRootPane rootPane ) {
|
||||
this.rootPane = rootPane;
|
||||
@@ -163,7 +166,25 @@ public class FlatTitlePane
|
||||
|
||||
createButtons();
|
||||
|
||||
setLayout( new BorderLayout() );
|
||||
setLayout( new BorderLayout() {
|
||||
@Override
|
||||
public void layoutContainer( Container target ) {
|
||||
super.layoutContainer( target );
|
||||
|
||||
// make left panel (with embedded menu bar) smaller if horizontal space is rare
|
||||
// to avoid that embedded menu bar overlaps button bar
|
||||
Insets insets = target.getInsets();
|
||||
int width = target.getWidth() - insets.left - insets.right;
|
||||
if( leftPanel.getWidth() + buttonPanel.getWidth() > width ) {
|
||||
int oldWidth = leftPanel.getWidth();
|
||||
int newWidth = Math.max( width - buttonPanel.getWidth(), 0 );
|
||||
leftPanel.setSize( newWidth, leftPanel.getHeight() );
|
||||
if( !getComponentOrientation().isLeftToRight() )
|
||||
leftPanel.setLocation( leftPanel.getX() + (oldWidth - newWidth), leftPanel.getY() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( leftPanel, BorderLayout.LINE_START );
|
||||
add( titleLabel, BorderLayout.CENTER );
|
||||
add( buttonPanel, BorderLayout.LINE_END );
|
||||
@@ -217,13 +238,19 @@ public class FlatTitlePane
|
||||
}
|
||||
|
||||
protected void activeChanged( boolean active ) {
|
||||
boolean hasEmbeddedMenuBar = rootPane.getJMenuBar() != null && isMenuBarEmbedded();
|
||||
Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground );
|
||||
Color foreground = FlatUIUtils.nonUIResource( active
|
||||
? (rootPane.getJMenuBar() != null && isMenuBarEmbedded() ? embeddedForeground : activeForeground)
|
||||
: inactiveForeground );
|
||||
Color foreground = FlatUIUtils.nonUIResource( active ? activeForeground : inactiveForeground );
|
||||
Color titleForeground = (hasEmbeddedMenuBar && active) ? FlatUIUtils.nonUIResource( embeddedForeground ) : foreground;
|
||||
|
||||
setBackground( background );
|
||||
titleLabel.setForeground( foreground );
|
||||
titleLabel.setForeground( titleForeground );
|
||||
iconifyButton.setForeground( foreground );
|
||||
maximizeButton.setForeground( foreground );
|
||||
restoreButton.setForeground( foreground );
|
||||
closeButton.setForeground( foreground );
|
||||
|
||||
titleLabel.setHorizontalAlignment( hasEmbeddedMenuBar ? SwingConstants.CENTER : SwingConstants.LEADING );
|
||||
|
||||
// this is necessary because hover/pressed colors are derived from background color
|
||||
iconifyButton.setBackground( background );
|
||||
@@ -244,6 +271,26 @@ public class FlatTitlePane
|
||||
iconifyButton.setVisible( true );
|
||||
maximizeButton.setVisible( resizable && !maximized );
|
||||
restoreButton.setVisible( resizable && maximized );
|
||||
|
||||
if( maximized &&
|
||||
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
||||
{
|
||||
rootPane.putClientProperty( "_flatlaf.maximizedBoundsUpToDate", null );
|
||||
|
||||
// In case that frame was maximized from custom code (e.g. when restoring
|
||||
// window state on application startup), then maximized bounds is not set
|
||||
// and the window would overlap Windows task bar.
|
||||
// To avoid this, update maximized bounds here and if it has changed
|
||||
// re-maximize windows so that maximized bounds are used.
|
||||
Rectangle oldMaximizedBounds = frame.getMaximizedBounds();
|
||||
updateMaximizedBounds();
|
||||
Rectangle newMaximizedBounds = frame.getMaximizedBounds();
|
||||
if( newMaximizedBounds != null && !newMaximizedBounds.equals( oldMaximizedBounds ) ) {
|
||||
int oldExtendedState = frame.getExtendedState();
|
||||
frame.setExtendedState( oldExtendedState & ~Frame.MAXIMIZED_BOTH );
|
||||
frame.setExtendedState( oldExtendedState );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// hide buttons because they are only supported in frames
|
||||
iconifyButton.setVisible( false );
|
||||
@@ -275,6 +322,8 @@ public class FlatTitlePane
|
||||
else {
|
||||
// no icon set on window --> use default icon
|
||||
Icon defaultIcon = UIManager.getIcon( "InternalFrame.icon" );
|
||||
if( defaultIcon != null && (defaultIcon.getIconWidth() == 0 || defaultIcon.getIconHeight() == 0) )
|
||||
defaultIcon = null;
|
||||
if( defaultIcon != null ) {
|
||||
if( defaultIcon instanceof ImageIcon )
|
||||
defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
|
||||
@@ -364,6 +413,12 @@ public class FlatTitlePane
|
||||
return FlatUIUtils.subtractInsets( bounds, UIScale.scale( getMenuBarMargins() ) );
|
||||
}
|
||||
|
||||
protected Insets getMenuBarMargins() {
|
||||
return getComponentOrientation().isLeftToRight()
|
||||
? menuBarMargins
|
||||
: new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left );
|
||||
}
|
||||
|
||||
protected void menuBarChanged() {
|
||||
menuBarPlaceholder.invalidate();
|
||||
|
||||
@@ -373,18 +428,43 @@ public class FlatTitlePane
|
||||
} );
|
||||
}
|
||||
|
||||
protected Insets getMenuBarMargins() {
|
||||
return getComponentOrientation().isLeftToRight()
|
||||
? menuBarMargins
|
||||
: new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left );
|
||||
protected void menuBarLayouted() {
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
}
|
||||
|
||||
/*debug
|
||||
@Override
|
||||
public void paint( Graphics g ) {
|
||||
super.paint( g );
|
||||
|
||||
if( debugTitleBarHeight > 0 ) {
|
||||
g.setColor( Color.green );
|
||||
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
|
||||
}
|
||||
if( debugHitTestSpots != null ) {
|
||||
g.setColor( Color.blue );
|
||||
for( Rectangle r : debugHitTestSpots )
|
||||
g.drawRect( r.x, r.y, r.width, r.height );
|
||||
}
|
||||
}
|
||||
debug*/
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
|
||||
protected void repaintWindowBorder() {
|
||||
int width = rootPane.getWidth();
|
||||
int height = rootPane.getHeight();
|
||||
Insets insets = rootPane.getInsets();
|
||||
rootPane.repaint( 0, 0, width, insets.top ); // top
|
||||
rootPane.repaint( 0, 0, insets.left, height ); // left
|
||||
rootPane.repaint( 0, height - insets.bottom, width, insets.bottom ); // bottom
|
||||
rootPane.repaint( width - insets.right, 0, insets.right, height ); // right
|
||||
}
|
||||
|
||||
/**
|
||||
* Iconifies the window.
|
||||
*/
|
||||
@@ -404,11 +484,24 @@ public class FlatTitlePane
|
||||
|
||||
Frame frame = (Frame) window;
|
||||
|
||||
updateMaximizedBounds();
|
||||
|
||||
// let our WindowStateListener know that the maximized bounds are up-to-date
|
||||
rootPane.putClientProperty( "_flatlaf.maximizedBoundsUpToDate", true );
|
||||
|
||||
// maximize window
|
||||
frame.setExtendedState( frame.getExtendedState() | Frame.MAXIMIZED_BOTH );
|
||||
}
|
||||
|
||||
protected void updateMaximizedBounds() {
|
||||
Frame frame = (Frame) window;
|
||||
|
||||
// set maximized bounds to avoid that maximized window overlaps Windows task bar
|
||||
// (if not running in JBR and if not modified from the application)
|
||||
Rectangle oldMaximizedBounds = frame.getMaximizedBounds();
|
||||
if( !hasJBRCustomDecoration() &&
|
||||
(frame.getMaximizedBounds() == null ||
|
||||
Objects.equals( frame.getMaximizedBounds(), rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) )
|
||||
(oldMaximizedBounds == null ||
|
||||
Objects.equals( oldMaximizedBounds, rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) )
|
||||
{
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
|
||||
@@ -429,7 +522,7 @@ public class FlatTitlePane
|
||||
int maximizedWidth = screenBounds.width;
|
||||
int maximizedHeight = screenBounds.height;
|
||||
|
||||
if( !SystemInfo.IS_JAVA_15_OR_LATER ) {
|
||||
if( !isMaximizedBoundsFixed() ) {
|
||||
// on Java 8 to 14, maximized x,y are 0,0 based on all screens in a multi-screen environment
|
||||
maximizedX = 0;
|
||||
maximizedY = 0;
|
||||
@@ -449,22 +542,36 @@ public class FlatTitlePane
|
||||
// (see https://bugs.openjdk.java.net/browse/JDK-8231564 and
|
||||
// https://bugs.openjdk.java.net/browse/JDK-8176359)
|
||||
// and except for Java 8 on secondary screens where primary screen is scaled
|
||||
Rectangle maximizedBounds = new Rectangle(
|
||||
Rectangle newMaximizedBounds = new Rectangle(
|
||||
maximizedX + screenInsets.left,
|
||||
maximizedY + screenInsets.top,
|
||||
maximizedWidth - screenInsets.left - screenInsets.right,
|
||||
maximizedHeight - screenInsets.top - screenInsets.bottom );
|
||||
|
||||
// change maximized bounds
|
||||
frame.setMaximizedBounds( maximizedBounds );
|
||||
if( !Objects.equals( oldMaximizedBounds, newMaximizedBounds ) ) {
|
||||
// change maximized bounds
|
||||
frame.setMaximizedBounds( newMaximizedBounds );
|
||||
|
||||
// remember maximized bounds in client property to be able to detect
|
||||
// whether maximized bounds are modified from the application
|
||||
rootPane.putClientProperty( "_flatlaf.maximizedBounds", maximizedBounds );
|
||||
// remember maximized bounds in client property to be able to detect
|
||||
// whether maximized bounds are modified from the application
|
||||
rootPane.putClientProperty( "_flatlaf.maximizedBounds", newMaximizedBounds );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maximize window
|
||||
frame.setExtendedState( frame.getExtendedState() | Frame.MAXIMIZED_BOTH );
|
||||
/**
|
||||
* Frame.setMaximizedBounds() behaves different on some Java versions after issues
|
||||
* https://bugs.openjdk.java.net/browse/JDK-8231564 and
|
||||
* https://bugs.openjdk.java.net/browse/JDK-8176359
|
||||
* (see also https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8176359)
|
||||
* were fixed in Java 15 and backported to 11.0.8 and 13.0.4.
|
||||
*/
|
||||
private boolean isMaximizedBoundsFixed() {
|
||||
return SystemInfo.isJava_15_orLater ||
|
||||
(SystemInfo.javaVersion >= SystemInfo.toVersion( 11, 0, 8, 0 ) &&
|
||||
SystemInfo.javaVersion < SystemInfo.toVersion( 12, 0, 0, 0 )) ||
|
||||
(SystemInfo.javaVersion >= SystemInfo.toVersion( 13, 0, 4, 0 ) &&
|
||||
SystemInfo.javaVersion < SystemInfo.toVersion( 14, 0, 0, 0 ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,6 +626,12 @@ public class FlatTitlePane
|
||||
titleBarHeight--;
|
||||
|
||||
JBRCustomDecorations.setHitTestSpotsAndTitleBarHeight( window, hitTestSpots, titleBarHeight );
|
||||
|
||||
/*debug
|
||||
debugHitTestSpots = hitTestSpots;
|
||||
debugTitleBarHeight = titleBarHeight;
|
||||
repaint();
|
||||
debug*/
|
||||
}
|
||||
|
||||
protected void addJBRHitTestSpot( JComponent c, boolean subtractMenuBarMargins, List<Rectangle> hitTestSpots ) {
|
||||
@@ -535,6 +648,11 @@ public class FlatTitlePane
|
||||
hitTestSpots.add( r );
|
||||
}
|
||||
|
||||
/*debug
|
||||
private List<Rectangle> debugHitTestSpots;
|
||||
private int debugTitleBarHeight;
|
||||
debug*/
|
||||
|
||||
//---- class TitlePaneBorder ----------------------------------------------
|
||||
|
||||
protected class FlatTitlePaneBorder
|
||||
@@ -613,6 +731,8 @@ public class FlatTitlePane
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
|
||||
repaintWindowBorder();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -622,6 +742,8 @@ public class FlatTitlePane
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
|
||||
repaintWindowBorder();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -632,8 +754,7 @@ public class FlatTitlePane
|
||||
|
||||
//---- interface MouseListener ----
|
||||
|
||||
private int lastXOnScreen;
|
||||
private int lastYOnScreen;
|
||||
private Point dragOffset;
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e ) {
|
||||
@@ -657,8 +778,10 @@ public class FlatTitlePane
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
lastXOnScreen = e.getXOnScreen();
|
||||
lastYOnScreen = e.getYOnScreen();
|
||||
if( window == null )
|
||||
return; // should newer occur
|
||||
|
||||
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
||||
}
|
||||
|
||||
@Override public void mouseReleased( MouseEvent e ) {}
|
||||
@@ -669,46 +792,45 @@ public class FlatTitlePane
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( window == null )
|
||||
return; // should newer occur
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
return; // do nothing if running in JBR
|
||||
|
||||
int xOnScreen = e.getXOnScreen();
|
||||
int yOnScreen = e.getYOnScreen();
|
||||
if( lastXOnScreen == xOnScreen && lastYOnScreen == yOnScreen )
|
||||
return;
|
||||
|
||||
// restore window if it is maximized
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
int state = frame.getExtendedState();
|
||||
if( (state & Frame.MAXIMIZED_BOTH) != 0 ) {
|
||||
int maximizedX = window.getX();
|
||||
int maximizedY = window.getY();
|
||||
int maximizedWidth = window.getWidth();
|
||||
|
||||
// restore window size, which also moves window to pre-maximized location
|
||||
frame.setExtendedState( state & ~Frame.MAXIMIZED_BOTH );
|
||||
|
||||
// fix drag offset to ensure that window remains under mouse position
|
||||
// for the case that dragging starts in the right area of the maximized window
|
||||
int restoredWidth = window.getWidth();
|
||||
int newX = maximizedX;
|
||||
JComponent rightComp = getComponentOrientation().isLeftToRight() ? buttonPanel : leftPanel;
|
||||
if( xOnScreen >= maximizedX + restoredWidth - rightComp.getWidth() - 10 )
|
||||
newX = xOnScreen + rightComp.getWidth() + 10 - restoredWidth;
|
||||
|
||||
// move window near mouse
|
||||
window.setLocation( newX, maximizedY );
|
||||
return;
|
||||
int center = restoredWidth / 2;
|
||||
if( dragOffset.x > center ) {
|
||||
// this is same/similar to what Windows 10 does
|
||||
if( dragOffset.x > maximizedWidth - center )
|
||||
dragOffset.x = restoredWidth - (maximizedWidth - dragOffset.x);
|
||||
else
|
||||
dragOffset.x = center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute new window location
|
||||
int newX = window.getX() + (xOnScreen - lastXOnScreen);
|
||||
int newY = window.getY() + (yOnScreen - lastYOnScreen);
|
||||
int newX = e.getXOnScreen() - dragOffset.x;
|
||||
int newY = e.getYOnScreen() - dragOffset.y;
|
||||
|
||||
if( newX == window.getX() && newY == window.getY() )
|
||||
return;
|
||||
|
||||
// move window
|
||||
window.setLocation( newX, newY );
|
||||
|
||||
lastXOnScreen = xOnScreen;
|
||||
lastYOnScreen = yOnScreen;
|
||||
}
|
||||
|
||||
@Override public void mouseMoved( MouseEvent e ) {}
|
||||
@@ -720,8 +842,13 @@ public class FlatTitlePane
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown( ComponentEvent e ) {
|
||||
// necessary for the case that the frame is maximized before it is shown
|
||||
frameStateChanged();
|
||||
}
|
||||
|
||||
@Override public void componentMoved( ComponentEvent e ) {}
|
||||
@Override public void componentShown( ComponentEvent e ) {}
|
||||
@Override public void componentHidden( ComponentEvent e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.UIManager;
|
||||
@@ -50,18 +49,17 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
||||
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault ToggleButton.pressedBackground Color
|
||||
* @uiDefault ToggleButton.disabledBackground Color optional
|
||||
* @uiDefault ToggleButton.disabledText Color
|
||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||
*
|
||||
* <!-- FlatToggleButtonUI -->
|
||||
*
|
||||
* @uiDefault ToggleButton.selectedBackground Color
|
||||
* @uiDefault ToggleButton.selectedForeground Color
|
||||
* @uiDefault ToggleButton.disabledBackground Color optional
|
||||
* @uiDefault ToggleButton.disabledText Color
|
||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||
*
|
||||
* <!-- FlatToggleButtonUI -->
|
||||
*
|
||||
* @uiDefault ToggleButton.tab.underlineHeight int
|
||||
* @uiDefault ToggleButton.tab.underlineColor Color
|
||||
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
||||
@@ -75,12 +73,6 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public class FlatToggleButtonUI
|
||||
extends FlatButtonUI
|
||||
{
|
||||
protected Color selectedBackground;
|
||||
protected Color selectedForeground;
|
||||
protected Color disabledSelectedBackground;
|
||||
|
||||
protected Color toolbarSelectedBackground;
|
||||
|
||||
protected int tabUnderlineHeight;
|
||||
protected Color tabUnderlineColor;
|
||||
protected Color tabDisabledUnderlineColor;
|
||||
@@ -108,12 +100,6 @@ public class FlatToggleButtonUI
|
||||
super.installDefaults( b );
|
||||
|
||||
if( !defaults_initialized ) {
|
||||
selectedBackground = UIManager.getColor( "ToggleButton.selectedBackground" );
|
||||
selectedForeground = UIManager.getColor( "ToggleButton.selectedForeground" );
|
||||
disabledSelectedBackground = UIManager.getColor( "ToggleButton.disabledSelectedBackground" );
|
||||
|
||||
toolbarSelectedBackground = UIManager.getColor( "ToggleButton.toolbar.selectedBackground" );
|
||||
|
||||
tabUnderlineHeight = UIManager.getInt( "ToggleButton.tab.underlineHeight" );
|
||||
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
||||
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
||||
@@ -185,30 +171,4 @@ public class FlatToggleButtonUI
|
||||
} else
|
||||
super.paintBackground( g, c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getBackground( JComponent c ) {
|
||||
ButtonModel model = ((AbstractButton)c).getModel();
|
||||
|
||||
if( model.isSelected() ) {
|
||||
// in toolbar use same colors for disabled and enabled because
|
||||
// we assume that toolbar icon is shown disabled
|
||||
boolean toolBarButton = isToolBarButton( c );
|
||||
return buttonStateColor( c,
|
||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
||||
null, null,
|
||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||
}
|
||||
|
||||
return super.getBackground( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getForeground( JComponent c ) {
|
||||
if( c.isEnabled() && ((AbstractButton)c).isSelected() && !isToolBarButton( c ) )
|
||||
return selectedForeground;
|
||||
|
||||
return super.getForeground( c );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ public class FlatToolTipUI
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
// do not show tool tip if text is empty
|
||||
String text = ((JToolTip)c).getTipText();
|
||||
if( text == null || text.isEmpty() )
|
||||
return new Dimension();
|
||||
|
||||
if( isMultiLine( c ) ) {
|
||||
FontMetrics fm = c.getFontMetrics( c.getFont() );
|
||||
Insets insets = c.getInsets();
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.LookAndFeel;
|
||||
@@ -75,6 +76,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Tree.dropCellBackground Color
|
||||
* @uiDefault Tree.dropCellForeground Color
|
||||
*
|
||||
* <!-- DefaultTreeCellEditor -->
|
||||
*
|
||||
* @uiDefault Tree.editorBorder Border
|
||||
* @uiDefault Tree.editorBorderSelectionColor Color
|
||||
*
|
||||
* <!-- FlatTreeUI -->
|
||||
*
|
||||
* @uiDefault Tree.border Border
|
||||
@@ -226,6 +232,11 @@ public class FlatTreeUI
|
||||
boolean isSelected = tree.isRowSelected( row );
|
||||
boolean isDropRow = isDropRow( row );
|
||||
|
||||
// if tree is used as cell renderer in another component (e.g. in Rhino JavaScript debugger),
|
||||
// check whether that component is focused to get correct selection colors
|
||||
if( !hasFocus && isSelected && tree.getParent() instanceof CellRendererPane )
|
||||
hasFocus = FlatUIUtils.isPermanentFocusOwner( tree.getParent().getParent() );
|
||||
|
||||
// wide selection background
|
||||
if( wideSelection && (isSelected || isDropRow) ) {
|
||||
// fill background
|
||||
|
||||
@@ -37,7 +37,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.function.Consumer;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
@@ -135,17 +137,44 @@ public class FlatUIUtils
|
||||
return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_HEIGHT, minimumHeight );
|
||||
}
|
||||
|
||||
public static boolean isTableCellEditor( Component c ) {
|
||||
public static boolean isCellEditor( Component c ) {
|
||||
// check whether used in cell editor (check 3 levels up)
|
||||
Component c2 = c;
|
||||
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
||||
Container parent = c2.getParent();
|
||||
if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c2 )
|
||||
return true;
|
||||
|
||||
c2 = parent;
|
||||
}
|
||||
|
||||
// check whether used as cell editor
|
||||
// Table.editor is set in JTable.GenericEditor constructor
|
||||
// Tree.cellEditor is set in sun.swing.FilePane.editFileName()
|
||||
String name = c.getName();
|
||||
if( "Table.editor".equals( name ) || "Tree.cellEditor".equals( name ) )
|
||||
return true;
|
||||
|
||||
// for using combo box as cell editor in table
|
||||
// JComboBox.isTableCellEditor is set in javax.swing.DefaultCellEditor(JComboBox) constructor
|
||||
return c instanceof JComponent && Boolean.TRUE.equals( ((JComponent)c).getClientProperty( "JComboBox.isTableCellEditor" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given component is the permanent focus owner and
|
||||
* is in the active window. Used to paint focus indicators.
|
||||
*/
|
||||
public static boolean isPermanentFocusOwner( Component c ) {
|
||||
return (KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner() == c);
|
||||
KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
return keyboardFocusManager.getPermanentFocusOwner() == c &&
|
||||
keyboardFocusManager.getActiveWindow() == SwingUtilities.windowForComponent( c );
|
||||
}
|
||||
|
||||
public static boolean isRoundRect( Component c ) {
|
||||
return c instanceof JComponent && FlatClientProperties.clientPropertyBoolean(
|
||||
(JComponent) c, FlatClientProperties.COMPONENT_ROUND_RECT, false );
|
||||
public static Boolean isRoundRect( Component c ) {
|
||||
return (c instanceof JComponent)
|
||||
? FlatClientProperties.clientPropertyBooleanStrict(
|
||||
(JComponent) c, FlatClientProperties.COMPONENT_ROUND_RECT, null )
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,7 +232,7 @@ public class FlatUIUtils
|
||||
* Paints an outer border, which is usually a focus border.
|
||||
* <p>
|
||||
* The outside bounds of the painted border are {@code x,y,width,height}.
|
||||
* The line width of the painted border is {@code focusWidth + lineWidth}.
|
||||
* The line thickness of the painted border is {@code focusWidth + lineWidth}.
|
||||
* The given arc diameter refers to the inner rectangle ({@code x,y,width,height} minus {@code focusWidth}).
|
||||
*
|
||||
* @see #paintComponentBorder
|
||||
@@ -212,6 +241,9 @@ public class FlatUIUtils
|
||||
public static void paintComponentOuterBorder( Graphics2D g, int x, int y, int width, int height,
|
||||
float focusWidth, float lineWidth, float arc )
|
||||
{
|
||||
if( focusWidth + lineWidth == 0 )
|
||||
return; // nothing to paint
|
||||
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||
@@ -248,6 +280,7 @@ public class FlatUIUtils
|
||||
* <p>
|
||||
* The outside bounds of the painted border are
|
||||
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
|
||||
* The line thickness of the painted border is {@code lineWidth}.
|
||||
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
|
||||
*
|
||||
* @see #paintComponentOuterBorder
|
||||
@@ -256,6 +289,9 @@ public class FlatUIUtils
|
||||
public static void paintComponentBorder( Graphics2D g, int x, int y, int width, int height,
|
||||
float focusWidth, float lineWidth, float arc )
|
||||
{
|
||||
if( lineWidth == 0 )
|
||||
return; // nothing to paint
|
||||
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static java.awt.Cursor.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import static javax.swing.SwingConstants.*;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
@@ -36,45 +36,60 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.function.Supplier;
|
||||
import javax.swing.DesktopManager;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Resizes frames and dialogs.
|
||||
* Resizes frames, dialogs or internal frames.
|
||||
* <p>
|
||||
* Could also be used to implement resize support for any Swing component
|
||||
* by creating a new subclass.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowResizer
|
||||
extends JComponent
|
||||
implements PropertyChangeListener, WindowStateListener, ComponentListener
|
||||
public abstract class FlatWindowResizer
|
||||
implements PropertyChangeListener, ComponentListener
|
||||
{
|
||||
private final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
|
||||
protected final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
|
||||
|
||||
private final JRootPane rootPane;
|
||||
protected final JComponent resizeComp;
|
||||
|
||||
private final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
|
||||
private final int cornerDragWidth = FlatUIUtils.getUIInt( "RootPane.cornerDragWidth", 16 );
|
||||
private final boolean honorMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorMinimumSizeOnResize" );
|
||||
protected final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
|
||||
protected final int cornerDragWidth = FlatUIUtils.getUIInt( "RootPane.cornerDragWidth", 16 );
|
||||
protected final boolean honorFrameMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorFrameMinimumSizeOnResize" );
|
||||
protected final boolean honorDialogMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorDialogMinimumSizeOnResize" );
|
||||
|
||||
private Window window;
|
||||
protected final DragBorderComponent topDragComp;
|
||||
protected final DragBorderComponent bottomDragComp;
|
||||
protected final DragBorderComponent leftDragComp;
|
||||
protected final DragBorderComponent rightDragComp;
|
||||
|
||||
public FlatWindowResizer( JRootPane rootPane ) {
|
||||
this.rootPane = rootPane;
|
||||
protected FlatWindowResizer( JComponent resizeComp ) {
|
||||
this.resizeComp = resizeComp;
|
||||
|
||||
setLayout( new BorderLayout() );
|
||||
add( createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR ), BorderLayout.NORTH );
|
||||
add( createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.SOUTH );
|
||||
add( createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR ), BorderLayout.WEST );
|
||||
add( createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.EAST );
|
||||
topDragComp = createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR );
|
||||
bottomDragComp = createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR );
|
||||
leftDragComp = createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR );
|
||||
rightDragComp = createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR );
|
||||
|
||||
rootPane.addComponentListener( this );
|
||||
rootPane.getLayeredPane().add( this, WINDOW_RESIZER_LAYER );
|
||||
Container cont = (resizeComp instanceof JRootPane) ? ((JRootPane)resizeComp).getLayeredPane() : resizeComp;
|
||||
Object cons = (cont instanceof JLayeredPane) ? WINDOW_RESIZER_LAYER : null;
|
||||
cont.add( topDragComp, cons, 0 );
|
||||
cont.add( bottomDragComp, cons, 1 );
|
||||
cont.add( leftDragComp, cons, 2 );
|
||||
cont.add( rightDragComp, cons, 3 );
|
||||
|
||||
if( rootPane.isDisplayable() )
|
||||
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
|
||||
resizeComp.addComponentListener( this );
|
||||
resizeComp.addPropertyChangeListener( "ancestor", this );
|
||||
|
||||
if( resizeComp.isDisplayable() )
|
||||
addNotify();
|
||||
}
|
||||
|
||||
protected DragBorderComponent createDragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
|
||||
@@ -82,83 +97,282 @@ public class FlatWindowResizer
|
||||
}
|
||||
|
||||
public void uninstall() {
|
||||
rootPane.removeComponentListener( this );
|
||||
rootPane.getLayeredPane().remove( this );
|
||||
removeNotify();
|
||||
|
||||
resizeComp.removeComponentListener( this );
|
||||
resizeComp.removePropertyChangeListener( "ancestor", this );
|
||||
|
||||
Container cont = topDragComp.getParent();
|
||||
cont.remove( topDragComp );
|
||||
cont.remove( bottomDragComp );
|
||||
cont.remove( leftDragComp );
|
||||
cont.remove( rightDragComp );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
Container parent = rootPane.getParent();
|
||||
window = (parent instanceof Window) ? (Window) parent : null;
|
||||
if( window instanceof Frame ) {
|
||||
window.addPropertyChangeListener( "resizable", this );
|
||||
window.addWindowStateListener( this );
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
if( window instanceof Frame ) {
|
||||
window.removePropertyChangeListener( "resizable", this );
|
||||
window.removeWindowStateListener( this );
|
||||
}
|
||||
window = null;
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren( Graphics g ) {
|
||||
super.paintChildren( g );
|
||||
|
||||
// this is necessary because Dialog.setResizable() does not fire events
|
||||
if( window instanceof Dialog )
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
private void updateVisibility() {
|
||||
boolean visible = isWindowResizable();
|
||||
if( visible == getComponent( 0 ).isVisible() )
|
||||
public void doLayout() {
|
||||
if( !topDragComp.isVisible() )
|
||||
return;
|
||||
|
||||
for( Component c : getComponents() )
|
||||
c.setVisible( visible );
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = resizeComp.getWidth();
|
||||
int height = resizeComp.getHeight();
|
||||
if( width == 0 || height == 0 )
|
||||
return;
|
||||
|
||||
Insets resizeInsets = getResizeInsets();
|
||||
int thickness = UIScale.scale( borderDragThickness );
|
||||
int topThickness = Math.max( resizeInsets.top, thickness );
|
||||
int bottomThickness = Math.max( resizeInsets.bottom, thickness );
|
||||
int leftThickness = Math.max( resizeInsets.left, thickness );
|
||||
int rightThickness = Math.max( resizeInsets.right, thickness );
|
||||
int y2 = y + topThickness;
|
||||
int height2 = height - topThickness - bottomThickness;
|
||||
|
||||
// set bounds of drag components
|
||||
topDragComp.setBounds( x, y, width, topThickness );
|
||||
bottomDragComp.setBounds( x, y + height - bottomThickness, width, bottomThickness );
|
||||
leftDragComp.setBounds( x, y2, leftThickness, height2 );
|
||||
rightDragComp.setBounds( x + width - rightThickness, y2, rightThickness, height2 );
|
||||
|
||||
// set corner drag widths
|
||||
int cornerDelta = UIScale.scale( cornerDragWidth - borderDragThickness );
|
||||
topDragComp.setCornerDragWidths( leftThickness + cornerDelta, rightThickness + cornerDelta );
|
||||
bottomDragComp.setCornerDragWidths( leftThickness + cornerDelta, rightThickness + cornerDelta );
|
||||
leftDragComp.setCornerDragWidths( cornerDelta, cornerDelta );
|
||||
rightDragComp.setCornerDragWidths( cornerDelta, cornerDelta );
|
||||
}
|
||||
|
||||
private boolean isWindowResizable() {
|
||||
if( window instanceof Frame )
|
||||
return ((Frame)window).isResizable() && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) == 0;
|
||||
if( window instanceof Dialog )
|
||||
return ((Dialog)window).isResizable();
|
||||
protected Insets getResizeInsets() {
|
||||
return new Insets( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
protected void addNotify() {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
protected void removeNotify() {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
protected void updateVisibility() {
|
||||
boolean visible = isWindowResizable();
|
||||
if( visible == topDragComp.isVisible() )
|
||||
return;
|
||||
|
||||
topDragComp.setVisible( visible );
|
||||
bottomDragComp.setVisible( visible );
|
||||
leftDragComp.setVisible( visible );
|
||||
|
||||
// The east component is not hidden, instead its bounds are set to 0,0,1,1 and
|
||||
// it is disabled. This is necessary so that DragBorderComponent.paintComponent() is invoked.
|
||||
rightDragComp.setEnabled( visible );
|
||||
if( visible ) {
|
||||
rightDragComp.setVisible( true ); // necessary because it is initially invisible
|
||||
doLayout();
|
||||
} else
|
||||
rightDragComp.setBounds( 0, 0, 1, 1 );
|
||||
}
|
||||
|
||||
boolean isDialog() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
updateVisibility();
|
||||
}
|
||||
protected abstract boolean isWindowResizable();
|
||||
protected abstract Rectangle getWindowBounds();
|
||||
protected abstract void setWindowBounds( Rectangle r );
|
||||
protected abstract boolean honorMinimumSizeOnResize();
|
||||
protected abstract Dimension getWindowMinimumSize();
|
||||
|
||||
protected void beginResizing( int direction ) {}
|
||||
protected void endResizing() {}
|
||||
|
||||
//---- interface PropertyChangeListener ----
|
||||
|
||||
@Override
|
||||
public void windowStateChanged( WindowEvent e ) {
|
||||
updateVisibility();
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case "ancestor":
|
||||
if( e.getNewValue() != null )
|
||||
addNotify();
|
||||
else
|
||||
removeNotify();
|
||||
break;
|
||||
|
||||
case "resizable":
|
||||
updateVisibility();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---- interface ComponentListener ----
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
|
||||
validate();
|
||||
doLayout();
|
||||
}
|
||||
|
||||
@Override public void componentMoved( ComponentEvent e ) {}
|
||||
@Override public void componentShown( ComponentEvent e ) {}
|
||||
@Override public void componentHidden( ComponentEvent e ) {}
|
||||
|
||||
//---- class WindowResizer ------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resizes frames and dialogs.
|
||||
*/
|
||||
public static class WindowResizer
|
||||
extends FlatWindowResizer
|
||||
implements WindowStateListener
|
||||
{
|
||||
protected Window window;
|
||||
|
||||
public WindowResizer( JRootPane rootPane ) {
|
||||
super( rootPane );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addNotify() {
|
||||
Container parent = resizeComp.getParent();
|
||||
window = (parent instanceof Window) ? (Window) parent : null;
|
||||
if( window instanceof Frame ) {
|
||||
window.addPropertyChangeListener( "resizable", this );
|
||||
window.addWindowStateListener( this );
|
||||
}
|
||||
|
||||
super.addNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeNotify() {
|
||||
if( window instanceof Frame ) {
|
||||
window.removePropertyChangeListener( "resizable", this );
|
||||
window.removeWindowStateListener( this );
|
||||
}
|
||||
window = null;
|
||||
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWindowResizable() {
|
||||
if( window instanceof Frame )
|
||||
return ((Frame)window).isResizable() && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) == 0;
|
||||
if( window instanceof Dialog )
|
||||
return ((Dialog)window).isResizable();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getWindowBounds() {
|
||||
return window.getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setWindowBounds( Rectangle r ) {
|
||||
window.setBounds( r );
|
||||
|
||||
// immediately layout drag border components
|
||||
doLayout();
|
||||
|
||||
if( Toolkit.getDefaultToolkit().isDynamicLayoutActive() ) {
|
||||
window.validate();
|
||||
resizeComp.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean honorMinimumSizeOnResize() {
|
||||
return
|
||||
(honorFrameMinimumSizeOnResize && window instanceof Frame) ||
|
||||
(honorDialogMinimumSizeOnResize && window instanceof Dialog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getWindowMinimumSize() {
|
||||
return window.getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isDialog() {
|
||||
return window instanceof Dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowStateChanged( WindowEvent e ) {
|
||||
updateVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
//---- class InternalFrameResizer -----------------------------------------
|
||||
|
||||
/**
|
||||
* Resizes internal frames.
|
||||
*/
|
||||
public static class InternalFrameResizer
|
||||
extends FlatWindowResizer
|
||||
{
|
||||
protected final Supplier<DesktopManager> desktopManager;
|
||||
|
||||
public InternalFrameResizer( JInternalFrame frame, Supplier<DesktopManager> desktopManager ) {
|
||||
super( frame );
|
||||
this.desktopManager = desktopManager;
|
||||
|
||||
frame.addPropertyChangeListener( "resizable", this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstall() {
|
||||
getFrame().removePropertyChangeListener( "resizable", this );
|
||||
|
||||
super.uninstall();
|
||||
}
|
||||
|
||||
private JInternalFrame getFrame() {
|
||||
return (JInternalFrame) resizeComp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Insets getResizeInsets() {
|
||||
return getFrame().getInsets();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWindowResizable() {
|
||||
return getFrame().isResizable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getWindowBounds() {
|
||||
return getFrame().getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setWindowBounds( Rectangle r ) {
|
||||
desktopManager.get().resizeFrame( getFrame(), r.x, r.y, r.width, r.height );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean honorMinimumSizeOnResize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getWindowMinimumSize() {
|
||||
return getFrame().getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beginResizing( int direction ) {
|
||||
desktopManager.get().beginResizingFrame( getFrame(), direction );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endResizing() {
|
||||
desktopManager.get().endResizingFrame( getFrame() );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class DragBorderComponent ------------------------------------------
|
||||
|
||||
protected class DragBorderComponent
|
||||
@@ -170,9 +384,15 @@ public class FlatWindowResizer
|
||||
private final int trailingResizeDir;
|
||||
|
||||
private int resizeDir = -1;
|
||||
private int dragStartMouseX;
|
||||
private int dragStartMouseY;
|
||||
private Rectangle dragStartWindowBounds;
|
||||
|
||||
private int leadingCornerDragWidth;
|
||||
private int trailingCornerDragWidth;
|
||||
|
||||
// offsets of mouse position to window edges
|
||||
private int dragLeftOffset;
|
||||
private int dragRightOffset;
|
||||
private int dragTopOffset;
|
||||
private int dragBottomOffset;
|
||||
|
||||
protected DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
|
||||
this.leadingResizeDir = leadingResizeDir;
|
||||
@@ -186,6 +406,11 @@ public class FlatWindowResizer
|
||||
addMouseMotionListener( this );
|
||||
}
|
||||
|
||||
void setCornerDragWidths( int leading, int trailing ) {
|
||||
leadingCornerDragWidth = leading;
|
||||
trailingCornerDragWidth = trailing;
|
||||
}
|
||||
|
||||
protected void setResizeDir( int resizeDir ) {
|
||||
if( this.resizeDir == resizeDir )
|
||||
return;
|
||||
@@ -200,13 +425,32 @@ public class FlatWindowResizer
|
||||
return new Dimension( thickness, thickness );
|
||||
}
|
||||
|
||||
/*debug
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
super.paintChildren( g );
|
||||
|
||||
// this is necessary because Dialog.setResizable() does not fire events
|
||||
if( isDialog() )
|
||||
updateVisibility();
|
||||
|
||||
/*debug
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
g.setColor( java.awt.Color.blue );
|
||||
boolean topOrBottom = (centerResizeDir == N_RESIZE_CURSOR || centerResizeDir == S_RESIZE_CURSOR);
|
||||
if( topOrBottom ) {
|
||||
g.drawLine( leadingCornerDragWidth, 0, leadingCornerDragWidth, height );
|
||||
g.drawLine( width - trailingCornerDragWidth, 0, width - trailingCornerDragWidth, height );
|
||||
} else {
|
||||
g.drawLine( 0, leadingCornerDragWidth, width, leadingCornerDragWidth );
|
||||
g.drawLine( 0, height - trailingCornerDragWidth, width, height - trailingCornerDragWidth );
|
||||
}
|
||||
|
||||
g.setColor( java.awt.Color.red );
|
||||
g.drawRect( 0, 0, getWidth() - 1, getHeight() - 1 );
|
||||
}
|
||||
g.drawRect( 0, 0, width - 1, height - 1 );
|
||||
debug*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e ) {
|
||||
@@ -214,112 +458,116 @@ debug*/
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
if( window == null )
|
||||
if( !isWindowResizable() )
|
||||
return;
|
||||
|
||||
dragStartMouseX = e.getXOnScreen();
|
||||
dragStartMouseY = e.getYOnScreen();
|
||||
dragStartWindowBounds = window.getBounds();
|
||||
int xOnScreen = e.getXOnScreen();
|
||||
int yOnScreen = e.getYOnScreen();
|
||||
Rectangle windowBounds = getWindowBounds();
|
||||
|
||||
// compute offsets of mouse position to window edges
|
||||
dragLeftOffset = xOnScreen - windowBounds.x;
|
||||
dragTopOffset = yOnScreen - windowBounds.y;
|
||||
dragRightOffset = windowBounds.x + windowBounds.width - xOnScreen;
|
||||
dragBottomOffset = windowBounds.y + windowBounds.height - yOnScreen;
|
||||
|
||||
int direction = 0;
|
||||
switch( resizeDir ) {
|
||||
case N_RESIZE_CURSOR: direction = NORTH; break;
|
||||
case S_RESIZE_CURSOR: direction = SOUTH; break;
|
||||
case W_RESIZE_CURSOR: direction = WEST; break;
|
||||
case E_RESIZE_CURSOR: direction = EAST; break;
|
||||
case NW_RESIZE_CURSOR: direction = NORTH_WEST; break;
|
||||
case NE_RESIZE_CURSOR: direction = NORTH_EAST; break;
|
||||
case SW_RESIZE_CURSOR: direction = SOUTH_WEST; break;
|
||||
case SE_RESIZE_CURSOR: direction = SOUTH_EAST; break;
|
||||
}
|
||||
beginResizing( direction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
dragStartWindowBounds = null;
|
||||
if( !isWindowResizable() )
|
||||
return;
|
||||
|
||||
dragLeftOffset = dragRightOffset = dragTopOffset = dragBottomOffset = 0;
|
||||
|
||||
endResizing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ) {
|
||||
}
|
||||
@Override public void mouseEntered( MouseEvent e ) {}
|
||||
@Override public void mouseExited( MouseEvent e ) {}
|
||||
|
||||
@Override
|
||||
public void mouseMoved( MouseEvent e ) {
|
||||
boolean topBottom = (centerResizeDir == N_RESIZE_CURSOR || centerResizeDir == S_RESIZE_CURSOR);
|
||||
int xy = topBottom ? e.getX() : e.getY();
|
||||
int wh = topBottom ? getWidth() : getHeight();
|
||||
int cornerWH = UIScale.scale( cornerDragWidth - (topBottom ? 0 : borderDragThickness) );
|
||||
boolean topOrBottom = (centerResizeDir == N_RESIZE_CURSOR || centerResizeDir == S_RESIZE_CURSOR);
|
||||
int xy = topOrBottom ? e.getX() : e.getY();
|
||||
int wh = topOrBottom ? getWidth() : getHeight();
|
||||
|
||||
setResizeDir( xy <= cornerWH
|
||||
setResizeDir( xy <= leadingCornerDragWidth
|
||||
? leadingResizeDir
|
||||
: (xy >= wh - cornerWH
|
||||
: (xy >= wh - trailingCornerDragWidth
|
||||
? trailingResizeDir
|
||||
: centerResizeDir) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( dragStartWindowBounds == null )
|
||||
return;
|
||||
|
||||
if( !isWindowResizable() )
|
||||
return;
|
||||
|
||||
int mouseDeltaX = e.getXOnScreen() - dragStartMouseX;
|
||||
int mouseDeltaY = e.getYOnScreen() - dragStartMouseY;
|
||||
int xOnScreen = e.getXOnScreen();
|
||||
int yOnScreen = e.getYOnScreen();
|
||||
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
int deltaWidth = 0;
|
||||
int deltaHeight = 0;
|
||||
|
||||
// north
|
||||
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
|
||||
deltaY = mouseDeltaY;
|
||||
deltaHeight = -mouseDeltaY;
|
||||
}
|
||||
|
||||
// south
|
||||
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
deltaHeight = mouseDeltaY;
|
||||
|
||||
// west
|
||||
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
|
||||
deltaX = mouseDeltaX;
|
||||
deltaWidth = -mouseDeltaX;
|
||||
}
|
||||
|
||||
// east
|
||||
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
deltaWidth = mouseDeltaX;
|
||||
// Get current window bounds and compute new bounds based 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
|
||||
// decide at some point that the window should be only on second screen
|
||||
// and adjusts its bounds.
|
||||
Rectangle oldBounds = getWindowBounds();
|
||||
Rectangle newBounds = new Rectangle( oldBounds );
|
||||
|
||||
// compute new window bounds
|
||||
Rectangle newBounds = new Rectangle( dragStartWindowBounds );
|
||||
newBounds.x += deltaX;
|
||||
newBounds.y += deltaY;
|
||||
newBounds.width += deltaWidth;
|
||||
newBounds.height += deltaHeight;
|
||||
|
||||
// top
|
||||
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
|
||||
newBounds.y = yOnScreen - dragTopOffset;
|
||||
newBounds.height += (oldBounds.y - newBounds.y);
|
||||
}
|
||||
|
||||
// bottom
|
||||
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y;
|
||||
|
||||
// left
|
||||
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
|
||||
newBounds.x = xOnScreen - dragLeftOffset;
|
||||
newBounds.width += (oldBounds.x - newBounds.x);
|
||||
}
|
||||
|
||||
// right
|
||||
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x;
|
||||
|
||||
// apply minimum window size
|
||||
Dimension minimumSize = honorMinimumSizeOnResize ? window.getMinimumSize() : null;
|
||||
Dimension minimumSize = honorMinimumSizeOnResize() ? getWindowMinimumSize() : null;
|
||||
if( minimumSize == null )
|
||||
minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
|
||||
if( newBounds.width < minimumSize.width ) {
|
||||
if( deltaX != 0 )
|
||||
if( newBounds.x != oldBounds.x )
|
||||
newBounds.x -= (minimumSize.width - newBounds.width);
|
||||
newBounds.width = minimumSize.width;
|
||||
}
|
||||
if( newBounds.height < minimumSize.height ) {
|
||||
if( deltaY != 0 )
|
||||
if( newBounds.y != oldBounds.y )
|
||||
newBounds.y -= (minimumSize.height - newBounds.height);
|
||||
newBounds.height = minimumSize.height;
|
||||
}
|
||||
|
||||
// set window bounds
|
||||
if( !newBounds.equals( dragStartWindowBounds ) ) {
|
||||
window.setBounds( newBounds );
|
||||
|
||||
// immediately layout drag border components
|
||||
FlatWindowResizer.this.setBounds( 0, 0, newBounds.width, newBounds.height );
|
||||
FlatWindowResizer.this.validate();
|
||||
|
||||
if( Toolkit.getDefaultToolkit().isDynamicLayoutActive() ) {
|
||||
window.validate();
|
||||
rootPane.repaint();
|
||||
}
|
||||
}
|
||||
if( !newBounds.equals( oldBounds ) )
|
||||
setWindowBounds( newBounds );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class JBRCustomDecorations
|
||||
initialized = true;
|
||||
|
||||
// requires JetBrains Runtime 11 and Windows 10
|
||||
if( !SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER || !SystemInfo.IS_WINDOWS_10_OR_LATER )
|
||||
if( !SystemInfo.isJetBrainsJVM_11_orLater || !SystemInfo.isWindows_10_orLater )
|
||||
return;
|
||||
|
||||
if( !FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, true ) )
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.Timer;
|
||||
|
||||
/**
|
||||
* Simple animator based on ideas and concepts from "Filthy Rich Clients" book
|
||||
* and "Timing Framework" library.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class Animator
|
||||
{
|
||||
private int duration;
|
||||
private int resolution = 10;
|
||||
private Interpolator interpolator;
|
||||
private final ArrayList<TimingTarget> targets = new ArrayList<>();
|
||||
private final Runnable endRunnable;
|
||||
|
||||
private boolean running;
|
||||
private boolean hasBegun;
|
||||
private boolean timeToStop;
|
||||
private long startTime;
|
||||
private Timer timer;
|
||||
|
||||
/**
|
||||
* Creates an animation that runs duration milliseconds.
|
||||
* Use {@link #addTarget(TimingTarget)} to receive timing events
|
||||
* and {@link #start()} to start the animation.
|
||||
*
|
||||
* @param duration the duration of the animation in milliseconds
|
||||
*/
|
||||
public Animator( int duration ) {
|
||||
this( duration, null, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation that runs duration milliseconds.
|
||||
* Use {@link #start()} to start the animation.
|
||||
*
|
||||
* @param duration the duration of the animation in milliseconds
|
||||
* @param target the target that receives timing events
|
||||
*/
|
||||
public Animator( int duration, TimingTarget target ) {
|
||||
this( duration, target, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation that runs duration milliseconds.
|
||||
* Use {@link #start()} to start the animation.
|
||||
*
|
||||
* @param duration the duration of the animation in milliseconds
|
||||
* @param target the target that receives timing events
|
||||
* @param endRunnable a runnable invoked when the animation ends; or {@code null}
|
||||
*/
|
||||
public Animator( int duration, TimingTarget target, Runnable endRunnable ) {
|
||||
setDuration( duration );
|
||||
addTarget( target );
|
||||
this.endRunnable = endRunnable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the animation in milliseconds.
|
||||
*/
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration of the animation in milliseconds.
|
||||
*
|
||||
* @throws IllegalStateException if animation is running
|
||||
* @throws IllegalArgumentException if duration is <= zero
|
||||
*/
|
||||
public void setDuration( int duration ) {
|
||||
throwExceptionIfRunning();
|
||||
if( duration <= 0 )
|
||||
throw new IllegalArgumentException();
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resolution of the animation in milliseconds (default is 10).
|
||||
* Resolution is the amount of time between timing events.
|
||||
*/
|
||||
public int getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resolution of the animation in milliseconds.
|
||||
*
|
||||
* @param resolution the resolution of the animation in milliseconds
|
||||
* @throws IllegalStateException if animation is running
|
||||
* @throws IllegalArgumentException if resolution is <= zero
|
||||
*/
|
||||
public void setResolution( int resolution ) {
|
||||
throwExceptionIfRunning();
|
||||
if( resolution <= 0 )
|
||||
throw new IllegalArgumentException();
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interpolator for the animation.
|
||||
* Default is {@code null}, which means linear.
|
||||
*/
|
||||
public Interpolator getInterpolator() {
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the interpolator for the animation.
|
||||
*
|
||||
* @throws IllegalStateException if animation is running
|
||||
*/
|
||||
public void setInterpolator( Interpolator interpolator ) {
|
||||
throwExceptionIfRunning();
|
||||
this.interpolator = interpolator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a target to the animation that receives timing events.
|
||||
*
|
||||
* @param target the target that receives timing events
|
||||
*/
|
||||
public void addTarget( TimingTarget target ) {
|
||||
if( target == null )
|
||||
return;
|
||||
|
||||
synchronized( targets ) {
|
||||
if( !targets.contains( target ) )
|
||||
targets.add( target );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a target from the animation.
|
||||
*
|
||||
* @param target the target that should be removed
|
||||
*/
|
||||
public void removeTarget( TimingTarget target ) {
|
||||
synchronized( targets ) {
|
||||
targets.remove( target );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the animation.
|
||||
*
|
||||
* @throws IllegalStateException if animation is running
|
||||
*/
|
||||
public void start() {
|
||||
throwExceptionIfRunning();
|
||||
|
||||
running = true;
|
||||
hasBegun = false;
|
||||
timeToStop = false;
|
||||
startTime = System.nanoTime() / 1000000;
|
||||
|
||||
timer = new Timer( resolution, e -> {
|
||||
if( !hasBegun ) {
|
||||
begin();
|
||||
hasBegun = true;
|
||||
}
|
||||
|
||||
timingEvent( getTimingFraction() );
|
||||
} );
|
||||
timer.setInitialDelay( 0 );
|
||||
timer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the animation before it normally ends.
|
||||
* Invokes {@link TimingTarget#end()} on timing targets.
|
||||
*/
|
||||
public void stop() {
|
||||
stop( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the animation before it normally ends.
|
||||
* Does not invoke {@link TimingTarget#end()} on timing targets.
|
||||
*/
|
||||
public void cancel() {
|
||||
stop( true );
|
||||
}
|
||||
|
||||
private void stop( boolean cancel ) {
|
||||
if( timer != null ) {
|
||||
timer.stop();
|
||||
timer = null;
|
||||
}
|
||||
|
||||
if( !cancel )
|
||||
end();
|
||||
|
||||
running = false;
|
||||
timeToStop = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this animation is running.
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
private float getTimingFraction() {
|
||||
long currentTime = System.nanoTime() / 1000000;
|
||||
long elapsedTime = currentTime - startTime;
|
||||
timeToStop = (elapsedTime >= duration);
|
||||
|
||||
float fraction = clampFraction( (float) elapsedTime / duration );
|
||||
if( interpolator != null )
|
||||
fraction = clampFraction( interpolator.interpolate( fraction ) );
|
||||
return fraction;
|
||||
}
|
||||
|
||||
private float clampFraction( float fraction ) {
|
||||
if( fraction < 0 )
|
||||
return 0;
|
||||
if( fraction > 1 )
|
||||
return 1;
|
||||
return fraction;
|
||||
}
|
||||
|
||||
private void timingEvent( float fraction ) {
|
||||
synchronized( targets ) {
|
||||
for( TimingTarget target : targets )
|
||||
target.timingEvent( fraction );
|
||||
}
|
||||
|
||||
if( timeToStop )
|
||||
stop();
|
||||
}
|
||||
|
||||
private void begin() {
|
||||
synchronized( targets ) {
|
||||
for( TimingTarget target : targets )
|
||||
target.begin();
|
||||
}
|
||||
}
|
||||
|
||||
private void end() {
|
||||
synchronized( targets ) {
|
||||
for( TimingTarget target : targets )
|
||||
target.end();
|
||||
}
|
||||
|
||||
if( endRunnable != null )
|
||||
endRunnable.run();
|
||||
}
|
||||
|
||||
private void throwExceptionIfRunning() {
|
||||
if( isRunning() )
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
//---- interface TimingTarget ---------------------------------------------
|
||||
|
||||
/**
|
||||
* Animation callbacks.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TimingTarget {
|
||||
/**
|
||||
* Invoked multiple times while animation is running.
|
||||
*
|
||||
* @param fraction the percent (0 to 1) elapsed of the current animation cycle
|
||||
*/
|
||||
void timingEvent( float fraction );
|
||||
|
||||
/**
|
||||
* Invoked when the animation begins.
|
||||
*/
|
||||
default void begin() {}
|
||||
|
||||
/**
|
||||
* Invoked when the animation ends.
|
||||
*/
|
||||
default void end() {}
|
||||
}
|
||||
|
||||
//---- interface Interpolator ---------------------------------------------
|
||||
|
||||
/**
|
||||
* Interpolator used by animation to change timing fraction. E.g. for easing.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Interpolator {
|
||||
/**
|
||||
* Interpolate the given fraction and returns a new fraction.
|
||||
* Both fractions are in range [0, 1].
|
||||
*
|
||||
* @param fraction the percent (0 to 1) elapsed of the current animation cycle
|
||||
* @return new fraction in range [0, 1]
|
||||
*/
|
||||
float interpolate( float fraction );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
/**
|
||||
* An interpolator for {@link Animator} that uses a cubic bezier curve.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class CubicBezierEasing
|
||||
implements Animator.Interpolator
|
||||
{
|
||||
// common cubic-bezier easing functions (same as in CSS)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function
|
||||
public static final CubicBezierEasing EASE = new CubicBezierEasing( 0.25f, 0.1f, 0.25f, 1f );
|
||||
public static final CubicBezierEasing EASE_IN = new CubicBezierEasing( 0.42f, 0f, 1f, 1f );
|
||||
public static final CubicBezierEasing EASE_IN_OUT = new CubicBezierEasing( 0.42f, 0f, 0.58f, 1f );
|
||||
public static final CubicBezierEasing EASE_OUT = new CubicBezierEasing( 0f, 0f, 0.58f, 1f );
|
||||
|
||||
private final float x1;
|
||||
private final float y1;
|
||||
private final float x2;
|
||||
private final float y2;
|
||||
|
||||
/**
|
||||
* Creates a cubic bezier easing interpolator with the given control points.
|
||||
* The start point of the cubic bezier curve is always 0,0 and the end point 1,1.
|
||||
*
|
||||
* @param x1 the x coordinate of the first control point in range [0, 1]
|
||||
* @param y1 the y coordinate of the first control point in range [0, 1]
|
||||
* @param x2 the x coordinate of the second control point in range [0, 1]
|
||||
* @param y2 the y coordinate of the second control point in range [0, 1]
|
||||
*/
|
||||
public CubicBezierEasing( float x1, float y1, float x2, float y2 ) {
|
||||
if( x1 < 0 || x1 > 1 || y1 < 0 || y1 > 1 ||
|
||||
x2 < 0 || x2 > 1 || y2 < 0 || y2 > 1 )
|
||||
throw new IllegalArgumentException( "control points must be in range [0, 1]");
|
||||
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.x2 = x2;
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float interpolate( float fraction ) {
|
||||
if( fraction <= 0 || fraction >= 1 )
|
||||
return fraction;
|
||||
|
||||
// use binary search
|
||||
float low = 0;
|
||||
float high = 1;
|
||||
while( true ) {
|
||||
float mid = (low + high) / 2;
|
||||
float estimate = cubicBezier( mid, x1, x2 );
|
||||
if( Math.abs( fraction - estimate ) < 0.0005f )
|
||||
return cubicBezier( mid, y1, y2 );
|
||||
if( estimate < fraction )
|
||||
low = mid;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the x or y point on a cubic bezier curve for a given t value.
|
||||
*
|
||||
* https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves
|
||||
*
|
||||
* The general cubic bezier formula is:
|
||||
* x = b0*x0 + b1*x1 + b2*x2 + b3*x3
|
||||
* y = b0*y0 + b1*y1 + b2*y2 + b3*y3
|
||||
*
|
||||
* where:
|
||||
* b0 = (1-t)^3
|
||||
* b1 = 3 * t * (1-t)^2
|
||||
* b2 = 3 * t^2 * (1-t)
|
||||
* b3 = t^3
|
||||
*
|
||||
* x0,y0 is always 0,0 and x3,y3 is 1,1, so we can simplify to:
|
||||
* x = b1*x1 + b2*x2 + b3
|
||||
* y = b1*x1 + b2*x2 + b3
|
||||
*/
|
||||
private static float cubicBezier( float t, float xy1, float xy2 ) {
|
||||
float invT = (1 - t);
|
||||
float b1 = 3 * t * (invT * invT);
|
||||
float b2 = 3 * (t * t) * invT;
|
||||
float b3 = t * t * t;
|
||||
return (b1 * xy1) + (b2 * xy2) + b3;
|
||||
}
|
||||
}
|
||||
@@ -117,10 +117,10 @@ public class HiDPIUtils
|
||||
* This methods computes a correction value for the Y position.
|
||||
*/
|
||||
public static float computeTextYCorrection( Graphics2D g ) {
|
||||
if( !useTextYCorrection() || !SystemInfo.IS_WINDOWS )
|
||||
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
||||
return 0;
|
||||
|
||||
if( !SystemInfo.IS_JAVA_9_OR_LATER )
|
||||
if( !SystemInfo.isJava_9_orLater )
|
||||
return UIScale.getUserScaleFactor() > 1 ? -UIScale.scale( 0.625f ) : 0;
|
||||
|
||||
AffineTransform t = g.getTransform();
|
||||
|
||||
@@ -48,10 +48,10 @@ public class JavaCompatibility
|
||||
synchronized( JavaCompatibility.class ) {
|
||||
if( drawStringUnderlineCharAtMethod == null ) {
|
||||
try {
|
||||
Class<?> cls = Class.forName( SystemInfo.IS_JAVA_9_OR_LATER
|
||||
Class<?> cls = Class.forName( SystemInfo.isJava_9_orLater
|
||||
? "javax.swing.plaf.basic.BasicGraphicsUtils"
|
||||
: "sun.swing.SwingUtilities2" );
|
||||
drawStringUnderlineCharAtMethod = cls.getMethod( "drawStringUnderlineCharAt", SystemInfo.IS_JAVA_9_OR_LATER
|
||||
drawStringUnderlineCharAtMethod = cls.getMethod( "drawStringUnderlineCharAt", SystemInfo.isJava_9_orLater
|
||||
? new Class[] { JComponent.class, Graphics2D.class, String.class, int.class, float.class, float.class }
|
||||
: new Class[] { JComponent.class, Graphics.class, String.class, int.class, int.class, int.class } );
|
||||
} catch( Exception ex ) {
|
||||
@@ -62,7 +62,7 @@ public class JavaCompatibility
|
||||
}
|
||||
|
||||
try {
|
||||
if( SystemInfo.IS_JAVA_9_OR_LATER )
|
||||
if( SystemInfo.isJava_9_orLater )
|
||||
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, (float) x, (float) y );
|
||||
else
|
||||
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, x, y );
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Component;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
/**
|
||||
* Empty border that scales insets.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class ScaledEmptyBorder
|
||||
extends EmptyBorder
|
||||
{
|
||||
public ScaledEmptyBorder( int top, int left, int bottom, int right ) {
|
||||
super( top, left, bottom, right );
|
||||
}
|
||||
|
||||
public ScaledEmptyBorder( Insets insets ) {
|
||||
super( insets );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets() {
|
||||
return new Insets( scale( top ), scale( left ), scale( bottom ), scale( right ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
insets.left = scale( left );
|
||||
insets.top = scale( top );
|
||||
insets.right = scale( right );
|
||||
insets.bottom = scale( bottom );
|
||||
return insets;
|
||||
}
|
||||
}
|
||||
@@ -27,55 +27,57 @@ import java.util.StringTokenizer;
|
||||
public class SystemInfo
|
||||
{
|
||||
// platforms
|
||||
public static final boolean IS_WINDOWS;
|
||||
public static final boolean IS_MAC;
|
||||
public static final boolean IS_LINUX;
|
||||
public static final boolean isWindows;
|
||||
public static final boolean isMacOS;
|
||||
public static final boolean isLinux;
|
||||
|
||||
// OS versions
|
||||
public static final boolean IS_WINDOWS_10_OR_LATER;
|
||||
public static final boolean IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER;
|
||||
public static final boolean IS_MAC_OS_10_14_MOJAVE;
|
||||
public static final boolean IS_MAC_OS_10_15_CATALINA_OR_LATER;
|
||||
public static final long osVersion;
|
||||
public static final boolean isWindows_10_orLater;
|
||||
public static final boolean isMacOS_10_11_ElCapitan_orLater;
|
||||
public static final boolean isMacOS_10_14_Mojave_orLater;
|
||||
public static final boolean isMacOS_10_15_Catalina_orLater;
|
||||
|
||||
// Java versions
|
||||
public static final boolean IS_JAVA_9_OR_LATER;
|
||||
public static final boolean IS_JAVA_11_OR_LATER;
|
||||
public static final boolean IS_JAVA_15_OR_LATER;
|
||||
public static final long javaVersion;
|
||||
public static final boolean isJava_9_orLater;
|
||||
public static final boolean isJava_11_orLater;
|
||||
public static final boolean isJava_15_orLater;
|
||||
|
||||
// Java VMs
|
||||
public static final boolean IS_JETBRAINS_JVM;
|
||||
public static final boolean IS_JETBRAINS_JVM_11_OR_LATER;
|
||||
public static final boolean isJetBrainsJVM;
|
||||
public static final boolean isJetBrainsJVM_11_orLater;
|
||||
|
||||
// UI toolkits
|
||||
public static final boolean IS_KDE;
|
||||
public static final boolean isKDE;
|
||||
|
||||
static {
|
||||
// platforms
|
||||
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
||||
IS_WINDOWS = osName.startsWith( "windows" );
|
||||
IS_MAC = osName.startsWith( "mac" );
|
||||
IS_LINUX = osName.startsWith( "linux" );
|
||||
isWindows = osName.startsWith( "windows" );
|
||||
isMacOS = osName.startsWith( "mac" );
|
||||
isLinux = osName.startsWith( "linux" );
|
||||
|
||||
// OS versions
|
||||
long osVersion = scanVersion( System.getProperty( "os.version" ) );
|
||||
IS_WINDOWS_10_OR_LATER = (IS_WINDOWS && osVersion >= toVersion( 10, 0, 0, 0 ));
|
||||
IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 11, 0, 0 ));
|
||||
IS_MAC_OS_10_14_MOJAVE = (IS_MAC && osVersion >= toVersion( 10, 14, 0, 0 ));
|
||||
IS_MAC_OS_10_15_CATALINA_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 15, 0, 0 ));
|
||||
osVersion = scanVersion( System.getProperty( "os.version" ) );
|
||||
isWindows_10_orLater = (isWindows && osVersion >= toVersion( 10, 0, 0, 0 ));
|
||||
isMacOS_10_11_ElCapitan_orLater = (isMacOS && osVersion >= toVersion( 10, 11, 0, 0 ));
|
||||
isMacOS_10_14_Mojave_orLater = (isMacOS && osVersion >= toVersion( 10, 14, 0, 0 ));
|
||||
isMacOS_10_15_Catalina_orLater = (isMacOS && osVersion >= toVersion( 10, 15, 0, 0 ));
|
||||
|
||||
// Java versions
|
||||
long javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||
IS_JAVA_9_OR_LATER = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||
IS_JAVA_11_OR_LATER = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||
IS_JAVA_15_OR_LATER = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||
|
||||
// Java VMs
|
||||
IS_JETBRAINS_JVM = System.getProperty( "java.vm.vendor", "Unknown" )
|
||||
isJetBrainsJVM = System.getProperty( "java.vm.vendor", "Unknown" )
|
||||
.toLowerCase( Locale.ENGLISH ).contains( "jetbrains" );
|
||||
IS_JETBRAINS_JVM_11_OR_LATER = IS_JETBRAINS_JVM && IS_JAVA_11_OR_LATER;
|
||||
isJetBrainsJVM_11_orLater = isJetBrainsJVM && isJava_11_orLater;
|
||||
|
||||
// UI toolkits
|
||||
IS_KDE = (IS_LINUX && System.getenv( "KDE_FULL_SESSION" ) != null);
|
||||
isKDE = (isLinux && System.getenv( "KDE_FULL_SESSION" ) != null);
|
||||
}
|
||||
|
||||
public static long scanVersion( String version ) {
|
||||
|
||||
@@ -90,10 +90,10 @@ public class UIScale
|
||||
|
||||
jreHiDPI = false;
|
||||
|
||||
if( SystemInfo.IS_JAVA_9_OR_LATER ) {
|
||||
if( SystemInfo.isJava_9_orLater ) {
|
||||
// Java 9 and later supports per-monitor scaling
|
||||
jreHiDPI = true;
|
||||
} else if( SystemInfo.IS_JETBRAINS_JVM ) {
|
||||
} else if( SystemInfo.isJetBrainsJVM ) {
|
||||
// IntelliJ IDEA ships its own JetBrains Java 8 JRE that may supports per-monitor scaling
|
||||
// see com.intellij.ui.JreHiDpiUtil.isJreHiDPIEnabled()
|
||||
try {
|
||||
@@ -177,26 +177,25 @@ public class UIScale
|
||||
// default font size
|
||||
float fontSizeDivider = 12f;
|
||||
|
||||
if( SystemInfo.IS_WINDOWS ) {
|
||||
if( SystemInfo.isWindows ) {
|
||||
// Windows LaF uses Tahoma font rather than the actual Windows system font (Segoe UI),
|
||||
// and its size is always ca. 10% smaller than the actual system font size.
|
||||
// Tahoma 11 is used at 100%
|
||||
if( "Tahoma".equals( font.getFamily() ) )
|
||||
fontSizeDivider = 11f;
|
||||
} else if( SystemInfo.IS_MAC ) {
|
||||
} else if( SystemInfo.isMacOS ) {
|
||||
// default font size on macOS is 13
|
||||
fontSizeDivider = 13f;
|
||||
} else if( SystemInfo.IS_LINUX ) {
|
||||
} else if( SystemInfo.isLinux ) {
|
||||
// default font size for Unity and Gnome is 15 and for KDE it is 13
|
||||
fontSizeDivider = SystemInfo.IS_KDE ? 13f : 15f;
|
||||
fontSizeDivider = SystemInfo.isKDE ? 13f : 15f;
|
||||
}
|
||||
|
||||
return font.getSize() / fontSizeDivider;
|
||||
}
|
||||
|
||||
private static boolean isUserScalingEnabled() {
|
||||
// same as in IntelliJ IDEA
|
||||
return FlatSystemProperties.getBoolean( "hidpi", true );
|
||||
return FlatSystemProperties.getBoolean( FlatSystemProperties.UI_SCALE_ENABLED, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,6 +203,9 @@ public class UIScale
|
||||
* to the given font.
|
||||
*/
|
||||
public static FontUIResource applyCustomScaleFactor( FontUIResource font ) {
|
||||
if( !isUserScalingEnabled() )
|
||||
return font;
|
||||
|
||||
String uiScale = System.getProperty( FlatSystemProperties.UI_SCALE );
|
||||
float scaleFactor = parseScaleFactor( uiScale );
|
||||
if( scaleFactor <= 0 )
|
||||
|
||||
@@ -21,18 +21,20 @@
|
||||
#---- variables ----
|
||||
|
||||
@background=#3c3f41
|
||||
@foreground=#bbbbbb
|
||||
@foreground=#bbb
|
||||
@selectionBackground=#4B6EAF
|
||||
@selectionForeground=@foreground
|
||||
@selectionInactiveBackground=#0D293E
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=#777777
|
||||
@disabledText=#888
|
||||
@textComponentBackground=#45494A
|
||||
@menuBackground=darken(@background,5%)
|
||||
@menuHoverBackground=lighten(@menuBackground,10%,derived)
|
||||
@menuCheckBackground=lighten(@menuBackground,10%,derived)
|
||||
@menuCheckHoverBackground=lighten(@menuBackground,20%,derived)
|
||||
@cellFocusColor=#000000
|
||||
@menuAcceleratorForeground=darken(@foreground,15%)
|
||||
@menuAcceleratorSelectionForeground=@selectionForeground
|
||||
@cellFocusColor=#000
|
||||
@icon=#adadad
|
||||
|
||||
# Drop (use lazy colors for IntelliJ platform themes, which usually do not specify these colors)
|
||||
@@ -42,24 +44,6 @@
|
||||
@dropLineShortColor=lighten(List.selectionBackground,30%,lazy)
|
||||
|
||||
|
||||
#---- globals ----
|
||||
|
||||
*.background=@background
|
||||
*.foreground=@foreground
|
||||
*.textBackground=@background
|
||||
*.textForeground=@foreground
|
||||
*.caretForeground=@foreground
|
||||
*.inactiveBackground=@background
|
||||
*.inactiveForeground=@foreground
|
||||
*.selectionBackground=@selectionBackground
|
||||
*.selectionForeground=@selectionForeground
|
||||
*.disabledBackground=@background
|
||||
*.disabledForeground=@disabledText
|
||||
*.disabledText=@disabledText
|
||||
*.acceleratorForeground=darken(@foreground,15%)
|
||||
*.acceleratorSelectionForeground=@selectionForeground
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
|
||||
activeCaption=#434E60
|
||||
@@ -74,6 +58,9 @@ controlDkShadow=lighten($controlShadow,10%)
|
||||
Button.background=#4c5052
|
||||
Button.hoverBackground=lighten($Button.background,3%,derived)
|
||||
Button.pressedBackground=lighten($Button.background,6%,derived)
|
||||
Button.selectedBackground=lighten($Button.background,10%,derived)
|
||||
Button.selectedForeground=@foreground
|
||||
Button.disabledSelectedBackground=lighten($Button.background,3%,derived)
|
||||
|
||||
Button.borderColor=#5e6060
|
||||
Button.disabledBorderColor=#5e6060
|
||||
@@ -81,7 +68,7 @@ Button.focusedBorderColor=#466d94
|
||||
Button.hoverBorderColor=$Button.focusedBorderColor
|
||||
|
||||
Button.default.background=#365880
|
||||
Button.default.foreground=#bbbbbb
|
||||
Button.default.foreground=#bbb
|
||||
Button.default.hoverBackground=lighten($Button.default.background,3%,derived)
|
||||
Button.default.pressedBackground=lighten($Button.default.background,6%,derived)
|
||||
Button.default.borderColor=#4c708c
|
||||
@@ -92,6 +79,7 @@ Button.default.boldText=true
|
||||
|
||||
Button.toolbar.hoverBackground=lighten($Button.background,1%,derived)
|
||||
Button.toolbar.pressedBackground=lighten($Button.background,4%,derived)
|
||||
Button.toolbar.selectedBackground=lighten($Button.background,7%,derived)
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
@@ -132,12 +120,10 @@ CheckBox.icon[filled].selectedPressedBackground=darken($CheckBox.icon[filled].se
|
||||
|
||||
#---- ComboBox ----
|
||||
|
||||
ComboBox.background=@textComponentBackground
|
||||
ComboBox.buttonBackground=@textComponentBackground
|
||||
ComboBox.buttonEditableBackground=#404445
|
||||
ComboBox.buttonArrowColor=#9A9DA1
|
||||
ComboBox.buttonDisabledArrowColor=#585858
|
||||
ComboBox.buttonHoverArrowColor=#bbbbbb
|
||||
ComboBox.buttonHoverArrowColor=#bbb
|
||||
|
||||
|
||||
#---- Component ----
|
||||
@@ -187,11 +173,6 @@ InternalFrame.activeDropShadowOpacity=0.5
|
||||
InternalFrame.inactiveDropShadowOpacity=0.75
|
||||
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.background=@textComponentBackground
|
||||
|
||||
|
||||
#---- Menu ----
|
||||
|
||||
Menu.icon.arrowColor=#A7A7A7
|
||||
@@ -201,7 +182,6 @@ Menu.icon.disabledArrowColor=#606060
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=#515151
|
||||
MenuBar.hoverBackground=@menuHoverBackground
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
@@ -228,15 +208,16 @@ PopupMenu.borderColor=#5e5e5e
|
||||
|
||||
#---- ProgressBar ----
|
||||
|
||||
ProgressBar.background=#555555
|
||||
ProgressBar.background=#555
|
||||
ProgressBar.foreground=#4A88C7
|
||||
ProgressBar.selectionForeground=@foreground
|
||||
ProgressBar.selectionBackground=@foreground
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
#---- RootPane ----
|
||||
|
||||
RadioButton.icon[filled].centerDiameter=5
|
||||
RootPane.activeBorderColor=darken(@background,7%,derived)
|
||||
RootPane.inactiveBorderColor=darken(@background,5%,derived)
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
@@ -259,7 +240,7 @@ Separator.foreground=#515151
|
||||
|
||||
Slider.trackColor=#646464
|
||||
Slider.thumbColor=#A6A6A6
|
||||
Slider.tickColor=#888888
|
||||
Slider.tickColor=#888
|
||||
Slider.hoverColor=darken($Slider.thumbColor,15%,derived)
|
||||
Slider.disabledForeground=#4c5052
|
||||
|
||||
@@ -272,7 +253,6 @@ SplitPaneDivider.oneTouchHoverArrowColor=#7A7D81
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.disabledForeground=@disabledText
|
||||
TabbedPane.underlineColor=#4A88C7
|
||||
TabbedPane.disabledUnderlineColor=#7a7a7a
|
||||
TabbedPane.hoverColor=#2e3133
|
||||
@@ -282,13 +262,11 @@ TabbedPane.contentAreaColor=#323232
|
||||
|
||||
#---- Table ----
|
||||
|
||||
Table.background=@textComponentBackground
|
||||
Table.gridColor=lighten($Table.background,3%)
|
||||
|
||||
|
||||
#---- TableHeader ----
|
||||
|
||||
TableHeader.background=@textComponentBackground
|
||||
TableHeader.separatorColor=lighten($TableHeader.background,10%)
|
||||
TableHeader.bottomSeparatorColor=$TableHeader.separatorColor
|
||||
|
||||
@@ -303,7 +281,6 @@ TitlePane.buttonPressedBackground=lighten($TitlePane.background,20%,derived)
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=lighten($ToggleButton.background,10%,derived)
|
||||
ToggleButton.selectedForeground=@foreground
|
||||
ToggleButton.disabledSelectedBackground=lighten($ToggleButton.background,3%,derived)
|
||||
|
||||
ToggleButton.toolbar.selectedBackground=lighten($ToggleButton.background,7%,derived)
|
||||
@@ -317,5 +294,4 @@ ToolTip.background=#1e2123
|
||||
|
||||
#---- Tree ----
|
||||
|
||||
Tree.background=@textComponentBackground
|
||||
Tree.hash=#505355
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Button.focusedBackground=null
|
||||
|
||||
Button.default.background=#4D8AC9
|
||||
Button.default.foreground=#FFFFFF
|
||||
Button.default.foreground=#fff
|
||||
Button.default.focusedBackground=null
|
||||
Button.default.borderColor=#3D75B2
|
||||
Button.default.hoverBorderColor=#A9C9F5
|
||||
@@ -36,7 +36,6 @@ Button.default.borderWidth=1
|
||||
#---- CheckBox ----
|
||||
|
||||
CheckBox.icon.style=filled
|
||||
CheckBox.icon[filled].focusWidth=2
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
@@ -67,6 +67,22 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
|
||||
@menuItemMargin=3,6,3,6
|
||||
|
||||
|
||||
#---- globals ----
|
||||
|
||||
*.background=@background
|
||||
*.foreground=@foreground
|
||||
*.caretForeground=@foreground
|
||||
*.inactiveBackground=@background
|
||||
*.inactiveForeground=@disabledText
|
||||
*.selectionBackground=@selectionBackground
|
||||
*.selectionForeground=@selectionForeground
|
||||
*.disabledBackground=@background
|
||||
*.disabledForeground=@disabledText
|
||||
*.disabledText=@disabledText
|
||||
*.acceleratorForeground=@menuAcceleratorForeground
|
||||
*.acceleratorSelectionForeground=@menuAcceleratorSelectionForeground
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
|
||||
desktop=@textComponentBackground
|
||||
@@ -135,6 +151,7 @@ Button.rollover=true
|
||||
Button.defaultButtonFollowsFocus=false
|
||||
[win]Button.defaultButtonFollowsFocus=true
|
||||
|
||||
Button.borderWidth=1
|
||||
Button.default.borderWidth=1
|
||||
|
||||
Button.toolbar.margin=3,3,3,3
|
||||
@@ -180,9 +197,11 @@ ComboBox.border=com.formdev.flatlaf.ui.FlatRoundBorder
|
||||
ComboBox.padding=2,6,2,6
|
||||
ComboBox.minimumWidth=72
|
||||
ComboBox.editorColumns=0
|
||||
ComboBox.maximumRowCount=20
|
||||
ComboBox.maximumRowCount=15
|
||||
[mac]ComboBox.showPopupOnNavigation=true
|
||||
ComboBox.buttonStyle=auto
|
||||
ComboBox.background=@textComponentBackground
|
||||
ComboBox.buttonBackground=@textComponentBackground
|
||||
|
||||
|
||||
#---- Component ----
|
||||
@@ -287,11 +306,13 @@ List.cellFocusColor=@cellFocusColor
|
||||
List.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Default
|
||||
List.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Focused
|
||||
List.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Selected
|
||||
List.background=@textComponentBackground
|
||||
List.selectionInactiveBackground=@selectionInactiveBackground
|
||||
List.selectionInactiveForeground=@selectionInactiveForeground
|
||||
List.dropCellBackground=@dropCellBackground
|
||||
List.dropCellForeground=@dropCellForeground
|
||||
List.dropLineColor=@dropLineColor
|
||||
List.showCellFocusIndicator=false
|
||||
|
||||
|
||||
#---- Menu ----
|
||||
@@ -311,6 +332,7 @@ Menu.background=@menuBackground
|
||||
|
||||
MenuBar.border=com.formdev.flatlaf.ui.FlatMenuBarBorder
|
||||
MenuBar.background=@menuBackground
|
||||
MenuBar.hoverBackground=@menuHoverBackground
|
||||
MenuBar.itemMargins=3,8,3,8
|
||||
|
||||
|
||||
@@ -371,6 +393,7 @@ PasswordField.margin=@textComponentMargin
|
||||
PasswordField.background=@textComponentBackground
|
||||
PasswordField.placeholderForeground=@disabledText
|
||||
PasswordField.echoChar=\u2022
|
||||
PasswordField.showCapsLock=true
|
||||
PasswordField.capsLockIcon=com.formdev.flatlaf.icons.FlatCapsLockIcon
|
||||
|
||||
|
||||
@@ -409,6 +432,7 @@ ProgressBar.repaintInterval=15
|
||||
RadioButton.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||
RadioButton.icon=com.formdev.flatlaf.icons.FlatRadioButtonIcon
|
||||
RadioButton.icon.centerDiameter=8
|
||||
RadioButton.icon[filled].centerDiameter=5
|
||||
RadioButton.margin=2,2,2,2
|
||||
RadioButton.iconTextGap=4
|
||||
RadioButton.rollover=true
|
||||
@@ -430,12 +454,15 @@ RadioButtonMenuItem.background=@menuBackground
|
||||
RootPane.border=com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder
|
||||
RootPane.borderDragThickness=5
|
||||
RootPane.cornerDragWidth=16
|
||||
RootPane.honorMinimumSizeOnResize=true
|
||||
RootPane.honorFrameMinimumSizeOnResize=false
|
||||
RootPane.honorDialogMinimumSizeOnResize=true
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.width=10
|
||||
ScrollBar.minimumThumbSize=10,10
|
||||
ScrollBar.maximumThumbSize=100000,100000
|
||||
ScrollBar.trackInsets=0,0,0,0
|
||||
ScrollBar.thumbInsets=0,0,0,0
|
||||
ScrollBar.trackArc=0
|
||||
@@ -448,10 +475,12 @@ ScrollBar.buttonArrowColor=$ComboBox.buttonArrowColor
|
||||
ScrollBar.buttonDisabledArrowColor=$ComboBox.buttonDisabledArrowColor
|
||||
ScrollBar.allowsAbsolutePositioning=true
|
||||
|
||||
[mac]ScrollBar.minimumThumbSize=18,18
|
||||
[mac]ScrollBar.thumbInsets=2,2,2,2
|
||||
[mac]ScrollBar.thumbArc=999
|
||||
[mac]ScrollBar.hoverThumbWithTrack=true
|
||||
|
||||
[linux]ScrollBar.minimumThumbSize=18,18
|
||||
[linux]ScrollBar.thumbInsets=2,2,2,2
|
||||
[linux]ScrollBar.thumbArc=999
|
||||
|
||||
@@ -515,6 +544,7 @@ TabbedPane.tabAreaInsets=0,0,0,0
|
||||
TabbedPane.selectedTabPadInsets=0,0,0,0
|
||||
TabbedPane.tabRunOverlay=0
|
||||
TabbedPane.tabsOverlapBorder=true
|
||||
TabbedPane.disabledForeground=@disabledText
|
||||
TabbedPane.shadow=@background
|
||||
TabbedPane.contentBorderInsets=null
|
||||
|
||||
@@ -524,6 +554,7 @@ TabbedPane.contentBorderInsets=null
|
||||
Table.rowHeight=20
|
||||
Table.showHorizontalLines=false
|
||||
Table.showVerticalLines=false
|
||||
Table.consistentHomeEndKeyBehavior=true
|
||||
Table.intercellSpacing={dimension}0,0
|
||||
Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder
|
||||
Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon
|
||||
@@ -536,6 +567,7 @@ Table.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Focuse
|
||||
Table.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Selected
|
||||
Table.focusCellBackground=@textComponentBackground
|
||||
Table.focusCellForeground=@foreground
|
||||
Table.background=@textComponentBackground
|
||||
Table.selectionInactiveBackground=@selectionInactiveBackground
|
||||
Table.selectionInactiveForeground=@selectionInactiveForeground
|
||||
Table.dropCellBackground=@dropCellBackground
|
||||
@@ -549,6 +581,7 @@ Table.dropLineShortColor=@dropLineShortColor
|
||||
TableHeader.height=25
|
||||
TableHeader.cellBorder=2,3,2,3
|
||||
TableHeader.focusCellBackground=$TableHeader.background
|
||||
TableHeader.background=@textComponentBackground
|
||||
|
||||
|
||||
#---- TextArea ----
|
||||
@@ -620,6 +653,7 @@ ToggleButton.rollover=true
|
||||
|
||||
ToggleButton.background=$Button.background
|
||||
ToggleButton.pressedBackground=$Button.pressedBackground
|
||||
ToggleButton.selectedForeground=@foreground
|
||||
|
||||
ToggleButton.toolbar.hoverBackground=$Button.toolbar.hoverBackground
|
||||
ToggleButton.toolbar.pressedBackground=$Button.toolbar.pressedBackground
|
||||
@@ -659,9 +693,12 @@ ToolTipManager.enableToolTipMode=activeApplication
|
||||
#---- Tree ----
|
||||
|
||||
Tree.border=1,1,1,1
|
||||
Tree.editorBorder=1,1,1,1,@cellFocusColor
|
||||
Tree.background=@textComponentBackground
|
||||
Tree.selectionInactiveBackground=@selectionInactiveBackground
|
||||
Tree.selectionInactiveForeground=@selectionInactiveForeground
|
||||
Tree.textBackground=$Tree.background
|
||||
Tree.textForeground=$Tree.foreground
|
||||
Tree.selectionBorderColor=@cellFocusColor
|
||||
Tree.dropCellBackground=@dropCellBackground
|
||||
Tree.dropCellForeground=@dropCellForeground
|
||||
@@ -671,6 +708,7 @@ Tree.rendererMargins=1,2,1,2
|
||||
Tree.wideSelection=true
|
||||
Tree.repaintWholeRow=true
|
||||
Tree.paintLines=false
|
||||
Tree.showCellFocusIndicator=false
|
||||
Tree.leftChildIndent=7
|
||||
Tree.rightChildIndent=11
|
||||
Tree.rowHeight=0
|
||||
|
||||
@@ -21,18 +21,20 @@
|
||||
#---- variables ----
|
||||
|
||||
@background=#f2f2f2
|
||||
@foreground=#000000
|
||||
@foreground=#000
|
||||
@selectionBackground=#2675BF
|
||||
@selectionForeground=#ffffff
|
||||
@selectionForeground=#fff
|
||||
@selectionInactiveBackground=#d4d4d4
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=#8C8C8C
|
||||
@textComponentBackground=#ffffff
|
||||
@textComponentBackground=#fff
|
||||
@menuBackground=#fff
|
||||
@menuHoverBackground=darken(@menuBackground,10%,derived)
|
||||
@menuCheckBackground=darken(@menuBackground,10%,derived)
|
||||
@menuCheckHoverBackground=darken(@menuBackground,20%,derived)
|
||||
@cellFocusColor=#000000
|
||||
@menuAcceleratorForeground=lighten(@foreground,30%)
|
||||
@menuAcceleratorSelectionForeground=@selectionForeground
|
||||
@cellFocusColor=#000
|
||||
@icon=#afafaf
|
||||
|
||||
# Drop (use lazy colors for IntelliJ platform themes, which usually do not specify these colors)
|
||||
@@ -42,24 +44,6 @@
|
||||
@dropLineShortColor=darken(List.selectionBackground,20%,lazy)
|
||||
|
||||
|
||||
#---- globals ----
|
||||
|
||||
*.background=@background
|
||||
*.foreground=@foreground
|
||||
*.textBackground=#cccccc
|
||||
*.textForeground=@foreground
|
||||
*.caretForeground=@foreground
|
||||
*.inactiveBackground=@background
|
||||
*.inactiveForeground=@disabledText
|
||||
*.selectionBackground=@selectionBackground
|
||||
*.selectionForeground=@selectionForeground
|
||||
*.disabledBackground=@background
|
||||
*.disabledForeground=@disabledText
|
||||
*.disabledText=@disabledText
|
||||
*.acceleratorForeground=lighten(@foreground,30%)
|
||||
*.acceleratorSelectionForeground=@selectionForeground
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
|
||||
activeCaption=#99b4d1
|
||||
@@ -71,10 +55,13 @@ controlDkShadow=darken($controlShadow,15%)
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.background=#ffffff
|
||||
Button.background=#fff
|
||||
Button.focusedBackground=#e3f1fa
|
||||
Button.hoverBackground=darken($Button.background,3%,derived)
|
||||
Button.pressedBackground=darken($Button.background,10%,derived)
|
||||
Button.selectedBackground=darken($Button.background,20%,derived)
|
||||
Button.selectedForeground=@foreground
|
||||
Button.disabledSelectedBackground=darken($Button.background,13%,derived)
|
||||
|
||||
Button.borderColor=$Component.borderColor
|
||||
Button.disabledBorderColor=$Component.disabledBorderColor
|
||||
@@ -94,13 +81,14 @@ Button.default.borderWidth=2
|
||||
|
||||
Button.toolbar.hoverBackground=darken($Button.background,12%,derived)
|
||||
Button.toolbar.pressedBackground=darken($Button.background,15%,derived)
|
||||
Button.toolbar.selectedBackground=$Button.selectedBackground
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
# enabled
|
||||
CheckBox.icon.borderColor=#b0b0b0
|
||||
CheckBox.icon.background=#FFFFFF
|
||||
CheckBox.icon.background=#fff
|
||||
CheckBox.icon.selectedBorderColor=$CheckBox.icon.borderColor
|
||||
CheckBox.icon.selectedBackground=$CheckBox.icon.background
|
||||
CheckBox.icon.checkmarkColor=#4F9EE3
|
||||
@@ -126,25 +114,23 @@ CheckBox.icon.pressedBackground=$Button.pressedBackground
|
||||
# enabled
|
||||
CheckBox.icon[filled].selectedBorderColor=#4B97D9
|
||||
CheckBox.icon[filled].selectedBackground=#4F9EE3
|
||||
CheckBox.icon[filled].checkmarkColor=#FFFFFF
|
||||
CheckBox.icon[filled].checkmarkColor=#fff
|
||||
# focused
|
||||
CheckBox.icon[filled].selectedFocusedBorderColor=#ACCFF7
|
||||
CheckBox.icon[filled].selectedFocusedBackground=$CheckBox.icon[filled].selectedBackground
|
||||
CheckBox.icon[filled].selectedFocusedCheckmarkColor=$CheckBox.icon.focusedBackground
|
||||
# hover
|
||||
CheckBox.icon[filled].selectedHoverBackground=#5E94CE
|
||||
CheckBox.icon[filled].selectedHoverBackground=darken($CheckBox.icon[filled].selectedBackground,5%)
|
||||
# pressed
|
||||
CheckBox.icon[filled].selectedPressedBackground=#72A1D4
|
||||
CheckBox.icon[filled].selectedPressedBackground=darken($CheckBox.icon[filled].selectedBackground,10%)
|
||||
|
||||
|
||||
#---- ComboBox ----
|
||||
|
||||
ComboBox.background=@textComponentBackground
|
||||
ComboBox.buttonBackground=@textComponentBackground
|
||||
ComboBox.buttonEditableBackground=#fafafa
|
||||
ComboBox.buttonArrowColor=#666666
|
||||
ComboBox.buttonArrowColor=#666
|
||||
ComboBox.buttonDisabledArrowColor=#ABABAB
|
||||
ComboBox.buttonHoverArrowColor=#999999
|
||||
ComboBox.buttonHoverArrowColor=#999
|
||||
|
||||
|
||||
#---- Component ----
|
||||
@@ -199,21 +185,15 @@ InternalFrame.activeDropShadowOpacity=0.25
|
||||
InternalFrame.inactiveDropShadowOpacity=0.5
|
||||
|
||||
|
||||
#---- List ----
|
||||
|
||||
List.background=@textComponentBackground
|
||||
|
||||
|
||||
#---- Menu ----
|
||||
|
||||
Menu.icon.arrowColor=#666666
|
||||
Menu.icon.arrowColor=#666
|
||||
Menu.icon.disabledArrowColor=#ABABAB
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=#cdcdcd
|
||||
MenuBar.hoverBackground=@menuHoverBackground
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
@@ -246,9 +226,10 @@ ProgressBar.selectionForeground=@textComponentBackground
|
||||
ProgressBar.selectionBackground=@foreground
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
#---- RootPane ----
|
||||
|
||||
RadioButton.icon[filled].centerDiameter=5
|
||||
RootPane.activeBorderColor=#707070
|
||||
RootPane.inactiveBorderColor=lighten($RootPane.activeBorderColor,20%,derived)
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
@@ -271,7 +252,7 @@ Separator.foreground=#d1d1d1
|
||||
|
||||
Slider.trackColor=#c4c4c4
|
||||
Slider.thumbColor=#6e6e6e
|
||||
Slider.tickColor=#888888
|
||||
Slider.tickColor=#888
|
||||
Slider.hoverColor=lighten($Slider.thumbColor,15%,derived)
|
||||
Slider.disabledForeground=#c0c0c0
|
||||
|
||||
@@ -279,12 +260,11 @@ Slider.disabledForeground=#c0c0c0
|
||||
#---- SplitPane ----
|
||||
|
||||
SplitPaneDivider.draggingColor=#c4c4c4
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=#333333
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=#333
|
||||
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.disabledForeground=@disabledText
|
||||
TabbedPane.underlineColor=#4083C9
|
||||
TabbedPane.disabledUnderlineColor=#ababab
|
||||
TabbedPane.hoverColor=#d9d9d9
|
||||
@@ -294,13 +274,11 @@ TabbedPane.contentAreaColor=#bfbfbf
|
||||
|
||||
#---- Table ----
|
||||
|
||||
Table.background=@textComponentBackground
|
||||
Table.gridColor=darken($Table.background,3%)
|
||||
|
||||
|
||||
#---- TableHeader ----
|
||||
|
||||
TableHeader.background=@textComponentBackground
|
||||
TableHeader.separatorColor=darken($TableHeader.background,10%)
|
||||
TableHeader.bottomSeparatorColor=$TableHeader.separatorColor
|
||||
|
||||
@@ -315,7 +293,6 @@ TitlePane.buttonPressedBackground=darken($TitlePane.background,20%,derived)
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=darken($ToggleButton.background,20%,derived)
|
||||
ToggleButton.selectedForeground=@foreground
|
||||
ToggleButton.disabledSelectedBackground=darken($ToggleButton.background,13%,derived)
|
||||
|
||||
ToggleButton.toolbar.selectedBackground=$ToggleButton.selectedBackground
|
||||
@@ -329,5 +306,4 @@ ToolTip.background=#fafafa
|
||||
|
||||
#---- Tree ----
|
||||
|
||||
Tree.background=@textComponentBackground
|
||||
Tree.hash=#E6E6E6
|
||||
|
||||
@@ -45,6 +45,24 @@ ToggleButton.endBackground=$ToggleButton.background
|
||||
|
||||
#---- theme specific ----
|
||||
|
||||
[Arc_Theme]ProgressBar.selectionBackground=#000
|
||||
[Arc_Theme]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Arc_Theme_-_Orange]ProgressBar.selectionBackground=#000
|
||||
[Arc_Theme_-_Orange]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Arc_Theme_Dark]ProgressBar.selectionBackground=#ddd
|
||||
[Arc_Theme_Dark]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionBackground=#ddd
|
||||
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Cobalt_2]CheckBox.icon.background=#002946
|
||||
[Cobalt_2]CheckBox.icon.checkmarkColor=#002946
|
||||
|
||||
[Dracula]ProgressBar.selectionBackground=#fff
|
||||
[Dracula]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Gruvbox_Dark_Hard]ToggleButton.selectedBackground=$ToggleButton.selectedBackground
|
||||
[Gruvbox_Dark_Hard]ToggleButton.toolbar.selectedBackground=$ToggleButton.toolbar.selectedBackground
|
||||
|
||||
@@ -62,3 +80,57 @@ ToggleButton.endBackground=$ToggleButton.background
|
||||
[High_contrast]ToggleButton.selectedForeground=#000
|
||||
[High_contrast]ToggleButton.disabledSelectedBackground=#444
|
||||
[High_contrast]ToggleButton.toolbar.selectedBackground=#fff
|
||||
|
||||
|
||||
# Material Theme UI Lite
|
||||
|
||||
[Dracula_Contrast]ProgressBar.selectionBackground=#fff
|
||||
[Dracula_Contrast]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[GitHub]ProgressBar.selectionBackground=#222
|
||||
[GitHub]ProgressBar.selectionForeground=#222
|
||||
|
||||
[GitHub_Contrast]ProgressBar.selectionBackground=#222
|
||||
[GitHub_Contrast]ProgressBar.selectionForeground=#222
|
||||
|
||||
[Light_Owl]ProgressBar.selectionBackground=#111
|
||||
[Light_Owl]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Light_Owl_Contrast]ProgressBar.selectionBackground=#111
|
||||
[Light_Owl_Contrast]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Material_Lighter]ProgressBar.selectionBackground=#222
|
||||
[Material_Lighter]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Material_Lighter_Contrast]ProgressBar.selectionBackground=#222
|
||||
[Material_Lighter_Contrast]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Material_Oceanic]ProgressBar.selectionBackground=#ddd
|
||||
[Material_Oceanic]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Material_Oceanic_Contrast]ProgressBar.selectionBackground=#ddd
|
||||
[Material_Oceanic_Contrast]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Material_Palenight]ProgressBar.selectionBackground=#ddd
|
||||
[Material_Palenight]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Material_Palenight_Contrast]ProgressBar.selectionBackground=#ddd
|
||||
[Material_Palenight_Contrast]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Night_Owl]ProgressBar.selectionBackground=#ddd
|
||||
[Night_Owl]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Night_Owl_Contrast]ProgressBar.selectionBackground=#ddd
|
||||
[Night_Owl_Contrast]ProgressBar.selectionForeground=#ddd
|
||||
|
||||
[Solarized_Dark]ProgressBar.selectionBackground=#ccc
|
||||
[Solarized_Dark]ProgressBar.selectionForeground=#ccc
|
||||
|
||||
[Material_Solarized_Dark_Contrast]ProgressBar.selectionBackground=#ccc
|
||||
[Material_Solarized_Dark_Contrast]ProgressBar.selectionForeground=#ccc
|
||||
|
||||
[Solarized_Light]ProgressBar.selectionBackground=#222
|
||||
[Solarized_Light]ProgressBar.selectionForeground=#fff
|
||||
|
||||
[Material_Solarized_Light_Contrast]ProgressBar.selectionBackground=#222
|
||||
[Material_Solarized_Light_Contrast]ProgressBar.selectionForeground=#fff
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.Component;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import net.miginfocom.swing.*;
|
||||
@@ -114,14 +115,14 @@ class BasicComponentsPanel
|
||||
JScrollPane scrollPane12 = new JScrollPane();
|
||||
JTextPane textPane4 = new JTextPane();
|
||||
JTextPane textPane5 = new JTextPane();
|
||||
JLabel label3 = new JLabel();
|
||||
JTextField textField5 = new JTextField();
|
||||
JComboBox<String> comboBox7 = new JComboBox<>();
|
||||
JSpinner spinner3 = new JSpinner();
|
||||
JLabel label4 = new JLabel();
|
||||
JTextField textField7 = new JTextField();
|
||||
JComboBox<String> comboBox8 = new JComboBox<>();
|
||||
JSpinner spinner4 = new JSpinner();
|
||||
JLabel errorHintsLabel = new JLabel();
|
||||
JTextField errorHintsTextField = new JTextField();
|
||||
JComboBox<String> errorHintsComboBox = new JComboBox<>();
|
||||
JSpinner errorHintsSpinner = new JSpinner();
|
||||
JLabel warningHintsLabel = new JLabel();
|
||||
JTextField warningHintsTextField = new JTextField();
|
||||
JComboBox<String> warningHintsComboBox = new JComboBox<>();
|
||||
JSpinner warningHintsSpinner = new JSpinner();
|
||||
JPopupMenu popupMenu1 = new JPopupMenu();
|
||||
JMenuItem cutMenuItem = new JMenuItem();
|
||||
JMenuItem copyMenuItem = new JMenuItem();
|
||||
@@ -129,12 +130,12 @@ class BasicComponentsPanel
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[sizegroup 1]" +
|
||||
"[sizegroup 1]" +
|
||||
"[sizegroup 1]" +
|
||||
"[sizegroup 1]" +
|
||||
"[]" +
|
||||
"[]",
|
||||
// rows
|
||||
@@ -606,44 +607,44 @@ class BasicComponentsPanel
|
||||
textPane5.setText("No scroll pane");
|
||||
add(textPane5, "cell 5 11,growx");
|
||||
|
||||
//---- label3 ----
|
||||
label3.setText("Error hints:");
|
||||
add(label3, "cell 0 12");
|
||||
//---- errorHintsLabel ----
|
||||
errorHintsLabel.setText("Error hints:");
|
||||
add(errorHintsLabel, "cell 0 12");
|
||||
|
||||
//---- textField5 ----
|
||||
textField5.putClientProperty("JComponent.outline", "error");
|
||||
add(textField5, "cell 1 12,growx");
|
||||
//---- errorHintsTextField ----
|
||||
errorHintsTextField.putClientProperty("JComponent.outline", "error");
|
||||
add(errorHintsTextField, "cell 1 12,growx");
|
||||
|
||||
//---- comboBox7 ----
|
||||
comboBox7.putClientProperty("JComponent.outline", "error");
|
||||
comboBox7.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
//---- errorHintsComboBox ----
|
||||
errorHintsComboBox.putClientProperty("JComponent.outline", "error");
|
||||
errorHintsComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"Editable"
|
||||
}));
|
||||
comboBox7.setEditable(true);
|
||||
add(comboBox7, "cell 2 12,growx");
|
||||
errorHintsComboBox.setEditable(true);
|
||||
add(errorHintsComboBox, "cell 2 12,growx");
|
||||
|
||||
//---- spinner3 ----
|
||||
spinner3.putClientProperty("JComponent.outline", "error");
|
||||
add(spinner3, "cell 3 12,growx");
|
||||
//---- errorHintsSpinner ----
|
||||
errorHintsSpinner.putClientProperty("JComponent.outline", "error");
|
||||
add(errorHintsSpinner, "cell 3 12,growx");
|
||||
|
||||
//---- label4 ----
|
||||
label4.setText("Warning hints:");
|
||||
add(label4, "cell 0 13");
|
||||
//---- warningHintsLabel ----
|
||||
warningHintsLabel.setText("Warning hints:");
|
||||
add(warningHintsLabel, "cell 0 13");
|
||||
|
||||
//---- textField7 ----
|
||||
textField7.putClientProperty("JComponent.outline", "warning");
|
||||
add(textField7, "cell 1 13,growx");
|
||||
//---- warningHintsTextField ----
|
||||
warningHintsTextField.putClientProperty("JComponent.outline", "warning");
|
||||
add(warningHintsTextField, "cell 1 13,growx");
|
||||
|
||||
//---- comboBox8 ----
|
||||
comboBox8.putClientProperty("JComponent.outline", "warning");
|
||||
comboBox8.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
//---- warningHintsComboBox ----
|
||||
warningHintsComboBox.putClientProperty("JComponent.outline", "warning");
|
||||
warningHintsComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"Not editable"
|
||||
}));
|
||||
add(comboBox8, "cell 2 13,growx");
|
||||
add(warningHintsComboBox, "cell 2 13,growx");
|
||||
|
||||
//---- spinner4 ----
|
||||
spinner4.putClientProperty("JComponent.outline", "warning");
|
||||
add(spinner4, "cell 3 13,growx");
|
||||
//---- warningHintsSpinner ----
|
||||
warningHintsSpinner.putClientProperty("JComponent.outline", "warning");
|
||||
add(warningHintsSpinner, "cell 3 13,growx");
|
||||
|
||||
//======== popupMenu1 ========
|
||||
{
|
||||
@@ -668,6 +669,33 @@ class BasicComponentsPanel
|
||||
cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() );
|
||||
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
||||
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
|
||||
|
||||
if( FlatLafDemo.screenshotsMode ) {
|
||||
Component[] components = {
|
||||
button13, button14, button15, button16, comboBox5, comboBox6,
|
||||
textField6, passwordField5,
|
||||
|
||||
formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4, formattedTextField5,
|
||||
textAreaLabel, scrollPane1, scrollPane2, scrollPane3, scrollPane4, textArea5,
|
||||
editorPaneLabel, scrollPane5, scrollPane6, scrollPane7, scrollPane8, editorPane5,
|
||||
textPaneLabel, scrollPane9, scrollPane10, scrollPane11, scrollPane12, textPane5,
|
||||
|
||||
errorHintsLabel, errorHintsTextField, errorHintsComboBox, errorHintsSpinner,
|
||||
warningHintsLabel, warningHintsTextField, warningHintsComboBox, warningHintsSpinner,
|
||||
};
|
||||
|
||||
for( Component c : components )
|
||||
c.setVisible( false );
|
||||
|
||||
// move password fields one row up
|
||||
Component[] formattedTextFields = { formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4 };
|
||||
Component[] passwordFields = { passwordFieldLabel, passwordField1, passwordField2, passwordField3, passwordField4 };
|
||||
MigLayout layout = (MigLayout) getLayout();
|
||||
for( int i = 0; i < passwordFields.length; i++ ) {
|
||||
Object cons = layout.getComponentConstraints( formattedTextFields[i] );
|
||||
layout.setComponentConstraints( passwordFields[i], cons );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
|
||||
@@ -7,8 +7,8 @@ new FormModel {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$columnConstraints": "[][][][][][]"
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[sizegroup 1][sizegroup 1][sizegroup 1][sizegroup 1][][]"
|
||||
"$rowConstraints": "[][][][][][][][][][][][]para[][]"
|
||||
} ) {
|
||||
name: "this"
|
||||
@@ -592,19 +592,19 @@ new FormModel {
|
||||
"value": "cell 5 11,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label3"
|
||||
name: "errorHintsLabel"
|
||||
"text": "Error hints:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 12"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField5"
|
||||
name: "errorHintsTextField"
|
||||
"$client.JComponent.outline": "error"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "comboBox7"
|
||||
name: "errorHintsComboBox"
|
||||
"$client.JComponent.outline": "error"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "Editable"
|
||||
@@ -615,25 +615,25 @@ new FormModel {
|
||||
"value": "cell 2 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||
name: "spinner3"
|
||||
name: "errorHintsSpinner"
|
||||
"$client.JComponent.outline": "error"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label4"
|
||||
name: "warningHintsLabel"
|
||||
"text": "Warning hints:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 13"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField7"
|
||||
name: "warningHintsTextField"
|
||||
"$client.JComponent.outline": "warning"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "comboBox8"
|
||||
name: "warningHintsComboBox"
|
||||
"$client.JComponent.outline": "warning"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "Not editable"
|
||||
@@ -643,7 +643,7 @@ new FormModel {
|
||||
"value": "cell 2 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||
name: "spinner4"
|
||||
name: "warningHintsSpinner"
|
||||
"$client.JComponent.outline": "warning"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 13,growx"
|
||||
|
||||
@@ -27,8 +27,12 @@ import javax.swing.UIManager.LookAndFeelInfo;
|
||||
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.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import net.miginfocom.layout.ConstraintParser;
|
||||
import net.miginfocom.layout.LC;
|
||||
import net.miginfocom.layout.UnitValue;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -43,6 +47,18 @@ class ControlBar
|
||||
ControlBar() {
|
||||
initComponents();
|
||||
|
||||
// remove top insets
|
||||
MigLayout layout = (MigLayout) getLayout();
|
||||
LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() );
|
||||
UnitValue[] insets = lc.getInsets();
|
||||
lc.setInsets( new UnitValue[] {
|
||||
new UnitValue( 0, UnitValue.PIXEL, null ),
|
||||
insets[1],
|
||||
insets[2],
|
||||
insets[3]
|
||||
} );
|
||||
layout.setLayoutConstraints( lc );
|
||||
|
||||
// initialize look and feels combo box
|
||||
DefaultComboBoxModel<LookAndFeelInfo> lafModel = new DefaultComboBoxModel<>();
|
||||
lafModel.addElement( new LookAndFeelInfo( "Flat Light (F1)", FlatLightLaf.class.getName() ) );
|
||||
@@ -58,9 +74,9 @@ class ControlBar
|
||||
className.equals( "com.sun.java.swing.plaf.motif.MotifLookAndFeel" ) )
|
||||
continue;
|
||||
|
||||
if( (SystemInfo.IS_WINDOWS && className.equals( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" )) ||
|
||||
(SystemInfo.IS_MAC && className.equals( "com.apple.laf.AquaLookAndFeel") ) ||
|
||||
(SystemInfo.IS_LINUX && className.equals( "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ) )
|
||||
if( (SystemInfo.isWindows && className.equals( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" )) ||
|
||||
(SystemInfo.isMacOS && className.equals( "com.apple.laf.AquaLookAndFeel") ) ||
|
||||
(SystemInfo.isLinux && className.equals( "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ) )
|
||||
name += " (F9)";
|
||||
else if( className.equals( MetalLookAndFeel.class.getName() ) )
|
||||
name += " (F12)";
|
||||
@@ -111,11 +127,11 @@ class ControlBar
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatIntelliJLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatDarculaLaf.class.getName() );
|
||||
|
||||
if( SystemInfo.IS_WINDOWS )
|
||||
if( SystemInfo.isWindows )
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
|
||||
else if( SystemInfo.IS_MAC )
|
||||
else if( SystemInfo.isMacOS )
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.apple.laf.AquaLookAndFeel" );
|
||||
else if( SystemInfo.IS_LINUX )
|
||||
else if( SystemInfo.isLinux )
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F12, MetalLookAndFeel.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F11, NimbusLookAndFeel.class.getName() );
|
||||
@@ -193,6 +209,8 @@ class ControlBar
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
try {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
// change look and feel
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
|
||||
@@ -202,6 +220,7 @@ class ControlBar
|
||||
|
||||
// update all components
|
||||
FlatLaf.updateUI();
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
|
||||
// increase size of frame if necessary
|
||||
int width = frame.getWidth();
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
@@ -64,6 +67,41 @@ class DataComponentsPanel
|
||||
}
|
||||
}
|
||||
|
||||
private void rowSelectionChanged() {
|
||||
table1.setRowSelectionAllowed( rowSelectionCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void columnSelectionChanged() {
|
||||
table1.setColumnSelectionAllowed( columnSelectionCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void showHorizontalLinesChanged() {
|
||||
table1.setShowHorizontalLines( showHorizontalLinesCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void showVerticalLinesChanged() {
|
||||
table1.setShowVerticalLines( showVerticalLinesCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void intercellSpacingChanged() {
|
||||
table1.setIntercellSpacing( intercellSpacingCheckBox.isSelected() ? new Dimension( 1, 1 ) : new Dimension() );
|
||||
}
|
||||
|
||||
private void redGridColorChanged() {
|
||||
table1.setGridColor( redGridColorCheckBox.isSelected() ? Color.red : UIManager.getColor( "Table.gridColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
showHorizontalLinesChanged();
|
||||
showVerticalLinesChanged();
|
||||
intercellSpacingChanged();
|
||||
} );
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
@@ -80,6 +118,13 @@ class DataComponentsPanel
|
||||
JLabel tableLabel = new JLabel();
|
||||
JScrollPane scrollPane5 = new JScrollPane();
|
||||
table1 = new JTable();
|
||||
JPanel tableOptionsPanel = new JPanel();
|
||||
showHorizontalLinesCheckBox = new JCheckBox();
|
||||
showVerticalLinesCheckBox = new JCheckBox();
|
||||
intercellSpacingCheckBox = new JCheckBox();
|
||||
redGridColorCheckBox = new JCheckBox();
|
||||
rowSelectionCheckBox = new JCheckBox();
|
||||
columnSelectionCheckBox = new JCheckBox();
|
||||
dndCheckBox = new JCheckBox();
|
||||
JPopupMenu popupMenu2 = new JPopupMenu();
|
||||
JMenuItem menuItem3 = new JMenuItem();
|
||||
@@ -89,20 +134,20 @@ class DataComponentsPanel
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[]" +
|
||||
"[200]" +
|
||||
"[200]",
|
||||
"[200,fill]" +
|
||||
"[200,fill]" +
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]" +
|
||||
"[::200]" +
|
||||
"[::150]" +
|
||||
"[]"));
|
||||
"[150,grow,sizegroup 1,fill]" +
|
||||
"[150,grow,sizegroup 1,fill]" +
|
||||
"[150,grow,sizegroup 1,fill]"));
|
||||
|
||||
//---- listLabel ----
|
||||
listLabel.setText("JList:");
|
||||
add(listLabel, "cell 0 0");
|
||||
add(listLabel, "cell 0 0,aligny top,growy 0");
|
||||
|
||||
//======== scrollPane1 ========
|
||||
{
|
||||
@@ -134,7 +179,7 @@ class DataComponentsPanel
|
||||
list1.setComponentPopupMenu(popupMenu2);
|
||||
scrollPane1.setViewportView(list1);
|
||||
}
|
||||
add(scrollPane1, "cell 1 0,growx");
|
||||
add(scrollPane1, "cell 1 0");
|
||||
|
||||
//======== scrollPane2 ========
|
||||
{
|
||||
@@ -166,11 +211,11 @@ class DataComponentsPanel
|
||||
list2.setEnabled(false);
|
||||
scrollPane2.setViewportView(list2);
|
||||
}
|
||||
add(scrollPane2, "cell 2 0,growx");
|
||||
add(scrollPane2, "cell 2 0");
|
||||
|
||||
//---- treeLabel ----
|
||||
treeLabel.setText("JTree:");
|
||||
add(treeLabel, "cell 0 1");
|
||||
add(treeLabel, "cell 0 1,aligny top,growy 0");
|
||||
|
||||
//======== scrollPane3 ========
|
||||
{
|
||||
@@ -207,7 +252,7 @@ class DataComponentsPanel
|
||||
tree1.setComponentPopupMenu(popupMenu2);
|
||||
scrollPane3.setViewportView(tree1);
|
||||
}
|
||||
add(scrollPane3, "cell 1 1,growx");
|
||||
add(scrollPane3, "cell 1 1");
|
||||
|
||||
//======== scrollPane4 ========
|
||||
{
|
||||
@@ -216,11 +261,11 @@ class DataComponentsPanel
|
||||
tree2.setEnabled(false);
|
||||
scrollPane4.setViewportView(tree2);
|
||||
}
|
||||
add(scrollPane4, "cell 2 1,growx");
|
||||
add(scrollPane4, "cell 2 1");
|
||||
|
||||
//---- tableLabel ----
|
||||
tableLabel.setText("JTable:");
|
||||
add(tableLabel, "cell 0 2");
|
||||
add(tableLabel, "cell 0 2,aligny top,growy 0");
|
||||
|
||||
//======== scrollPane5 ========
|
||||
{
|
||||
@@ -297,13 +342,61 @@ class DataComponentsPanel
|
||||
table1.setComponentPopupMenu(popupMenu2);
|
||||
scrollPane5.setViewportView(table1);
|
||||
}
|
||||
add(scrollPane5, "cell 1 2 2 1,growx,width 300");
|
||||
add(scrollPane5, "cell 1 2 2 1,width 300");
|
||||
|
||||
//---- dndCheckBox ----
|
||||
dndCheckBox.setText("enable drag and drop");
|
||||
dndCheckBox.setMnemonic('D');
|
||||
dndCheckBox.addActionListener(e -> dndChanged());
|
||||
add(dndCheckBox, "cell 0 3 3 1");
|
||||
//======== tableOptionsPanel ========
|
||||
{
|
||||
tableOptionsPanel.setLayout(new MigLayout(
|
||||
"insets 0,hidemode 3",
|
||||
// columns
|
||||
"[]",
|
||||
// rows
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]0"));
|
||||
|
||||
//---- showHorizontalLinesCheckBox ----
|
||||
showHorizontalLinesCheckBox.setText("show horizontal lines");
|
||||
showHorizontalLinesCheckBox.addActionListener(e -> showHorizontalLinesChanged());
|
||||
tableOptionsPanel.add(showHorizontalLinesCheckBox, "cell 0 0");
|
||||
|
||||
//---- showVerticalLinesCheckBox ----
|
||||
showVerticalLinesCheckBox.setText("show vertical lines");
|
||||
showVerticalLinesCheckBox.addActionListener(e -> showVerticalLinesChanged());
|
||||
tableOptionsPanel.add(showVerticalLinesCheckBox, "cell 0 1");
|
||||
|
||||
//---- intercellSpacingCheckBox ----
|
||||
intercellSpacingCheckBox.setText("intercell spacing");
|
||||
intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged());
|
||||
tableOptionsPanel.add(intercellSpacingCheckBox, "cell 0 2");
|
||||
|
||||
//---- redGridColorCheckBox ----
|
||||
redGridColorCheckBox.setText("red grid color");
|
||||
redGridColorCheckBox.addActionListener(e -> redGridColorChanged());
|
||||
tableOptionsPanel.add(redGridColorCheckBox, "cell 0 3");
|
||||
|
||||
//---- rowSelectionCheckBox ----
|
||||
rowSelectionCheckBox.setText("row selection");
|
||||
rowSelectionCheckBox.setSelected(true);
|
||||
rowSelectionCheckBox.addActionListener(e -> rowSelectionChanged());
|
||||
tableOptionsPanel.add(rowSelectionCheckBox, "cell 0 4");
|
||||
|
||||
//---- columnSelectionCheckBox ----
|
||||
columnSelectionCheckBox.setText("column selection");
|
||||
columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged());
|
||||
tableOptionsPanel.add(columnSelectionCheckBox, "cell 0 5");
|
||||
|
||||
//---- dndCheckBox ----
|
||||
dndCheckBox.setText("enable drag and drop");
|
||||
dndCheckBox.setMnemonic('D');
|
||||
dndCheckBox.addActionListener(e -> dndChanged());
|
||||
tableOptionsPanel.add(dndCheckBox, "cell 0 6");
|
||||
}
|
||||
add(tableOptionsPanel, "cell 3 2");
|
||||
|
||||
//======== popupMenu2 ========
|
||||
{
|
||||
@@ -336,6 +429,12 @@ class DataComponentsPanel
|
||||
private JTree tree1;
|
||||
private JTree tree2;
|
||||
private JTable table1;
|
||||
private JCheckBox showHorizontalLinesCheckBox;
|
||||
private JCheckBox showVerticalLinesCheckBox;
|
||||
private JCheckBox intercellSpacingCheckBox;
|
||||
private JCheckBox redGridColorCheckBox;
|
||||
private JCheckBox rowSelectionCheckBox;
|
||||
private JCheckBox columnSelectionCheckBox;
|
||||
private JCheckBox dndCheckBox;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -7,16 +7,16 @@ new FormModel {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$columnConstraints": "[][200][200]"
|
||||
"$rowConstraints": "[][::200][::150][]"
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][200,fill][200,fill][fill]"
|
||||
"$rowConstraints": "[150,grow,sizegroup 1,fill][150,grow,sizegroup 1,fill][150,grow,sizegroup 1,fill]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "listLabel"
|
||||
"text": "JList:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
"value": "cell 0 0,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane1"
|
||||
@@ -46,7 +46,7 @@ new FormModel {
|
||||
}
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 0,growx"
|
||||
"value": "cell 1 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane2"
|
||||
@@ -76,13 +76,13 @@ new FormModel {
|
||||
}
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0,growx"
|
||||
"value": "cell 2 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "treeLabel"
|
||||
"text": "JTree:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
"value": "cell 0 1,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane3"
|
||||
@@ -150,7 +150,7 @@ new FormModel {
|
||||
}
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 1,growx"
|
||||
"value": "cell 1 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane4"
|
||||
@@ -162,13 +162,13 @@ new FormModel {
|
||||
}
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 1,growx"
|
||||
"value": "cell 2 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "tableLabel"
|
||||
"text": "JTable:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
"value": "cell 0 2,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane5"
|
||||
@@ -307,22 +307,92 @@ new FormModel {
|
||||
}
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 2 2 1,growx,width 300"
|
||||
"value": "cell 1 2 2 1,width 300"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "dndCheckBox"
|
||||
"text": "enable drag and drop"
|
||||
"mnemonic": 68
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets 0,hidemode 3"
|
||||
"$columnConstraints": "[]"
|
||||
"$rowConstraints": "[]0[]0[]0[]0[]0[]0[]0"
|
||||
} ) {
|
||||
name: "tableOptionsPanel"
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "showHorizontalLinesCheckBox"
|
||||
"text": "show horizontal lines"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showHorizontalLinesChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "showVerticalLinesCheckBox"
|
||||
"text": "show vertical lines"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showVerticalLinesChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "intercellSpacingCheckBox"
|
||||
"text": "intercell spacing"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "intercellSpacingChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "redGridColorCheckBox"
|
||||
"text": "red grid color"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "redGridColorChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "rowSelectionCheckBox"
|
||||
"text": "row selection"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "rowSelectionChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "columnSelectionCheckBox"
|
||||
"text": "column selection"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "columnSelectionChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 5"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "dndCheckBox"
|
||||
"text": "enable drag and drop"
|
||||
"mnemonic": 68
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 6"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 3 3 1"
|
||||
"value": "cell 3 2"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 790, 715 )
|
||||
"size": new java.awt.Dimension( 790, 745 )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
|
||||
name: "popupMenu2"
|
||||
@@ -346,7 +416,7 @@ new FormModel {
|
||||
"text": "Noop Action"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 740 )
|
||||
"location": new java.awt.Point( 0, 800 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,23 @@ import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.StyleContext;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.demo.HintManager.Hint;
|
||||
import com.formdev.flatlaf.demo.extras.*;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
||||
import com.formdev.flatlaf.extras.SVGUtils;
|
||||
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
||||
import net.miginfocom.layout.ConstraintParser;
|
||||
import net.miginfocom.layout.LC;
|
||||
import net.miginfocom.layout.UnitValue;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -56,6 +63,61 @@ class DemoFrame
|
||||
|
||||
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
||||
tabbedPane.setSelectedIndex( tabIndex );
|
||||
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
showHints();
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
FlatUIDefaultsInspector.hide();
|
||||
}
|
||||
|
||||
private void showHints() {
|
||||
Hint fontMenuHint = new Hint(
|
||||
"Use 'Font' menu to increase/decrease font size or try different fonts.",
|
||||
fontMenu, SwingConstants.BOTTOM, "hint.fontMenu", null );
|
||||
|
||||
Hint optionsMenuHint = new Hint(
|
||||
"Use 'Options' menu to try out various FlatLaf options.",
|
||||
optionsMenu, SwingConstants.BOTTOM, "hint.optionsMenu", fontMenuHint );
|
||||
|
||||
Hint themesHint = new Hint(
|
||||
"Use 'Themes' list to try out various themes.",
|
||||
themesPanel, SwingConstants.LEFT, "hint.themesPanel", optionsMenuHint );
|
||||
|
||||
HintManager.showHint( themesHint );
|
||||
}
|
||||
|
||||
private void clearHints() {
|
||||
HintManager.hideAllHints();
|
||||
|
||||
Preferences state = DemoPrefs.getState();
|
||||
state.remove( "hint.fontMenu" );
|
||||
state.remove( "hint.optionsMenu" );
|
||||
state.remove( "hint.themesPanel" );
|
||||
}
|
||||
|
||||
private void showUIDefaultsInspector() {
|
||||
FlatUIDefaultsInspector.show();
|
||||
}
|
||||
|
||||
private void newActionPerformed() {
|
||||
NewDialog newDialog = new NewDialog( this );
|
||||
newDialog.setVisible( true );
|
||||
}
|
||||
|
||||
private void openActionPerformed() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.showOpenDialog( this );
|
||||
}
|
||||
|
||||
private void saveAsActionPerformed() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.showSaveDialog( this );
|
||||
}
|
||||
|
||||
private void exitActionPerformed() {
|
||||
@@ -105,14 +167,26 @@ class DemoFrame
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void animatedLafChangeChanged() {
|
||||
System.setProperty( "flatlaf.animatedLafChange", String.valueOf( animatedLafChangeMenuItem.isSelected() ) );
|
||||
}
|
||||
|
||||
private void showHintsChanged() {
|
||||
clearHints();
|
||||
showHints();
|
||||
}
|
||||
|
||||
private void fontFamilyChanged( ActionEvent e ) {
|
||||
String fontFamily = e.getActionCommand();
|
||||
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
Font font = UIManager.getFont( "defaultFont" );
|
||||
Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() );
|
||||
UIManager.put( "defaultFont", newFont );
|
||||
|
||||
FlatLaf.updateUI();
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
}
|
||||
|
||||
private void fontSizeChanged( ActionEvent e ) {
|
||||
@@ -216,6 +290,7 @@ class DemoFrame
|
||||
JMenu fileMenu = new JMenu();
|
||||
JMenuItem newMenuItem = new JMenuItem();
|
||||
JMenuItem openMenuItem = new JMenuItem();
|
||||
JMenuItem saveAsMenuItem = new JMenuItem();
|
||||
JMenuItem closeMenuItem = new JMenuItem();
|
||||
JMenuItem exitMenuItem = new JMenuItem();
|
||||
JMenu editMenu = new JMenu();
|
||||
@@ -235,6 +310,7 @@ class DemoFrame
|
||||
JMenuItem projectViewMenuItem = new JMenuItem();
|
||||
JMenuItem structureViewMenuItem = new JMenuItem();
|
||||
JMenuItem propertiesViewMenuItem = new JMenuItem();
|
||||
JMenuItem menuItem2 = new JMenuItem();
|
||||
JMenuItem menuItem1 = new JMenuItem();
|
||||
JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem();
|
||||
JRadioButtonMenuItem radioButtonMenuItem2 = new JRadioButtonMenuItem();
|
||||
@@ -243,11 +319,14 @@ class DemoFrame
|
||||
JMenuItem restoreFontMenuItem = new JMenuItem();
|
||||
JMenuItem incrFontMenuItem = new JMenuItem();
|
||||
JMenuItem decrFontMenuItem = new JMenuItem();
|
||||
JMenu optionsMenu = new JMenu();
|
||||
optionsMenu = new JMenu();
|
||||
windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem();
|
||||
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
|
||||
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
|
||||
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
|
||||
animatedLafChangeMenuItem = new JCheckBoxMenuItem();
|
||||
JMenuItem showHintsMenuItem = new JMenuItem();
|
||||
JMenuItem showUIDefaultsInspectorMenuItem = new JMenuItem();
|
||||
JMenu helpMenu = new JMenu();
|
||||
JMenuItem aboutMenuItem = new JMenuItem();
|
||||
JToolBar toolBar1 = new JToolBar();
|
||||
@@ -267,7 +346,7 @@ class DemoFrame
|
||||
OptionPanePanel optionPanePanel = new OptionPanePanel();
|
||||
ExtrasPanel extrasPanel1 = new ExtrasPanel();
|
||||
controlBar = new ControlBar();
|
||||
IJThemesPanel themesPanel = new IJThemesPanel();
|
||||
themesPanel = new IJThemesPanel();
|
||||
|
||||
//======== this ========
|
||||
setTitle("FlatLaf Demo");
|
||||
@@ -287,15 +366,22 @@ class DemoFrame
|
||||
newMenuItem.setText("New");
|
||||
newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
newMenuItem.setMnemonic('N');
|
||||
newMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
newMenuItem.addActionListener(e -> newActionPerformed());
|
||||
fileMenu.add(newMenuItem);
|
||||
|
||||
//---- openMenuItem ----
|
||||
openMenuItem.setText("Open");
|
||||
openMenuItem.setText("Open...");
|
||||
openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
openMenuItem.setMnemonic('O');
|
||||
openMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
openMenuItem.addActionListener(e -> openActionPerformed());
|
||||
fileMenu.add(openMenuItem);
|
||||
|
||||
//---- saveAsMenuItem ----
|
||||
saveAsMenuItem.setText("Save As...");
|
||||
saveAsMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
saveAsMenuItem.setMnemonic('S');
|
||||
saveAsMenuItem.addActionListener(e -> saveAsActionPerformed());
|
||||
fileMenu.add(saveAsMenuItem);
|
||||
fileMenu.addSeparator();
|
||||
|
||||
//---- closeMenuItem ----
|
||||
@@ -426,6 +512,11 @@ class DemoFrame
|
||||
}
|
||||
viewMenu.add(menu1);
|
||||
|
||||
//---- menuItem2 ----
|
||||
menuItem2.setText("Disabled Item");
|
||||
menuItem2.setEnabled(false);
|
||||
viewMenu.add(menuItem2);
|
||||
|
||||
//---- menuItem1 ----
|
||||
menuItem1.setText("<html>some <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>");
|
||||
viewMenu.add(menuItem1);
|
||||
@@ -501,6 +592,22 @@ class DemoFrame
|
||||
alwaysShowMnemonicsMenuItem.setText("Always show mnemonics");
|
||||
alwaysShowMnemonicsMenuItem.addActionListener(e -> alwaysShowMnemonics());
|
||||
optionsMenu.add(alwaysShowMnemonicsMenuItem);
|
||||
|
||||
//---- animatedLafChangeMenuItem ----
|
||||
animatedLafChangeMenuItem.setText("Animated Laf Change");
|
||||
animatedLafChangeMenuItem.setSelected(true);
|
||||
animatedLafChangeMenuItem.addActionListener(e -> animatedLafChangeChanged());
|
||||
optionsMenu.add(animatedLafChangeMenuItem);
|
||||
|
||||
//---- showHintsMenuItem ----
|
||||
showHintsMenuItem.setText("Show hints");
|
||||
showHintsMenuItem.addActionListener(e -> showHintsChanged());
|
||||
optionsMenu.add(showHintsMenuItem);
|
||||
|
||||
//---- showUIDefaultsInspectorMenuItem ----
|
||||
showUIDefaultsInspectorMenuItem.setText("Show UI Defaults Inspector");
|
||||
showUIDefaultsInspectorMenuItem.addActionListener(e -> showUIDefaultsInspector());
|
||||
optionsMenu.add(showUIDefaultsInspectorMenuItem);
|
||||
}
|
||||
menuBar1.add(optionsMenu);
|
||||
|
||||
@@ -612,15 +719,30 @@ class DemoFrame
|
||||
.getSupportsWindowDecorations() || JBRCustomDecorations.isSupported();
|
||||
windowDecorationsCheckBoxMenuItem.setEnabled( supportsWindowDecorations && !JBRCustomDecorations.isSupported() );
|
||||
menuBarEmbeddedCheckBoxMenuItem.setEnabled( supportsWindowDecorations );
|
||||
|
||||
// remove contentPanel bottom insets
|
||||
MigLayout layout = (MigLayout) contentPanel.getLayout();
|
||||
LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() );
|
||||
UnitValue[] insets = lc.getInsets();
|
||||
lc.setInsets( new UnitValue[] {
|
||||
insets[0],
|
||||
insets[1],
|
||||
new UnitValue( 0, UnitValue.PIXEL, null ),
|
||||
insets[3]
|
||||
} );
|
||||
layout.setLayoutConstraints( lc );
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JMenu fontMenu;
|
||||
private JMenu optionsMenu;
|
||||
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
|
||||
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
|
||||
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
|
||||
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
|
||||
private JCheckBoxMenuItem animatedLafChangeMenuItem;
|
||||
private JTabbedPane tabbedPane;
|
||||
private ControlBar controlBar;
|
||||
private IJThemesPanel themesPanel;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -114,6 +114,9 @@ new FormModel {
|
||||
} )
|
||||
add( new FormComponent( "com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel" ) {
|
||||
name: "themesPanel"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "East"
|
||||
} )
|
||||
@@ -128,14 +131,21 @@ new FormModel {
|
||||
"text": "New"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 78, 4226, false )
|
||||
"mnemonic": 78
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "newActionPerformed", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "openMenuItem"
|
||||
"text": "Open"
|
||||
"text": "Open..."
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 79, 4226, false )
|
||||
"mnemonic": 79
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openActionPerformed", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "saveAsMenuItem"
|
||||
"text": "Save As..."
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 83, 4226, false )
|
||||
"mnemonic": 83
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsActionPerformed", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator2"
|
||||
@@ -264,6 +274,11 @@ new FormModel {
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem2"
|
||||
"text": "Disabled Item"
|
||||
"enabled": false
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem1"
|
||||
"text": "<html>some <b color=\"red\">HTML</b> <i color=\"blue\">text</i></html>"
|
||||
@@ -322,6 +337,9 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "optionsMenu"
|
||||
"text": "Options"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "windowDecorationsCheckBoxMenuItem"
|
||||
"text": "Window decorations"
|
||||
@@ -356,6 +374,25 @@ new FormModel {
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alwaysShowMnemonics", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "animatedLafChangeMenuItem"
|
||||
"text": "Animated Laf Change"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "animatedLafChangeChanged", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "showHintsMenuItem"
|
||||
"text": "Show hints"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showHintsChanged", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "showUIDefaultsInspectorMenuItem"
|
||||
"text": "Show UI Defaults Inspector"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showUIDefaultsInspector", false ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "helpMenu"
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.extras.FlatInspector;
|
||||
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
@@ -30,9 +33,11 @@ public class FlatLafDemo
|
||||
static final String PREFS_ROOT_PATH = "/flatlaf-demo";
|
||||
static final String KEY_TAB = "tab";
|
||||
|
||||
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
||||
|
||||
public static void main( String[] args ) {
|
||||
// on macOS enable screen menu bar
|
||||
if( SystemInfo.IS_MAC && System.getProperty( "apple.laf.useScreenMenuBar" ) == null )
|
||||
if( SystemInfo.isMacOS && System.getProperty( "apple.laf.useScreenMenuBar" ) == null )
|
||||
System.setProperty( "apple.laf.useScreenMenuBar", "true" );
|
||||
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
@@ -42,15 +47,22 @@ public class FlatLafDemo
|
||||
JFrame.setDefaultLookAndFeelDecorated( true );
|
||||
JDialog.setDefaultLookAndFeelDecorated( true );
|
||||
|
||||
// application specific UI defaults
|
||||
FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.demo" );
|
||||
|
||||
// set look and feel
|
||||
DemoPrefs.initLaf( args );
|
||||
|
||||
// install inspector
|
||||
// install inspectors
|
||||
FlatInspector.install( "ctrl shift alt X" );
|
||||
FlatUIDefaultsInspector.install( "ctrl shift alt Y" );
|
||||
|
||||
// create frame
|
||||
DemoFrame frame = new DemoFrame();
|
||||
|
||||
if( FlatLafDemo.screenshotsMode )
|
||||
frame.setPreferredSize( new Dimension( 1280, 620 ) );
|
||||
|
||||
// show frame
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo( null );
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.ui.FlatDropShadowBorder;
|
||||
import com.formdev.flatlaf.ui.FlatPopupMenuBorder;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class HintManager
|
||||
{
|
||||
private static final List<HintPanel> hintPanels = new ArrayList<>();
|
||||
|
||||
static void showHint( Hint hint ) {
|
||||
// check whether user already closed the hint
|
||||
if( DemoPrefs.getState().getBoolean( hint.prefsKey, false ) ) {
|
||||
if( hint.nextHint != null )
|
||||
showHint( hint.nextHint );
|
||||
return;
|
||||
}
|
||||
|
||||
HintPanel hintPanel = new HintPanel( hint );
|
||||
hintPanel.showHint();
|
||||
|
||||
hintPanels.add( hintPanel );
|
||||
}
|
||||
|
||||
static void hideAllHints() {
|
||||
HintPanel[] hintPanels2 = hintPanels.toArray( new HintPanel[hintPanels.size()] );
|
||||
for( HintPanel hintPanel : hintPanels2 )
|
||||
hintPanel.hideHint();
|
||||
}
|
||||
|
||||
//---- class HintPanel ----------------------------------------------------
|
||||
|
||||
static class Hint
|
||||
{
|
||||
private final String message;
|
||||
private final Component owner;
|
||||
private final int position;
|
||||
private final String prefsKey;
|
||||
private final Hint nextHint;
|
||||
|
||||
Hint( String message, Component owner, int position, String prefsKey, Hint nextHint ) {
|
||||
this.message = message;
|
||||
this.owner = owner;
|
||||
this.position = position;
|
||||
this.prefsKey = prefsKey;
|
||||
this.nextHint = nextHint;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class HintPanel ----------------------------------------------------
|
||||
|
||||
private static class HintPanel
|
||||
extends JPanel
|
||||
{
|
||||
private final Hint hint;
|
||||
|
||||
private JPanel popup;
|
||||
|
||||
private HintPanel( Hint hint ) {
|
||||
this.hint = hint;
|
||||
|
||||
initComponents();
|
||||
|
||||
hintLabel.setText( "<html>" + hint.message + "</html>" );
|
||||
|
||||
// grab all mouse events to avoid that components overlapped
|
||||
// by the hint panel receive them
|
||||
addMouseListener( new MouseAdapter() {} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
|
||||
setBackground( UIManager.getColor( "HintPanel.backgroundColor" ) );
|
||||
setBorder( new FlatPopupMenuBorder() );
|
||||
}
|
||||
|
||||
void showHint() {
|
||||
JRootPane rootPane = SwingUtilities.getRootPane( hint.owner );
|
||||
if( rootPane == null )
|
||||
return;
|
||||
|
||||
JLayeredPane layeredPane = rootPane.getLayeredPane();
|
||||
|
||||
// create a popup panel that has a drop shadow
|
||||
popup = new JPanel( new BorderLayout() ) {
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
|
||||
setBorder( new FlatDropShadowBorder(
|
||||
UIManager.getColor( "Popup.dropShadowColor" ),
|
||||
UIManager.getInsets( "Popup.dropShadowInsets" ),
|
||||
FlatUIUtils.getUIFloat( "Popup.dropShadowOpacity", 0.5f ) ) );
|
||||
|
||||
// use invokeLater because at this time the UI delegates
|
||||
// of child components are not yet updated
|
||||
EventQueue.invokeLater( () -> {
|
||||
validate();
|
||||
setSize( getPreferredSize() );
|
||||
} );
|
||||
}
|
||||
};
|
||||
popup.setOpaque( false );
|
||||
popup.add( this );
|
||||
|
||||
// calculate x/y location for hint popup
|
||||
Point pt = SwingUtilities.convertPoint( hint.owner, 0, 0, layeredPane );
|
||||
int x = pt.x;
|
||||
int y = pt.y;
|
||||
Dimension size = popup.getPreferredSize();
|
||||
int gap = UIScale.scale( 6 );
|
||||
|
||||
switch( hint.position ) {
|
||||
case SwingConstants.LEFT:
|
||||
x -= size.width + gap;
|
||||
break;
|
||||
|
||||
case SwingConstants.TOP:
|
||||
y -= size.height + gap;
|
||||
break;
|
||||
|
||||
case SwingConstants.RIGHT:
|
||||
x += hint.owner.getWidth() + gap;
|
||||
break;
|
||||
|
||||
case SwingConstants.BOTTOM:
|
||||
y += hint.owner.getHeight() + gap;
|
||||
break;
|
||||
}
|
||||
|
||||
// set hint popup size and show it
|
||||
popup.setBounds( x, y, size.width, size.height );
|
||||
layeredPane.add( popup, JLayeredPane.POPUP_LAYER );
|
||||
}
|
||||
|
||||
void hideHint() {
|
||||
if( popup != null ) {
|
||||
Container parent = popup.getParent();
|
||||
if( parent != null ) {
|
||||
parent.remove( popup );
|
||||
parent.repaint( popup.getX(), popup.getY(), popup.getWidth(), popup.getHeight() );
|
||||
}
|
||||
}
|
||||
|
||||
hintPanels.remove( this );
|
||||
}
|
||||
|
||||
private void gotIt() {
|
||||
// hide hint
|
||||
hideHint();
|
||||
|
||||
// remember that user closed the hint
|
||||
DemoPrefs.getState().putBoolean( hint.prefsKey, true );
|
||||
|
||||
// show next hint (if any)
|
||||
if( hint.nextHint != null )
|
||||
HintManager.showHint( hint.nextHint );
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
hintLabel = new JLabel();
|
||||
gotItButton = new JButton();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[::200,fill]",
|
||||
// rows
|
||||
"[]para" +
|
||||
"[]"));
|
||||
|
||||
//---- hintLabel ----
|
||||
hintLabel.setText("hint");
|
||||
add(hintLabel, "cell 0 0");
|
||||
|
||||
//---- gotItButton ----
|
||||
gotItButton.setText("Got it!");
|
||||
gotItButton.setFocusable(false);
|
||||
gotItButton.addActionListener(e -> gotIt());
|
||||
add(gotItButton, "cell 0 1,alignx right,growx 0");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JLabel hintLabel;
|
||||
private JButton gotItButton;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[::200,fill]"
|
||||
"$rowConstraints": "[]para[]"
|
||||
} ) {
|
||||
name: "panel"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.className": "HintPanel"
|
||||
}
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "hintLabel"
|
||||
"text": "hint"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "gotItButton"
|
||||
"text": "Got it!"
|
||||
"focusable": false
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "gotIt", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1,alignx right,growx 0"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 400, 300 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,6 @@ class MoreComponentsPanel
|
||||
JSeparator separator2 = new JSeparator();
|
||||
JSlider slider2 = new JSlider();
|
||||
JSlider slider4 = new JSlider();
|
||||
JScrollPane scrollPane14 = new JScrollPane();
|
||||
progressBar3 = new JProgressBar();
|
||||
progressBar4 = new JProgressBar();
|
||||
JToolBar toolBar2 = new JToolBar();
|
||||
@@ -67,11 +66,12 @@ class MoreComponentsPanel
|
||||
JButton button10 = new JButton();
|
||||
JButton button11 = new JButton();
|
||||
JToggleButton toggleButton7 = new JToggleButton();
|
||||
JPanel panel2 = new JPanel();
|
||||
JLabel scrollBarLabel = new JLabel();
|
||||
JScrollBar scrollBar1 = new JScrollBar();
|
||||
JLabel label4 = new JLabel();
|
||||
JScrollBar scrollBar4 = new JScrollBar();
|
||||
JPanel panel3 = new JPanel();
|
||||
JLabel label4 = new JLabel();
|
||||
JLabel label3 = new JLabel();
|
||||
JScrollPane scrollPane15 = new JScrollPane();
|
||||
JEditorPane editorPane6 = new JEditorPane();
|
||||
@@ -81,7 +81,6 @@ class MoreComponentsPanel
|
||||
JScrollBar scrollBar6 = new JScrollBar();
|
||||
JLabel separatorLabel = new JLabel();
|
||||
JSeparator separator1 = new JSeparator();
|
||||
JPanel panel2 = new JPanel();
|
||||
JLabel sliderLabel = new JLabel();
|
||||
JSlider slider1 = new JSlider();
|
||||
JSlider slider6 = new JSlider();
|
||||
@@ -105,13 +104,12 @@ class MoreComponentsPanel
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]",
|
||||
// rows
|
||||
"[]" +
|
||||
@@ -142,7 +140,7 @@ class MoreComponentsPanel
|
||||
}
|
||||
scrollPane13.setViewportView(panel1);
|
||||
}
|
||||
add(scrollPane13, "cell 1 0,grow,width 70,height 70");
|
||||
add(scrollPane13, "cell 1 0,grow,width 70,height 40");
|
||||
add(scrollBar2, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar3 ----
|
||||
@@ -165,7 +163,7 @@ class MoreComponentsPanel
|
||||
//---- slider2 ----
|
||||
slider2.setOrientation(SwingConstants.VERTICAL);
|
||||
slider2.setValue(30);
|
||||
add(slider2, "cell 2 0 1 6,growy");
|
||||
add(slider2, "cell 2 0 1 6,growy,height 100");
|
||||
|
||||
//---- slider4 ----
|
||||
slider4.setMinorTickSpacing(10);
|
||||
@@ -174,19 +172,18 @@ class MoreComponentsPanel
|
||||
slider4.setPaintLabels(true);
|
||||
slider4.setOrientation(SwingConstants.VERTICAL);
|
||||
slider4.setValue(30);
|
||||
add(slider4, "cell 2 0 1 6,growy");
|
||||
add(scrollPane14, "cell 3 0,grow");
|
||||
add(slider4, "cell 2 0 1 6,growy,height 100");
|
||||
|
||||
//---- progressBar3 ----
|
||||
progressBar3.setOrientation(SwingConstants.VERTICAL);
|
||||
progressBar3.setValue(60);
|
||||
add(progressBar3, "cell 4 0 1 6,growy");
|
||||
add(progressBar3, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- progressBar4 ----
|
||||
progressBar4.setOrientation(SwingConstants.VERTICAL);
|
||||
progressBar4.setValue(60);
|
||||
progressBar4.setStringPainted(true);
|
||||
add(progressBar4, "cell 4 0 1 6,growy");
|
||||
add(progressBar4, "cell 2 0 1 6,growy");
|
||||
|
||||
//======== toolBar2 ========
|
||||
{
|
||||
@@ -209,7 +206,14 @@ class MoreComponentsPanel
|
||||
toggleButton7.setIcon(UIManager.getIcon("Tree.closedIcon"));
|
||||
toolBar2.add(toggleButton7);
|
||||
}
|
||||
add(toolBar2, "cell 4 0 1 6,growy");
|
||||
add(toolBar2, "cell 2 0 1 6,growy");
|
||||
|
||||
//======== panel2 ========
|
||||
{
|
||||
panel2.setBorder(new TitledBorder("TitledBorder"));
|
||||
panel2.setLayout(new FlowLayout());
|
||||
}
|
||||
add(panel2, "cell 3 0 1 6,grow");
|
||||
|
||||
//---- scrollBarLabel ----
|
||||
scrollBarLabel.setText("JScrollBar:");
|
||||
@@ -219,10 +223,6 @@ class MoreComponentsPanel
|
||||
scrollBar1.setOrientation(Adjustable.HORIZONTAL);
|
||||
add(scrollBar1, "cell 1 1,growx");
|
||||
|
||||
//---- label4 ----
|
||||
label4.setText("HTML:");
|
||||
add(label4, "cell 5 1");
|
||||
|
||||
//---- scrollBar4 ----
|
||||
scrollBar4.setOrientation(Adjustable.HORIZONTAL);
|
||||
scrollBar4.setEnabled(false);
|
||||
@@ -238,11 +238,16 @@ class MoreComponentsPanel
|
||||
// rows
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- label4 ----
|
||||
label4.setText("HTML:");
|
||||
panel3.add(label4, "cell 0 0");
|
||||
|
||||
//---- label3 ----
|
||||
label3.setText("<html>JLabel HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a></html>");
|
||||
panel3.add(label3, "cell 0 0");
|
||||
panel3.add(label3, "cell 0 1");
|
||||
|
||||
//======== scrollPane15 ========
|
||||
{
|
||||
@@ -252,7 +257,7 @@ class MoreComponentsPanel
|
||||
editorPane6.setText("JEditorPane HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a>");
|
||||
scrollPane15.setViewportView(editorPane6);
|
||||
}
|
||||
panel3.add(scrollPane15, "cell 0 1,grow");
|
||||
panel3.add(scrollPane15, "cell 0 2,grow");
|
||||
|
||||
//======== scrollPane16 ========
|
||||
{
|
||||
@@ -262,9 +267,9 @@ class MoreComponentsPanel
|
||||
textPane6.setText("JTextPane HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a>");
|
||||
scrollPane16.setViewportView(textPane6);
|
||||
}
|
||||
panel3.add(scrollPane16, "cell 0 2,grow");
|
||||
panel3.add(scrollPane16, "cell 0 3,grow");
|
||||
}
|
||||
add(panel3, "cell 5 2 1 9,aligny top,growy 0");
|
||||
add(panel3, "cell 4 0 1 8,aligny top,growy 0");
|
||||
|
||||
//---- scrollBar5 ----
|
||||
scrollBar5.setOrientation(Adjustable.HORIZONTAL);
|
||||
@@ -282,13 +287,6 @@ class MoreComponentsPanel
|
||||
add(separatorLabel, "cell 0 5");
|
||||
add(separator1, "cell 1 5,growx");
|
||||
|
||||
//======== panel2 ========
|
||||
{
|
||||
panel2.setBorder(new TitledBorder("TitledBorder"));
|
||||
panel2.setLayout(new FlowLayout());
|
||||
}
|
||||
add(panel2, "cell 3 5,grow");
|
||||
|
||||
//---- sliderLabel ----
|
||||
sliderLabel.setText("JSlider:");
|
||||
add(sliderLabel, "cell 0 6");
|
||||
@@ -389,6 +387,17 @@ class MoreComponentsPanel
|
||||
}
|
||||
add(toolBar1, "cell 1 10 3 1,growx");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
|
||||
if( FlatLafDemo.screenshotsMode ) {
|
||||
Component[] components = new Component[] {
|
||||
indeterminateCheckBox,
|
||||
toolTipLabel, toolTip1, toolTip2,
|
||||
toolBarLabel, toolBar1, toolBar2,
|
||||
};
|
||||
|
||||
for( Component c : components )
|
||||
c.setVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -7,8 +7,8 @@ new FormModel {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$columnConstraints": "[][][][][][]"
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][][][][]"
|
||||
"$rowConstraints": "[][][][][][][][][][][]"
|
||||
} ) {
|
||||
name: "this"
|
||||
@@ -27,7 +27,7 @@ new FormModel {
|
||||
"preferredSize": new java.awt.Dimension( 200, 200 )
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 0,grow,width 70,height 70"
|
||||
"value": "cell 1 0,grow,width 70,height 40"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar2"
|
||||
@@ -64,7 +64,7 @@ new FormModel {
|
||||
"orientation": 1
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
"value": "cell 2 0 1 6,growy,height 100"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider4"
|
||||
@@ -75,12 +75,7 @@ new FormModel {
|
||||
"orientation": 1
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane14"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 0,grow"
|
||||
"value": "cell 2 0 1 6,growy,height 100"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar3"
|
||||
@@ -90,7 +85,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar4"
|
||||
@@ -101,7 +96,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||
name: "toolBar2"
|
||||
@@ -126,7 +121,13 @@ new FormModel {
|
||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel2"
|
||||
"border": new javax.swing.border.TitledBorder( "TitledBorder" )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 0 1 6,grow"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "scrollBarLabel"
|
||||
@@ -140,12 +141,6 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 1,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label4"
|
||||
"text": "HTML:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar4"
|
||||
"orientation": 0
|
||||
@@ -155,16 +150,22 @@ new FormModel {
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$columnConstraints": "[]"
|
||||
"$rowConstraints": "[][][]"
|
||||
"$rowConstraints": "[][][][]"
|
||||
"$layoutConstraints": "ltr,insets 0,hidemode 3"
|
||||
} ) {
|
||||
name: "panel3"
|
||||
"opaque": false
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label4"
|
||||
"text": "HTML:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label3"
|
||||
"text": "<html>JLabel HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a></html>"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane15"
|
||||
@@ -174,7 +175,7 @@ new FormModel {
|
||||
"text": "JEditorPane HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a>"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1,grow"
|
||||
"value": "cell 0 2,grow"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane16"
|
||||
@@ -184,10 +185,10 @@ new FormModel {
|
||||
"text": "JTextPane HTML<br>Sample <b>content</b><br> <u>text</u> with <a href=\"#\">link</a>"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2,grow"
|
||||
"value": "cell 0 3,grow"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 2 1 9,aligny top,growy 0"
|
||||
"value": "cell 4 0 1 8,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar5"
|
||||
@@ -215,12 +216,6 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 5,growx"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel2"
|
||||
"border": new javax.swing.border.TitledBorder( "TitledBorder" )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 5,grow"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "sliderLabel"
|
||||
"text": "JSlider:"
|
||||
@@ -365,7 +360,7 @@ new FormModel {
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 790, 715 )
|
||||
"size": new java.awt.Dimension( 700, 420 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.swing.*;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class NewDialog
|
||||
extends JDialog
|
||||
{
|
||||
NewDialog( Window owner ) {
|
||||
super( owner );
|
||||
initComponents();
|
||||
|
||||
// hide menubar, which is here for testing
|
||||
menuBar1.setVisible( false );
|
||||
|
||||
getRootPane().setDefaultButton( okButton );
|
||||
|
||||
// register ESC key to close frame
|
||||
((JComponent)getContentPane()).registerKeyboardAction(
|
||||
e -> dispose(),
|
||||
KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ),
|
||||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||
}
|
||||
|
||||
private void okActionPerformed() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
private void cancelActionPerformed() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
dialogPane = new JPanel();
|
||||
contentPanel = new JPanel();
|
||||
label1 = new JLabel();
|
||||
textField1 = new JTextField();
|
||||
label3 = new JLabel();
|
||||
comboBox2 = new JComboBox<>();
|
||||
label2 = new JLabel();
|
||||
comboBox1 = new JComboBox<>();
|
||||
buttonBar = new JPanel();
|
||||
okButton = new JButton();
|
||||
cancelButton = new JButton();
|
||||
menuBar1 = new JMenuBar();
|
||||
menu1 = new JMenu();
|
||||
menuItem8 = new JMenuItem();
|
||||
menuItem7 = new JMenuItem();
|
||||
menuItem6 = new JMenuItem();
|
||||
menuItem5 = new JMenuItem();
|
||||
menuItem4 = new JMenuItem();
|
||||
menuItem3 = new JMenuItem();
|
||||
menuItem2 = new JMenuItem();
|
||||
menuItem1 = new JMenuItem();
|
||||
menu2 = new JMenu();
|
||||
menuItem18 = new JMenuItem();
|
||||
menuItem17 = new JMenuItem();
|
||||
menuItem16 = new JMenuItem();
|
||||
menuItem15 = new JMenuItem();
|
||||
menuItem14 = new JMenuItem();
|
||||
menuItem13 = new JMenuItem();
|
||||
menuItem12 = new JMenuItem();
|
||||
menuItem11 = new JMenuItem();
|
||||
menuItem10 = new JMenuItem();
|
||||
menuItem9 = new JMenuItem();
|
||||
menu3 = new JMenu();
|
||||
menuItem25 = new JMenuItem();
|
||||
menuItem26 = new JMenuItem();
|
||||
menuItem24 = new JMenuItem();
|
||||
menuItem23 = new JMenuItem();
|
||||
menuItem22 = new JMenuItem();
|
||||
menuItem21 = new JMenuItem();
|
||||
menuItem20 = new JMenuItem();
|
||||
menuItem19 = new JMenuItem();
|
||||
popupMenu1 = new JPopupMenu();
|
||||
cutMenuItem = new JMenuItem();
|
||||
copyMenuItem = new JMenuItem();
|
||||
pasteMenuItem = new JMenuItem();
|
||||
|
||||
//======== this ========
|
||||
setTitle("New");
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setModal(true);
|
||||
Container contentPane = getContentPane();
|
||||
contentPane.setLayout(new BorderLayout());
|
||||
|
||||
//======== dialogPane ========
|
||||
{
|
||||
dialogPane.setLayout(new BorderLayout());
|
||||
|
||||
//======== contentPanel ========
|
||||
{
|
||||
contentPanel.setLayout(new MigLayout(
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[fill]" +
|
||||
"[grow,fill]",
|
||||
// rows
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("Name:");
|
||||
contentPanel.add(label1, "cell 0 0");
|
||||
|
||||
//---- textField1 ----
|
||||
textField1.setComponentPopupMenu(popupMenu1);
|
||||
contentPanel.add(textField1, "cell 1 0");
|
||||
|
||||
//---- label3 ----
|
||||
label3.setText("Package:");
|
||||
contentPanel.add(label3, "cell 0 1");
|
||||
|
||||
//---- comboBox2 ----
|
||||
comboBox2.setEditable(true);
|
||||
comboBox2.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"com.myapp",
|
||||
"com.myapp.core",
|
||||
"com.myapp.ui",
|
||||
"com.myapp.util",
|
||||
"com.myapp.extras",
|
||||
"com.myapp.components",
|
||||
"com.myapp.dialogs",
|
||||
"com.myapp.windows"
|
||||
}));
|
||||
contentPanel.add(comboBox2, "cell 1 1");
|
||||
|
||||
//---- label2 ----
|
||||
label2.setText("Type:");
|
||||
contentPanel.add(label2, "cell 0 2");
|
||||
|
||||
//---- comboBox1 ----
|
||||
comboBox1.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"Class",
|
||||
"Interface",
|
||||
"Package",
|
||||
"Annotation",
|
||||
"Enum",
|
||||
"Record",
|
||||
"Java Project",
|
||||
"Project",
|
||||
"Folder",
|
||||
"File"
|
||||
}));
|
||||
contentPanel.add(comboBox1, "cell 1 2");
|
||||
}
|
||||
dialogPane.add(contentPanel, BorderLayout.CENTER);
|
||||
|
||||
//======== buttonBar ========
|
||||
{
|
||||
buttonBar.setLayout(new MigLayout(
|
||||
"insets dialog,alignx right",
|
||||
// columns
|
||||
"[button,fill]" +
|
||||
"[button,fill]",
|
||||
// rows
|
||||
null));
|
||||
|
||||
//---- okButton ----
|
||||
okButton.setText("OK");
|
||||
okButton.addActionListener(e -> okActionPerformed());
|
||||
buttonBar.add(okButton, "cell 0 0");
|
||||
|
||||
//---- cancelButton ----
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.addActionListener(e -> cancelActionPerformed());
|
||||
buttonBar.add(cancelButton, "cell 1 0");
|
||||
}
|
||||
dialogPane.add(buttonBar, BorderLayout.SOUTH);
|
||||
|
||||
//======== menuBar1 ========
|
||||
{
|
||||
|
||||
//======== menu1 ========
|
||||
{
|
||||
menu1.setText("text");
|
||||
|
||||
//---- menuItem8 ----
|
||||
menuItem8.setText("text");
|
||||
menu1.add(menuItem8);
|
||||
|
||||
//---- menuItem7 ----
|
||||
menuItem7.setText("text");
|
||||
menu1.add(menuItem7);
|
||||
|
||||
//---- menuItem6 ----
|
||||
menuItem6.setText("text");
|
||||
menu1.add(menuItem6);
|
||||
|
||||
//---- menuItem5 ----
|
||||
menuItem5.setText("text");
|
||||
menu1.add(menuItem5);
|
||||
|
||||
//---- menuItem4 ----
|
||||
menuItem4.setText("text");
|
||||
menu1.add(menuItem4);
|
||||
|
||||
//---- menuItem3 ----
|
||||
menuItem3.setText("text");
|
||||
menu1.add(menuItem3);
|
||||
|
||||
//---- menuItem2 ----
|
||||
menuItem2.setText("text");
|
||||
menu1.add(menuItem2);
|
||||
|
||||
//---- menuItem1 ----
|
||||
menuItem1.setText("text");
|
||||
menu1.add(menuItem1);
|
||||
}
|
||||
menuBar1.add(menu1);
|
||||
|
||||
//======== menu2 ========
|
||||
{
|
||||
menu2.setText("text");
|
||||
|
||||
//---- menuItem18 ----
|
||||
menuItem18.setText("text");
|
||||
menu2.add(menuItem18);
|
||||
|
||||
//---- menuItem17 ----
|
||||
menuItem17.setText("text");
|
||||
menu2.add(menuItem17);
|
||||
|
||||
//---- menuItem16 ----
|
||||
menuItem16.setText("text");
|
||||
menu2.add(menuItem16);
|
||||
|
||||
//---- menuItem15 ----
|
||||
menuItem15.setText("text");
|
||||
menu2.add(menuItem15);
|
||||
|
||||
//---- menuItem14 ----
|
||||
menuItem14.setText("text");
|
||||
menu2.add(menuItem14);
|
||||
|
||||
//---- menuItem13 ----
|
||||
menuItem13.setText("text");
|
||||
menu2.add(menuItem13);
|
||||
|
||||
//---- menuItem12 ----
|
||||
menuItem12.setText("text");
|
||||
menu2.add(menuItem12);
|
||||
|
||||
//---- menuItem11 ----
|
||||
menuItem11.setText("text");
|
||||
menu2.add(menuItem11);
|
||||
|
||||
//---- menuItem10 ----
|
||||
menuItem10.setText("text");
|
||||
menu2.add(menuItem10);
|
||||
|
||||
//---- menuItem9 ----
|
||||
menuItem9.setText("text");
|
||||
menu2.add(menuItem9);
|
||||
}
|
||||
menuBar1.add(menu2);
|
||||
|
||||
//======== menu3 ========
|
||||
{
|
||||
menu3.setText("text");
|
||||
|
||||
//---- menuItem25 ----
|
||||
menuItem25.setText("text");
|
||||
menu3.add(menuItem25);
|
||||
|
||||
//---- menuItem26 ----
|
||||
menuItem26.setText("text");
|
||||
menu3.add(menuItem26);
|
||||
|
||||
//---- menuItem24 ----
|
||||
menuItem24.setText("text");
|
||||
menu3.add(menuItem24);
|
||||
|
||||
//---- menuItem23 ----
|
||||
menuItem23.setText("text");
|
||||
menu3.add(menuItem23);
|
||||
|
||||
//---- menuItem22 ----
|
||||
menuItem22.setText("text");
|
||||
menu3.add(menuItem22);
|
||||
|
||||
//---- menuItem21 ----
|
||||
menuItem21.setText("text");
|
||||
menu3.add(menuItem21);
|
||||
|
||||
//---- menuItem20 ----
|
||||
menuItem20.setText("text");
|
||||
menu3.add(menuItem20);
|
||||
|
||||
//---- menuItem19 ----
|
||||
menuItem19.setText("text");
|
||||
menu3.add(menuItem19);
|
||||
}
|
||||
menuBar1.add(menu3);
|
||||
}
|
||||
dialogPane.add(menuBar1, BorderLayout.NORTH);
|
||||
}
|
||||
contentPane.add(dialogPane, BorderLayout.CENTER);
|
||||
pack();
|
||||
setLocationRelativeTo(getOwner());
|
||||
|
||||
//======== popupMenu1 ========
|
||||
{
|
||||
|
||||
//---- cutMenuItem ----
|
||||
cutMenuItem.setText("Cut");
|
||||
cutMenuItem.setMnemonic('C');
|
||||
popupMenu1.add(cutMenuItem);
|
||||
|
||||
//---- copyMenuItem ----
|
||||
copyMenuItem.setText("Copy");
|
||||
copyMenuItem.setMnemonic('O');
|
||||
popupMenu1.add(copyMenuItem);
|
||||
|
||||
//---- pasteMenuItem ----
|
||||
pasteMenuItem.setText("Paste");
|
||||
pasteMenuItem.setMnemonic('P');
|
||||
popupMenu1.add(pasteMenuItem);
|
||||
}
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JPanel dialogPane;
|
||||
private JPanel contentPanel;
|
||||
private JLabel label1;
|
||||
private JTextField textField1;
|
||||
private JLabel label3;
|
||||
private JComboBox<String> comboBox2;
|
||||
private JLabel label2;
|
||||
private JComboBox<String> comboBox1;
|
||||
private JPanel buttonBar;
|
||||
private JButton okButton;
|
||||
private JButton cancelButton;
|
||||
private JMenuBar menuBar1;
|
||||
private JMenu menu1;
|
||||
private JMenuItem menuItem8;
|
||||
private JMenuItem menuItem7;
|
||||
private JMenuItem menuItem6;
|
||||
private JMenuItem menuItem5;
|
||||
private JMenuItem menuItem4;
|
||||
private JMenuItem menuItem3;
|
||||
private JMenuItem menuItem2;
|
||||
private JMenuItem menuItem1;
|
||||
private JMenu menu2;
|
||||
private JMenuItem menuItem18;
|
||||
private JMenuItem menuItem17;
|
||||
private JMenuItem menuItem16;
|
||||
private JMenuItem menuItem15;
|
||||
private JMenuItem menuItem14;
|
||||
private JMenuItem menuItem13;
|
||||
private JMenuItem menuItem12;
|
||||
private JMenuItem menuItem11;
|
||||
private JMenuItem menuItem10;
|
||||
private JMenuItem menuItem9;
|
||||
private JMenu menu3;
|
||||
private JMenuItem menuItem25;
|
||||
private JMenuItem menuItem26;
|
||||
private JMenuItem menuItem24;
|
||||
private JMenuItem menuItem23;
|
||||
private JMenuItem menuItem22;
|
||||
private JMenuItem menuItem21;
|
||||
private JMenuItem menuItem20;
|
||||
private JMenuItem menuItem19;
|
||||
private JPopupMenu popupMenu1;
|
||||
private JMenuItem cutMenuItem;
|
||||
private JMenuItem copyMenuItem;
|
||||
private JMenuItem pasteMenuItem;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
add( new FormWindow( "javax.swing.JDialog", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "this"
|
||||
"title": "New"
|
||||
"defaultCloseOperation": 2
|
||||
"modal": true
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "dialogPane"
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[fill][grow,fill]"
|
||||
"$rowConstraints": "[][][]"
|
||||
} ) {
|
||||
name: "contentPanel"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label1"
|
||||
"text": "Name:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField1"
|
||||
"componentPopupMenu": new FormReference( "popupMenu1" )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label3"
|
||||
"text": "Package:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "comboBox2"
|
||||
"editable": true
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "com.myapp"
|
||||
addElement( "com.myapp" )
|
||||
addElement( "com.myapp.core" )
|
||||
addElement( "com.myapp.ui" )
|
||||
addElement( "com.myapp.util" )
|
||||
addElement( "com.myapp.extras" )
|
||||
addElement( "com.myapp.components" )
|
||||
addElement( "com.myapp.dialogs" )
|
||||
addElement( "com.myapp.windows" )
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label2"
|
||||
"text": "Type:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "comboBox1"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "Class"
|
||||
addElement( "Class" )
|
||||
addElement( "Interface" )
|
||||
addElement( "Package" )
|
||||
addElement( "Annotation" )
|
||||
addElement( "Enum" )
|
||||
addElement( "Record" )
|
||||
addElement( "Java Project" )
|
||||
addElement( "Project" )
|
||||
addElement( "Folder" )
|
||||
addElement( "File" )
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 2"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog,alignx right"
|
||||
"$columnConstraints": "[button,fill][button,fill]"
|
||||
"$rowSpecs": "[fill]"
|
||||
} ) {
|
||||
name: "buttonBar"
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "okButton"
|
||||
"text": "OK"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "okActionPerformed", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "cancelButton"
|
||||
"text": "Cancel"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "cancelActionPerformed", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 0"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "South"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
|
||||
name: "menuBar1"
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "menu1"
|
||||
"text": "text"
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem8"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem7"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem6"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem5"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem4"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem3"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem2"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem1"
|
||||
"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: "menuItem18"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem17"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem16"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem15"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem14"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem13"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem12"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem11"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem10"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem9"
|
||||
"text": "text"
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "menu3"
|
||||
"text": "text"
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem25"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem26"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem24"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem23"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem22"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem21"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem20"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem19"
|
||||
"text": "text"
|
||||
} )
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "North"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 330, 210 )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
|
||||
name: "popupMenu1"
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "cutMenuItem"
|
||||
"text": "Cut"
|
||||
"mnemonic": 67
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "copyMenuItem"
|
||||
"text": "Copy"
|
||||
"mnemonic": 79
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "pasteMenuItem"
|
||||
"text": "Paste"
|
||||
"mnemonic": 80
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 220 )
|
||||
"size": new java.awt.Dimension( 91, 87 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ class OptionPanePanel
|
||||
//======== panel9 ========
|
||||
{
|
||||
panel9.setLayout(new MigLayout(
|
||||
"flowy,hidemode 3",
|
||||
"flowy,insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[]" +
|
||||
"[]" +
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -12,7 +12,7 @@ new FormModel {
|
||||
name: "scrollPane1"
|
||||
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
|
||||
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "flowy,hidemode 3"
|
||||
"$layoutConstraints": "flowy,insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][][fill]"
|
||||
"$rowConstraints": "[top][top][top][top][top][top][top][top]"
|
||||
} ) {
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
/*
|
||||
* Created by JFormDesigner on Tue Aug 27 21:47:02 CEST 2019
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
@@ -20,6 +32,8 @@ class TabsPanel
|
||||
{
|
||||
TabsPanel() {
|
||||
initComponents();
|
||||
|
||||
addInitialTabs( tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 );
|
||||
}
|
||||
|
||||
private void tabScrollChanged() {
|
||||
@@ -28,8 +42,20 @@ class TabsPanel
|
||||
tabbedPane2.setTabLayoutPolicy( tabLayoutPolicy );
|
||||
tabbedPane3.setTabLayoutPolicy( tabLayoutPolicy );
|
||||
tabbedPane4.setTabLayoutPolicy( tabLayoutPolicy );
|
||||
|
||||
if( !autoMoreTabs && tabScrollCheckBox.isSelected() && !moreTabsCheckBox.isSelected() ) {
|
||||
moreTabsCheckBox.setSelected( true );
|
||||
moreTabsChanged();
|
||||
autoMoreTabs = true;
|
||||
} else if( autoMoreTabs && !tabScrollCheckBox.isSelected() && moreTabsCheckBox.isSelected() ) {
|
||||
moreTabsCheckBox.setSelected( false );
|
||||
moreTabsChanged();
|
||||
autoMoreTabs = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean autoMoreTabs;
|
||||
|
||||
private void showTabSeparatorsChanged() {
|
||||
Boolean showTabSeparators = showTabSeparatorsCheckBox.isSelected() ? true : null;
|
||||
tabbedPane1.putClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
|
||||
@@ -52,15 +78,17 @@ class TabsPanel
|
||||
addRemoveMoreTabs( tabbedPane2, moreTabs );
|
||||
addRemoveMoreTabs( tabbedPane3, moreTabs );
|
||||
addRemoveMoreTabs( tabbedPane4, moreTabs );
|
||||
|
||||
autoMoreTabs = false;
|
||||
}
|
||||
|
||||
private void addRemoveMoreTabs( JTabbedPane tabbedPane, boolean add ) {
|
||||
if( add ) {
|
||||
tabbedPane.addTab( "Tab 4", new JLabel( "tab 4" ) );
|
||||
tabbedPane.addTab( "Tab 5", new JLabel( "tab 5" ) );
|
||||
tabbedPane.addTab( "Tab 6", new JLabel( "tab 6" ) );
|
||||
tabbedPane.addTab( "Tab 7", new JLabel( "tab 7" ) );
|
||||
tabbedPane.addTab( "Tab 8", new JLabel( "tab 8" ) );
|
||||
addTab( tabbedPane, "Tab 4", "tab content 4" );
|
||||
addTab( tabbedPane, "Tab 5", "tab content 5" );
|
||||
addTab( tabbedPane, "Tab 6", "tab content 6" );
|
||||
addTab( tabbedPane, "Tab 7", "tab content 7" );
|
||||
addTab( tabbedPane, "Tab 8", "tab content 8" );
|
||||
} else {
|
||||
int tabCount = tabbedPane.getTabCount();
|
||||
if( tabCount > 3 ) {
|
||||
@@ -70,6 +98,39 @@ class TabsPanel
|
||||
}
|
||||
}
|
||||
|
||||
private void addInitialTabs( JTabbedPane... tabbedPanes ) {
|
||||
for( JTabbedPane tabbedPane : tabbedPanes ) {
|
||||
String placement = "unknown";
|
||||
switch( tabbedPane.getTabPlacement() ) {
|
||||
case JTabbedPane.TOP: placement = "TOP"; break;
|
||||
case JTabbedPane.BOTTOM: placement = "BOTTOM"; break;
|
||||
case JTabbedPane.LEFT: placement = "LEFT"; break;
|
||||
case JTabbedPane.RIGHT: placement = "RIGHT"; break;
|
||||
}
|
||||
addTab( tabbedPane, "Tab 1", "<html><center>" + placement + "<br>tab placement</center></html>" );
|
||||
|
||||
JComponent tab2 = createTab( "tab content 2" );
|
||||
tab2.setBorder( new LineBorder( Color.magenta ) );
|
||||
tabbedPane.addTab( "Second Tab", tab2 );
|
||||
|
||||
addTab( tabbedPane, "Disabled", "tab content 3" );
|
||||
tabbedPane.setEnabledAt( 2, false );
|
||||
}
|
||||
}
|
||||
|
||||
private void addTab( JTabbedPane tabbedPane, String title, String text ) {
|
||||
tabbedPane.addTab( title, createTab( text ) );
|
||||
}
|
||||
|
||||
private JComponent createTab( String text ) {
|
||||
JLabel label = new JLabel( text );
|
||||
label.setHorizontalAlignment( SwingConstants.CENTER );
|
||||
|
||||
JPanel tab = new JPanel( new BorderLayout() );
|
||||
tab.add( label, BorderLayout.CENTER );
|
||||
return tab;
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JPanel panel9 = new JPanel();
|
||||
@@ -77,31 +138,19 @@ class TabsPanel
|
||||
JSplitPane splitPane3 = new JSplitPane();
|
||||
JSplitPane splitPane1 = new JSplitPane();
|
||||
JPanel panel10 = new JPanel();
|
||||
JLabel label1 = new JLabel();
|
||||
JPanel panel11 = new JPanel();
|
||||
JLabel label2 = new JLabel();
|
||||
JSplitPane splitPane2 = new JSplitPane();
|
||||
JPanel panel12 = new JPanel();
|
||||
JLabel label3 = new JLabel();
|
||||
JPanel panel13 = new JPanel();
|
||||
JLabel label4 = new JLabel();
|
||||
JLabel tabbedPaneLabel = new JLabel();
|
||||
tabbedPane1 = new JTabbedPane();
|
||||
JPanel panel1 = new JPanel();
|
||||
JLabel label1 = new JLabel();
|
||||
JPanel panel2 = new JPanel();
|
||||
JLabel label2 = new JLabel();
|
||||
tabbedPane3 = new JTabbedPane();
|
||||
JPanel panel5 = new JPanel();
|
||||
JLabel label5 = new JLabel();
|
||||
JPanel panel6 = new JPanel();
|
||||
JLabel label6 = new JLabel();
|
||||
tabbedPane2 = new JTabbedPane();
|
||||
JPanel panel3 = new JPanel();
|
||||
JLabel label3 = new JLabel();
|
||||
JPanel panel4 = new JPanel();
|
||||
JLabel label4 = new JLabel();
|
||||
tabbedPane4 = new JTabbedPane();
|
||||
JPanel panel7 = new JPanel();
|
||||
JLabel label7 = new JLabel();
|
||||
JPanel panel8 = new JPanel();
|
||||
JLabel label8 = new JLabel();
|
||||
JPanel panel14 = new JPanel();
|
||||
moreTabsCheckBox = new JCheckBox();
|
||||
tabScrollCheckBox = new JCheckBox();
|
||||
@@ -111,7 +160,7 @@ class TabsPanel
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[grow,fill]",
|
||||
// rows
|
||||
@@ -120,8 +169,8 @@ class TabsPanel
|
||||
//======== panel9 ========
|
||||
{
|
||||
panel9.setLayout(new FormLayout(
|
||||
"70dlu:grow, $lcgap, 70dlu:grow",
|
||||
"default, $lgap, fill:70dlu, $lgap, pref, 2*($lgap, fill:70dlu:grow), $lgap, pref"));
|
||||
"70dlu:grow, $ugap, 70dlu:grow",
|
||||
"default, $lgap, fill:70dlu, $pgap, pref, $lgap, 2*(fill:80dlu:grow, $ugap), pref"));
|
||||
|
||||
//---- splitPaneLabel ----
|
||||
splitPaneLabel.setText("JSplitPane:");
|
||||
@@ -134,19 +183,30 @@ class TabsPanel
|
||||
//======== splitPane1 ========
|
||||
{
|
||||
splitPane1.setResizeWeight(0.5);
|
||||
splitPane1.setOneTouchExpandable(true);
|
||||
|
||||
//======== panel10 ========
|
||||
{
|
||||
panel10.setBackground(Color.orange);
|
||||
panel10.setLayout(new FlowLayout());
|
||||
panel10.setBackground(new Color(217, 163, 67));
|
||||
panel10.setLayout(new BorderLayout());
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("LEFT");
|
||||
label1.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
label1.setForeground(Color.white);
|
||||
panel10.add(label1, BorderLayout.CENTER);
|
||||
}
|
||||
splitPane1.setLeftComponent(panel10);
|
||||
|
||||
//======== panel11 ========
|
||||
{
|
||||
panel11.setBackground(Color.magenta);
|
||||
panel11.setLayout(new FlowLayout());
|
||||
panel11.setBackground(new Color(98, 181, 67));
|
||||
panel11.setLayout(new BorderLayout());
|
||||
|
||||
//---- label2 ----
|
||||
label2.setText("RIGHT");
|
||||
label2.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
label2.setForeground(Color.white);
|
||||
panel11.add(label2, BorderLayout.CENTER);
|
||||
}
|
||||
splitPane1.setRightComponent(panel11);
|
||||
}
|
||||
@@ -156,19 +216,30 @@ class TabsPanel
|
||||
{
|
||||
splitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||
splitPane2.setResizeWeight(0.5);
|
||||
splitPane2.setOneTouchExpandable(true);
|
||||
|
||||
//======== panel12 ========
|
||||
{
|
||||
panel12.setBackground(Color.orange);
|
||||
panel12.setLayout(new FlowLayout());
|
||||
panel12.setBackground(new Color(242, 101, 34));
|
||||
panel12.setLayout(new BorderLayout());
|
||||
|
||||
//---- label3 ----
|
||||
label3.setText("TOP");
|
||||
label3.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
label3.setForeground(Color.white);
|
||||
panel12.add(label3, BorderLayout.CENTER);
|
||||
}
|
||||
splitPane2.setTopComponent(panel12);
|
||||
|
||||
//======== panel13 ========
|
||||
{
|
||||
panel13.setBackground(Color.magenta);
|
||||
panel13.setLayout(new FlowLayout());
|
||||
panel13.setBackground(new Color(64, 182, 224));
|
||||
panel13.setLayout(new BorderLayout());
|
||||
|
||||
//---- label4 ----
|
||||
label4.setText("BOTTOM");
|
||||
label4.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
label4.setForeground(Color.white);
|
||||
panel13.add(label4, BorderLayout.CENTER);
|
||||
}
|
||||
splitPane2.setBottomComponent(panel13);
|
||||
}
|
||||
@@ -179,112 +250,23 @@ class TabsPanel
|
||||
//---- tabbedPaneLabel ----
|
||||
tabbedPaneLabel.setText("JTabbedPane:");
|
||||
panel9.add(tabbedPaneLabel, cc.xy(1, 5));
|
||||
|
||||
//======== tabbedPane1 ========
|
||||
{
|
||||
|
||||
//======== panel1 ========
|
||||
{
|
||||
panel1.setLayout(new FlowLayout());
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("TOP");
|
||||
panel1.add(label1);
|
||||
}
|
||||
tabbedPane1.addTab("Tab 1", panel1);
|
||||
|
||||
//======== panel2 ========
|
||||
{
|
||||
panel2.setBorder(new LineBorder(Color.magenta));
|
||||
panel2.setLayout(new FlowLayout());
|
||||
}
|
||||
tabbedPane1.addTab("Tab 2", panel2);
|
||||
|
||||
//---- label2 ----
|
||||
label2.setText("text");
|
||||
tabbedPane1.addTab("Tab 3", label2);
|
||||
}
|
||||
panel9.add(tabbedPane1, cc.xy(1, 7));
|
||||
|
||||
//======== tabbedPane3 ========
|
||||
{
|
||||
tabbedPane3.setTabPlacement(SwingConstants.LEFT);
|
||||
|
||||
//======== panel5 ========
|
||||
{
|
||||
panel5.setLayout(new FlowLayout());
|
||||
|
||||
//---- label5 ----
|
||||
label5.setText("LEFT");
|
||||
panel5.add(label5);
|
||||
}
|
||||
tabbedPane3.addTab("Tab 1", panel5);
|
||||
|
||||
//======== panel6 ========
|
||||
{
|
||||
panel6.setBorder(new LineBorder(Color.magenta));
|
||||
panel6.setLayout(new FlowLayout());
|
||||
}
|
||||
tabbedPane3.addTab("Tab 2", panel6);
|
||||
|
||||
//---- label6 ----
|
||||
label6.setText("text");
|
||||
tabbedPane3.addTab("Tab 3", label6);
|
||||
}
|
||||
panel9.add(tabbedPane3, cc.xy(3, 7));
|
||||
|
||||
//======== tabbedPane2 ========
|
||||
{
|
||||
tabbedPane2.setTabPlacement(SwingConstants.BOTTOM);
|
||||
|
||||
//======== panel3 ========
|
||||
{
|
||||
panel3.setLayout(new FlowLayout());
|
||||
|
||||
//---- label3 ----
|
||||
label3.setText("BOTTOM");
|
||||
panel3.add(label3);
|
||||
}
|
||||
tabbedPane2.addTab("Tab 1", panel3);
|
||||
|
||||
//======== panel4 ========
|
||||
{
|
||||
panel4.setBorder(new LineBorder(Color.magenta));
|
||||
panel4.setLayout(new FlowLayout());
|
||||
}
|
||||
tabbedPane2.addTab("Tab 2", panel4);
|
||||
tabbedPane2.setEnabledAt(1, false);
|
||||
|
||||
//---- label4 ----
|
||||
label4.setText("text");
|
||||
tabbedPane2.addTab("Tab 3", label4);
|
||||
}
|
||||
panel9.add(tabbedPane2, cc.xy(1, 9));
|
||||
|
||||
//======== tabbedPane4 ========
|
||||
{
|
||||
tabbedPane4.setTabPlacement(SwingConstants.RIGHT);
|
||||
|
||||
//======== panel7 ========
|
||||
{
|
||||
panel7.setLayout(new FlowLayout());
|
||||
|
||||
//---- label7 ----
|
||||
label7.setText("RIGHT");
|
||||
panel7.add(label7);
|
||||
}
|
||||
tabbedPane4.addTab("Tab 1", panel7);
|
||||
|
||||
//======== panel8 ========
|
||||
{
|
||||
panel8.setBorder(new LineBorder(Color.magenta));
|
||||
panel8.setLayout(new FlowLayout());
|
||||
}
|
||||
tabbedPane4.addTab("Tab 2", panel8);
|
||||
|
||||
//---- label8 ----
|
||||
label8.setText("text");
|
||||
tabbedPane4.addTab("Tab 3", label8);
|
||||
}
|
||||
panel9.add(tabbedPane4, cc.xy(3, 9));
|
||||
|
||||
@@ -301,25 +283,24 @@ class TabsPanel
|
||||
"[center]"));
|
||||
|
||||
//---- moreTabsCheckBox ----
|
||||
moreTabsCheckBox.setText("more tabs");
|
||||
moreTabsCheckBox.setText("More tabs");
|
||||
moreTabsCheckBox.setMnemonic('M');
|
||||
moreTabsCheckBox.addActionListener(e -> moreTabsChanged());
|
||||
panel14.add(moreTabsCheckBox, "cell 0 0");
|
||||
|
||||
//---- tabScrollCheckBox ----
|
||||
tabScrollCheckBox.setText("tabLayoutPolicy = SCROLL");
|
||||
tabScrollCheckBox.setText("Use scroll layout");
|
||||
tabScrollCheckBox.setMnemonic('S');
|
||||
tabScrollCheckBox.addActionListener(e -> tabScrollChanged());
|
||||
panel14.add(tabScrollCheckBox, "cell 1 0,alignx left,growx 0");
|
||||
|
||||
//---- showTabSeparatorsCheckBox ----
|
||||
showTabSeparatorsCheckBox.setText("JTabbedPane.showTabSeparators");
|
||||
showTabSeparatorsCheckBox.setText("Show tab separators");
|
||||
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
|
||||
panel14.add(showTabSeparatorsCheckBox, "cell 2 0");
|
||||
|
||||
//---- hasFullBorderCheckBox ----
|
||||
hasFullBorderCheckBox.setText("JTabbedPane.hasFullBorder");
|
||||
hasFullBorderCheckBox.setMnemonic('F');
|
||||
hasFullBorderCheckBox.setText("Show content border");
|
||||
hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
|
||||
panel14.add(hasFullBorderCheckBox, "cell 3 0,alignx left,growx 0");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -7,14 +7,14 @@ new FormModel {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[grow,fill]"
|
||||
"$rowConstraints": "[grow,fill]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class com.jgoodies.forms.layout.FormLayout ) {
|
||||
"$columnSpecs": "70dlu:grow, labelcompgap, 70dlu:grow"
|
||||
"$rowSpecs": "default, linegap, fill:70dlu, linegap, pref, linegap, fill:70dlu:grow, linegap, fill:70dlu:grow, linegap, pref"
|
||||
"$columnSpecs": "70dlu:grow, unrelgap, 70dlu:grow"
|
||||
"$rowSpecs": "default, linegap, fill:70dlu, pargap, pref, linegap, fill:80dlu:grow, unrelgap, fill:80dlu:grow, unrelgap, pref"
|
||||
} ) {
|
||||
name: "panel9"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -27,16 +27,31 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JSplitPane", new FormLayoutManager( class javax.swing.JSplitPane ) ) {
|
||||
name: "splitPane1"
|
||||
"resizeWeight": 0.5
|
||||
"oneTouchExpandable": true
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "panel10"
|
||||
"background": sfield java.awt.Color orange
|
||||
"background": new java.awt.Color( 217, 163, 67, 255 )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label1"
|
||||
"text": "LEFT"
|
||||
"horizontalAlignment": 0
|
||||
"foreground": sfield java.awt.Color white
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "left"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "panel11"
|
||||
"background": sfield java.awt.Color magenta
|
||||
"background": new java.awt.Color( 98, 181, 67, 255 )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label2"
|
||||
"text": "RIGHT"
|
||||
"horizontalAlignment": 0
|
||||
"foreground": sfield java.awt.Color white
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "right"
|
||||
} )
|
||||
@@ -47,16 +62,31 @@ new FormModel {
|
||||
name: "splitPane2"
|
||||
"orientation": 0
|
||||
"resizeWeight": 0.5
|
||||
"oneTouchExpandable": true
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "panel12"
|
||||
"background": sfield java.awt.Color orange
|
||||
"background": new java.awt.Color( 242, 101, 34, 255 )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label3"
|
||||
"text": "TOP"
|
||||
"horizontalAlignment": 0
|
||||
"foreground": sfield java.awt.Color white
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "left"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "panel13"
|
||||
"background": sfield java.awt.Color magenta
|
||||
"background": new java.awt.Color( 64, 182, 224, 255 )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label4"
|
||||
"text": "BOTTOM"
|
||||
"horizontalAlignment": 0
|
||||
"foreground": sfield java.awt.Color white
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "right"
|
||||
} )
|
||||
@@ -79,27 +109,6 @@ new FormModel {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel1"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label1"
|
||||
"text": "TOP"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel2"
|
||||
"border": &LineBorder0 new javax.swing.border.LineBorder( sfield java.awt.Color magenta, 1, false )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label2"
|
||||
"text": "text"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 3"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
||||
"gridX": 1
|
||||
"gridY": 7
|
||||
@@ -110,27 +119,6 @@ new FormModel {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel5"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label5"
|
||||
"text": "LEFT"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel6"
|
||||
"border": #LineBorder0
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label6"
|
||||
"text": "text"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 3"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
||||
"gridX": 3
|
||||
"gridY": 7
|
||||
@@ -141,28 +129,6 @@ new FormModel {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel3"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label3"
|
||||
"text": "BOTTOM"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel4"
|
||||
"border": #LineBorder0
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 2"
|
||||
"enabled": false
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label4"
|
||||
"text": "text"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 3"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
||||
"gridY": 9
|
||||
} )
|
||||
@@ -172,27 +138,6 @@ new FormModel {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel7"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label7"
|
||||
"text": "RIGHT"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel8"
|
||||
"border": #LineBorder0
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label8"
|
||||
"text": "text"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 3"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
||||
"gridX": 3
|
||||
"gridY": 9
|
||||
@@ -205,7 +150,7 @@ new FormModel {
|
||||
name: "panel14"
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "moreTabsCheckBox"
|
||||
"text": "more tabs"
|
||||
"text": "More tabs"
|
||||
"mnemonic": 77
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
@@ -216,7 +161,7 @@ new FormModel {
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "tabScrollCheckBox"
|
||||
"text": "tabLayoutPolicy = SCROLL"
|
||||
"text": "Use scroll layout"
|
||||
"mnemonic": 83
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
@@ -227,7 +172,7 @@ new FormModel {
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "showTabSeparatorsCheckBox"
|
||||
"text": "JTabbedPane.showTabSeparators"
|
||||
"text": "Show tab separators"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
@@ -237,8 +182,7 @@ new FormModel {
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "hasFullBorderCheckBox"
|
||||
"text": "JTabbedPane.hasFullBorder"
|
||||
"mnemonic": 70
|
||||
"text": "Show content border"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
@@ -255,7 +199,7 @@ new FormModel {
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 610, 515 )
|
||||
"size": new java.awt.Dimension( 625, 515 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class ExtrasPanel
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[]" +
|
||||
"[]" +
|
||||
@@ -98,7 +98,7 @@ public class ExtrasPanel
|
||||
//---- triStateLabel1 ----
|
||||
triStateLabel1.setText("text");
|
||||
triStateLabel1.setEnabled(false);
|
||||
add(triStateLabel1, "cell 2 1");
|
||||
add(triStateLabel1, "cell 2 1,gapx 30");
|
||||
|
||||
//---- label2 ----
|
||||
label2.setText("SVG Icons:");
|
||||
|
||||
@@ -4,7 +4,7 @@ new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][][left]"
|
||||
"$rowConstraints": "[]para[][][]"
|
||||
} ) {
|
||||
@@ -33,7 +33,7 @@ new FormModel {
|
||||
"text": "text"
|
||||
"enabled": false
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 1"
|
||||
"value": "cell 2 1,gapx 30"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label2"
|
||||
|
||||
@@ -25,6 +25,7 @@ class IJThemeInfo
|
||||
{
|
||||
final String name;
|
||||
final String resourceName;
|
||||
final boolean dark;
|
||||
final String license;
|
||||
final String licenseFile;
|
||||
final String sourceCodeUrl;
|
||||
@@ -32,13 +33,14 @@ class IJThemeInfo
|
||||
final File themeFile;
|
||||
final String lafClassName;
|
||||
|
||||
IJThemeInfo( String name, String resourceName,
|
||||
IJThemeInfo( String name, String resourceName, boolean dark,
|
||||
String license, String licenseFile,
|
||||
String sourceCodeUrl, String sourceCodePath,
|
||||
File themeFile, String lafClassName )
|
||||
{
|
||||
this.name = name;
|
||||
this.resourceName = resourceName;
|
||||
this.dark = dark;
|
||||
this.license = license;
|
||||
this.licenseFile = licenseFile;
|
||||
this.sourceCodeUrl = sourceCodeUrl;
|
||||
|
||||
@@ -55,12 +55,13 @@ class IJThemesManager
|
||||
String resourceName = e.getKey();
|
||||
Map<String, String> value = (Map<String, String>) e.getValue();
|
||||
String name = value.get( "name" );
|
||||
boolean dark = Boolean.parseBoolean( value.get( "dark" ) );
|
||||
String license = value.get( "license" );
|
||||
String licenseFile = value.get( "licenseFile" );
|
||||
String sourceCodeUrl = value.get( "sourceCodeUrl" );
|
||||
String sourceCodePath = value.get( "sourceCodePath" );
|
||||
|
||||
bundledThemes.add( new IJThemeInfo( name, resourceName, license, licenseFile, sourceCodeUrl, sourceCodePath, null, null ) );
|
||||
bundledThemes.add( new IJThemeInfo( name, resourceName, dark, license, licenseFile, sourceCodeUrl, sourceCodePath, null, null ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ class IJThemesManager
|
||||
String name = fname.endsWith( ".properties" )
|
||||
? StringUtils.removeTrailing( fname, ".properties" )
|
||||
: StringUtils.removeTrailing( fname, ".theme.json" );
|
||||
moreThemes.add( new IJThemeInfo( name, null, null, null, null, null, f, null ) );
|
||||
moreThemes.add( new IJThemeInfo( name, null, false, null, null, null, null, f, null ) );
|
||||
lastModifiedMap.put( f, f.lastModified() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.demo.intellijthemes;
|
||||
import java.awt.Component;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
@@ -49,6 +50,7 @@ import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.FlatPropertiesLaf;
|
||||
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.StringUtils;
|
||||
import net.miginfocom.swing.*;
|
||||
@@ -119,6 +121,10 @@ public class IJThemesPanel
|
||||
}
|
||||
|
||||
private void updateThemesList() {
|
||||
int filterLightDark = filterComboBox.getSelectedIndex();
|
||||
boolean showLight = (filterLightDark != 2);
|
||||
boolean showDark = (filterLightDark != 1);
|
||||
|
||||
// load theme infos
|
||||
themesManager.loadBundledThemes();
|
||||
themesManager.loadThemesFromDirectory();
|
||||
@@ -128,15 +134,22 @@ public class IJThemesPanel
|
||||
themesManager.bundledThemes.sort( comparator );
|
||||
themesManager.moreThemes.sort( comparator );
|
||||
|
||||
// remember selection (must be invoked before clearing themes field)
|
||||
IJThemeInfo oldSel = themesList.getSelectedValue();
|
||||
|
||||
themes.clear();
|
||||
categories.clear();
|
||||
|
||||
// add core themes at beginning
|
||||
categories.put( themes.size(), "Core Themes" );
|
||||
themes.add( new IJThemeInfo( "Flat Light", null, null, null, null, null, null, FlatLightLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "Flat Dark", null, null, null, null, null, null, FlatDarkLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "Flat IntelliJ", null, null, null, null, null, null, FlatIntelliJLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "Flat Darcula", null, null, null, null, null, null, FlatDarculaLaf.class.getName() ) );
|
||||
if( showLight )
|
||||
themes.add( new IJThemeInfo( "Flat Light", null, false, null, null, null, null, null, FlatLightLaf.class.getName() ) );
|
||||
if( showDark )
|
||||
themes.add( new IJThemeInfo( "Flat Dark", null, true, null, null, null, null, null, FlatDarkLaf.class.getName() ) );
|
||||
if( showLight )
|
||||
themes.add( new IJThemeInfo( "Flat IntelliJ", null, false, null, null, null, null, null, FlatIntelliJLaf.class.getName() ) );
|
||||
if( showDark )
|
||||
themes.add( new IJThemeInfo( "Flat Darcula", null, true, null, null, null, null, null, FlatDarculaLaf.class.getName() ) );
|
||||
|
||||
// add themes from directory
|
||||
categories.put( themes.size(), "Current Directory" );
|
||||
@@ -145,15 +158,17 @@ public class IJThemesPanel
|
||||
// add uncategorized bundled themes
|
||||
categories.put( themes.size(), "IntelliJ Themes" );
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
if( !ti.name.contains( "/" ) )
|
||||
boolean show = (showLight && !ti.dark) || (showDark && ti.dark);
|
||||
if( show && !ti.name.contains( "/" ) )
|
||||
themes.add( ti );
|
||||
}
|
||||
|
||||
// add categorized bundled themes
|
||||
String lastCategory = null;
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
boolean show = (showLight && !ti.dark) || (showDark && ti.dark);
|
||||
int sep = ti.name.indexOf( '/' );
|
||||
if( sep < 0 )
|
||||
if( !show || sep < 0 )
|
||||
continue;
|
||||
|
||||
String category = ti.name.substring( 0, sep ).trim();
|
||||
@@ -165,9 +180,6 @@ public class IJThemesPanel
|
||||
themes.add( ti );
|
||||
}
|
||||
|
||||
// remember selection
|
||||
IJThemeInfo oldSel = themesList.getSelectedValue();
|
||||
|
||||
// fill themes list
|
||||
themesList.setModel( new AbstractListModel<IJThemeInfo>() {
|
||||
@Override
|
||||
@@ -193,6 +205,18 @@ public class IJThemesPanel
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// select first theme if none selected
|
||||
if( themesList.getSelectedIndex() < 0 )
|
||||
themesList.setSelectedIndex( 0 );
|
||||
}
|
||||
|
||||
// scroll selection into visible area
|
||||
int sel = themesList.getSelectedIndex();
|
||||
if( sel >= 0 ) {
|
||||
Rectangle bounds = themesList.getCellBounds( sel, sel );
|
||||
if( bounds != null )
|
||||
themesList.scrollRectToVisible( bounds );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +243,8 @@ public class IJThemesPanel
|
||||
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
return;
|
||||
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel( themeInfo.lafClassName );
|
||||
} catch( Exception ex ) {
|
||||
@@ -226,6 +252,8 @@ public class IJThemesPanel
|
||||
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
|
||||
}
|
||||
} else if( themeInfo.themeFile != null ) {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
try {
|
||||
if( themeInfo.themeFile.getName().endsWith( ".properties" ) ) {
|
||||
FlatLaf.install( new FlatPropertiesLaf( themeInfo.name, themeInfo.themeFile ) );
|
||||
@@ -238,12 +266,15 @@ public class IJThemesPanel
|
||||
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
|
||||
}
|
||||
} else {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
IntelliJTheme.install( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.resourceName ) );
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.RESOURCE_PREFIX + themeInfo.resourceName );
|
||||
}
|
||||
|
||||
// update all components
|
||||
FlatLaf.updateUI();
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
}
|
||||
|
||||
private void saveTheme() {
|
||||
@@ -373,12 +404,17 @@ public class IJThemesPanel
|
||||
isAdjustingThemesList = false;
|
||||
}
|
||||
|
||||
private void filterChanged() {
|
||||
updateThemesList();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JLabel themesLabel = new JLabel();
|
||||
toolBar = new JToolBar();
|
||||
saveButton = new JButton();
|
||||
sourceCodeButton = new JButton();
|
||||
filterComboBox = new JComboBox<>();
|
||||
themesScrollPane = new JScrollPane();
|
||||
themesList = new JList<>();
|
||||
|
||||
@@ -411,6 +447,17 @@ public class IJThemesPanel
|
||||
}
|
||||
add(toolBar, "cell 0 0,alignx right,growx 0");
|
||||
|
||||
//---- filterComboBox ----
|
||||
filterComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"all",
|
||||
"light",
|
||||
"dark"
|
||||
}));
|
||||
filterComboBox.putClientProperty("JComponent.minimumWidth", 0);
|
||||
filterComboBox.setFocusable(false);
|
||||
filterComboBox.addActionListener(e -> filterChanged());
|
||||
add(filterComboBox, "cell 0 0,alignx right,growx 0");
|
||||
|
||||
//======== themesScrollPane ========
|
||||
{
|
||||
|
||||
@@ -427,6 +474,7 @@ public class IJThemesPanel
|
||||
private JToolBar toolBar;
|
||||
private JButton saveButton;
|
||||
private JButton sourceCodeButton;
|
||||
private JComboBox<String> filterComboBox;
|
||||
private JScrollPane themesScrollPane;
|
||||
private JList<IJThemeInfo> themesList;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -34,6 +34,20 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0,alignx right,growx 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "filterComboBox"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "all"
|
||||
addElement( "all" )
|
||||
addElement( "light" )
|
||||
addElement( "dark" )
|
||||
}
|
||||
"$client.JComponent.minimumWidth": 0
|
||||
"focusable": false
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0,alignx right,growx 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "themesScrollPane"
|
||||
add( new FormComponent( "javax.swing.JList" ) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 2020 FormDev Software GmbH
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
HintPanel.backgroundColor=darken(#ffffe1,80%)
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 2020 FormDev Software GmbH
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
HintPanel.backgroundColor=#ffffe1
|
||||
@@ -13,6 +13,38 @@
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/resources/arc-theme-orange.theme.json"
|
||||
},
|
||||
"arc_theme_dark.theme.json": {
|
||||
"name": "Arc Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/resources/arc_theme_dark.theme.json"
|
||||
},
|
||||
"arc_theme_dark_orange.theme.json": {
|
||||
"name": "Arc Dark - Orange",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/resources/arc_theme_dark_orange.theme.json"
|
||||
},
|
||||
"Carbon.theme.json": {
|
||||
"name": "Carbon",
|
||||
"dark": true,
|
||||
"license": "Apache License 2.0",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/luisfer0793/theme-carbon",
|
||||
"sourceCodePath": "blob/master/resources/matte_carbon_basics.theme.json"
|
||||
},
|
||||
"Cobalt_2.theme.json": {
|
||||
"name": "Cobalt 2",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Cobalt_2.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/ngehlert/cobalt2",
|
||||
"sourceCodePath": "blob/master/Cobalt2-UI-Theme/resources/Cobalt_2.theme.json"
|
||||
},
|
||||
"Cyan.theme.json": {
|
||||
"name": "Cyan light",
|
||||
"license": "MIT",
|
||||
@@ -22,6 +54,7 @@
|
||||
},
|
||||
"DarkFlatTheme.theme.json": {
|
||||
"name": "Dark Flat",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "DarkFlatTheme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/nerzhulart/DarkFlatTheme",
|
||||
@@ -29,6 +62,7 @@
|
||||
},
|
||||
"DarkPurple.theme.json": {
|
||||
"name": "Dark purple",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "DarkPurple.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/DarkPurpleTheme",
|
||||
@@ -36,6 +70,7 @@
|
||||
},
|
||||
"Dracula.theme.json": {
|
||||
"name": "Dracula",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Dracula.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/dracula/jetbrains",
|
||||
@@ -43,6 +78,7 @@
|
||||
},
|
||||
"Gradianto_dark_fuchsia.theme.json": {
|
||||
"name": "Gradianto Dark Fuchsia",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
@@ -50,6 +86,7 @@
|
||||
},
|
||||
"Gradianto_deep_ocean.theme.json": {
|
||||
"name": "Gradianto Deep Ocean",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
@@ -57,6 +94,7 @@
|
||||
},
|
||||
"Gradianto_midnight_blue.theme.json": {
|
||||
"name": "Gradianto Midnight Blue",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
@@ -71,6 +109,7 @@
|
||||
},
|
||||
"gruvbox_dark_hard.theme.json": {
|
||||
"name": "Gruvbox Dark Hard",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
@@ -78,6 +117,7 @@
|
||||
},
|
||||
"gruvbox_dark_medium.theme.json": {
|
||||
"name": "Gruvbox Dark Medium",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
@@ -85,6 +125,7 @@
|
||||
},
|
||||
"gruvbox_dark_soft.theme.json": {
|
||||
"name": "Gruvbox Dark Soft",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
@@ -92,6 +133,7 @@
|
||||
},
|
||||
"HiberbeeDark.theme.json": {
|
||||
"name": "Hiberbee Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Hiberbee.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Hiberbee/code-highlight-themes",
|
||||
@@ -99,6 +141,7 @@
|
||||
},
|
||||
"HighContrast.theme.json": {
|
||||
"name": "High contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "HighContrast.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/HighContrastTheme",
|
||||
@@ -113,6 +156,7 @@
|
||||
},
|
||||
"MaterialTheme.theme.json": {
|
||||
"name": "Material Design Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "MaterialTheme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/xinkunZ/NotReallyMDTheme",
|
||||
@@ -120,6 +164,7 @@
|
||||
},
|
||||
"Monocai.theme.json": {
|
||||
"name": "Monocai",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Monocai.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/bmikaili/intellij-monocai-theme",
|
||||
@@ -127,6 +172,7 @@
|
||||
},
|
||||
"nord.theme.json": {
|
||||
"name": "Nord",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "nord.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/arcticicestudio/nord-jetbrains",
|
||||
@@ -134,27 +180,30 @@
|
||||
},
|
||||
"one_dark.theme.json": {
|
||||
"name": "One Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "one_dark.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/one-dark/jetbrains-one-dark-theme",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/one_dark.theme.json"
|
||||
"sourceCodePath": "blob/master/buildSrc/templates/oneDark.template.theme.json"
|
||||
},
|
||||
"solarized_dark_theme.theme.json": {
|
||||
"SolarizedDark.theme.json": {
|
||||
"name": "Solarized Dark",
|
||||
"license": "MIT",
|
||||
"licenseFile": "solarized_dark_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/snowe2010/solarized-jetbrains",
|
||||
"sourceCodePath": "blob/master/src/solarized_dark_theme.theme.json"
|
||||
"dark": true,
|
||||
"license": "The Unlicense",
|
||||
"licenseFile": "Solarized.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/4lex4/intellij-platform-solarized",
|
||||
"sourceCodePath": "blob/master/resources/SolarizedDark.theme.json"
|
||||
},
|
||||
"solarized_light_theme.theme.json": {
|
||||
"SolarizedLight.theme.json": {
|
||||
"name": "Solarized Light",
|
||||
"license": "MIT",
|
||||
"licenseFile": "solarized_light_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/snowe2010/solarized-jetbrains",
|
||||
"sourceCodePath": "blob/master/src/solarized_light_theme.theme.json"
|
||||
"license": "The Unlicense",
|
||||
"licenseFile": "Solarized.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/4lex4/intellij-platform-solarized",
|
||||
"sourceCodePath": "blob/master/resources/SolarizedLight.theme.json"
|
||||
},
|
||||
"Spacegray.theme.json": {
|
||||
"name": "Spacegray",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "Spacegray.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mturlo/intellij-spacegray",
|
||||
@@ -162,6 +211,7 @@
|
||||
},
|
||||
"vuesion_theme.theme.json": {
|
||||
"name": "Vuesion",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "vuesion_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/vuesion/intellij-theme",
|
||||
@@ -170,6 +220,7 @@
|
||||
|
||||
"material-theme-ui-lite/Arc Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Arc Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -177,6 +228,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Arc Dark Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Arc Dark Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -184,6 +236,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Atom One Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Atom One Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -191,6 +244,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Atom One Dark Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Atom One Dark Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -212,6 +266,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Dracula.theme.json": {
|
||||
"name": "Material Theme UI Lite / Dracula",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -219,6 +274,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Dracula Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Dracula Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -254,6 +310,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Darker.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Darker",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -261,6 +318,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Darker Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Darker Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -268,6 +326,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Deep Ocean.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Deep Ocean",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -275,6 +334,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Deep Ocean Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Deep Ocean Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -296,6 +356,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Oceanic.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Oceanic",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -303,6 +364,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Oceanic Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Oceanic Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -310,6 +372,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Palenight.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Palenight",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -317,6 +380,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Material Palenight Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Palenight Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -324,6 +388,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Monokai Pro.theme.json": {
|
||||
"name": "Material Theme UI Lite / Monokai Pro",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -331,6 +396,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Monokai Pro Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Monokai Pro Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -338,6 +404,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Night Owl.theme.json": {
|
||||
"name": "Material Theme UI Lite / Night Owl",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -345,6 +412,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Night Owl Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Night Owl Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -352,6 +420,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Solarized Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Solarized Dark",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
@@ -359,6 +428,7 @@
|
||||
},
|
||||
"material-theme-ui-lite/Solarized Dark Contrast.theme.json": {
|
||||
"name": "Material Theme UI Lite / Solarized Dark Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
|
||||
@@ -3,14 +3,20 @@ FlatLaf Extras
|
||||
|
||||
This sub-project provides some additional components and classes:
|
||||
|
||||
- [FlatInspector](src/main/java/com/formdev/flatlaf/extras/FlatInspector.java):
|
||||
A simple UI inspector that shows information about UI component at mouse
|
||||
location in a tooltip.
|
||||
- [FlatSVGIcon](src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java): An
|
||||
icon that displays SVG using
|
||||
[svgSalamander](https://github.com/JFormDesigner/svgSalamander).
|
||||
- [TriStateCheckBox](src/main/java/com/formdev/flatlaf/extras/TriStateCheckBox.java):
|
||||
A tri-state check box.
|
||||
- [FlatSVGIcon](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/FlatSVGIcon.html):
|
||||
An icon that displays SVG using
|
||||
[svgSalamander](https://github.com/JFormDesigner/svgSalamander).\
|
||||

|
||||
- [TriStateCheckBox](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/TriStateCheckBox.html):
|
||||
A tri-state check box.\
|
||||

|
||||
- [FlatAnimatedLafChange](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/FlatAnimatedLafChange.html):
|
||||
Animated Laf (theme) changing.
|
||||
- [FlatInspector](#ui-inspector): A simple UI inspector that shows information
|
||||
about UI component at mouse location in a tooltip.
|
||||
- [FlatUIDefaultsInspector](#ui-defaults-inspector): A simple UI defaults
|
||||
inspector that shows a window with all UI defaults used in current theme (look
|
||||
and feel).
|
||||
|
||||
|
||||
Download
|
||||
@@ -34,3 +40,45 @@ you can download here:
|
||||
|
||||
[](https://bintray.com/jformdesigner/flatlaf/flatlaf/_latestVersion)
|
||||
[](https://bintray.com/jformdesigner/svgSalamander/svgSalamander/_latestVersion)
|
||||
|
||||
|
||||
Tools
|
||||
-----
|
||||
|
||||
### UI Inspector
|
||||
|
||||
A simple UI inspector that shows information about UI component at mouse
|
||||
location in a tooltip, which may be useful while developing an application.
|
||||
Should be not installed in released applications.
|
||||
|
||||
Once installed with following code (e.g. in method `main`), it can be activated
|
||||
for the active window with the given keystroke:
|
||||
|
||||
~~~java
|
||||
FlatInspector.install( "ctrl shift alt X" );
|
||||
~~~
|
||||
|
||||

|
||||
|
||||
When the UI inspector is active some additional keys are available:
|
||||
|
||||
- press <kbd>Esc</kbd> key to disable UI inspector
|
||||
- press <kbd>Ctrl</kbd> key to increase inspection level, which shows
|
||||
information about parent of UI component at mouse location
|
||||
- press <kbd>Shift</kbd> key to decrease inspection level
|
||||
|
||||
|
||||
### UI Defaults Inspector
|
||||
|
||||
A simple UI defaults inspector that shows a window with all UI defaults used in
|
||||
current theme (look and feel), which may be useful while developing an
|
||||
application. Should be not installed in released applications.
|
||||
|
||||
Once installed with following code (e.g. in method `main`), it can be activated
|
||||
with the given keystroke:
|
||||
|
||||
~~~java
|
||||
FlatUIDefaultsInspector.install( "ctrl shift alt Y" );
|
||||
~~~
|
||||
|
||||

|
||||
|
||||
@@ -22,7 +22,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
implementation( "com.formdev:svgSalamander:1.1.2.1" )
|
||||
implementation( "com.formdev:svgSalamander:1.1.2.3" )
|
||||
}
|
||||
|
||||
flatlafModuleInfo {
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.extras;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Window;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.RootPaneContainer;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.Animator;
|
||||
|
||||
/**
|
||||
* Animated look and feel changing.
|
||||
* <p>
|
||||
* Invoke {@link #showSnapshot()} before setting look and feel and
|
||||
* {@link #hideSnapshotWithAnimation()} after updating UI. E.g.
|
||||
* <pre>
|
||||
* FlatAnimatedLafChange.showSnapshot();
|
||||
* UIManager.setLookAndFeel( lafClassName );
|
||||
* FlatLaf.updateUI();
|
||||
* FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
* </pre>
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatAnimatedLafChange
|
||||
{
|
||||
/**
|
||||
* The duration of the animation in milliseconds. Default is 160 ms.
|
||||
*/
|
||||
public static int duration = 160;
|
||||
|
||||
/**
|
||||
* The resolution of the animation in milliseconds. Default is 40 ms.
|
||||
*/
|
||||
public static int resolution = 40;
|
||||
|
||||
private static Animator animator;
|
||||
private static final Map<JLayeredPane, JComponent> oldUIsnapshots = new WeakHashMap<>();
|
||||
private static final Map<JLayeredPane, JComponent> newUIsnapshots = new WeakHashMap<>();
|
||||
private static float alpha;
|
||||
private static boolean inShowSnapshot;
|
||||
|
||||
/**
|
||||
* Create a snapshot of the old UI and shows it on top of the UI.
|
||||
* Invoke before setting new look and feel.
|
||||
*/
|
||||
public static void showSnapshot() {
|
||||
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
||||
return;
|
||||
|
||||
// stop already running animation
|
||||
if( animator != null )
|
||||
animator.stop();
|
||||
|
||||
alpha = 1;
|
||||
|
||||
// show snapshot of old UI
|
||||
showSnapshot( true, oldUIsnapshots );
|
||||
}
|
||||
|
||||
private static void showSnapshot( boolean useAlpha, Map<JLayeredPane, JComponent> map ) {
|
||||
inShowSnapshot = true;
|
||||
|
||||
// create snapshots for all shown windows
|
||||
Window[] windows = Window.getWindows();
|
||||
for( Window window : windows ) {
|
||||
if( !(window instanceof RootPaneContainer) || !window.isShowing() )
|
||||
continue;
|
||||
|
||||
// create snapshot image
|
||||
// (using volatile image to have correct sub-pixel text rendering on Java 9+)
|
||||
VolatileImage snapshot = window.createVolatileImage( window.getWidth(), window.getHeight() );
|
||||
if( snapshot == null )
|
||||
continue;
|
||||
|
||||
// paint window to snapshot image
|
||||
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||
layeredPane.paint( snapshot.getGraphics() );
|
||||
|
||||
// create snapshot layer, which is added to layered pane and paints
|
||||
// snapshot with animated alpha
|
||||
JComponent snapshotLayer = new JComponent() {
|
||||
@Override
|
||||
public void paint( Graphics g ) {
|
||||
if( inShowSnapshot || snapshot.contentsLost() )
|
||||
return;
|
||||
|
||||
if( useAlpha )
|
||||
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
||||
g.drawImage( snapshot, 0, 0, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
// release system resources used by volatile image
|
||||
snapshot.flush();
|
||||
}
|
||||
};
|
||||
if( !useAlpha )
|
||||
snapshotLayer.setOpaque( true );
|
||||
snapshotLayer.setSize( layeredPane.getSize() );
|
||||
|
||||
// add image layer to layered pane
|
||||
layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + (useAlpha ? 2 : 1) ) );
|
||||
map.put( layeredPane, snapshotLayer );
|
||||
}
|
||||
|
||||
inShowSnapshot = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an animation that shows the snapshot (created by {@link #showSnapshot()}
|
||||
* with an decreasing alpha. At the end, the snapshot is removed and the new UI is shown.
|
||||
* Invoke after updating UI.
|
||||
*/
|
||||
public static void hideSnapshotWithAnimation() {
|
||||
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
||||
return;
|
||||
|
||||
if( oldUIsnapshots.isEmpty() )
|
||||
return;
|
||||
|
||||
// show snapshot of new UI
|
||||
showSnapshot( false, newUIsnapshots );
|
||||
|
||||
// create animator
|
||||
animator = new Animator( duration, fraction -> {
|
||||
if( fraction < 0.1 || fraction > 0.9 )
|
||||
return; // ignore initial and last events
|
||||
|
||||
alpha = 1f - fraction;
|
||||
|
||||
// repaint snapshots
|
||||
for( Map.Entry<JLayeredPane, JComponent> e : oldUIsnapshots.entrySet() ) {
|
||||
if( e.getKey().isShowing() )
|
||||
e.getValue().repaint();
|
||||
}
|
||||
}, () -> {
|
||||
hideSnapshot();
|
||||
animator = null;
|
||||
} );
|
||||
|
||||
animator.setResolution( resolution );
|
||||
animator.start();
|
||||
}
|
||||
|
||||
private static void hideSnapshot() {
|
||||
hideSnapshot( oldUIsnapshots );
|
||||
hideSnapshot( newUIsnapshots );
|
||||
}
|
||||
|
||||
private static void hideSnapshot( Map<JLayeredPane, JComponent> map ) {
|
||||
// remove snapshots
|
||||
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
||||
e.getKey().remove( e.getValue() );
|
||||
e.getKey().repaint();
|
||||
}
|
||||
|
||||
map.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops a running animation (if any) and hides the snapshot.
|
||||
*/
|
||||
public static void stop() {
|
||||
if( animator != null )
|
||||
animator.stop();
|
||||
else
|
||||
hideSnapshot();
|
||||
}
|
||||
}
|
||||
@@ -158,10 +158,20 @@ public class FlatInspector
|
||||
} else if( id == KeyEvent.KEY_RELEASED && wasCtrlOrShiftKeyPressed ) {
|
||||
if( keyCode == KeyEvent.VK_CONTROL ) {
|
||||
inspectParentLevel++;
|
||||
inspect( lastX, lastY );
|
||||
int parentLevel = inspect( lastX, lastY );
|
||||
|
||||
// limit level
|
||||
if( inspectParentLevel > parentLevel )
|
||||
inspectParentLevel = parentLevel;
|
||||
} else if( keyCode == KeyEvent.VK_SHIFT && inspectParentLevel > 0 ) {
|
||||
inspectParentLevel--;
|
||||
inspect( lastX, lastY );
|
||||
int parentLevel = inspect( lastX, lastY );
|
||||
|
||||
// decrease level
|
||||
if( inspectParentLevel > parentLevel ) {
|
||||
inspectParentLevel = Math.max( parentLevel - 1, 0 );
|
||||
inspect( lastX, lastY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,24 +258,28 @@ public class FlatInspector
|
||||
} );
|
||||
}
|
||||
|
||||
private void inspect( int x, int y ) {
|
||||
private int inspect( int x, int y ) {
|
||||
Point pt = SwingUtilities.convertPoint( rootPane.getGlassPane(), x, y, rootPane );
|
||||
Component c = getDeepestComponentAt( rootPane, pt.x, pt.y );
|
||||
int parentLevel = 0;
|
||||
for( int i = 0; i < inspectParentLevel && c != null; i++ ) {
|
||||
Container parent = c.getParent();
|
||||
if( parent == null )
|
||||
break;
|
||||
|
||||
c = parent;
|
||||
parentLevel++;
|
||||
}
|
||||
|
||||
if( c == lastComponent )
|
||||
return;
|
||||
return parentLevel;
|
||||
|
||||
lastComponent = c;
|
||||
|
||||
highlight( c );
|
||||
showToolTip( c, x, y );
|
||||
showToolTip( c, x, y, parentLevel );
|
||||
|
||||
return parentLevel;
|
||||
}
|
||||
|
||||
private Component getDeepestComponentAt( Component parent, int x, int y ) {
|
||||
@@ -338,7 +352,7 @@ public class FlatInspector
|
||||
return c;
|
||||
}
|
||||
|
||||
private void showToolTip( Component c, int x, int y ) {
|
||||
private void showToolTip( Component c, int x, int y, int parentLevel ) {
|
||||
if( c == null ) {
|
||||
if( tip != null )
|
||||
tip.setVisible( false );
|
||||
@@ -356,7 +370,7 @@ public class FlatInspector
|
||||
} else
|
||||
tip.setVisible( true );
|
||||
|
||||
tip.setTipText( buildToolTipText( c ) );
|
||||
tip.setTipText( buildToolTipText( c, parentLevel ) );
|
||||
|
||||
int tx = x + UIScale.scale( 8 );
|
||||
int ty = y + UIScale.scale( 16 );
|
||||
@@ -377,7 +391,7 @@ public class FlatInspector
|
||||
tip.repaint();
|
||||
}
|
||||
|
||||
private String buildToolTipText( Component c ) {
|
||||
private static String buildToolTipText( Component c, int parentLevel ) {
|
||||
String name = c.getClass().getName();
|
||||
name = name.substring( name.lastIndexOf( '.' ) + 1 );
|
||||
|
||||
@@ -441,10 +455,10 @@ public class FlatInspector
|
||||
text += "Left-to-right: " + c.getComponentOrientation().isLeftToRight() + '\n';
|
||||
text += "Parent: " + (c.getParent() != null ? c.getParent().getClass().getName() : "null");
|
||||
|
||||
if( inspectParentLevel > 0 )
|
||||
text += "\n\nParent level: " + inspectParentLevel;
|
||||
if( parentLevel > 0 )
|
||||
text += "\n\nParent level: " + parentLevel;
|
||||
|
||||
if( inspectParentLevel > 0 )
|
||||
if( parentLevel > 0 )
|
||||
text += "\n(press Ctrl/Shift to increase/decrease level)";
|
||||
else
|
||||
text += "\n\n(press Ctrl key to inspect parent)";
|
||||
|
||||
@@ -50,11 +50,18 @@ public class FlatSVGIcon
|
||||
private static final SVGUniverse svgUniverse = new SVGUniverse();
|
||||
|
||||
private final String name;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private SVGDiagram diagram;
|
||||
private boolean dark;
|
||||
|
||||
public FlatSVGIcon( String name ) {
|
||||
this( name, null );
|
||||
}
|
||||
|
||||
public FlatSVGIcon( String name, ClassLoader classLoader ) {
|
||||
this.name = name;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
@@ -79,7 +86,14 @@ public class FlatSVGIcon
|
||||
int dotIndex = name.lastIndexOf( '.' );
|
||||
name = name.substring( 0, dotIndex ) + "_dark" + name.substring( dotIndex );
|
||||
}
|
||||
return FlatSVGIcon.class.getClassLoader().getResource( name );
|
||||
|
||||
ClassLoader cl = (classLoader != null) ? classLoader : FlatSVGIcon.class.getClassLoader();
|
||||
return cl.getResource( name );
|
||||
}
|
||||
|
||||
public boolean hasFound() {
|
||||
update();
|
||||
return diagram != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,911 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.extras;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.icons.FlatAbstractIcon;
|
||||
import com.formdev.flatlaf.ui.FlatBorder;
|
||||
import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
import com.formdev.flatlaf.ui.FlatMarginBorder;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.GrayFilter;
|
||||
import com.formdev.flatlaf.util.HSLColor;
|
||||
import com.formdev.flatlaf.util.ScaledEmptyBorder;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* A simple UI defaults inspector that shows a window with all UI defaults used
|
||||
* in current look and feel.
|
||||
* <p>
|
||||
* To use it in an application install it with:
|
||||
* <pre>
|
||||
* FlatUIDefaultsInspector.install( "ctrl shift alt Y" );
|
||||
* </pre>
|
||||
* This can be done e.g. in the main() method and allows enabling (and disabling)
|
||||
* the UI defaults inspector with the given keystroke.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatUIDefaultsInspector
|
||||
{
|
||||
private static final int KEY_MODIFIERS_MASK = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK;
|
||||
|
||||
private static FlatUIDefaultsInspector inspector;
|
||||
|
||||
private final String title;
|
||||
private final PropertyChangeListener lafListener = this::lafChanged;
|
||||
private final PropertyChangeListener lafDefaultsListener = this::lafDefaultsChanged;
|
||||
private boolean refreshPending;
|
||||
|
||||
/**
|
||||
* Installs a key listener into the application that allows enabling and disabling
|
||||
* the UI inspector with the given keystroke (e.g. "ctrl shift alt Y").
|
||||
*/
|
||||
public static void install( String activationKeys ) {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( activationKeys );
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener( e -> {
|
||||
if( e.getID() == KeyEvent.KEY_RELEASED &&
|
||||
((KeyEvent)e).getKeyCode() == keyStroke.getKeyCode() &&
|
||||
(((KeyEvent)e).getModifiersEx() & KEY_MODIFIERS_MASK) == (keyStroke.getModifiers() & KEY_MODIFIERS_MASK) )
|
||||
{
|
||||
show();
|
||||
}
|
||||
}, AWTEvent.KEY_EVENT_MASK );
|
||||
}
|
||||
|
||||
public static void show() {
|
||||
if( inspector != null ) {
|
||||
inspector.ensureOnScreen();
|
||||
inspector.frame.toFront();
|
||||
return;
|
||||
}
|
||||
|
||||
inspector = new FlatUIDefaultsInspector();
|
||||
inspector.frame.setVisible( true );
|
||||
}
|
||||
|
||||
public static void hide() {
|
||||
if( inspector != null )
|
||||
inspector.frame.dispose();
|
||||
}
|
||||
|
||||
private FlatUIDefaultsInspector() {
|
||||
initComponents();
|
||||
|
||||
title = frame.getTitle();
|
||||
updateWindowTitle();
|
||||
|
||||
panel.setBorder( new ScaledEmptyBorder( 10, 10, 10, 10 ) );
|
||||
filterPanel.setBorder( new ScaledEmptyBorder( 0, 0, 10, 0 ) );
|
||||
|
||||
// initialize filter
|
||||
filterField.getDocument().addDocumentListener( new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate( DocumentEvent e ) {
|
||||
filterChanged();
|
||||
}
|
||||
@Override
|
||||
public void insertUpdate( DocumentEvent e ) {
|
||||
filterChanged();
|
||||
}
|
||||
@Override
|
||||
public void changedUpdate( DocumentEvent e ) {
|
||||
filterChanged();
|
||||
}
|
||||
} );
|
||||
delegateKey( KeyEvent.VK_UP, "unitScrollUp" );
|
||||
delegateKey( KeyEvent.VK_DOWN, "unitScrollDown" );
|
||||
delegateKey( KeyEvent.VK_PAGE_UP, "scrollUp" );
|
||||
delegateKey( KeyEvent.VK_PAGE_DOWN, "scrollDown" );
|
||||
|
||||
// initialize table
|
||||
table.setModel( new ItemsTableModel( getUIDefaultsItems() ) );
|
||||
table.setDefaultRenderer( String.class, new KeyRenderer() );
|
||||
table.setDefaultRenderer( Item.class, new ValueRenderer() );
|
||||
table.getRowSorter().setSortKeys( Collections.singletonList(
|
||||
new RowSorter.SortKey( 0, SortOrder.ASCENDING ) ) );
|
||||
|
||||
// restore window bounds
|
||||
Preferences prefs = getPrefs();
|
||||
int x = prefs.getInt( "x", -1 );
|
||||
int y = prefs.getInt( "y", -1 );
|
||||
int width = prefs.getInt( "width", UIScale.scale( 600 ) );
|
||||
int height = prefs.getInt( "height", UIScale.scale( 800 ) );
|
||||
frame.setSize( width, height );
|
||||
if( x != -1 && y != -1 ) {
|
||||
frame.setLocation( x, y );
|
||||
ensureOnScreen();
|
||||
} else
|
||||
frame.setLocationRelativeTo( null );
|
||||
|
||||
// restore column widths
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
columnModel.getColumn( 0 ).setPreferredWidth( prefs.getInt( "column1width", 100 ) );
|
||||
columnModel.getColumn( 1 ).setPreferredWidth( prefs.getInt( "column2width", 100 ) );
|
||||
|
||||
// restore filter
|
||||
String filter = prefs.get( "filter", "" );
|
||||
String valueType = prefs.get( "valueType", null );
|
||||
if( filter != null && !filter.isEmpty() )
|
||||
filterField.setText( filter );
|
||||
if( valueType != null )
|
||||
valueTypeField.setSelectedItem( valueType );
|
||||
|
||||
UIManager.addPropertyChangeListener( lafListener );
|
||||
UIManager.getDefaults().addPropertyChangeListener( lafDefaultsListener );
|
||||
|
||||
// register F5 key to refresh
|
||||
((JComponent)frame.getContentPane()).registerKeyboardAction(
|
||||
e -> refresh(),
|
||||
KeyStroke.getKeyStroke( KeyEvent.VK_F5, 0, false ),
|
||||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||
|
||||
// register ESC key to close frame
|
||||
((JComponent)frame.getContentPane()).registerKeyboardAction(
|
||||
e -> frame.dispose(),
|
||||
KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ),
|
||||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||
}
|
||||
|
||||
private void delegateKey( int keyCode, String actionKey ) {
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( keyCode, 0 );
|
||||
String actionMapKey = "delegate-" + actionKey;
|
||||
|
||||
filterField.getInputMap().put( keyStroke, actionMapKey );
|
||||
filterField.getActionMap().put( actionMapKey, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e ) {
|
||||
Action action = scrollPane.getActionMap().get( actionKey );
|
||||
if( action != null ) {
|
||||
action.actionPerformed( new ActionEvent( scrollPane,
|
||||
e.getID(), actionKey, e.getWhen(), e.getModifiers() ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private void ensureOnScreen() {
|
||||
Rectangle frameBounds = frame.getBounds();
|
||||
boolean onScreen = false;
|
||||
for( GraphicsDevice screen : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) {
|
||||
GraphicsConfiguration gc = screen.getDefaultConfiguration();
|
||||
Rectangle screenBounds = FlatUIUtils.subtractInsets( gc.getBounds(),
|
||||
Toolkit.getDefaultToolkit().getScreenInsets( gc ) );
|
||||
if( frameBounds.intersects( screenBounds ) ) {
|
||||
onScreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !onScreen )
|
||||
frame.setLocationRelativeTo( null );
|
||||
}
|
||||
|
||||
void lafChanged( PropertyChangeEvent e ) {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
refresh();
|
||||
}
|
||||
|
||||
void lafDefaultsChanged( PropertyChangeEvent e ) {
|
||||
if( refreshPending )
|
||||
return;
|
||||
|
||||
refreshPending = true;
|
||||
EventQueue.invokeLater( () -> {
|
||||
refresh();
|
||||
refreshPending = false;
|
||||
} );
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
ItemsTableModel model = (ItemsTableModel) table.getModel();
|
||||
model.setItems( getUIDefaultsItems() );
|
||||
|
||||
updateWindowTitle();
|
||||
}
|
||||
|
||||
private Item[] getUIDefaultsItems() {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults();
|
||||
|
||||
Set<Entry<Object, Object>> defaultsSet = defaults.entrySet();
|
||||
ArrayList<Item> items = new ArrayList<>( defaultsSet.size() );
|
||||
HashSet<Object> keys = new HashSet<>( defaultsSet.size() );
|
||||
for( Entry<Object,Object> e : defaultsSet ) {
|
||||
Object key = e.getKey();
|
||||
|
||||
// ignore non-string keys
|
||||
if( !(key instanceof String) )
|
||||
continue;
|
||||
|
||||
// ignore values of type Class
|
||||
Object value = defaults.get( key );
|
||||
if( value instanceof Class )
|
||||
continue;
|
||||
|
||||
// avoid duplicate keys if UIManager.put(key,value) was used to override a LaF value
|
||||
if( !keys.add( key ) )
|
||||
continue;
|
||||
|
||||
// check whether key was overridden using UIManager.put(key,value)
|
||||
Object lafValue = null;
|
||||
if( defaults.containsKey( key ) )
|
||||
lafValue = lafDefaults.get( key );
|
||||
|
||||
// add item
|
||||
items.add( new Item( String.valueOf( key ), value, lafValue ) );
|
||||
}
|
||||
|
||||
return items.toArray( new Item[items.size()] );
|
||||
}
|
||||
|
||||
private void updateWindowTitle() {
|
||||
frame.setTitle( title + " - " + UIManager.getLookAndFeel().getName() );
|
||||
}
|
||||
|
||||
private void saveWindowBounds() {
|
||||
Preferences prefs = getPrefs();
|
||||
prefs.putInt( "x", frame.getX() );
|
||||
prefs.putInt( "y", frame.getY() );
|
||||
prefs.putInt( "width", frame.getWidth() );
|
||||
prefs.putInt( "height", frame.getHeight() );
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
prefs.putInt( "column1width", columnModel.getColumn( 0 ).getWidth() );
|
||||
prefs.putInt( "column2width", columnModel.getColumn( 1 ).getWidth() );
|
||||
}
|
||||
|
||||
private Preferences getPrefs() {
|
||||
return Preferences.userRoot().node( "flatlaf-uidefaults-inspector" );
|
||||
}
|
||||
|
||||
private void windowClosed() {
|
||||
UIManager.removePropertyChangeListener( lafListener );
|
||||
UIManager.getDefaults().removePropertyChangeListener( lafDefaultsListener );
|
||||
|
||||
inspector = null;
|
||||
}
|
||||
|
||||
private void filterChanged() {
|
||||
String filter = filterField.getText().trim();
|
||||
String valueType = (String) valueTypeField.getSelectedItem();
|
||||
|
||||
// split filter string on space characters
|
||||
String[] filters = filter.split( " +" );
|
||||
for( int i = 0; i < filters.length; i++ )
|
||||
filters[i] = filters[i].toLowerCase( Locale.ENGLISH );
|
||||
|
||||
ItemsTableModel model = (ItemsTableModel) table.getModel();
|
||||
model.setFilter( item -> {
|
||||
if( valueType != null &&
|
||||
!valueType.equals( "(any)" ) &&
|
||||
!valueType.equals( typeOfValue( item.value ) ) )
|
||||
return false;
|
||||
|
||||
String lkey = item.key.toLowerCase( Locale.ENGLISH );
|
||||
String lvalue = item.getValueAsString().toLowerCase( Locale.ENGLISH );
|
||||
for( String f : filters ) {
|
||||
if( lkey.contains( f ) || lvalue.contains( f ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
|
||||
Preferences prefs = getPrefs();
|
||||
prefs.put( "filter", filter );
|
||||
prefs.put( "valueType", valueType );
|
||||
}
|
||||
|
||||
private String typeOfValue( Object value ) {
|
||||
if( value instanceof Boolean )
|
||||
return "Boolean";
|
||||
if( value instanceof Border )
|
||||
return "Border";
|
||||
if( value instanceof Color )
|
||||
return "Color";
|
||||
if( value instanceof Dimension )
|
||||
return "Dimension";
|
||||
if( value instanceof Float )
|
||||
return "Float";
|
||||
if( value instanceof Font )
|
||||
return "Font";
|
||||
if( value instanceof Icon )
|
||||
return "Icon";
|
||||
if( value instanceof Insets )
|
||||
return "Insets";
|
||||
if( value instanceof Integer )
|
||||
return "Integer";
|
||||
if( value instanceof String )
|
||||
return "String";
|
||||
return "(other)";
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
frame = new JFrame();
|
||||
panel = new JPanel();
|
||||
filterPanel = new JPanel();
|
||||
flterLabel = new JLabel();
|
||||
filterField = new JTextField();
|
||||
valueTypeLabel = new JLabel();
|
||||
valueTypeField = new JComboBox<>();
|
||||
scrollPane = new JScrollPane();
|
||||
table = new JTable();
|
||||
|
||||
//======== frame ========
|
||||
{
|
||||
frame.setTitle("UI Defaults Inspector");
|
||||
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
FlatUIDefaultsInspector.this.windowClosed();
|
||||
}
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
saveWindowBounds();
|
||||
}
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
saveWindowBounds();
|
||||
}
|
||||
});
|
||||
Container frameContentPane = frame.getContentPane();
|
||||
frameContentPane.setLayout(new BorderLayout());
|
||||
|
||||
//======== panel ========
|
||||
{
|
||||
panel.setLayout(new BorderLayout());
|
||||
|
||||
//======== filterPanel ========
|
||||
{
|
||||
filterPanel.setLayout(new GridBagLayout());
|
||||
((GridBagLayout)filterPanel.getLayout()).columnWidths = new int[] {0, 0, 0, 0, 0};
|
||||
((GridBagLayout)filterPanel.getLayout()).rowHeights = new int[] {0, 0};
|
||||
((GridBagLayout)filterPanel.getLayout()).columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 1.0E-4};
|
||||
((GridBagLayout)filterPanel.getLayout()).rowWeights = new double[] {0.0, 1.0E-4};
|
||||
|
||||
//---- flterLabel ----
|
||||
flterLabel.setText("Filter:");
|
||||
flterLabel.setLabelFor(filterField);
|
||||
flterLabel.setDisplayedMnemonic('F');
|
||||
filterPanel.add(flterLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 10), 0, 0));
|
||||
|
||||
//---- filterField ----
|
||||
filterField.putClientProperty("JTextField.placeholderText", "enter one or more filter strings, separated by space characters");
|
||||
filterPanel.add(filterField, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 10), 0, 0));
|
||||
|
||||
//---- valueTypeLabel ----
|
||||
valueTypeLabel.setText("Value Type:");
|
||||
valueTypeLabel.setLabelFor(valueTypeField);
|
||||
valueTypeLabel.setDisplayedMnemonic('T');
|
||||
filterPanel.add(valueTypeLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 10), 0, 0));
|
||||
|
||||
//---- valueTypeField ----
|
||||
valueTypeField.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"(any)",
|
||||
"Boolean",
|
||||
"Border",
|
||||
"Color",
|
||||
"Dimension",
|
||||
"Float",
|
||||
"Font",
|
||||
"Icon",
|
||||
"Insets",
|
||||
"Integer",
|
||||
"String",
|
||||
"(other)"
|
||||
}));
|
||||
valueTypeField.addActionListener(e -> filterChanged());
|
||||
filterPanel.add(valueTypeField, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
new Insets(0, 0, 0, 0), 0, 0));
|
||||
}
|
||||
panel.add(filterPanel, BorderLayout.NORTH);
|
||||
|
||||
//======== scrollPane ========
|
||||
{
|
||||
|
||||
//---- table ----
|
||||
table.setAutoCreateRowSorter(true);
|
||||
scrollPane.setViewportView(table);
|
||||
}
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
frameContentPane.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JFrame frame;
|
||||
private JPanel panel;
|
||||
private JPanel filterPanel;
|
||||
private JLabel flterLabel;
|
||||
private JTextField filterField;
|
||||
private JLabel valueTypeLabel;
|
||||
private JComboBox<String> valueTypeField;
|
||||
private JScrollPane scrollPane;
|
||||
private JTable table;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
//---- class Item ---------------------------------------------------------
|
||||
|
||||
private static class Item {
|
||||
final String key;
|
||||
final Object value;
|
||||
final Object lafValue;
|
||||
|
||||
private String valueStr;
|
||||
|
||||
Item( String key, Object value, Object lafValue ) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.lafValue = lafValue;
|
||||
}
|
||||
|
||||
String getValueAsString() {
|
||||
if( valueStr == null )
|
||||
valueStr = valueAsString( value );
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
static String valueAsString( Object value ) {
|
||||
if( value instanceof Color ) {
|
||||
Color color = (Color) value;
|
||||
HSLColor hslColor = new HSLColor( color );
|
||||
if( color.getAlpha() == 255 ) {
|
||||
return String.format( "%s rgb(%d, %d, %d) hsl(%d, %d, %d)",
|
||||
color2hex( color ),
|
||||
color.getRed(), color.getGreen(), color.getBlue(),
|
||||
(int) hslColor.getHue(), (int) hslColor.getSaturation(),
|
||||
(int) hslColor.getLuminance() );
|
||||
} else {
|
||||
return String.format( "%s rgba(%d, %d, %d, %d) hsla(%d, %d, %d, %d)",
|
||||
color2hex( color ),
|
||||
color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha(),
|
||||
(int) hslColor.getHue(), (int) hslColor.getSaturation(),
|
||||
(int) hslColor.getLuminance(), (int) (hslColor.getAlpha() * 100) );
|
||||
}
|
||||
} else if( value instanceof Insets ) {
|
||||
Insets insets = (Insets) value;
|
||||
return insets.top + "," + insets.left + "," + insets.bottom + "," + insets.right;
|
||||
} else if( value instanceof Dimension ) {
|
||||
Dimension dim = (Dimension) value;
|
||||
return dim.width + "," + dim.height;
|
||||
} else if( value instanceof Font ) {
|
||||
Font font = (Font) value;
|
||||
String s = font.getFamily() + " " + font.getSize();
|
||||
if( font.isBold() )
|
||||
s += " bold";
|
||||
if( font.isItalic() )
|
||||
s += " italic";
|
||||
return s;
|
||||
} else if( value instanceof Icon ) {
|
||||
Icon icon = (Icon) value;
|
||||
return icon.getIconWidth() + "x" + icon.getIconHeight() + " " + icon.getClass().getName();
|
||||
} else if( value instanceof Border ) {
|
||||
Border border = (Border) value;
|
||||
if( border instanceof FlatLineBorder ) {
|
||||
FlatLineBorder lineBorder = (FlatLineBorder) border;
|
||||
return valueAsString( lineBorder.getUnscaledBorderInsets() )
|
||||
+ " " + Item.color2hex( lineBorder.getLineColor() )
|
||||
+ " " + lineBorder.getLineThickness()
|
||||
+ " " + border.getClass().getName();
|
||||
} else if( border instanceof EmptyBorder ) {
|
||||
Insets insets = (border instanceof FlatEmptyBorder)
|
||||
? ((FlatEmptyBorder)border).getUnscaledBorderInsets()
|
||||
: ((EmptyBorder)border).getBorderInsets();
|
||||
return valueAsString( insets ) + " " + border.getClass().getName();
|
||||
} else if( border instanceof FlatBorder || border instanceof FlatMarginBorder )
|
||||
return border.getClass().getName();
|
||||
else
|
||||
return String.valueOf( value );
|
||||
} else if( value instanceof GrayFilter ) {
|
||||
GrayFilter grayFilter = (GrayFilter) value;
|
||||
return grayFilter.getBrightness() + "," + grayFilter.getContrast()
|
||||
+ " " + grayFilter.getAlpha() + " " + grayFilter.getClass().getName();
|
||||
} else if( value instanceof ActionMap ) {
|
||||
ActionMap actionMap = (ActionMap) value;
|
||||
return "ActionMap (" + actionMap.size() + ")";
|
||||
} else if( value instanceof InputMap ) {
|
||||
InputMap inputMap = (InputMap) value;
|
||||
return "InputMap (" + inputMap.size() + ")";
|
||||
} else if( value instanceof Object[] )
|
||||
return Arrays.toString( (Object[]) value );
|
||||
else if( value instanceof int[] )
|
||||
return Arrays.toString( (int[]) value );
|
||||
else
|
||||
return String.valueOf( value );
|
||||
}
|
||||
|
||||
private static String color2hex( Color color ) {
|
||||
int rgb = color.getRGB();
|
||||
boolean hasAlpha = color.getAlpha() != 255;
|
||||
|
||||
boolean useShortFormat =
|
||||
(rgb & 0xf0000000) == (rgb & 0xf000000) << 4 &&
|
||||
(rgb & 0xf00000) == (rgb & 0xf0000) << 4 &&
|
||||
(rgb & 0xf000) == (rgb & 0xf00) << 4 &&
|
||||
(rgb & 0xf0) == (rgb & 0xf) << 4;
|
||||
|
||||
if( useShortFormat ) {
|
||||
int srgb = ((rgb & 0xf0000) >> 8) | ((rgb & 0xf00) >> 4) | (rgb & 0xf);
|
||||
return String.format( hasAlpha ? "#%03X%X" : "#%03X", srgb, (rgb >> 24) & 0xf );
|
||||
} else
|
||||
return String.format( hasAlpha ? "#%06X%02X" : "#%06X", rgb & 0xffffff, (rgb >> 24) & 0xff );
|
||||
}
|
||||
|
||||
// used for sorting by value
|
||||
@Override
|
||||
public String toString() {
|
||||
return getValueAsString();
|
||||
}
|
||||
}
|
||||
|
||||
//---- class ItemsTableModel ----------------------------------------------
|
||||
|
||||
private static class ItemsTableModel
|
||||
extends AbstractTableModel
|
||||
{
|
||||
private Item[] allItems;
|
||||
private Item[] items;
|
||||
private Predicate<Item> filter;
|
||||
|
||||
ItemsTableModel( Item[] items ) {
|
||||
this.allItems = this.items = items;
|
||||
}
|
||||
|
||||
void setItems( Item[] items ) {
|
||||
this.allItems = this.items = items;
|
||||
setFilter( filter );
|
||||
}
|
||||
|
||||
void setFilter( Predicate<Item> filter ) {
|
||||
this.filter = filter;
|
||||
|
||||
if( filter != null ) {
|
||||
ArrayList<Item> list = new ArrayList<>( allItems.length );
|
||||
for( Item item : allItems ) {
|
||||
if( filter.test( item ) )
|
||||
list.add( item );
|
||||
}
|
||||
items = list.toArray( new Item[list.size()] );
|
||||
} else
|
||||
items = allItems;
|
||||
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName( int columnIndex ) {
|
||||
switch( columnIndex ) {
|
||||
case 0: return "Name";
|
||||
case 1: return "Value";
|
||||
}
|
||||
return super.getColumnName( columnIndex );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass( int columnIndex ) {
|
||||
switch( columnIndex ) {
|
||||
case 0: return String.class;
|
||||
case 1: return Item.class;
|
||||
}
|
||||
return super.getColumnClass( columnIndex );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt( int rowIndex, int columnIndex ) {
|
||||
Item item = items[rowIndex];
|
||||
switch( columnIndex ) {
|
||||
case 0: return item.key;
|
||||
case 1: return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class Renderer -----------------------------------------------------
|
||||
|
||||
private static class Renderer
|
||||
extends DefaultTableCellRenderer
|
||||
{
|
||||
protected boolean selected;
|
||||
protected boolean first;
|
||||
|
||||
protected void init( JTable table, String key, boolean selected, int row ) {
|
||||
this.selected = selected;
|
||||
|
||||
first = false;
|
||||
if( row > 0 ) {
|
||||
String previousKey = (String) table.getValueAt( row - 1, 0 );
|
||||
int dot = key.indexOf( '.' );
|
||||
if( dot > 0 ) {
|
||||
String prefix = key.substring( 0, dot + 1 );
|
||||
first = !previousKey.startsWith( prefix );
|
||||
} else
|
||||
first = previousKey.indexOf( '.' ) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintSeparator( Graphics g ) {
|
||||
if( first && !selected ) {
|
||||
g.setColor( FlatLaf.isLafDark() ? Color.gray : Color.lightGray );
|
||||
g.fillRect( 0, 0, getWidth() - 1, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
protected String layoutLabel( FontMetrics fm, String text, Rectangle textR ) {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
Insets insets = getInsets();
|
||||
|
||||
Rectangle viewR = new Rectangle( insets.left, insets.top,
|
||||
width - (insets.left + insets.right),
|
||||
height - (insets.top + insets.bottom) );
|
||||
Rectangle iconR = new Rectangle();
|
||||
|
||||
return SwingUtilities.layoutCompoundLabel( this, fm, text, null,
|
||||
getVerticalAlignment(), getHorizontalAlignment(),
|
||||
getVerticalTextPosition(), getHorizontalTextPosition(),
|
||||
viewR, iconR, textR, getIconTextGap() );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class KeyRenderer --------------------------------------------------
|
||||
|
||||
private static class KeyRenderer
|
||||
extends Renderer
|
||||
{
|
||||
private String key;
|
||||
private boolean isOverridden;
|
||||
private Icon overriddenIcon;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent( JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column )
|
||||
{
|
||||
key = (String) value;
|
||||
init( table, key, isSelected, row );
|
||||
|
||||
Item item = (Item) table.getValueAt( row, 1 );
|
||||
isOverridden = (item.lafValue != null);
|
||||
|
||||
// set tooltip
|
||||
String toolTipText = key;
|
||||
if( isOverridden )
|
||||
toolTipText += " \n\nLaF UI default value was overridden with UIManager.put(key,value).";
|
||||
setToolTipText( toolTipText );
|
||||
|
||||
return super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
|
||||
FontMetrics fm = getFontMetrics( getFont() );
|
||||
Rectangle textR = new Rectangle();
|
||||
String clippedText = layoutLabel( fm, key, textR );
|
||||
int x = textR.x;
|
||||
int y = textR.y + fm.getAscent();
|
||||
|
||||
int dot = key.indexOf( '.' );
|
||||
if( dot > 0 && !selected ) {
|
||||
g.setColor( UIManager.getColor( "Label.disabledForeground" ) );
|
||||
|
||||
if( dot >= clippedText.length() )
|
||||
FlatUIUtils.drawString( this, g, clippedText, x, y );
|
||||
else {
|
||||
String prefix = clippedText.substring( 0, dot + 1 );
|
||||
String subkey = clippedText.substring( dot + 1 );
|
||||
|
||||
FlatUIUtils.drawString( this, g, prefix, x, y );
|
||||
|
||||
g.setColor( getForeground() );
|
||||
FlatUIUtils.drawString( this, g, subkey, x + fm.stringWidth( prefix ), y );
|
||||
}
|
||||
} else {
|
||||
g.setColor( getForeground() );
|
||||
FlatUIUtils.drawString( this, g, clippedText, x, y );
|
||||
}
|
||||
|
||||
if( isOverridden ) {
|
||||
if( overriddenIcon == null ) {
|
||||
overriddenIcon = new FlatAbstractIcon( 16, 16, null ) {
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
g2.setColor( FlatUIUtils.getUIColor( "Actions.Red", Color.red ) );
|
||||
g2.setStroke( new BasicStroke( 2f ) );
|
||||
g2.draw( FlatUIUtils.createPath( false, 3,10, 8,5, 13,10 ) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
overriddenIcon.paintIcon( this, g,
|
||||
getWidth() - overriddenIcon.getIconWidth(),
|
||||
(getHeight() - overriddenIcon.getIconHeight()) / 2 );
|
||||
}
|
||||
|
||||
paintSeparator( g );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class ValueRenderer ------------------------------------------------
|
||||
|
||||
private static class ValueRenderer
|
||||
extends Renderer
|
||||
{
|
||||
private Item item;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent( JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column )
|
||||
{
|
||||
item = (Item) value;
|
||||
init( table, item.key, isSelected, row );
|
||||
|
||||
// reset background, foreground and icon
|
||||
if( !(item.value instanceof Color) ) {
|
||||
setBackground( null );
|
||||
setForeground( null );
|
||||
}
|
||||
if( !(item.value instanceof Icon) )
|
||||
setIcon( null );
|
||||
|
||||
// value to string
|
||||
value = item.getValueAsString();
|
||||
|
||||
super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
||||
|
||||
if( item.value instanceof Color ) {
|
||||
Color color = (Color) item.value;
|
||||
boolean isDark = new HSLColor( color ).getLuminance() < 70;
|
||||
setBackground( color );
|
||||
setForeground( isDark ? Color.white : Color.black );
|
||||
} else if( item.value instanceof Icon ) {
|
||||
Icon icon = (Icon) item.value;
|
||||
setIcon( new SafeIcon( icon ) );
|
||||
}
|
||||
|
||||
// set tooltip
|
||||
String toolTipText = String.valueOf( item.value );
|
||||
if( item.lafValue != null ) {
|
||||
toolTipText += " \n\nLaF UI default value was overridden with UIManager.put(key,value):\n "
|
||||
+ Item.valueAsString( item.lafValue ) + "\n " + String.valueOf( item.lafValue );
|
||||
}
|
||||
setToolTipText( toolTipText );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
if( item.value instanceof Color ) {
|
||||
// fill background
|
||||
g.setColor( getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
|
||||
// layout text
|
||||
FontMetrics fm = getFontMetrics( getFont() );
|
||||
String text = getText();
|
||||
Rectangle textR = new Rectangle();
|
||||
layoutLabel( fm, text, textR );
|
||||
int x = textR.x;
|
||||
int y = textR.y + fm.getAscent();
|
||||
|
||||
g.setColor( getForeground() );
|
||||
|
||||
// paint rgb() and hsl() horizontally aligned
|
||||
int rgbIndex = text.indexOf( "rgb" );
|
||||
int hslIndex = text.indexOf( "hsl" );
|
||||
if( rgbIndex > 0 && hslIndex > rgbIndex ) {
|
||||
String hexText = text.substring( 0, rgbIndex );
|
||||
String rgbText = text.substring( rgbIndex, hslIndex );
|
||||
String hslText = text.substring( hslIndex );
|
||||
int hexWidth = Math.max( fm.stringWidth( hexText ), fm.stringWidth( "#DDDDDD " ) );
|
||||
int rgbWidth = Math.max( fm.stringWidth( rgbText ), fm.stringWidth( "rgb(444, 444, 444) " ) );
|
||||
FlatUIUtils.drawString( this, g, hexText, x, y );
|
||||
FlatUIUtils.drawString( this, g, rgbText, x + hexWidth, y );
|
||||
FlatUIUtils.drawString( this, g, hslText, x + hexWidth + rgbWidth, y );
|
||||
} else
|
||||
FlatUIUtils.drawString( this, g, text, x, y );
|
||||
} else
|
||||
super.paintComponent( g );
|
||||
|
||||
paintSeparator( g );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class SafeIcon -----------------------------------------------------
|
||||
|
||||
private static class SafeIcon
|
||||
implements Icon
|
||||
{
|
||||
private final Icon icon;
|
||||
|
||||
SafeIcon( Icon icon ) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
int width = getIconWidth();
|
||||
int height = getIconHeight();
|
||||
|
||||
try {
|
||||
g.setColor( UIManager.getColor( "Panel.background" ) );
|
||||
g.fillRect( x, y, width, height );
|
||||
|
||||
icon.paintIcon( c, g, x, y );
|
||||
} catch( Exception ex ) {
|
||||
g.setColor( Color.red );
|
||||
g.drawRect( x, y, width - 1, height - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return icon.getIconWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return icon.getIconHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
add( new FormWindow( "javax.swing.JFrame", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "frame"
|
||||
"title": "UI Defaults Inspector"
|
||||
"defaultCloseOperation": 2
|
||||
"$sizePolicy": 2
|
||||
"$locationPolicy": 2
|
||||
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowClosed", "windowClosed", false ) )
|
||||
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowClosing", "saveWindowBounds", false ) )
|
||||
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowDeactivated", "saveWindowBounds", false ) )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||
name: "panel"
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.GridBagLayout ) {
|
||||
"$columnSpecs": "0, 0:1.0, 0, 0"
|
||||
"$rowSpecs": "0"
|
||||
"$hGap": 10
|
||||
"$vGap": 5
|
||||
"$alignLeft": true
|
||||
"$alignTop": true
|
||||
} ) {
|
||||
name: "filterPanel"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "flterLabel"
|
||||
"text": "Filter:"
|
||||
"labelFor": new FormReference( "filterField" )
|
||||
"displayedMnemonic": 70
|
||||
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "filterField"
|
||||
"$client.JTextField.placeholderText": "enter one or more filter strings, separated by space characters"
|
||||
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
|
||||
"gridx": 1
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "valueTypeLabel"
|
||||
"text": "Value Type:"
|
||||
"labelFor": new FormReference( "valueTypeField" )
|
||||
"displayedMnemonic": 84
|
||||
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
|
||||
"gridx": 2
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "valueTypeField"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "(any)"
|
||||
addElement( "(any)" )
|
||||
addElement( "Boolean" )
|
||||
addElement( "Border" )
|
||||
addElement( "Color" )
|
||||
addElement( "Dimension" )
|
||||
addElement( "Float" )
|
||||
addElement( "Font" )
|
||||
addElement( "Icon" )
|
||||
addElement( "Insets" )
|
||||
addElement( "Integer" )
|
||||
addElement( "String" )
|
||||
addElement( "(other)" )
|
||||
}
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "String"
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
|
||||
"gridx": 3
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "North"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane"
|
||||
add( new FormComponent( "javax.swing.JTable" ) {
|
||||
name: "table"
|
||||
"autoCreateRowSorter": true
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "Center"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 400, 300 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
module com.formdev.flatlaf.extras {
|
||||
requires java.desktop;
|
||||
requires java.prefs;
|
||||
requires static com.kitfox.svg; // optional at runtime
|
||||
requires com.formdev.flatlaf;
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@ Name | Class
|
||||
-----|------
|
||||
[Arc](https://gitlab.com/zlamalp/arc-theme-idea) | `com.formdev.flatlaf.intellijthemes.FlatArcIJTheme`
|
||||
[Arc - Orange](https://gitlab.com/zlamalp/arc-theme-idea) | `com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme`
|
||||
[Arc Dark](https://gitlab.com/zlamalp/arc-theme-idea) | `com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme`
|
||||
[Arc Dark - Orange](https://gitlab.com/zlamalp/arc-theme-idea) | `com.formdev.flatlaf.intellijthemes.FlatArcDarkOrangeIJTheme`
|
||||
[Carbon](https://github.com/luisfer0793/theme-carbon) | `com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme`
|
||||
[Cobalt 2](https://github.com/ngehlert/cobalt2) | `com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme`
|
||||
[Cyan light](https://github.com/OlyaB/CyanTheme) | `com.formdev.flatlaf.intellijthemes.FlatCyanLightIJTheme`
|
||||
[Dark Flat](https://github.com/nerzhulart/DarkFlatTheme) | `com.formdev.flatlaf.intellijthemes.FlatDarkFlatIJTheme`
|
||||
[Dark purple](https://github.com/OlyaB/DarkPurpleTheme) | `com.formdev.flatlaf.intellijthemes.FlatDarkPurpleIJTheme`
|
||||
@@ -67,8 +71,8 @@ Name | Class
|
||||
[Monocai](https://github.com/bmikaili/intellij-monocai-theme) | `com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme`
|
||||
[Nord](https://github.com/arcticicestudio/nord-jetbrains) | `com.formdev.flatlaf.intellijthemes.FlatNordIJTheme`
|
||||
[One Dark](https://github.com/one-dark/jetbrains-one-dark-theme) | `com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme`
|
||||
[Solarized Dark](https://github.com/snowe2010/solarized-jetbrains) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme`
|
||||
[Solarized Light](https://github.com/snowe2010/solarized-jetbrains) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme`
|
||||
[Solarized Dark](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme`
|
||||
[Solarized Light](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme`
|
||||
[Spacegray](https://github.com/mturlo/intellij-spacegray) | `com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme`
|
||||
[Vuesion](https://github.com/vuesion/intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme`
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@ public class FlatAllIJThemes
|
||||
public static final LookAndFeelInfo[] INFOS = {
|
||||
new LookAndFeelInfo( "Arc", "com.formdev.flatlaf.intellijthemes.FlatArcIJTheme" ),
|
||||
new LookAndFeelInfo( "Arc - Orange", "com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme" ),
|
||||
new LookAndFeelInfo( "Arc Dark", "com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme" ),
|
||||
new LookAndFeelInfo( "Arc Dark - Orange", "com.formdev.flatlaf.intellijthemes.FlatArcDarkOrangeIJTheme" ),
|
||||
new LookAndFeelInfo( "Carbon", "com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme" ),
|
||||
new LookAndFeelInfo( "Cobalt 2", "com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme" ),
|
||||
new LookAndFeelInfo( "Cyan light", "com.formdev.flatlaf.intellijthemes.FlatCyanLightIJTheme" ),
|
||||
new LookAndFeelInfo( "Dark Flat", "com.formdev.flatlaf.intellijthemes.FlatDarkFlatIJTheme" ),
|
||||
new LookAndFeelInfo( "Dark purple", "com.formdev.flatlaf.intellijthemes.FlatDarkPurpleIJTheme" ),
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.intellijthemes;
|
||||
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatArcDarkIJTheme
|
||||
extends IntelliJTheme.ThemeLaf
|
||||
{
|
||||
public static boolean install( ) {
|
||||
try {
|
||||
return install( new FlatArcDarkIJTheme() );
|
||||
} catch( RuntimeException ex ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public FlatArcDarkIJTheme() {
|
||||
super( Utils.loadTheme( "arc_theme_dark.theme.json" ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.intellijthemes;
|
||||
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatArcDarkOrangeIJTheme
|
||||
extends IntelliJTheme.ThemeLaf
|
||||
{
|
||||
public static boolean install( ) {
|
||||
try {
|
||||
return install( new FlatArcDarkOrangeIJTheme() );
|
||||
} catch( RuntimeException ex ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public FlatArcDarkOrangeIJTheme() {
|
||||
super( Utils.loadTheme( "arc_theme_dark_orange.theme.json" ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.intellijthemes;
|
||||
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCarbonIJTheme
|
||||
extends IntelliJTheme.ThemeLaf
|
||||
{
|
||||
public static boolean install( ) {
|
||||
try {
|
||||
return install( new FlatCarbonIJTheme() );
|
||||
} catch( RuntimeException ex ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public FlatCarbonIJTheme() {
|
||||
super( Utils.loadTheme( "Carbon.theme.json" ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.intellijthemes;
|
||||
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCobalt2IJTheme
|
||||
extends IntelliJTheme.ThemeLaf
|
||||
{
|
||||
public static boolean install( ) {
|
||||
try {
|
||||
return install( new FlatCobalt2IJTheme() );
|
||||
} catch( RuntimeException ex ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public FlatCobalt2IJTheme() {
|
||||
super( Utils.loadTheme( "Cobalt_2.theme.json" ) );
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,6 @@ public class FlatSolarizedDarkIJTheme
|
||||
}
|
||||
|
||||
public FlatSolarizedDarkIJTheme() {
|
||||
super( Utils.loadTheme( "solarized_dark_theme.theme.json" ) );
|
||||
super( Utils.loadTheme( "SolarizedDark.theme.json" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,6 @@ public class FlatSolarizedLightIJTheme
|
||||
}
|
||||
|
||||
public FlatSolarizedLightIJTheme() {
|
||||
super( Utils.loadTheme( "solarized_light_theme.theme.json" ) );
|
||||
super( Utils.loadTheme( "SolarizedLight.theme.json" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
@@ -0,0 +1,353 @@
|
||||
{
|
||||
"name": "Carbon",
|
||||
"dark": true,
|
||||
"author": "Luis Fernando Jimenez",
|
||||
"editorScheme": "/themes/Carbon.xml",
|
||||
"ui": {
|
||||
"*": {
|
||||
"foreground": "#bac8cb",
|
||||
"background": "#172030",
|
||||
"borderColor": "#213047",
|
||||
"disabledBorderColor": "#586e75",
|
||||
"selectionBackground": "#0A677A",
|
||||
"selectionForeground": "#fdf6e3",
|
||||
"selectionInactiveBackground": "#1E2A3E",
|
||||
"selectionBackgroundInactive": "#1E2A3E",
|
||||
"lightSelectionBackground": "#074855",
|
||||
"lightSelectionForeground": "#839496",
|
||||
"lightSelectionInactiveBackground": "#073642",
|
||||
"lightSelectionInactiveForeground": "#839496",
|
||||
"separatorColor": "#213047",
|
||||
"lineSeparatorColor": "#213047",
|
||||
"disabledBackground": "#1E2A3E",
|
||||
"inactiveBackground": "#1E2A3E",
|
||||
"disabledForeground": "#657778",
|
||||
"disabledText": "#657778",
|
||||
"inactiveForeground": "#657778",
|
||||
"acceleratorForeground": "#abb9bc",
|
||||
"acceleratorSelectionForeground": "#abb9bc"
|
||||
},
|
||||
|
||||
"ActionButton": {
|
||||
"hoverBackground": "26354f",
|
||||
"hoverBorderColor": "#074855",
|
||||
"pressedBackground": "#074855",
|
||||
"pressedBorderColor": "#074855"
|
||||
},
|
||||
|
||||
"Borders": {
|
||||
"color": "#213047",
|
||||
"ContrastBorderColor": "#213047"
|
||||
},
|
||||
|
||||
"Button": {
|
||||
"startBackground": "#074855",
|
||||
"endBackground": "#074855",
|
||||
"startBorderColor": "#93a1a1",
|
||||
"endBorderColor": "#93a1a1",
|
||||
"default": {
|
||||
"foreground": "#fdf6e3",
|
||||
"startBackground": "#0A677A",
|
||||
"endBackground": "#0A677A",
|
||||
"startBorderColor": "#0A677Ac3",
|
||||
"endBorderColor": "#0A677Ac3",
|
||||
"focusedBorderColor": "#839496",
|
||||
"focusColor": "#778282"
|
||||
}
|
||||
},
|
||||
|
||||
"ComboBox": {
|
||||
"nonEditableBackground": "#1e2a3e",
|
||||
"background": "#1e2a3e",
|
||||
"ArrowButton": {
|
||||
"iconColor": "#a3aaa9",
|
||||
"disabledIconColor": "#839496",
|
||||
"nonEditableBackground": "#1e2a3e"
|
||||
}
|
||||
},
|
||||
|
||||
"ComboPopup.border": "1,1,1,1,213047",
|
||||
|
||||
"CompletionPopup": {
|
||||
"matchForeground": "#02858E"
|
||||
},
|
||||
|
||||
"Component": {
|
||||
"errorFocusColor": "#bf616a",
|
||||
"focusColor": "#0c9294",
|
||||
"focusedBorderColor": "#0c9294",
|
||||
"focusWidth": 2,
|
||||
"inactiveErrorFocusColor": "#bf616a",
|
||||
"inactiveWarningFocusColor": "#8f9544",
|
||||
"infoForeground": "#bac8cb",
|
||||
"warningFocusColor": "#8f9544"
|
||||
},
|
||||
|
||||
"Counter": {
|
||||
"background": "#0A677A",
|
||||
"foreground": "#bac8cb"
|
||||
},
|
||||
|
||||
"DefaultTabs": {
|
||||
"underlineColor": "#2aa198",
|
||||
"hoverBackground": "#1E2A3E",
|
||||
"inactiveUnderlineColor": "#446a73"
|
||||
},
|
||||
|
||||
"DragAndDrop": {
|
||||
"areaForeground": "#bac8cb",
|
||||
"areaBackground": "#1E2A3E",
|
||||
"areaBorderColor": "#213047"
|
||||
},
|
||||
|
||||
"Editor": {
|
||||
"background": "#172030",
|
||||
"foreground": "#bac8cb",
|
||||
"shortcutForeground": "#2aa198"
|
||||
},
|
||||
|
||||
"EditorPane.inactiveBackground": "#1E2A3E",
|
||||
|
||||
"EditorTabs": {
|
||||
"underlineColor": "#2aa198",
|
||||
"borderColor": "#213047",
|
||||
"underlinedTabBackground": "#1E2A3E",
|
||||
"hoverMaskColor": "#1E2A3E"
|
||||
},
|
||||
|
||||
"FileColor": {
|
||||
"Yellow": "#1b2f41",
|
||||
"Rose": "#bf616a",
|
||||
"Green": "#112634"
|
||||
},
|
||||
|
||||
"Group.disabledSeparatorColor": "#213047",
|
||||
|
||||
"InplaceRefactoringPopup.borderColor": "#213047",
|
||||
|
||||
"Link": {
|
||||
"activeForeground": "#0a7285",
|
||||
"hoverForeground": "#0a7285",
|
||||
"pressedForeground": "#0a7285",
|
||||
"visitedForeground": "#0a7285",
|
||||
"secondaryForeground": "#75BAB5"
|
||||
},
|
||||
|
||||
"Label.errorForeground": "#af304a",
|
||||
|
||||
"NavBar.borderColor": "#213047",
|
||||
|
||||
"Notification": {
|
||||
"background": "#1E2A3E",
|
||||
"borderColor": "#586E75",
|
||||
"errorForeground": "#bac8cb",
|
||||
"errorBackground": "#4d232e",
|
||||
"errorBorderColor": "#802e44",
|
||||
"MoreButton": {
|
||||
"background": "#1E2A3E",
|
||||
"foreground": "#bac8cb",
|
||||
"innerBorderColor": "#213047"
|
||||
},
|
||||
"ToolWindow": {
|
||||
"informativeForeground": "#bac8cb",
|
||||
"informativeBackground": "#074855",
|
||||
"informativeBorderColor": "#213047",
|
||||
"warningForeground": "#bac8cb",
|
||||
"warningBackground": "#8d8d55",
|
||||
"warningBorderColor": "#213047",
|
||||
"errorForeground": "#bac8cb",
|
||||
"errorBackground": "#802d43",
|
||||
"errorBorderColor": "#4d1c2b"
|
||||
}
|
||||
},
|
||||
|
||||
"ParameterInfo": {
|
||||
"background": "#1E2A3E",
|
||||
"foreground": "#bac8cb",
|
||||
"infoForeground": "ababb3",
|
||||
"currentOverloadBackground": "#1E2A3E",
|
||||
"currentParameterForeground": "#02858e"
|
||||
},
|
||||
|
||||
"Plugins": {
|
||||
"Tab": {
|
||||
"selectedForeground": "#bac8cb",
|
||||
"selectedBackground": "#074855",
|
||||
"hoverBackground": "#1E2A3E"
|
||||
},
|
||||
"eapTagBackground": "#02858e",
|
||||
"SectionHeader.background": "#1E2A3E",
|
||||
"tagBackground": "#1E2A3E",
|
||||
"tagForeground": "#bac8cb",
|
||||
"Button": {
|
||||
"installForeground": "#bac8cb",
|
||||
"installBorderColor": "#02858e",
|
||||
"installFillForeground": "#bac8cb",
|
||||
"installFillBackground": "#172030",
|
||||
"updateForeground": "#bac8cb",
|
||||
"updateBackground": "#02858e",
|
||||
"updateBorderColor": "#213047"
|
||||
},
|
||||
"lightSelectionBackground": "#1E2A3E"
|
||||
},
|
||||
|
||||
"Popup": {
|
||||
"paintBorder": true,
|
||||
"borderColor": "#213047",
|
||||
"inactiveBorderColor": "#213047",
|
||||
"Toolbar.borderColor": "#213047",
|
||||
"Header.activeBackground": "#172030",
|
||||
"Header.inactiveBackground": "#172030",
|
||||
"separatorForeground": "#213047",
|
||||
"Advertiser": {
|
||||
"foreground": "#bac8cb",
|
||||
"borderColor": "#213047",
|
||||
"borderInsets": "4,8,3,0"
|
||||
}
|
||||
},
|
||||
|
||||
"PopupMenu": {
|
||||
"borderWidth": 1,
|
||||
"borderInsets": "1,1,1,1"
|
||||
},
|
||||
|
||||
"ProgressBar": {
|
||||
"trackColor": "#1E2A3E",
|
||||
"progressColor": "#029098",
|
||||
"indeterminateStartColor": "#02858e",
|
||||
"indeterminateEndColor": "#2cb0a7",
|
||||
"failedColor": "#ff4262",
|
||||
"failedEndColor": "#a12a3e",
|
||||
"passedColor": "#2cb0a7",
|
||||
"passedEndColor": "#026d76"
|
||||
},
|
||||
|
||||
"SearchEverywhere": {
|
||||
"Header.background": "#1E2A3E",
|
||||
"Tab": {
|
||||
"selectedForeground": "#bac8cb",
|
||||
"selectedBackground": "#074855"
|
||||
},
|
||||
"SearchField": {
|
||||
"background": "#172030",
|
||||
"borderColor": "#213047"
|
||||
},
|
||||
"Advertiser.foreground": "#bac8cb"
|
||||
},
|
||||
|
||||
"SearchMatch": {
|
||||
"startBackground": "#e1e797",
|
||||
"endBackground": "#e1e797"
|
||||
},
|
||||
|
||||
"SpeedSearch": {
|
||||
"foreground": "#bac8cb",
|
||||
"borderColor": "#213047",
|
||||
"background": "#1E2A3E",
|
||||
"errorForeground": "#e0555e"
|
||||
},
|
||||
|
||||
"SplitPane.background": "#172030",
|
||||
|
||||
"StatusBar.borderColor": "#213047",
|
||||
|
||||
"Table": {
|
||||
"foreground": "#bac8cb",
|
||||
"background": "#172030",
|
||||
"stripeColor": "#1E2A3E",
|
||||
"selectionForeground": "#fdf6e3",
|
||||
"selectionBackground": "#074855",
|
||||
"focusCellForeground": "#fdf6e3",
|
||||
"dropLineColor": "#213047",
|
||||
"gridColor": "#213047",
|
||||
"lightSelectionInactiveForeground": "#bac8cb",
|
||||
"lightSelectionForeground": "#bac8cb",
|
||||
"selectionInactiveForeground": "#bac8cb",
|
||||
"lightSelectionBackground": "#074855",
|
||||
"lightSelectionInactiveBackground": "#063944"
|
||||
},
|
||||
|
||||
"TabbedPane": {
|
||||
"hoverColor": "#1E2A3E",
|
||||
"underlineColor": "#0A677A",
|
||||
"disabledUnderlineColor": "#5e5b6b",
|
||||
"contentAreaColor": "#213047"
|
||||
},
|
||||
|
||||
"ToggleButton": {
|
||||
"onBackground": "#0A677A",
|
||||
"borderColor": "#213047"
|
||||
},
|
||||
|
||||
"ToolTip": {
|
||||
"background": "#172030",
|
||||
"Actions.background": "#1E2A3E"
|
||||
},
|
||||
|
||||
"ToolWindow": {
|
||||
"Header": {
|
||||
"background": "#1E2A3E",
|
||||
"inactiveBackground": "#1E2A3E"
|
||||
},
|
||||
"HeaderTab": {
|
||||
"selectedBackground": "#1E2A3E",
|
||||
"hoverBackground": "#1E2A3E",
|
||||
"selectedInactiveBackground": "#1E2A3E",
|
||||
"hoverInactiveBackground": "#1E2A3E"
|
||||
},
|
||||
"Button": {
|
||||
"selectedBackground": "#1E2A3E",
|
||||
"hoverBackground": "#1E2A3E"
|
||||
}
|
||||
},
|
||||
|
||||
"Tree.rowHeight": 22,
|
||||
|
||||
"VersionControl": {
|
||||
"GitLog.localBranchIconColor": "#02858e",
|
||||
"GitLog.remoteBranchIconColor": "#214760",
|
||||
"Log.Commit.currentBranchBackground": "#1e2a3e",
|
||||
"FileHistory.Commit.selectedBranchBackground": "#3f5d6e"
|
||||
},
|
||||
|
||||
"Viewport.background": "#172030",
|
||||
|
||||
"WelcomeScreen.background": "#172030",
|
||||
|
||||
"WelcomeScreen": {
|
||||
"Projects.selectionInactiveBackground": "#172030",
|
||||
"separatorColor": "#172030"
|
||||
}
|
||||
},
|
||||
|
||||
"icons": {
|
||||
"ColorPalette": {
|
||||
"Actions.Red": "#ff4262",
|
||||
"Actions.Green": "#52b455",
|
||||
"Actions.Grey": "#bac8cb",
|
||||
"Actions.Yellow": "#e1e797",
|
||||
"Actions.Blue": "#44a6d2",
|
||||
"Actions.GreyInline.Dark": "#9f99bfb3",
|
||||
"Objects.Grey": "#808C97",
|
||||
"Objects.RedStatus": "#af304a",
|
||||
"Objects.Red": "#c6455a",
|
||||
"Objects.Pink": "#f98b9e",
|
||||
"Objects.Yellow": "#e1e797",
|
||||
"Objects.Green": "#27b26f",
|
||||
"Objects.Blue": "#2F7A99",
|
||||
"Objects.Purple": "#B692CE",
|
||||
"Objects.BlackText": "#0b1015",
|
||||
"Objects.YellowDark": "#acaf44",
|
||||
"Objects.GreenAndroid": "#78c257",
|
||||
"Checkbox.Background.Default.Dark": "#1E2A3E",
|
||||
"Checkbox.Border.Default.Dark": "#586e75",
|
||||
"Checkbox.Foreground.Selected.Dark": "#bac8cb",
|
||||
"Checkbox.Focus.Wide.Dark": "#93a1a1",
|
||||
"Checkbox.Focus.Thin.Default.Dark": "#839496",
|
||||
"Checkbox.Focus.Thin.Selected.Dark": "#839496",
|
||||
"Checkbox.Background.Disabled.Dark": "#1a2334",
|
||||
"Checkbox.Border.Disabled.Dark": "#657778",
|
||||
"Checkbox.Foreground.Disabled.Dark": "#657778"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright 2019 Tyler B. Thrailkill
|
||||
Copyright 2020 Nicolas Gehlert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
{
|
||||
"name": "Cobalt 2",
|
||||
"author": "Nicolas Gehlert <info@ngehlert.de>",
|
||||
"dark": true,
|
||||
"editorScheme": "/Cobalt_2.xml",
|
||||
"colors": {
|
||||
"basicBackground": "#002946",
|
||||
"secondaryBackground": "#001b36",
|
||||
"borderColor": "#545454",
|
||||
"hue1": "#003854",
|
||||
"hue2": "#003f5e",
|
||||
"hue3": "#267DA2",
|
||||
"contrast": "#ff9d00",
|
||||
"contrastHue1": "#9a5000",
|
||||
"textColor": "#FFF0C7"
|
||||
},
|
||||
"ui": {
|
||||
"*": {
|
||||
"background": "basicBackground",
|
||||
"foreground": "textColor",
|
||||
"selectionBackground": "hue2"
|
||||
},
|
||||
"ActionButton": {
|
||||
"pressedBackground": "hue3",
|
||||
"pressedBorderColor": "hue3",
|
||||
"hoverBackground": "hue2",
|
||||
"hoverBorderColor": "hue2"
|
||||
},
|
||||
"CompletionPopup": {
|
||||
"selectionBackground": "basicBackground"
|
||||
},
|
||||
"Borders": {
|
||||
"ContrastBorderColor": "borderColor",
|
||||
"color": "borderColor"
|
||||
},
|
||||
"Button": {
|
||||
"background": "secondaryBackground",
|
||||
"startBackground": "hue3",
|
||||
"endBackground": "hue2",
|
||||
"startBorderColor": "hue3",
|
||||
"endBorderColor": "hue2",
|
||||
"default": {
|
||||
"startBackground": "contrast",
|
||||
"endBackground": "contrastHue1",
|
||||
"startBorderColor": "contrast",
|
||||
"endBorderColor": "contrastHue1"
|
||||
}
|
||||
},
|
||||
"CheckBox": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"CheckBoxMenuItem": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ColorChooser": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ComboBox": {
|
||||
"ArrowButton": {
|
||||
"background": "basicBackground",
|
||||
"nonEditableBackground": "basicBackground"
|
||||
},
|
||||
"background": "secondaryBackground",
|
||||
"foreground": "textColor",
|
||||
"nonEditableBackground": "secondaryBackground"
|
||||
},
|
||||
"DefaultTabs": {
|
||||
"background": "secondaryBackground",
|
||||
"borderColor": "borderColor",
|
||||
"hoverBackground": "hue1"
|
||||
},
|
||||
"EditorTabs": {
|
||||
"background": "secondaryBackground",
|
||||
"borderColor": "borderColor",
|
||||
"underlinedTabBackground": "hue1"
|
||||
},
|
||||
"Link": {
|
||||
"activeForeground": "contrast",
|
||||
"hoverForeground": "contrast",
|
||||
"visitedForeground": "contrast"
|
||||
},
|
||||
"Label": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"List": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"Menu": {
|
||||
"background": "secondaryBackground",
|
||||
"foreground": "textColor"
|
||||
},
|
||||
"MenuBar": {
|
||||
"disabledBackground": "secondaryBackground"
|
||||
},
|
||||
"OptionPane": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"Panel": {
|
||||
"background": "secondaryBackground",
|
||||
"foreground": "textColor"
|
||||
},
|
||||
"PasswordField": {
|
||||
"background": "secondaryBackground",
|
||||
"selectionBackground": "secondaryBackground"
|
||||
},
|
||||
"Popup": {
|
||||
"Toolbar.background": "basicBackground"
|
||||
},
|
||||
"PopupMenu": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ProgressBar": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"Plugins": {
|
||||
"lightSelectionBackground": "hue2"
|
||||
},
|
||||
"RadioButton": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"RadioButtonMenuItem": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ScrollBar": {
|
||||
"background": "hue1"
|
||||
},
|
||||
"ScrollPane": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"Slider": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"Spinner": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"SplitPane": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"TabbedPane": {
|
||||
"background": "secondaryBackground",
|
||||
"contentAreaColor": "borderColor"
|
||||
},
|
||||
"TextField": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"TextPane": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ToggleButton": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ToolBar": {
|
||||
"background": "secondaryBackground"
|
||||
},
|
||||
"ToolTip": {
|
||||
"background": "hue2"
|
||||
},
|
||||
"ToolWindow": {
|
||||
"Header.background": "basicBackground",
|
||||
"Header.borderColor": "borderColor",
|
||||
"Header.inactiveBackground": "secondaryBackground"
|
||||
},
|
||||
"Tree": {
|
||||
"background": "basicBackground",
|
||||
"modifiedItemForeground": "contrast"
|
||||
},
|
||||
"Viewport": {
|
||||
"background": "secondaryBackground"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"ColorPalette": {
|
||||
"Checkbox.Background.Default.Dark": "#002946",
|
||||
"Checkbox.Background.Default": "#002946",
|
||||
"Checkbox.Background.Selected.Dark": "#FF9D00",
|
||||
"Checkbox.Background.Selected": "#FF9D00",
|
||||
"Checkbox.Foreground.Selected.Dark": "#002240",
|
||||
"Checkbox.Foreground.Selected": "#002240"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user