mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-09 16:25:10 +03:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27f9614633 | ||
|
|
2211cc5596 | ||
|
|
46f0393648 | ||
|
|
b4c1a97687 | ||
|
|
adcef385b0 | ||
|
|
48e38b2855 | ||
|
|
2cc8327a08 | ||
|
|
404e80082c | ||
|
|
3fbc21347a | ||
|
|
d76f0e2241 | ||
|
|
e5fcc59805 | ||
|
|
de82dac873 | ||
|
|
a14ef72177 | ||
|
|
6ee5234351 | ||
|
|
398a041ddf | ||
|
|
02bb73c335 | ||
|
|
f37c4cdc4d | ||
|
|
d5c9bcddc8 | ||
|
|
f3f8c81518 | ||
|
|
a99ffd4821 | ||
|
|
7b5a9d9949 | ||
|
|
feb8d0591e | ||
|
|
2197808631 | ||
|
|
36b3ccc34f | ||
|
|
a5b69d712c | ||
|
|
8edcca9745 | ||
|
|
f3b1f4b608 | ||
|
|
879a8aaa6d | ||
|
|
900d005d89 | ||
|
|
c8225171a3 | ||
|
|
c513c052fc | ||
|
|
711c4dd2b5 | ||
|
|
81f1ebd1db | ||
|
|
c722934510 | ||
|
|
3ffe8e225d | ||
|
|
6d86cf8f9c | ||
|
|
e6e19110b2 | ||
|
|
b5c13bd1b3 | ||
|
|
b129fe437c | ||
|
|
645be4bfa3 | ||
|
|
321c49ee32 | ||
|
|
84db2f9b65 | ||
|
|
6ba1a419bc | ||
|
|
3de329a332 | ||
|
|
f175c36736 | ||
|
|
f1de65b471 | ||
|
|
5069013e6e | ||
|
|
c0642ed620 | ||
|
|
a145673dd1 | ||
|
|
223af48c09 | ||
|
|
d72cfc37d6 | ||
|
|
3ba8133890 | ||
|
|
a907cd7f46 | ||
|
|
3b740cb494 | ||
|
|
0f0f21a7b1 | ||
|
|
537f6703c0 | ||
|
|
da0c562ac2 | ||
|
|
0bef71907c | ||
|
|
0ebd43bc5f | ||
|
|
3092fced3c | ||
|
|
a02784fcba | ||
|
|
924abde89e | ||
|
|
f011468819 | ||
|
|
11f459d5b0 | ||
|
|
974f7d5d68 | ||
|
|
e60db4ff90 | ||
|
|
ebe1cd3367 | ||
|
|
30db9d13a5 | ||
|
|
368611359c | ||
|
|
746918c054 |
37
CHANGELOG.md
37
CHANGELOG.md
@@ -1,6 +1,43 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 0.21
|
||||
|
||||
- ScrollBar: Show decrease/increase arrow buttons if client property
|
||||
"JScrollBar.showButtons" is set to `true` on `JScrollPane` or `JScrollBar`.
|
||||
(issue #25)
|
||||
- `FlatLaf.isNativeLookAndFeel()` now returns `false`.
|
||||
- Button: Optionally support gradient borders, gradient backgrounds and shadows
|
||||
for improved compatibility with IntelliJ platform themes (e.g. for Vuesion,
|
||||
Spacegray and Material Design Dark themes).
|
||||
- Button: Fixed help button styling in IntelliJ platform themes.
|
||||
- ScrollPane: Paint disabled border if view component (e.g. JTextPane) is
|
||||
disabled.
|
||||
- Fixed Swing system colors in dark themes.
|
||||
|
||||
|
||||
## 0.20
|
||||
|
||||
- Support using IntelliJ platform themes (.theme.json files).
|
||||
- Support `JFileChooser`. (issue #5)
|
||||
- Look and feel identifier returned by `FlatLaf.getID()` now always starts with
|
||||
"FlatLaf". Use `UIManager.getLookAndFeel().getID().startsWith( "FlatLaf" )` to
|
||||
check whether the current look and feel is FlatLaf.
|
||||
- Fixed selection background of checkbox in table cell.
|
||||
- Fixed color of links in HTML text.
|
||||
- Fixed jittery submenu rendering on Mac. (issue #10)
|
||||
- Fixed "cannot find symbol" error in NetBeans editor, when source/binary format
|
||||
is set to JDK 9 (or later) in NetBeans project. (issue #13)
|
||||
- Button: Make button square if button text is "..." or a single character.
|
||||
- ComboBox: Fixed issues with NetBeans `org.openide.awt.ColorComboBox`
|
||||
component.
|
||||
- Hex color values in `.properties` files now must start with a `#` character.
|
||||
- SwingX: Support `JXTitledPanel`. (issue #22)
|
||||
- SwingX: Fixed too wide border when using date picker as table cell editor.
|
||||
(issue #24)
|
||||
- JIDE Common Layer: Fixed `JidePopup` border.
|
||||
|
||||
|
||||
## 0.18
|
||||
|
||||
- TextField and TextArea: Do not apply minimum width if `columns` property is
|
||||
|
||||
14
README.md
14
README.md
@@ -16,6 +16,16 @@ IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
|
||||

|
||||
|
||||
|
||||
IntelliJ Platform Themes
|
||||
------------------------
|
||||
|
||||
FlatLaf can use 3rd party themes created for IntelliJ Platform:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||
@@ -35,7 +45,7 @@ build script:
|
||||
|
||||
groupId: com.formdev
|
||||
artifactId: flatlaf
|
||||
version: 0.18
|
||||
version: 0.21
|
||||
|
||||
Otherwise download `flatlaf-<version>.jar` here:
|
||||
|
||||
@@ -46,7 +56,7 @@ Addons
|
||||
------
|
||||
|
||||
- [SwingX](flatlaf-swingx)
|
||||
- [JIDE Common Layer](https://github.com/jidesoft/jide-oss)
|
||||
- [JIDE Common Layer](flatlaf-jide-oss)
|
||||
|
||||
|
||||
Documentation
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
version = "0.18"
|
||||
version = "0.21"
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
|
||||
4
flatlaf-core/README.md
Normal file
4
flatlaf-core/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
FlatLaf Core
|
||||
============
|
||||
|
||||
This sub-project contains the FlatLaf core source code.
|
||||
@@ -35,8 +35,8 @@ if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
tasks {
|
||||
@@ -58,12 +58,7 @@ tasks {
|
||||
archiveBaseName.set( "flatlaf" )
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
manifest.attributes(
|
||||
"Multi-Release" to "true"
|
||||
)
|
||||
|
||||
into( "META-INF/versions/9" ) {
|
||||
from( sourceSets["module-info"].output )
|
||||
from( sourceSets["module-info"].output ) {
|
||||
include( "module-info.class" )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,52 @@ import javax.swing.JComponent;
|
||||
*/
|
||||
public interface FlatClientProperties
|
||||
{
|
||||
/**
|
||||
* Specifies type of a button.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JButton}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||
* <strong>Allowed Values</strong> {@link BUTTON_TYPE_HELP}
|
||||
*/
|
||||
String BUTTON_TYPE = "JButton.buttonType";
|
||||
|
||||
/**
|
||||
* Paint a help button (circle with question mark).
|
||||
*
|
||||
* @see #BUTTON_TYPE
|
||||
*/
|
||||
String BUTTON_TYPE_HELP = "help";
|
||||
|
||||
/**
|
||||
* Specifies selected state of a checkbox.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JCheckBox}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||
* <strong>Allowed Values</strong> {@link SELECTED_STATE_INDETERMINATE}
|
||||
*/
|
||||
String SELECTED_STATE = "JButton.selectedState";
|
||||
|
||||
/**
|
||||
* Paint an indeterminate state on a checkbox.
|
||||
*
|
||||
* @see #SELECTED_STATE
|
||||
*/
|
||||
String SELECTED_STATE_INDETERMINATE = "indeterminate";
|
||||
|
||||
/**
|
||||
* Specifies whether the decrease/increase arrow buttons of a scrollbar are shown.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JScrollBar} or {@link javax.swing.JScrollPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String SCROLL_BAR_SHOW_BUTTONS = "JScrollBar.showButtons";
|
||||
|
||||
/**
|
||||
* Specifies whether a full border is painted around a tabbed pane.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder";
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,17 +29,21 @@ import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
@@ -59,6 +63,8 @@ public abstract class FlatLaf
|
||||
private KeyEventPostProcessor mnemonicListener;
|
||||
private static boolean altKeyPressed;
|
||||
|
||||
private Consumer<UIDefaults> postInitialization;
|
||||
|
||||
public static boolean install( LookAndFeel newLookAndFeel ) {
|
||||
try {
|
||||
UIManager.setLookAndFeel( newLookAndFeel );
|
||||
@@ -69,16 +75,24 @@ public abstract class FlatLaf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the look and feel identifier.
|
||||
* <p>
|
||||
* Syntax: "FlatLaf - ${theme-name}"
|
||||
* <p>
|
||||
* Use {@code UIManager.getLookAndFeel().getID().startsWith( "FlatLaf" )}
|
||||
* to check whether the current look and feel is FlatLaf.
|
||||
*/
|
||||
@Override
|
||||
public String getID() {
|
||||
return getName();
|
||||
return "FlatLaf - " + getName();
|
||||
}
|
||||
|
||||
public abstract boolean isDark();
|
||||
|
||||
@Override
|
||||
public boolean isNativeLookAndFeel() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,6 +106,11 @@ public abstract class FlatLaf
|
||||
|
||||
super.initialize();
|
||||
|
||||
// make sure that a plain popup factory is used (otherwise sub-menu rendering
|
||||
// is "jittery" on Mac, where AquaLookAndFeel installs its own popup factory)
|
||||
if( PopupFactory.getSharedInstance().getClass() != PopupFactory.class )
|
||||
PopupFactory.setSharedInstance( new PopupFactory() );
|
||||
|
||||
// add mnemonic listener
|
||||
mnemonicListener = e -> {
|
||||
if( e.getKeyCode() == KeyEvent.VK_ALT )
|
||||
@@ -117,6 +136,18 @@ public abstract class FlatLaf
|
||||
};
|
||||
Toolkit.getDefaultToolkit().addPropertyChangeListener( desktopPropertyName, desktopPropertyListener );
|
||||
}
|
||||
|
||||
// Following code should be ideally in initialize(), but needs color from UI defaults.
|
||||
// Do not move this code to getDefaults() to avoid side effects in the case that
|
||||
// getDefaults() is directly invoked from 3rd party code. E.g. `new FlatLightLaf().getDefaults()`.
|
||||
postInitialization = defaults -> {
|
||||
// update link color in HTML text
|
||||
Color linkColor = defaults.getColor( "Component.linkColor" );
|
||||
if( linkColor != null ) {
|
||||
new HTMLEditorKit().getStyleSheet().addRule(
|
||||
String.format( "a { color: #%06x; }", linkColor.getRGB() & 0xffffff ) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,6 +165,10 @@ public abstract class FlatLaf
|
||||
mnemonicListener = null;
|
||||
}
|
||||
|
||||
// restore default link color
|
||||
new HTMLEditorKit().getStyleSheet().addRule( "a { color: blue; }" );
|
||||
postInitialization = null;
|
||||
|
||||
if( base != null )
|
||||
base.uninitialize();
|
||||
|
||||
@@ -164,6 +199,9 @@ public abstract class FlatLaf
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults defaults = getBase().getDefaults();
|
||||
|
||||
// add Metal resource bundle, which is required for FlatFileChooserUI
|
||||
defaults.addResourceBundle( "com.sun.swing.internal.plaf.metal.resources.metal" );
|
||||
|
||||
// initialize some defaults (for overriding) that are used in basic UI delegates,
|
||||
// but are not set in MetalLookAndFeel or BasicLookAndFeel
|
||||
Color control = defaults.getColor( "control" );
|
||||
@@ -186,15 +224,31 @@ public abstract class FlatLaf
|
||||
Object aquaMenuBarUI = useScreenMenuBar ? defaults.get( "MenuBarUI" ) : null;
|
||||
|
||||
initFonts( defaults );
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), defaults );
|
||||
initIconColors( defaults, isDark() );
|
||||
|
||||
// load defaults from properties
|
||||
List<Class<?>> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading();
|
||||
if( lafClassesForDefaultsLoading != null )
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, defaults );
|
||||
else
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), defaults );
|
||||
|
||||
// use Aqua MenuBarUI if Mac screen menubar is enabled
|
||||
if( useScreenMenuBar )
|
||||
defaults.put( "MenuBarUI", aquaMenuBarUI );
|
||||
|
||||
if( postInitialization != null ) {
|
||||
postInitialization.accept( defaults );
|
||||
postInitialization = null;
|
||||
}
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
List<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void initFonts( UIDefaults defaults ) {
|
||||
FontUIResource uiFont = null;
|
||||
|
||||
@@ -231,8 +285,43 @@ public abstract class FlatLaf
|
||||
defaults.put( "MenuItem.acceleratorFont", uiFont );
|
||||
}
|
||||
|
||||
public static List<String> split( String str, char delim ) {
|
||||
return UIDefaultsLoader.split( str, delim );
|
||||
/**
|
||||
* Adds the default color palette for action icons and object icons to the given UIDefaults.
|
||||
* <p>
|
||||
* This method is public and static to allow using the color palette with
|
||||
* other LaFs (e.g. Windows LaF). To do so invoke:
|
||||
* {@code FlatLaf.initIconColors( UIManager.getLookAndFeelDefaults(), false );}
|
||||
* after
|
||||
* {@code UIManager.setLookAndFeel( ... );}.
|
||||
* <p>
|
||||
* The colors are based on IntelliJ Platform
|
||||
* <a href="https://jetbrains.design/intellij/principles/icons/#action-icons">Action icons</a>
|
||||
* and
|
||||
* <a href="https://jetbrains.design/intellij/principles/icons/#noun-icons">Noun icons</a>
|
||||
*/
|
||||
public static void initIconColors( UIDefaults defaults, boolean dark ) {
|
||||
// colors for action icons
|
||||
// see https://jetbrains.design/intellij/principles/icons/#action-icons
|
||||
defaults.put( "Actions.Red", new ColorUIResource( !dark ? 0xDB5860 : 0xC75450 ) );
|
||||
defaults.put( "Actions.Yellow", new ColorUIResource( !dark ? 0xEDA200 : 0xF0A732 ) );
|
||||
defaults.put( "Actions.Green", new ColorUIResource( !dark ? 0x59A869 : 0x499C54 ) );
|
||||
defaults.put( "Actions.Blue", new ColorUIResource( !dark ? 0x389FD6 : 0x3592C4 ) );
|
||||
defaults.put( "Actions.Grey", new ColorUIResource( !dark ? 0x6E6E6E : 0xAFB1B3 ) );
|
||||
defaults.put( "Actions.GreyInline", new ColorUIResource( !dark ? 0x7F8B91 : 0x7F8B91 ) );
|
||||
|
||||
// colors for object icons
|
||||
// see https://jetbrains.design/intellij/principles/icons/#noun-icons
|
||||
defaults.put( "Objects.Grey", new ColorUIResource( 0x9AA7B0 ) );
|
||||
defaults.put( "Objects.Blue", new ColorUIResource( 0x40B6E0 ) );
|
||||
defaults.put( "Objects.Green", new ColorUIResource( 0x62B543 ) );
|
||||
defaults.put( "Objects.Yellow", new ColorUIResource( 0xF4AF3D ) );
|
||||
defaults.put( "Objects.YellowDark", new ColorUIResource( 0xD9A343 ) );
|
||||
defaults.put( "Objects.Purple", new ColorUIResource( 0xB99BF8 ) );
|
||||
defaults.put( "Objects.Pink", new ColorUIResource( 0xF98B9E ) );
|
||||
defaults.put( "Objects.Red", new ColorUIResource( 0xF26522 ) );
|
||||
defaults.put( "Objects.RedStatus", new ColorUIResource( 0xE05555 ) );
|
||||
defaults.put( "Objects.GreenAndroid", new ColorUIResource( 0xA4C639 ) );
|
||||
defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) );
|
||||
}
|
||||
|
||||
private static void reSetLookAndFeel() {
|
||||
|
||||
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import com.formdev.flatlaf.json.Json;
|
||||
import com.formdev.flatlaf.json.ParseException;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
|
||||
/**
|
||||
* This class supports loading IntelliJ .theme.json files and using them as a Laf.
|
||||
*
|
||||
* .theme.json files are used by Theme plugins for IntelliJ IDEA and other
|
||||
* JetBrains IDEs that are based on IntelliJ platform.
|
||||
*
|
||||
* Here you can find IntelliJ Theme plugins:
|
||||
* https://plugins.jetbrains.com/search?tags=Theme
|
||||
*
|
||||
* The IntelliJ .theme.json file are documented here:
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class IntelliJTheme
|
||||
{
|
||||
public final String name;
|
||||
public final boolean dark;
|
||||
public final String author;
|
||||
|
||||
private final Map<String, String> colors;
|
||||
private final Map<String, Object> ui;
|
||||
private final Map<String, Object> icons;
|
||||
|
||||
private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream,
|
||||
* creates a Laf instance for it and installs it.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
public static boolean install( InputStream in ) {
|
||||
try {
|
||||
return FlatLaf.install( createLaf( in ) );
|
||||
} catch( Exception ex ) {
|
||||
System.err.println( "Failed to load IntelliJ theme" );
|
||||
ex.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream and
|
||||
* creates a Laf instance for it.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
public static FlatLaf createLaf( InputStream in )
|
||||
throws IOException, ParseException
|
||||
{
|
||||
return createLaf( new IntelliJTheme( in ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Laf instance for the given IntelliJ theme.
|
||||
*/
|
||||
public static FlatLaf createLaf( IntelliJTheme theme ) {
|
||||
return new ThemeLaf( theme );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream.
|
||||
*
|
||||
* The input stream is automatically closed.
|
||||
* Using a buffered input stream is not necessary.
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public IntelliJTheme( InputStream in )
|
||||
throws IOException, ParseException
|
||||
{
|
||||
Map<String, Object> json;
|
||||
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 ) ) {
|
||||
json = (Map<String, Object>) Json.parse( reader );
|
||||
}
|
||||
|
||||
name = (String) json.get( "name" );
|
||||
dark = Boolean.parseBoolean( (String) json.get( "dark" ) );
|
||||
author = (String) json.get( "author" );
|
||||
|
||||
colors = (Map<String, String>) json.get( "colors" );
|
||||
ui = (Map<String, Object>) json.get( "ui" );
|
||||
icons = (Map<String, Object>) json.get( "icons" );
|
||||
}
|
||||
|
||||
private void applyProperties( UIDefaults defaults ) {
|
||||
if( ui == null )
|
||||
return;
|
||||
|
||||
defaults.put( "Component.isIntelliJTheme", true );
|
||||
|
||||
// enable button shadows
|
||||
defaults.put( "Button.paintShadow", true );
|
||||
defaults.put( "Button.shadowWidth", dark ? 2 : 1 );
|
||||
|
||||
loadNamedColors( defaults );
|
||||
|
||||
// convert Json "ui" structure to UI defaults
|
||||
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
|
||||
Set<String> uiKeys = new HashSet<>();
|
||||
for( Map.Entry<String, Object> e : ui.entrySet() )
|
||||
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
|
||||
applyColorPalette( defaults );
|
||||
applyCheckBoxColors( defaults );
|
||||
|
||||
// IDEA uses a SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
||||
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
||||
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
||||
if( helpButtonBackground == null )
|
||||
helpButtonBackground = defaults.get( "Button.background" );
|
||||
if( helpButtonBorderColor == null )
|
||||
helpButtonBorderColor = defaults.get( "Button.borderColor" );
|
||||
defaults.put( "HelpButton.background", helpButtonBackground );
|
||||
defaults.put( "HelpButton.borderColor", helpButtonBorderColor );
|
||||
defaults.put( "HelpButton.disabledBackground", defaults.get( "Panel.background" ) );
|
||||
defaults.put( "HelpButton.disabledBorderColor", defaults.get( "Button.disabledBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
|
||||
|
||||
// IDEA uses TextField.background for editable ComboBox and Spinner
|
||||
defaults.put( "ComboBox.editableBackground", defaults.get( "TextField.background" ) );
|
||||
defaults.put( "Spinner.background", defaults.get( "TextField.background" ) );
|
||||
|
||||
// Spinner arrow button always has same colors as ComboBox arrow button
|
||||
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
|
||||
defaults.put( "Spinner.buttonArrowColor", defaults.get( "ComboBox.buttonArrowColor" ) );
|
||||
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
|
||||
|
||||
// some themes specify colors for TextField.background, but forget to specify it for other components
|
||||
// (probably because those components are not used in IntelliJ)
|
||||
if( uiKeys.contains( "TextField.background" ) ) {
|
||||
Object textFieldBackground = defaults.get( "TextField.background" );
|
||||
if( !uiKeys.contains( "FormattedTextField.background" ) )
|
||||
defaults.put( "FormattedTextField.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "PasswordField.background" ) )
|
||||
defaults.put( "PasswordField.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "EditorPane.background" ) )
|
||||
defaults.put( "EditorPane.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "TextArea.background" ) )
|
||||
defaults.put( "TextArea.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "TextPane.background" ) )
|
||||
defaults.put( "TextPane.background", textFieldBackground );
|
||||
if( !uiKeys.contains( "Spinner.background" ) )
|
||||
defaults.put( "Spinner.background", textFieldBackground );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#defining-named-colors
|
||||
*/
|
||||
private void loadNamedColors( UIDefaults defaults ) {
|
||||
if( colors == null )
|
||||
return;
|
||||
|
||||
namedColors = new HashMap<>();
|
||||
|
||||
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||
String value = e.getValue();
|
||||
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
||||
if( color != null ) {
|
||||
String key = e.getKey();
|
||||
namedColors.put( key, color );
|
||||
defaults.put( "ColorPalette." + e.getKey(), color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#custom-ui-control-colors
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
||||
if( value instanceof Map ) {
|
||||
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
||||
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
} else {
|
||||
uiKeys.add( key );
|
||||
|
||||
// map keys
|
||||
key = uiKeyMapping.getOrDefault( key, key );
|
||||
if( key.isEmpty() )
|
||||
return; // ignore key
|
||||
|
||||
String valueStr = value.toString();
|
||||
|
||||
// map named colors
|
||||
Object uiValue = namedColors.get( valueStr );
|
||||
|
||||
// parse value
|
||||
if( uiValue == null ) {
|
||||
// fix errors (missing '#' for colors)
|
||||
if( !valueStr.startsWith( "#" ) && (key.endsWith( "ground" ) || key.endsWith( "Color" )) )
|
||||
valueStr = fixColorIfValid( "#" + valueStr, valueStr );
|
||||
else if( valueStr.startsWith( "##" ) )
|
||||
valueStr = fixColorIfValid( valueStr.substring( 1 ), valueStr );
|
||||
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) ) {
|
||||
List<String> parts = StringUtils.split( valueStr, ',' );
|
||||
if( parts.size() == 5 && !parts.get( 4 ).startsWith( "#" ) ) {
|
||||
parts.set( 4, "#" + parts.get( 4 ) );
|
||||
valueStr = String.join( ",", parts );
|
||||
}
|
||||
}
|
||||
|
||||
// parse value
|
||||
try {
|
||||
uiValue = UIDefaultsLoader.parseValue( key, valueStr );
|
||||
} catch( RuntimeException ex ) {
|
||||
UIDefaultsLoader.logParseError( key, valueStr, ex );
|
||||
return; // ignore invalid value
|
||||
}
|
||||
}
|
||||
|
||||
if( key.startsWith( "*." ) ) {
|
||||
// wildcard
|
||||
String tail = key.substring( 1 );
|
||||
|
||||
// because we can not iterate over the UI defaults keys while
|
||||
// modifying UI defaults in the same loop, we have to copy the keys
|
||||
if( defaultsKeysCache.size() != defaults.size() ) {
|
||||
defaultsKeysCache.clear();
|
||||
Enumeration<Object> e = defaults.keys();
|
||||
while( e.hasMoreElements() )
|
||||
defaultsKeysCache.add( e.nextElement() );
|
||||
}
|
||||
|
||||
// replace all values in UI defaults that match the wildcard key
|
||||
for( Object k : defaultsKeysCache ) {
|
||||
if( k instanceof String ) {
|
||||
// support replacing of mapped keys
|
||||
// (e.g. set ComboBox.buttonEditableBackground to *.background
|
||||
// because it is mapped from ComboBox.ArrowButton.background)
|
||||
String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
|
||||
if( km.endsWith( tail ) && !noWildcardReplace.contains( k ) && !((String)k).startsWith( "CheckBox.icon." ) )
|
||||
defaults.put( k, uiValue );
|
||||
}
|
||||
}
|
||||
} else
|
||||
defaults.put( key, uiValue );
|
||||
}
|
||||
}
|
||||
|
||||
private String fixColorIfValid( String newColorStr, String colorStr ) {
|
||||
try {
|
||||
// check whether it is valid
|
||||
UIDefaultsLoader.parseColorRGBA( newColorStr );
|
||||
|
||||
return newColorStr;
|
||||
} catch( IllegalArgumentException ex ) {
|
||||
return colorStr;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyColorPalette( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||
continue;
|
||||
|
||||
if( dark )
|
||||
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
if( color != null )
|
||||
defaults.put( key, color );
|
||||
}
|
||||
}
|
||||
|
||||
private ColorUIResource toColor( String value ) {
|
||||
// map named colors
|
||||
ColorUIResource color = namedColors.get( value );
|
||||
|
||||
// parse color
|
||||
return (color != null) ? color : UIDefaultsLoader.parseColor( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Because IDEA uses SVGs for check boxes and radio buttons the colors for
|
||||
* this two components are specified in "icons > ColorPalette".
|
||||
* FlatLaf uses vector icons and expects colors for the two components in UI defaults.
|
||||
*/
|
||||
private void applyCheckBoxColors( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
boolean checkboxModified = false;
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( !key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||
continue;
|
||||
|
||||
if( key.equals( "Checkbox.Background.Default" ) ||
|
||||
key.equals( "Checkbox.Foreground.Selected" ) )
|
||||
{
|
||||
// This two keys do not work correctly in IDEA because they
|
||||
// map SVG color "#ffffff" to another color, but checkBox.svg and
|
||||
// radio.svg (in package com.intellij.ide.ui.laf.icons.intellij)
|
||||
// use "#fff". So use white to get same appearance as in IDEA.
|
||||
value = "#ffffff";
|
||||
}
|
||||
|
||||
if( dark )
|
||||
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||
|
||||
String newKey = checkboxKeyMapping.get( key );
|
||||
if( newKey != null ) {
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
if( color != null )
|
||||
defaults.put( newKey, color );
|
||||
|
||||
checkboxModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// When IDEA replaces colors in SVGs it uses color values and not the keys
|
||||
// from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that
|
||||
// have same color value:
|
||||
// - Checkbox.Background.Default.Dark has same color as Checkbox.Background.Selected.Dark
|
||||
// - Checkbox.Border.Default.Dark has same color as Checkbox.Border.Selected.Dark
|
||||
// - Checkbox.Focus.Thin.Default.Dark has same color as Checkbox.Focus.Thin.Selected.Dark
|
||||
//
|
||||
// So if only e.g. Checkbox.Background.Default.Dark is specified in .theme.json,
|
||||
// then this color is also used for Checkbox.Background.Selected.Dark.
|
||||
// Occurs e.g. in "Dark purple" theme.
|
||||
fixCheckBoxColor( defaults, colorPalette, "Checkbox.Background.Default.Dark", "Checkbox.Background.Selected.Dark" );
|
||||
fixCheckBoxColor( defaults, colorPalette, "Checkbox.Border.Default.Dark", "Checkbox.Border.Selected.Dark" );
|
||||
fixCheckBoxColor( defaults, colorPalette, "Checkbox.Focus.Thin.Default.Dark", "Checkbox.Focus.Thin.Selected.Dark" );
|
||||
|
||||
// remove hover and pressed colors
|
||||
if( checkboxModified ) {
|
||||
defaults.remove( "CheckBox.icon.hoverBorderColor" );
|
||||
defaults.remove( "CheckBox.icon.focusedBackground" );
|
||||
defaults.remove( "CheckBox.icon.hoverBackground" );
|
||||
defaults.remove( "CheckBox.icon.pressedBackground" );
|
||||
defaults.remove( "CheckBox.icon.selectedHoverBackground" );
|
||||
defaults.remove( "CheckBox.icon.selectedPressedBackground" );
|
||||
}
|
||||
}
|
||||
|
||||
private void fixCheckBoxColor( UIDefaults defaults, Map<String, Object> colorPalette, String key1, String key2 ) {
|
||||
if( colorPalette.containsKey( key1 ) == colorPalette.containsKey( key2 ) )
|
||||
return;
|
||||
|
||||
String newKey1 = checkboxKeyMapping.get( StringUtils.removeTrailing( key1, ".Dark" ) );
|
||||
String newKey2 = checkboxKeyMapping.get( StringUtils.removeTrailing( key2, ".Dark" ) );
|
||||
if( colorPalette.containsKey( key1 ) )
|
||||
defaults.put( newKey2, defaults.get( newKey1 ) );
|
||||
else
|
||||
defaults.put( newKey1, defaults.get( newKey2 ) );
|
||||
}
|
||||
|
||||
private static Map<String, String> uiKeyMapping = new HashMap<>();
|
||||
private static Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
||||
private static Map<String, String> checkboxKeyMapping = new HashMap<>();
|
||||
private static Set<String> noWildcardReplace = new HashSet<>();
|
||||
|
||||
static {
|
||||
// ComboBox
|
||||
uiKeyMapping.put( "ComboBox.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.background", "ComboBox.buttonEditableBackground" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.iconColor", "ComboBox.buttonArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.nonEditableBackground", "ComboBox.buttonBackground" );
|
||||
|
||||
// ProgressBar
|
||||
uiKeyMapping.put( "ProgressBar.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
|
||||
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
|
||||
|
||||
// ScrollBar
|
||||
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
|
||||
uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" );
|
||||
|
||||
// Slider
|
||||
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
|
||||
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
|
||||
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" );
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Disabled", "CheckBox.icon.disabledBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Default", "CheckBox.icon.focusedBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Wide", "CheckBox.icon.focusedColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Foreground.Disabled", "CheckBox.icon.disabledCheckmarkColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Selected", "CheckBox.icon.selectedBackground" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" );
|
||||
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" );
|
||||
|
||||
// because FlatLaf uses Button.background and Button.borderColor,
|
||||
// but IDEA uses Button.startBackground and Button.startBorderColor,
|
||||
// our default button background and border colors may be replaced by
|
||||
// wildcard *.background and *.borderColor colors
|
||||
noWildcardReplace.add( "Button.background" );
|
||||
noWildcardReplace.add( "Button.borderColor" );
|
||||
noWildcardReplace.add( "Button.default.background" );
|
||||
noWildcardReplace.add( "Button.default.borderColor" );
|
||||
noWildcardReplace.add( "ToggleButton.background" );
|
||||
}
|
||||
|
||||
//---- class ThemeLaf -----------------------------------------------------
|
||||
|
||||
public static class ThemeLaf
|
||||
extends FlatLaf
|
||||
{
|
||||
private final IntelliJTheme theme;
|
||||
|
||||
public ThemeLaf( IntelliJTheme theme ) {
|
||||
this.theme = theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return theme.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return theme.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDark() {
|
||||
return theme.dark;
|
||||
}
|
||||
|
||||
public IntelliJTheme getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
UIDefaults defaults = super.getDefaults();
|
||||
theme.applyProperties( defaults );
|
||||
return defaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
lafClasses.add( FlatLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||
lafClasses.add( ThemeLaf.class );
|
||||
return lafClasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import javax.swing.text.StyleContext;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
@@ -151,7 +152,7 @@ class LinuxFontPolicy
|
||||
int size = 10;
|
||||
|
||||
if( generalFont != null ) {
|
||||
List<String> strs = FlatLaf.split( generalFont, ',' );
|
||||
List<String> strs = StringUtils.split( generalFont, ',' );
|
||||
try {
|
||||
family = strs.get( 0 );
|
||||
size = Integer.parseInt( strs.get( 1 ) );
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.awt.Insets;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -39,6 +40,8 @@ import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
import com.formdev.flatlaf.util.ColorFunctions;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
import com.formdev.flatlaf.util.ScaledNumber;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Load UI defaults from properties files associated to Flat LaF classes and add to UI defaults.
|
||||
@@ -70,7 +73,13 @@ class UIDefaultsLoader
|
||||
lafClasses.add( 0, lafClass );
|
||||
}
|
||||
|
||||
loadDefaultsFromProperties( lafClasses, defaults );
|
||||
}
|
||||
|
||||
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, UIDefaults defaults ) {
|
||||
try {
|
||||
List<ClassLoader> addonClassLoaders = new ArrayList<>();
|
||||
|
||||
// load properties files
|
||||
Properties properties = new Properties();
|
||||
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
|
||||
@@ -88,6 +97,31 @@ class UIDefaultsLoader
|
||||
if( in != null )
|
||||
properties.load( in );
|
||||
}
|
||||
|
||||
ClassLoader addonClassLoader = addon.getClass().getClassLoader();
|
||||
if( !addonClassLoaders.contains( addonClassLoader ) )
|
||||
addonClassLoaders.add( addonClassLoader );
|
||||
}
|
||||
}
|
||||
|
||||
// collect all platform specific keys (but do not modify properties)
|
||||
ArrayList<String> platformSpecificKeys = new ArrayList<>();
|
||||
for( Object key : properties.keySet() ) {
|
||||
if( ((String)key).startsWith( "[" ) )
|
||||
platformSpecificKeys.add( (String) key );
|
||||
}
|
||||
|
||||
// remove platform specific properties and re-add only properties
|
||||
// for current platform, but with platform prefix removed
|
||||
if( !platformSpecificKeys.isEmpty() ) {
|
||||
String platformPrefix =
|
||||
SystemInfo.IS_WINDOWS ? "[win]" :
|
||||
SystemInfo.IS_MAC ? "[mac]" :
|
||||
SystemInfo.IS_LINUX ? "[linux]" : "[unknown]";
|
||||
for( String key : platformSpecificKeys ) {
|
||||
Object value = properties.remove( key );
|
||||
if( key.startsWith( platformPrefix ) )
|
||||
properties.put( key.substring( platformPrefix.length() ), value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +138,7 @@ class UIDefaultsLoader
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
try {
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver ) );
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( key, value, ex );
|
||||
}
|
||||
@@ -129,7 +163,7 @@ class UIDefaultsLoader
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
try {
|
||||
defaults.put( key, parseValue( key, value, resolver ) );
|
||||
defaults.put( key, parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( key, value, ex );
|
||||
}
|
||||
@@ -139,7 +173,7 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
private static void logParseError( String key, String value, RuntimeException ex ) {
|
||||
static void logParseError( String key, String value, RuntimeException ex ) {
|
||||
System.err.println( "Failed to parse: '" + key + '=' + value + '\'' );
|
||||
System.err.println( " " + ex.getMessage() );
|
||||
}
|
||||
@@ -168,9 +202,13 @@ class UIDefaultsLoader
|
||||
return resolveValue( properties, newValue );
|
||||
}
|
||||
|
||||
private enum ValueType { UNKNOWN, STRING, INTEGER, BORDER, ICON, INSETS, SIZE, COLOR, SCALEDNUMBER }
|
||||
private enum ValueType { UNKNOWN, STRING, INTEGER, BORDER, ICON, INSETS, SIZE, COLOR, SCALEDNUMBER, INSTANCE, CLASS }
|
||||
|
||||
private static Object parseValue( String key, String value, Function<String, String> resolver ) {
|
||||
static Object parseValue( String key, String value ) {
|
||||
return parseValue( key, value, v -> v, Collections.emptyList() );
|
||||
}
|
||||
|
||||
private static Object parseValue( String key, String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
value = value.trim();
|
||||
|
||||
// null, false, true
|
||||
@@ -183,7 +221,9 @@ class UIDefaultsLoader
|
||||
ValueType valueType = ValueType.UNKNOWN;
|
||||
|
||||
// check whether value type is specified in the value
|
||||
if( value.startsWith( TYPE_PREFIX ) ) {
|
||||
if( value.startsWith( "#" ) )
|
||||
valueType = ValueType.COLOR;
|
||||
else if( value.startsWith( TYPE_PREFIX ) ) {
|
||||
int end = value.indexOf( TYPE_PREFIX_END );
|
||||
if( end != -1 ) {
|
||||
try {
|
||||
@@ -200,7 +240,9 @@ class UIDefaultsLoader
|
||||
|
||||
// determine value type from key
|
||||
if( valueType == ValueType.UNKNOWN ) {
|
||||
if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
||||
if( key.endsWith( "ground" ) || key.endsWith( "Color" ) )
|
||||
valueType = ValueType.COLOR;
|
||||
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
||||
valueType = ValueType.BORDER;
|
||||
else if( key.endsWith( ".icon" ) || key.endsWith( "Icon" ) )
|
||||
valueType = ValueType.ICON;
|
||||
@@ -211,22 +253,26 @@ class UIDefaultsLoader
|
||||
valueType = ValueType.SIZE;
|
||||
else if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
||||
valueType = ValueType.INTEGER;
|
||||
else if( key.endsWith( "UI" ) )
|
||||
valueType = ValueType.STRING;
|
||||
}
|
||||
|
||||
// parse value
|
||||
switch( valueType ) {
|
||||
case STRING: return value;
|
||||
case INTEGER: return parseInteger( value, true );
|
||||
case BORDER: return parseBorder( value, resolver );
|
||||
case ICON: return parseInstance( value );
|
||||
case BORDER: return parseBorder( value, resolver, addonClassLoaders );
|
||||
case ICON: return parseInstance( value, addonClassLoaders );
|
||||
case INSETS: return parseInsets( value );
|
||||
case SIZE: return parseSize( value );
|
||||
case COLOR: return parseColor( value, true );
|
||||
case COLOR: return parseColorOrFunction( value, true );
|
||||
case SCALEDNUMBER: return parseScaledNumber( value );
|
||||
case INSTANCE: return parseInstance( value, addonClassLoaders );
|
||||
case CLASS: return parseClass( value, addonClassLoaders );
|
||||
case UNKNOWN:
|
||||
default:
|
||||
// colors
|
||||
ColorUIResource color = parseColor( value, false );
|
||||
ColorUIResource color = parseColorOrFunction( value, false );
|
||||
if( color != null )
|
||||
return color;
|
||||
|
||||
@@ -240,13 +286,13 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
private static Object parseBorder( String value, Function<String, String> resolver ) {
|
||||
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
if( value.indexOf( ',' ) >= 0 ) {
|
||||
// top,left,bottom,right[,lineColor]
|
||||
List<String> parts = split( value, ',' );
|
||||
List<String> parts = StringUtils.split( value, ',' );
|
||||
Insets insets = parseInsets( value );
|
||||
ColorUIResource lineColor = (parts.size() == 5)
|
||||
? parseColor( resolver.apply( parts.get( 4 ) ), true )
|
||||
? parseColorOrFunction( resolver.apply( parts.get( 4 ) ), true )
|
||||
: null;
|
||||
|
||||
return (LazyValue) t -> {
|
||||
@@ -255,13 +301,13 @@ class UIDefaultsLoader
|
||||
: new FlatEmptyBorder( insets );
|
||||
};
|
||||
} else
|
||||
return parseInstance( value );
|
||||
return parseInstance( value, addonClassLoaders );
|
||||
}
|
||||
|
||||
private static Object parseInstance( String value ) {
|
||||
private static Object parseInstance( String value, List<ClassLoader> addonClassLoaders ) {
|
||||
return (LazyValue) t -> {
|
||||
try {
|
||||
return Class.forName( value ).newInstance();
|
||||
return findClass( value, addonClassLoaders ).newInstance();
|
||||
} catch( InstantiationException | IllegalAccessException | ClassNotFoundException ex ) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
@@ -269,8 +315,37 @@ class UIDefaultsLoader
|
||||
};
|
||||
}
|
||||
|
||||
private static Object parseClass( String value, List<ClassLoader> addonClassLoaders ) {
|
||||
return (LazyValue) t -> {
|
||||
try {
|
||||
return findClass( value, addonClassLoaders );
|
||||
} catch( ClassNotFoundException ex ) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Class<?> findClass( String className, List<ClassLoader> addonClassLoaders )
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
try {
|
||||
return Class.forName( className );
|
||||
} catch( ClassNotFoundException ex ) {
|
||||
// search in addons class loaders
|
||||
for( ClassLoader addonClassLoader : addonClassLoaders ) {
|
||||
try {
|
||||
return addonClassLoader.loadClass( className );
|
||||
} catch( ClassNotFoundException ex2 ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static Insets parseInsets( String value ) {
|
||||
List<String> numbers = split( value, ',' );
|
||||
List<String> numbers = StringUtils.split( value, ',' );
|
||||
try {
|
||||
return new InsetsUIResource(
|
||||
Integer.parseInt( numbers.get( 0 ) ),
|
||||
@@ -283,7 +358,7 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
private static Dimension parseSize( String value ) {
|
||||
List<String> numbers = split( value, ',' );
|
||||
List<String> numbers = StringUtils.split( value, ',' );
|
||||
try {
|
||||
return new DimensionUIResource(
|
||||
Integer.parseInt( numbers.get( 0 ) ),
|
||||
@@ -293,20 +368,24 @@ class UIDefaultsLoader
|
||||
}
|
||||
}
|
||||
|
||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
||||
private static ColorUIResource parseColorOrFunction( String value, boolean reportError ) {
|
||||
if( value.endsWith( ")" ) )
|
||||
return parseColorFunctions( value, reportError );
|
||||
|
||||
try {
|
||||
int rgb = Integer.parseInt( value, 16 );
|
||||
if( value.length() == 6 )
|
||||
return new ColorUIResource( rgb );
|
||||
if( value.length() == 8 )
|
||||
return new ColorUIResource( new Color( rgb, true ) );
|
||||
return parseColor( value, reportError );
|
||||
}
|
||||
|
||||
if( reportError )
|
||||
throw new NumberFormatException( value );
|
||||
} catch( NumberFormatException ex ) {
|
||||
static ColorUIResource parseColor( String value ) {
|
||||
return parseColor( value, false );
|
||||
}
|
||||
|
||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
||||
try {
|
||||
int rgba = parseColorRGBA( value );
|
||||
return ((rgba & 0xff000000) == 0xff000000)
|
||||
? new ColorUIResource( rgba )
|
||||
: new ColorUIResource( new Color( rgba, true ) );
|
||||
} catch( IllegalArgumentException ex ) {
|
||||
if( reportError )
|
||||
throw new IllegalArgumentException( "invalid color '" + value + "'" );
|
||||
|
||||
@@ -315,6 +394,50 @@ class UIDefaultsLoader
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA}
|
||||
* format and returns it as {@code rgba} integer suitable for {@link java.awt.Color},
|
||||
* which includes alpha component in bits 24-31.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
static int parseColorRGBA( String value ) {
|
||||
int len = value.length();
|
||||
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// parse hex
|
||||
int n = 0;
|
||||
for( int i = 1; i < len; i++ ) {
|
||||
char ch = value.charAt( i );
|
||||
|
||||
int digit;
|
||||
if( ch >= '0' && ch <= '9' )
|
||||
digit = ch - '0';
|
||||
else if( ch >= 'a' && ch <= 'f' )
|
||||
digit = ch - 'a' + 10;
|
||||
else if( ch >= 'A' && ch <= 'F' )
|
||||
digit = ch - 'A' + 10;
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
n = (n << 4) | digit;
|
||||
}
|
||||
|
||||
if( len <= 5 ) {
|
||||
// double nibbles
|
||||
int n1 = n & 0xf000;
|
||||
int n2 = n & 0xf00;
|
||||
int n3 = n & 0xf0;
|
||||
int n4 = n & 0xf;
|
||||
n = (n1 << 16) | (n1 << 12) | (n2 << 12) | (n2 << 8) | (n3 << 8) | (n3 << 4) | (n4 << 4) | n4;
|
||||
}
|
||||
|
||||
return (len == 4 || len == 7)
|
||||
? (0xff000000 | n) // set alpha to 255
|
||||
: (((n >> 8) & 0xffffff) | ((n & 0xff) << 24)); // move alpha from lowest to highest byte
|
||||
}
|
||||
|
||||
private static ColorUIResource parseColorFunctions( String value, boolean reportError ) {
|
||||
int paramsStart = value.indexOf( '(' );
|
||||
if( paramsStart < 0 ) {
|
||||
@@ -324,7 +447,7 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
String function = value.substring( 0, paramsStart ).trim();
|
||||
List<String> params = split( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
||||
List<String> params = StringUtils.split( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
||||
if( params.isEmpty() )
|
||||
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
|
||||
|
||||
@@ -390,18 +513,4 @@ class UIDefaultsLoader
|
||||
throw new NumberFormatException( "invalid integer '" + value + "'" );
|
||||
}
|
||||
}
|
||||
|
||||
static List<String> split( String str, char delim ) {
|
||||
ArrayList<String> strs = new ArrayList<>();
|
||||
int delimIndex = str.indexOf( delim );
|
||||
int index = 0;
|
||||
while( delimIndex >= 0 ) {
|
||||
strs.add( str.substring( index, delimIndex ) );
|
||||
index = delimIndex + 1;
|
||||
delimIndex = str.indexOf( delim, index );
|
||||
}
|
||||
strs.add( str.substring( index ) );
|
||||
|
||||
return strs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,18 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Table.sortIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -32,6 +35,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatAscendingSortIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||
|
||||
public FlatAscendingSortIcon() {
|
||||
@@ -41,6 +45,14 @@ public class FlatAscendingSortIcon
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.setColor( sortIconColor );
|
||||
g.fill( FlatUIUtils.createPath( 0.5,5, 9.5,5, 5,0 ) );
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,5, 5,1, 9,5 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0.5,5, 5,0, 9.5,5 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault CheckBox.icon.focusedColor Color optional; defaults to Component.focusColor
|
||||
* @uiDefault CheckBox.icon.borderColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||
@@ -62,7 +63,8 @@ public class FlatCheckBoxIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
protected final Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusedColor",
|
||||
UIManager.getColor( "Component.focusColor" ) );
|
||||
protected final int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 );
|
||||
|
||||
protected final Color borderColor = UIManager.getColor( "CheckBox.icon.borderColor" );
|
||||
|
||||
@@ -16,15 +16,18 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Table.sortIconColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -32,6 +35,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatDescendingSortIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||
|
||||
public FlatDescendingSortIcon() {
|
||||
@@ -41,6 +45,14 @@ public class FlatDescendingSortIcon
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.setColor( sortIconColor );
|
||||
g.fill( FlatUIUtils.createPath( 0.5,0, 9.5,0, 5,5 ) );
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 9,1 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0.5,0, 5,5, 9.5,0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "details view" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.detailsViewColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ public class FlatFileChooserDetailsViewIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserDetailsViewIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.detailsViewColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.homeFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileChooserHomeFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserHomeFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.homeFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "list view" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.listViewColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ public class FlatFileChooserListViewIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserListViewIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.listViewColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.newFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileChooserNewFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileChooserNewFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.newFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
@@ -24,15 +25,18 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileChooser.icon.upFolderColor Color
|
||||
* @uiDefault Actions.Grey Color
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatFileChooserUpFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color blueColor = UIManager.getColor( "Actions.Blue" );
|
||||
|
||||
public FlatFileChooserUpFolderIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.upFolderColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,6 +51,8 @@ public class FlatFileChooserUpFolderIcon
|
||||
*/
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 9,5, 9,9, 13,9, 13,5, 14,5, 14,13, 2,13 ) );
|
||||
|
||||
g.setColor( blueColor );
|
||||
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "computer" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.computerColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewComputerIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewComputerIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.computerColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "directory" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.directoryColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileViewDirectoryIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewDirectoryIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.directoryColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "file" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.fileColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public class FlatFileViewFileIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewFileIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.fileColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.floppyDriveColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewFloppyDriveIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewFloppyDriveIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.floppyDriveColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
||||
/**
|
||||
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* @uiDefault FileView.icon.hardDriveColor Color
|
||||
* @uiDefault Objects.Grey Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ public class FlatFileViewHardDriveIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
public FlatFileViewHardDriveIcon() {
|
||||
super( 16, 16, UIManager.getColor( "FileView.icon.hardDriveColor" ) );
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,7 @@ public class FlatMenuArrowIcon
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 5,5, 0,9.5 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,12 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* Base class for icons for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.foreground Color
|
||||
* @uiDefault OptionPane.icon.foreground Color default is transparent
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -35,8 +36,8 @@ public abstract class FlatOptionPaneAbstractIcon
|
||||
{
|
||||
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
||||
|
||||
protected FlatOptionPaneAbstractIcon( String colorKey ) {
|
||||
super( 32, 32, UIManager.getColor( colorKey ) );
|
||||
protected FlatOptionPaneAbstractIcon( String colorKey, String defaultColorKey ) {
|
||||
super( 32, 32, FlatUIUtils.getUIColor( colorKey, defaultColorKey ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Error" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.errorColor Color
|
||||
* @uiDefault OptionPane.icon.errorColor Color optional; defaults to Actions.Red
|
||||
* @uiDefault Actions.Red Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneErrorIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneErrorIcon() {
|
||||
super( "OptionPane.icon.errorColor" );
|
||||
super( "OptionPane.icon.errorColor", "Actions.Red" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Information" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.informationColor Color
|
||||
* @uiDefault OptionPane.icon.informationColor Color optional; defaults to Actions.Blue
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneInformationIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneInformationIcon() {
|
||||
super( "OptionPane.icon.informationColor" );
|
||||
super( "OptionPane.icon.informationColor", "Actions.Blue" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
||||
/**
|
||||
* "Question" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.questionColor Color
|
||||
* @uiDefault OptionPane.icon.questionColor Color optional; defaults to Actions.Blue
|
||||
* @uiDefault Actions.Blue Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneQuestionIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneQuestionIcon() {
|
||||
super( "OptionPane.icon.questionColor" );
|
||||
super( "OptionPane.icon.questionColor", "Actions.Blue" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "Warning" icon for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.icon.warningColor Color
|
||||
* @uiDefault OptionPane.icon.warningColor Color optional; defaults to Actions.Yellow
|
||||
* @uiDefault Actions.Yellow Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneWarningIcon
|
||||
extends FlatOptionPaneAbstractIcon
|
||||
{
|
||||
public FlatOptionPaneWarningIcon() {
|
||||
super( "OptionPane.icon.warningColor" );
|
||||
super( "OptionPane.icon.warningColor", "Actions.Yellow" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class Json
|
||||
{
|
||||
public static Object parse( Reader reader )
|
||||
throws IOException, ParseException
|
||||
{
|
||||
DefaultHandler handler = new DefaultHandler();
|
||||
new JsonParser( handler ).parse( reader );
|
||||
return handler.getValue();
|
||||
}
|
||||
|
||||
//---- class DefaultHandler -----------------------------------------------
|
||||
|
||||
static class DefaultHandler
|
||||
extends JsonHandler<List<Object>, Map<String, Object>>
|
||||
{
|
||||
private Object value;
|
||||
|
||||
@Override
|
||||
public List<Object> startArray() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> startObject() {
|
||||
return new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endNull() {
|
||||
value = "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endBoolean( boolean bool ) {
|
||||
value = bool ? "true" : "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endString( String string ) {
|
||||
value = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endNumber( String string ) {
|
||||
value = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray( List<Object> array ) {
|
||||
value = array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject( Map<String, Object> object ) {
|
||||
value = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArrayValue( List<Object> array ) {
|
||||
array.add( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObjectValue( Map<String, Object> object, String name ) {
|
||||
object.put( name, value );
|
||||
}
|
||||
|
||||
Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 EclipseSource.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 OR COPYRIGHT HOLDERS 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.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
|
||||
/**
|
||||
* A handler for parser events. Instances of this class can be given to a {@link JsonParser}. The
|
||||
* parser will then call the methods of the given handler while reading the input.
|
||||
* <p>
|
||||
* The default implementations of these methods do nothing. Subclasses may override only those
|
||||
* methods they are interested in. They can use <code>getLocation()</code> to access the current
|
||||
* character position of the parser at any point. The <code>start*</code> methods will be called
|
||||
* while the location points to the first character of the parsed element. The <code>end*</code>
|
||||
* methods will be called while the location points to the character position that directly follows
|
||||
* the last character of the parsed element. Example:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* ["lorem ipsum"]
|
||||
* ^ ^
|
||||
* startString endString
|
||||
* </pre>
|
||||
* <p>
|
||||
* Subclasses that build an object representation of the parsed JSON can return arbitrary handler
|
||||
* objects for JSON arrays and JSON objects in {@link #startArray()} and {@link #startObject()}.
|
||||
* These handler objects will then be provided in all subsequent parser events for this particular
|
||||
* array or object. They can be used to keep track the elements of a JSON array or object.
|
||||
* </p>
|
||||
*
|
||||
* @param <A>
|
||||
* The type of handlers used for JSON arrays
|
||||
* @param <O>
|
||||
* The type of handlers used for JSON objects
|
||||
* @see JsonParser
|
||||
*/
|
||||
abstract class JsonHandler<A, O> {
|
||||
|
||||
JsonParser parser;
|
||||
|
||||
/**
|
||||
* Returns the current parser location.
|
||||
*
|
||||
* @return the current parser location
|
||||
*/
|
||||
protected Location getLocation() {
|
||||
return parser.getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a <code>null</code> literal in the JSON input. This method will be
|
||||
* called when reading the first character of the literal.
|
||||
*/
|
||||
public void startNull() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a <code>null</code> literal in the JSON input. This method will be called
|
||||
* after reading the last character of the literal.
|
||||
*/
|
||||
public void endNull() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a boolean literal (<code>true</code> or <code>false</code>) in the
|
||||
* JSON input. This method will be called when reading the first character of the literal.
|
||||
*/
|
||||
public void startBoolean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a boolean literal (<code>true</code> or <code>false</code>) in the JSON
|
||||
* input. This method will be called after reading the last character of the literal.
|
||||
*
|
||||
* @param value
|
||||
* the parsed boolean value
|
||||
*/
|
||||
public void endBoolean(boolean value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a string in the JSON input. This method will be called when reading
|
||||
* the opening double quote character (<code>'"'</code>).
|
||||
*/
|
||||
public void startString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a string in the JSON input. This method will be called after reading the
|
||||
* closing double quote character (<code>'"'</code>).
|
||||
*
|
||||
* @param string
|
||||
* the parsed string
|
||||
*/
|
||||
public void endString(String string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of a number in the JSON input. This method will be called when reading
|
||||
* the first character of the number.
|
||||
*/
|
||||
public void startNumber() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of a number in the JSON input. This method will be called after reading the
|
||||
* last character of the number.
|
||||
*
|
||||
* @param string
|
||||
* the parsed number string
|
||||
*/
|
||||
public void endNumber(String string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an array in the JSON input. This method will be called when reading
|
||||
* the opening square bracket character (<code>'['</code>).
|
||||
* <p>
|
||||
* This method may return an object to handle subsequent parser events for this array. This array
|
||||
* handler will then be provided in all calls to {@link #startArrayValue(Object)
|
||||
* startArrayValue()}, {@link #endArrayValue(Object) endArrayValue()}, and
|
||||
* {@link #endArray(Object) endArray()} for this array.
|
||||
* </p>
|
||||
*
|
||||
* @return a handler for this array, or <code>null</code> if not needed
|
||||
*/
|
||||
public A startArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an array in the JSON input. This method will be called after reading the
|
||||
* closing square bracket character (<code>']'</code>).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void endArray(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an array element in the JSON input. This method will be called when
|
||||
* reading the first character of the element, just before the call to the <code>start</code>
|
||||
* method for the specific element type ({@link #startString()}, {@link #startNumber()}, etc.).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void startArrayValue(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an array element in the JSON input. This method will be called after
|
||||
* reading the last character of the element value, just after the <code>end</code> method for the
|
||||
* specific element type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||
* endNumber()}, etc.).
|
||||
*
|
||||
* @param array
|
||||
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void endArrayValue(A array) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of an object in the JSON input. This method will be called when reading
|
||||
* the opening curly bracket character (<code>'{'</code>).
|
||||
* <p>
|
||||
* This method may return an object to handle subsequent parser events for this object. This
|
||||
* object handler will be provided in all calls to {@link #startObjectName(Object)
|
||||
* startObjectName()}, {@link #endObjectName(Object, String) endObjectName()},
|
||||
* {@link #startObjectValue(Object, String) startObjectValue()},
|
||||
* {@link #endObjectValue(Object, String) endObjectValue()}, and {@link #endObject(Object)
|
||||
* endObject()} for this object.
|
||||
* </p>
|
||||
*
|
||||
* @return a handler for this object, or <code>null</code> if not needed
|
||||
*/
|
||||
public O startObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object in the JSON input. This method will be called after reading the
|
||||
* closing curly bracket character (<code>'}'</code>).
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
*/
|
||||
public void endObject(O object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||
* called when reading the opening quote character ('"') of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||
* provided
|
||||
*/
|
||||
public void startObjectName(O object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object member name in the JSON input. This method will be called after
|
||||
* reading the closing quote character (<code>'"'</code>) of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
* @param name
|
||||
* the parsed member name
|
||||
*/
|
||||
public void endObjectName(O object, String name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||
* called when reading the opening quote character ('"') of the member name.
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||
* provided
|
||||
* @param name
|
||||
* the member name
|
||||
*/
|
||||
public void startObjectValue(O object, String name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the end of an object member value in the JSON input. This method will be called after
|
||||
* reading the last character of the member value, just after the <code>end</code> method for the
|
||||
* specific member type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||
* endNumber()}, etc.).
|
||||
*
|
||||
* @param object
|
||||
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||
* @param name
|
||||
* the parsed member name
|
||||
*/
|
||||
public void endObjectValue(O object, String name) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, 2016 EclipseSource.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 OR COPYRIGHT HOLDERS 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.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
|
||||
/**
|
||||
* A streaming parser for JSON text. The parser reports all events to a given handler.
|
||||
*/
|
||||
class JsonParser {
|
||||
|
||||
private static final int MAX_NESTING_LEVEL = 1000;
|
||||
private static final int MIN_BUFFER_SIZE = 10;
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1024;
|
||||
|
||||
private final JsonHandler<Object, Object> handler;
|
||||
private Reader reader;
|
||||
private char[] buffer;
|
||||
private int bufferOffset;
|
||||
private int index;
|
||||
private int fill;
|
||||
private int line;
|
||||
private int lineOffset;
|
||||
private int current;
|
||||
private StringBuilder captureBuffer;
|
||||
private int captureStart;
|
||||
private int nestingLevel;
|
||||
|
||||
/*
|
||||
* | bufferOffset
|
||||
* v
|
||||
* [a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t] < input
|
||||
* [l|m|n|o|p|q|r|s|t|?|?] < buffer
|
||||
* ^ ^
|
||||
* | index fill
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new JsonParser with the given handler. The parser will report all parser events to
|
||||
* this handler.
|
||||
*
|
||||
* @param handler
|
||||
* the handler to process parser events
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public JsonParser(JsonHandler<?, ?> handler) {
|
||||
if (handler == null) {
|
||||
throw new NullPointerException("handler is null");
|
||||
}
|
||||
this.handler = (JsonHandler<Object, Object>)handler;
|
||||
handler.parser = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given input string. The input must contain a valid JSON value, optionally padded
|
||||
* with whitespace.
|
||||
*
|
||||
* @param string
|
||||
* the input string, must be valid JSON
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(String string) {
|
||||
if (string == null) {
|
||||
throw new NullPointerException("string is null");
|
||||
}
|
||||
int bufferSize = Math.max(MIN_BUFFER_SIZE, Math.min(DEFAULT_BUFFER_SIZE, string.length()));
|
||||
try {
|
||||
parse(new StringReader(string), bufferSize);
|
||||
} catch (IOException exception) {
|
||||
// StringReader does not throw IOException
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||
* valid JSON value, optionally padded with whitespace.
|
||||
* <p>
|
||||
* Characters are read in chunks into a default-sized input buffer. Hence, wrapping a reader in an
|
||||
* additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||
* </p>
|
||||
*
|
||||
* @param reader
|
||||
* the reader to read the input from
|
||||
* @throws IOException
|
||||
* if an I/O error occurs in the reader
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(Reader reader) throws IOException {
|
||||
parse(reader, DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||
* valid JSON value, optionally padded with whitespace.
|
||||
* <p>
|
||||
* Characters are read in chunks into an input buffer of the given size. Hence, wrapping a reader
|
||||
* in an additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||
* </p>
|
||||
*
|
||||
* @param reader
|
||||
* the reader to read the input from
|
||||
* @param buffersize
|
||||
* the size of the input buffer in chars
|
||||
* @throws IOException
|
||||
* if an I/O error occurs in the reader
|
||||
* @throws ParseException
|
||||
* if the input is not valid JSON
|
||||
*/
|
||||
public void parse(Reader reader, int buffersize) throws IOException {
|
||||
if (reader == null) {
|
||||
throw new NullPointerException("reader is null");
|
||||
}
|
||||
if (buffersize <= 0) {
|
||||
throw new IllegalArgumentException("buffersize is zero or negative");
|
||||
}
|
||||
this.reader = reader;
|
||||
buffer = new char[buffersize];
|
||||
bufferOffset = 0;
|
||||
index = 0;
|
||||
fill = 0;
|
||||
line = 1;
|
||||
lineOffset = 0;
|
||||
current = 0;
|
||||
captureStart = -1;
|
||||
read();
|
||||
skipWhiteSpace();
|
||||
readValue();
|
||||
skipWhiteSpace();
|
||||
if (!isEndOfText()) {
|
||||
throw error("Unexpected character");
|
||||
}
|
||||
}
|
||||
|
||||
private void readValue() throws IOException {
|
||||
switch (current) {
|
||||
case 'n':
|
||||
readNull();
|
||||
break;
|
||||
case 't':
|
||||
readTrue();
|
||||
break;
|
||||
case 'f':
|
||||
readFalse();
|
||||
break;
|
||||
case '"':
|
||||
readString();
|
||||
break;
|
||||
case '[':
|
||||
readArray();
|
||||
break;
|
||||
case '{':
|
||||
readObject();
|
||||
break;
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
readNumber();
|
||||
break;
|
||||
default:
|
||||
throw expected("value");
|
||||
}
|
||||
}
|
||||
|
||||
private void readArray() throws IOException {
|
||||
Object array = handler.startArray();
|
||||
read();
|
||||
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||
throw error("Nesting too deep");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
if (readChar(']')) {
|
||||
nestingLevel--;
|
||||
handler.endArray(array);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
skipWhiteSpace();
|
||||
handler.startArrayValue(array);
|
||||
readValue();
|
||||
handler.endArrayValue(array);
|
||||
skipWhiteSpace();
|
||||
} while (readChar(','));
|
||||
if (!readChar(']')) {
|
||||
throw expected("',' or ']'");
|
||||
}
|
||||
nestingLevel--;
|
||||
handler.endArray(array);
|
||||
}
|
||||
|
||||
private void readObject() throws IOException {
|
||||
Object object = handler.startObject();
|
||||
read();
|
||||
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||
throw error("Nesting too deep");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
if (readChar('}')) {
|
||||
nestingLevel--;
|
||||
handler.endObject(object);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
skipWhiteSpace();
|
||||
handler.startObjectName(object);
|
||||
String name = readName();
|
||||
handler.endObjectName(object, name);
|
||||
skipWhiteSpace();
|
||||
if (!readChar(':')) {
|
||||
throw expected("':'");
|
||||
}
|
||||
skipWhiteSpace();
|
||||
handler.startObjectValue(object, name);
|
||||
readValue();
|
||||
handler.endObjectValue(object, name);
|
||||
skipWhiteSpace();
|
||||
} while (readChar(','));
|
||||
if (!readChar('}')) {
|
||||
throw expected("',' or '}'");
|
||||
}
|
||||
nestingLevel--;
|
||||
handler.endObject(object);
|
||||
}
|
||||
|
||||
private String readName() throws IOException {
|
||||
if (current != '"') {
|
||||
throw expected("name");
|
||||
}
|
||||
return readStringInternal();
|
||||
}
|
||||
|
||||
private void readNull() throws IOException {
|
||||
handler.startNull();
|
||||
read();
|
||||
readRequiredChar('u');
|
||||
readRequiredChar('l');
|
||||
readRequiredChar('l');
|
||||
handler.endNull();
|
||||
}
|
||||
|
||||
private void readTrue() throws IOException {
|
||||
handler.startBoolean();
|
||||
read();
|
||||
readRequiredChar('r');
|
||||
readRequiredChar('u');
|
||||
readRequiredChar('e');
|
||||
handler.endBoolean(true);
|
||||
}
|
||||
|
||||
private void readFalse() throws IOException {
|
||||
handler.startBoolean();
|
||||
read();
|
||||
readRequiredChar('a');
|
||||
readRequiredChar('l');
|
||||
readRequiredChar('s');
|
||||
readRequiredChar('e');
|
||||
handler.endBoolean(false);
|
||||
}
|
||||
|
||||
private void readRequiredChar(char ch) throws IOException {
|
||||
if (!readChar(ch)) {
|
||||
throw expected("'" + ch + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private void readString() throws IOException {
|
||||
handler.startString();
|
||||
handler.endString(readStringInternal());
|
||||
}
|
||||
|
||||
private String readStringInternal() throws IOException {
|
||||
read();
|
||||
startCapture();
|
||||
while (current != '"') {
|
||||
if (current == '\\') {
|
||||
pauseCapture();
|
||||
readEscape();
|
||||
startCapture();
|
||||
} else if (current < 0x20) {
|
||||
throw expected("valid string character");
|
||||
} else {
|
||||
read();
|
||||
}
|
||||
}
|
||||
String string = endCapture();
|
||||
read();
|
||||
return string;
|
||||
}
|
||||
|
||||
private void readEscape() throws IOException {
|
||||
read();
|
||||
switch (current) {
|
||||
case '"':
|
||||
case '/':
|
||||
case '\\':
|
||||
captureBuffer.append((char)current);
|
||||
break;
|
||||
case 'b':
|
||||
captureBuffer.append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
captureBuffer.append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
captureBuffer.append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
captureBuffer.append('\r');
|
||||
break;
|
||||
case 't':
|
||||
captureBuffer.append('\t');
|
||||
break;
|
||||
case 'u':
|
||||
char[] hexChars = new char[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
read();
|
||||
if (!isHexDigit()) {
|
||||
throw expected("hexadecimal digit");
|
||||
}
|
||||
hexChars[i] = (char)current;
|
||||
}
|
||||
captureBuffer.append((char)Integer.parseInt(new String(hexChars), 16));
|
||||
break;
|
||||
default:
|
||||
throw expected("valid escape sequence");
|
||||
}
|
||||
read();
|
||||
}
|
||||
|
||||
private void readNumber() throws IOException {
|
||||
handler.startNumber();
|
||||
startCapture();
|
||||
readChar('-');
|
||||
int firstDigit = current;
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
if (firstDigit != '0') {
|
||||
while (readDigit()) {
|
||||
}
|
||||
}
|
||||
readFraction();
|
||||
readExponent();
|
||||
handler.endNumber(endCapture());
|
||||
}
|
||||
|
||||
private boolean readFraction() throws IOException {
|
||||
if (!readChar('.')) {
|
||||
return false;
|
||||
}
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
while (readDigit()) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readExponent() throws IOException {
|
||||
if (!readChar('e') && !readChar('E')) {
|
||||
return false;
|
||||
}
|
||||
if (!readChar('+')) {
|
||||
readChar('-');
|
||||
}
|
||||
if (!readDigit()) {
|
||||
throw expected("digit");
|
||||
}
|
||||
while (readDigit()) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readChar(char ch) throws IOException {
|
||||
if (current != ch) {
|
||||
return false;
|
||||
}
|
||||
read();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readDigit() throws IOException {
|
||||
if (!isDigit()) {
|
||||
return false;
|
||||
}
|
||||
read();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void skipWhiteSpace() throws IOException {
|
||||
while (isWhiteSpace()) {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private void read() throws IOException {
|
||||
if (index == fill) {
|
||||
if (captureStart != -1) {
|
||||
captureBuffer.append(buffer, captureStart, fill - captureStart);
|
||||
captureStart = 0;
|
||||
}
|
||||
bufferOffset += fill;
|
||||
fill = reader.read(buffer, 0, buffer.length);
|
||||
index = 0;
|
||||
if (fill == -1) {
|
||||
current = -1;
|
||||
index++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (current == '\n') {
|
||||
line++;
|
||||
lineOffset = bufferOffset + index;
|
||||
}
|
||||
current = buffer[index++];
|
||||
}
|
||||
|
||||
private void startCapture() {
|
||||
if (captureBuffer == null) {
|
||||
captureBuffer = new StringBuilder();
|
||||
}
|
||||
captureStart = index - 1;
|
||||
}
|
||||
|
||||
private void pauseCapture() {
|
||||
int end = current == -1 ? index : index - 1;
|
||||
captureBuffer.append(buffer, captureStart, end - captureStart);
|
||||
captureStart = -1;
|
||||
}
|
||||
|
||||
private String endCapture() {
|
||||
int start = captureStart;
|
||||
int end = index - 1;
|
||||
captureStart = -1;
|
||||
if (captureBuffer.length() > 0) {
|
||||
captureBuffer.append(buffer, start, end - start);
|
||||
String captured = captureBuffer.toString();
|
||||
captureBuffer.setLength(0);
|
||||
return captured;
|
||||
}
|
||||
return new String(buffer, start, end - start);
|
||||
}
|
||||
|
||||
Location getLocation() {
|
||||
int offset = bufferOffset + index - 1;
|
||||
int column = offset - lineOffset + 1;
|
||||
return new Location(offset, line, column);
|
||||
}
|
||||
|
||||
private ParseException expected(String expected) {
|
||||
if (isEndOfText()) {
|
||||
return error("Unexpected end of input");
|
||||
}
|
||||
return error("Expected " + expected);
|
||||
}
|
||||
|
||||
private ParseException error(String message) {
|
||||
return new ParseException(message, getLocation());
|
||||
}
|
||||
|
||||
private boolean isWhiteSpace() {
|
||||
return current == ' ' || current == '\t' || current == '\n' || current == '\r';
|
||||
}
|
||||
|
||||
private boolean isDigit() {
|
||||
return current >= '0' && current <= '9';
|
||||
}
|
||||
|
||||
private boolean isHexDigit() {
|
||||
return current >= '0' && current <= '9'
|
||||
|| current >= 'a' && current <= 'f'
|
||||
|| current >= 'A' && current <= 'F';
|
||||
}
|
||||
|
||||
private boolean isEndOfText() {
|
||||
return current == -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 EclipseSource.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 OR COPYRIGHT HOLDERS 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.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
|
||||
/**
|
||||
* An immutable object that represents a location in the parsed text.
|
||||
*/
|
||||
public class Location {
|
||||
|
||||
/**
|
||||
* The absolute character index, starting at 0.
|
||||
*/
|
||||
public final int offset;
|
||||
|
||||
/**
|
||||
* The line number, starting at 1.
|
||||
*/
|
||||
public final int line;
|
||||
|
||||
/**
|
||||
* The column number, starting at 1.
|
||||
*/
|
||||
public final int column;
|
||||
|
||||
Location(int offset, int line, int column) {
|
||||
this.offset = offset;
|
||||
this.column = column;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return line + ":" + column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Location other = (Location)obj;
|
||||
return offset == other.offset && column == other.column && line == other.line;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, 2016 EclipseSource.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 OR COPYRIGHT HOLDERS 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.
|
||||
******************************************************************************/
|
||||
|
||||
// from https://github.com/ralfstx/minimal-json
|
||||
|
||||
package com.formdev.flatlaf.json;
|
||||
|
||||
/**
|
||||
* An unchecked exception to indicate that an input does not qualify as valid JSON.
|
||||
*/
|
||||
public class ParseException extends RuntimeException {
|
||||
|
||||
private final Location location;
|
||||
|
||||
ParseException(String message, Location location) {
|
||||
super(message + " at " + location);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location at which the error occurred.
|
||||
*
|
||||
* @return the error location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute character index at which the error occurred. The offset of the first
|
||||
* character of a document is 0.
|
||||
*
|
||||
* @return the character offset at which the error occurred, will be >= 0
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getOffset() {
|
||||
return location.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line number in which the error occurred. The number of the first line is 1.
|
||||
*
|
||||
* @return the line in which the error occurred, will be >= 1
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getLine() {
|
||||
return location.line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column number at which the error occurred, i.e. the number of the character in its
|
||||
* line. The number of the first character of a line is 1.
|
||||
*
|
||||
* @return the column in which the error occurred, will be >= 1
|
||||
* @deprecated Use {@link #getLocation()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getColumn() {
|
||||
return location.column;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,12 +38,15 @@ public class FlatArrowButton
|
||||
extends BasicArrowButton
|
||||
implements UIResource
|
||||
{
|
||||
public static final int DEFAULT_ARROW_WIDTH = 8;
|
||||
|
||||
private final boolean chevron;
|
||||
private final Color foreground;
|
||||
private final Color disabledForeground;
|
||||
private final Color hoverForeground;
|
||||
private final Color hoverBackground;
|
||||
|
||||
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
||||
private int xOffset = 0;
|
||||
private int yOffset = 0;
|
||||
|
||||
@@ -80,6 +83,14 @@ public class FlatArrowButton
|
||||
}
|
||||
}
|
||||
|
||||
public int getArrowWidth() {
|
||||
return arrowWidth;
|
||||
}
|
||||
|
||||
public void setArrowWidth( int arrowWidth ) {
|
||||
this.arrowWidth = arrowWidth;
|
||||
}
|
||||
|
||||
protected boolean isHover() {
|
||||
return hover;
|
||||
}
|
||||
@@ -128,8 +139,8 @@ public class FlatArrowButton
|
||||
int direction = getDirection();
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
|
||||
int w = scale( chevron ? 8 : 9 );
|
||||
int h = scale( chevron ? 4 : 5 );
|
||||
int w = scale( arrowWidth + (chevron ? 0 : 1) );
|
||||
int h = scale( (arrowWidth / 2) + (chevron ? 0 : 1) );
|
||||
int rw = vert ? w : h;
|
||||
int rh = vert ? h : w;
|
||||
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) );
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Paint;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
@@ -71,7 +72,7 @@ public class FlatBorder
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
||||
boolean isCellEditor = isTableCellEditor( c );
|
||||
float focusWidth = isCellEditor ? 0 : getFocusWidth();
|
||||
float borderWidth = getBorderWidth( c );
|
||||
float arc = isCellEditor ? 0 : getArc();
|
||||
@@ -82,7 +83,7 @@ public class FlatBorder
|
||||
getLineWidth() + scale( (float) innerFocusWidth ), arc );
|
||||
}
|
||||
|
||||
g2.setColor( getBorderColor( c ) );
|
||||
g2.setPaint( getBorderColor( c ) );
|
||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
@@ -93,13 +94,24 @@ public class FlatBorder
|
||||
return focusColor;
|
||||
}
|
||||
|
||||
protected Color getBorderColor( Component c ) {
|
||||
boolean enabled = c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
||||
return enabled
|
||||
protected Paint getBorderColor( Component c ) {
|
||||
return isEnabled( c )
|
||||
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
||||
: disabledBorderColor;
|
||||
}
|
||||
|
||||
protected boolean isEnabled( Component c ) {
|
||||
if( c instanceof JScrollPane ) {
|
||||
// check whether view component is disabled
|
||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||
Component view = (viewport != null) ? viewport.getView() : null;
|
||||
if( view != null && !isEnabled( view ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
||||
}
|
||||
|
||||
protected boolean isFocused( Component c ) {
|
||||
if( c instanceof JScrollPane ) {
|
||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||
@@ -132,9 +144,13 @@ public class FlatBorder
|
||||
return c.hasFocus();
|
||||
}
|
||||
|
||||
protected boolean isTableCellEditor( Component c ) {
|
||||
return FlatUIUtils.isTableCellEditor( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
||||
boolean isCellEditor = isTableCellEditor( c );
|
||||
float ow = (isCellEditor ? 0 : getFocusWidth()) + getLineWidth();
|
||||
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.formdev.flatlaf.ui;
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Paint;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.UIResource;
|
||||
@@ -29,10 +31,14 @@ import javax.swing.plaf.UIResource;
|
||||
* Border for {@link javax.swing.JButton}.
|
||||
*
|
||||
* @uiDefault Button.borderColor Color
|
||||
* @uiDefault Button.startBorderColor Color optional; if set, a gradient paint is used and Button.borderColor is ignored
|
||||
* @uiDefault Button.endBorderColor Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.disabledBorderColor Color
|
||||
* @uiDefault Button.focusedBorderColor Color
|
||||
* @uiDefault Button.hoverBorderColor Color optional
|
||||
* @uiDefault Button.default.borderColor Color
|
||||
* @uiDefault Button.default.startBorderColor Color optional; if set, a gradient paint is used and Button.default.borderColor is ignored
|
||||
* @uiDefault Button.default.endBorderColor Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||
* @uiDefault Button.default.focusedBorderColor Color
|
||||
* @uiDefault Button.default.focusColor Color
|
||||
@@ -44,11 +50,13 @@ import javax.swing.plaf.UIResource;
|
||||
public class FlatButtonBorder
|
||||
extends FlatBorder
|
||||
{
|
||||
protected final Color borderColor = UIManager.getColor( "Button.borderColor" );
|
||||
protected final Color borderColor = FlatUIUtils.getUIColor( "Button.startBorderColor", "Button.borderColor" );
|
||||
protected final Color endBorderColor = UIManager.getColor( "Button.endBorderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
||||
protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
||||
protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
||||
protected final Color defaultBorderColor = UIManager.getColor( "Button.default.borderColor" );
|
||||
protected final Color defaultBorderColor = FlatUIUtils.getUIColor( "Button.default.startBorderColor", "Button.default.borderColor" );
|
||||
protected final Color defaultEndBorderColor = UIManager.getColor( "Button.default.endBorderColor" );
|
||||
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" );
|
||||
@@ -67,14 +75,22 @@ public class FlatButtonBorder
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getBorderColor( Component c ) {
|
||||
protected Paint getBorderColor( Component c ) {
|
||||
boolean def = FlatButtonUI.isDefaultButton( c );
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
Paint color = FlatButtonUI.buttonStateColor( c,
|
||||
def ? defaultBorderColor : borderColor,
|
||||
disabledBorderColor,
|
||||
def ? defaultFocusedBorderColor : focusedBorderColor,
|
||||
def ? defaultHoverBorderColor : hoverBorderColor,
|
||||
null );
|
||||
|
||||
// change to gradient paint if start/end colors are specified
|
||||
Color startBg = def ? defaultBorderColor : borderColor;
|
||||
Color endBg = def ? defaultEndBorderColor : endBorderColor;
|
||||
if( color == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||
color = new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,9 +23,11 @@ import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
@@ -39,26 +41,44 @@ import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicButtonUI -->
|
||||
*
|
||||
* @uiDefault Button.font Font
|
||||
* @uiDefault Button.background Color
|
||||
* @uiDefault Button.foreground Color
|
||||
* @uiDefault Button.border Border
|
||||
* @uiDefault Button.margin Insets
|
||||
* @uiDefault Button.rollover boolean
|
||||
*
|
||||
* <!-- FlatButtonUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Button.arc int
|
||||
* @uiDefault Button.minimumWidth int
|
||||
* @uiDefault Button.iconTextGap int
|
||||
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
||||
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
||||
* @uiDefault Button.focusedBackground Color optional
|
||||
* @uiDefault Button.hoverBackground Color optional
|
||||
* @uiDefault Button.pressedBackground Color optional
|
||||
* @uiDefault Button.disabledText 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
|
||||
* @uiDefault Button.default.foreground Color
|
||||
* @uiDefault Button.default.focusedBackground Color optional
|
||||
* @uiDefault Button.default.hoverBackground Color optional
|
||||
* @uiDefault Button.default.pressedBackground Color optional
|
||||
* @uiDefault Button.default.boldText boolean
|
||||
* @uiDefault Button.paintShadow boolean default is false
|
||||
* @uiDefault Button.shadowWidth int default is 2
|
||||
* @uiDefault Button.shadowColor Color optional
|
||||
* @uiDefault Button.default.shadowColor Color optional
|
||||
* @uiDefault Button.toolbar.hoverBackground Color
|
||||
* @uiDefault Button.toolbar.pressedBackground Color
|
||||
*
|
||||
@@ -72,18 +92,25 @@ public class FlatButtonUI
|
||||
protected int minimumWidth;
|
||||
protected int iconTextGap;
|
||||
|
||||
protected Color startBackground;
|
||||
protected Color endBackground;
|
||||
protected Color focusedBackground;
|
||||
protected Color hoverBackground;
|
||||
protected Color pressedBackground;
|
||||
protected Color disabledText;
|
||||
|
||||
protected Color defaultBackground;
|
||||
protected Color defaultEndBackground;
|
||||
protected Color defaultForeground;
|
||||
protected Color defaultFocusedBackground;
|
||||
protected Color defaultHoverBackground;
|
||||
protected Color defaultPressedBackground;
|
||||
protected boolean defaultBoldText;
|
||||
|
||||
protected int shadowWidth;
|
||||
protected Color shadowColor;
|
||||
protected Color defaultShadowColor;
|
||||
|
||||
protected Color toolbarHoverBackground;
|
||||
protected Color toolbarPressedBackground;
|
||||
|
||||
@@ -111,12 +138,21 @@ public class FlatButtonUI
|
||||
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
||||
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
||||
|
||||
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||
|
||||
defaultBackground = UIManager.getColor( "Button.default.background" );
|
||||
if( UIManager.getBoolean( "Button.paintShadow" ) ) {
|
||||
shadowWidth = FlatUIUtils.getUIInt( "Button.shadowWidth", 2 );
|
||||
shadowColor = UIManager.getColor( "Button.shadowColor" );
|
||||
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||
}
|
||||
|
||||
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||
@@ -131,6 +167,12 @@ public class FlatButtonUI
|
||||
defaults_initialized = true;
|
||||
}
|
||||
|
||||
if( startBackground != null ) {
|
||||
Color bg = b.getBackground();
|
||||
if( bg == null || bg instanceof UIResource )
|
||||
b.setBackground( startBackground );
|
||||
}
|
||||
|
||||
LookAndFeel.installProperty( b, "opaque", false );
|
||||
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
||||
|
||||
@@ -154,10 +196,13 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
static boolean isIconOnlyButton( Component c ) {
|
||||
String text;
|
||||
return c instanceof JButton &&
|
||||
((JButton)c).getIcon() != null &&
|
||||
((text = ((JButton)c).getText()) == null || text.isEmpty());
|
||||
if( !(c instanceof JButton) )
|
||||
return false;
|
||||
|
||||
Icon icon = ((JButton)c).getIcon();
|
||||
String text = ((JButton)c).getText();
|
||||
return (icon != null && (text == null || text.isEmpty())) ||
|
||||
(icon == null && text != null && ("...".equals( text ) || text.length() == 1));
|
||||
}
|
||||
|
||||
static boolean isHelpButton( Component c ) {
|
||||
@@ -189,8 +234,23 @@ public class FlatButtonUI
|
||||
Border border = c.getBorder();
|
||||
float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0;
|
||||
float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0;
|
||||
boolean def = isDefaultButton( c );
|
||||
|
||||
FlatUIUtils.setColor( g2, background, isDefaultButton(c) ? defaultBackground : c.getBackground() );
|
||||
// paint shadow
|
||||
Color shadowColor = def ? defaultShadowColor : this.shadowColor;
|
||||
if( shadowColor != null && shadowWidth > 0 && focusWidth > 0 && !c.hasFocus() && c.isEnabled() ) {
|
||||
g2.setColor( shadowColor );
|
||||
g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ),
|
||||
c.getWidth() - focusWidth * 2, c.getHeight() - focusWidth * 2, arc, arc ) );
|
||||
}
|
||||
|
||||
// paint background
|
||||
Color startBg = def ? defaultBackground : startBackground;
|
||||
Color endBg = def ? defaultEndBackground : endBackground;
|
||||
if( background == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||
g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) );
|
||||
else
|
||||
FlatUIUtils.setColor( g2, background, def ? defaultBackground : c.getBackground() );
|
||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
@@ -286,8 +346,11 @@ public class FlatButtonUI
|
||||
|
||||
Dimension prefSize = super.getPreferredSize( c );
|
||||
|
||||
// apply minimum width, if not in toolbar and not a icon-only button
|
||||
if( !isToolBarButton( c ) && !isIconOnlyButton( c ) )
|
||||
// make button square if it is a icon-only button
|
||||
// or apply minimum width, if not in toolbar and not a icon-only button
|
||||
if( isIconOnlyButton( c ) )
|
||||
prefSize.width = Math.max( prefSize.width, prefSize.height );
|
||||
else if( !isToolBarButton( c ) )
|
||||
prefSize.width = Math.max( prefSize.width, scale( minimumWidth + (focusWidth * 2) ) );
|
||||
|
||||
return prefSize;
|
||||
|
||||
@@ -25,6 +25,26 @@ import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBoxMenuItem}.
|
||||
*
|
||||
* <!-- BasicCheckBoxMenuItemUI -->
|
||||
*
|
||||
* @uiDefault CheckBoxMenuItem.font Font
|
||||
* @uiDefault CheckBoxMenuItem.background Color
|
||||
* @uiDefault CheckBoxMenuItem.foreground Color
|
||||
* @uiDefault CheckBoxMenuItem.disabledForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.selectionBackground Color
|
||||
* @uiDefault CheckBoxMenuItem.selectionForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.acceleratorForeground Color
|
||||
* @uiDefault CheckBoxMenuItem.acceleratorSelectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||
* @uiDefault CheckBoxMenuItem.border Border
|
||||
* @uiDefault CheckBoxMenuItem.borderPainted boolean
|
||||
* @uiDefault CheckBoxMenuItem.margin Insets
|
||||
* @uiDefault CheckBoxMenuItem.arrowIcon Icon
|
||||
* @uiDefault CheckBoxMenuItem.checkIcon Icon
|
||||
* @uiDefault CheckBoxMenuItem.opaque boolean
|
||||
* @uiDefault CheckBoxMenuItem.evenHeight boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxMenuItemUI
|
||||
|
||||
@@ -22,6 +22,21 @@ import javax.swing.plaf.ComponentUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBox}.
|
||||
*
|
||||
* <!-- BasicRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault CheckBox.font Font
|
||||
* @uiDefault CheckBox.background Color
|
||||
* @uiDefault CheckBox.foreground Color
|
||||
* @uiDefault CheckBox.border Border
|
||||
* @uiDefault CheckBox.margin Insets
|
||||
* @uiDefault CheckBox.rollover boolean
|
||||
* @uiDefault CheckBox.icon Icon
|
||||
*
|
||||
* <!-- FlatRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault CheckBox.iconTextGap int
|
||||
* @uiDefault CheckBox.disabledText Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatCheckBoxUI
|
||||
|
||||
@@ -26,6 +26,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JColorChooser}.
|
||||
*
|
||||
* <!-- BasicColorChooserUI -->
|
||||
*
|
||||
* @uiDefault ColorChooser.font Font
|
||||
* @uiDefault ColorChooser.background Color
|
||||
* @uiDefault ColorChooser.foreground Color
|
||||
* @uiDefault ColorChooser.showPreviewPanelText boolean
|
||||
* @uiDefault ColorChooser.swatchesSwatchSize Dimension
|
||||
* @uiDefault ColorChooser.swatchesRecentSwatchSize Dimension
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.awt.event.MouseListener;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.WeakReference;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
@@ -56,13 +57,24 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicComboBoxUI -->
|
||||
*
|
||||
* @uiDefault ComboBox.font Font
|
||||
* @uiDefault ComboBox.background Color
|
||||
* @uiDefault ComboBox.foreground Color
|
||||
* @uiDefault ComboBox.border Border
|
||||
* @uiDefault ComboBox.padding Insets
|
||||
* @uiDefault ComboBox.squareButton boolean default is true
|
||||
*
|
||||
* <!-- FlatComboBoxUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.arc int
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
|
||||
* @uiDefault ComboBox.disabledBackground Color
|
||||
* @uiDefault ComboBox.disabledForeground Color
|
||||
* @uiDefault ComboBox.buttonBackground Color
|
||||
@@ -79,9 +91,11 @@ public class FlatComboBoxUI
|
||||
protected int focusWidth;
|
||||
protected int arc;
|
||||
protected String arrowType;
|
||||
protected boolean isIntelliJTheme;
|
||||
protected Color borderColor;
|
||||
protected Color disabledBorderColor;
|
||||
|
||||
protected Color editableBackground;
|
||||
protected Color disabledBackground;
|
||||
protected Color disabledForeground;
|
||||
|
||||
@@ -94,6 +108,8 @@ public class FlatComboBoxUI
|
||||
private MouseListener hoverListener;
|
||||
private boolean hover;
|
||||
|
||||
private WeakReference<Component> lastRendererComponent;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatComboBoxUI();
|
||||
}
|
||||
@@ -129,9 +145,11 @@ public class FlatComboBoxUI
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
arc = UIManager.getInt( "Component.arc" );
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
|
||||
editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
|
||||
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
||||
disabledForeground = UIManager.getColor( "ComboBox.disabledForeground" );
|
||||
|
||||
@@ -154,6 +172,7 @@ public class FlatComboBoxUI
|
||||
borderColor = null;
|
||||
disabledBorderColor = null;
|
||||
|
||||
editableBackground = null;
|
||||
disabledBackground = null;
|
||||
disabledForeground = null;
|
||||
|
||||
@@ -294,7 +313,9 @@ public class FlatComboBoxUI
|
||||
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
||||
|
||||
// paint background
|
||||
g2.setColor( enabled ? c.getBackground() : disabledBackground );
|
||||
g2.setColor( enabled
|
||||
? (editableBackground != null && comboBox.isEditable() ? editableBackground : c.getBackground())
|
||||
: getDisabledBackground( comboBox ) );
|
||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
||||
|
||||
// paint arrow button background
|
||||
@@ -324,15 +345,15 @@ public class FlatComboBoxUI
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||
CellPaddingBorder.uninstall( renderer );
|
||||
uninstallCellPaddingBorder( renderer );
|
||||
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
|
||||
c.setFont( comboBox.getFont() );
|
||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||
CellPaddingBorder.uninstall( c );
|
||||
uninstallCellPaddingBorder( c );
|
||||
|
||||
boolean enabled = comboBox.isEnabled();
|
||||
c.setForeground( enabled ? comboBox.getForeground() : disabledForeground );
|
||||
c.setBackground( enabled ? comboBox.getBackground() : disabledBackground );
|
||||
c.setBackground( enabled ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
|
||||
|
||||
boolean shouldValidate = (c instanceof JPanel);
|
||||
if( padding != null )
|
||||
@@ -349,10 +370,38 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
||||
g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : disabledBackground );
|
||||
g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
|
||||
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
|
||||
}
|
||||
|
||||
private Color getDisabledBackground( JComponent c ) {
|
||||
return isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getDefaultSize() {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||
uninstallCellPaddingBorder( renderer );
|
||||
|
||||
Dimension size = super.getDefaultSize();
|
||||
|
||||
uninstallCellPaddingBorder( renderer );
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getDisplaySize() {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||
uninstallCellPaddingBorder( renderer );
|
||||
|
||||
Dimension displaySize = super.getDisplaySize();
|
||||
|
||||
uninstallCellPaddingBorder( renderer );
|
||||
return displaySize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getSizeForComponent( Component comp ) {
|
||||
Dimension size = super.getSizeForComponent( comp );
|
||||
@@ -376,6 +425,14 @@ public class FlatComboBoxUI
|
||||
return null;
|
||||
}
|
||||
|
||||
private void uninstallCellPaddingBorder( Object o ) {
|
||||
CellPaddingBorder.uninstall( o );
|
||||
if( lastRendererComponent != null ) {
|
||||
CellPaddingBorder.uninstall( lastRendererComponent );
|
||||
lastRendererComponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatComboPopup -----------------------------------------------
|
||||
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
@@ -459,6 +516,7 @@ public class FlatComboBoxUI
|
||||
{
|
||||
ListCellRenderer renderer = comboBox.getRenderer();
|
||||
CellPaddingBorder.uninstall( renderer );
|
||||
CellPaddingBorder.uninstall( lastRendererComponent );
|
||||
|
||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||
@@ -469,6 +527,8 @@ public class FlatComboBoxUI
|
||||
paddingBorder.install( (JComponent) c );
|
||||
}
|
||||
|
||||
lastRendererComponent = (c != renderer) ? new WeakReference<>( c ) : null;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -503,6 +563,9 @@ public class FlatComboBoxUI
|
||||
}
|
||||
|
||||
static void uninstall( Object o ) {
|
||||
if( o instanceof WeakReference )
|
||||
o = ((WeakReference<?>)o).get();
|
||||
|
||||
if( !(o instanceof JComponent) )
|
||||
return;
|
||||
|
||||
|
||||
@@ -18,18 +18,37 @@ package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicEditorPaneUI -->
|
||||
*
|
||||
* @uiDefault EditorPane.font Font
|
||||
* @uiDefault EditorPane.background Color also used if not editable
|
||||
* @uiDefault EditorPane.foreground Color
|
||||
* @uiDefault EditorPane.caretForeground Color
|
||||
* @uiDefault EditorPane.selectionBackground Color
|
||||
* @uiDefault EditorPane.selectionForeground Color
|
||||
* @uiDefault EditorPane.disabledBackground Color used if not enabled
|
||||
* @uiDefault EditorPane.inactiveBackground Color used if not editable
|
||||
* @uiDefault EditorPane.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault EditorPane.border Border
|
||||
* @uiDefault EditorPane.margin Insets
|
||||
* @uiDefault EditorPane.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatEditorPaneUI -->
|
||||
*
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -37,6 +56,7 @@ public class FlatEditorPaneUI
|
||||
extends BasicEditorPaneUI
|
||||
{
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
|
||||
private Object oldHonorDisplayProperties;
|
||||
|
||||
@@ -49,6 +69,7 @@ public class FlatEditorPaneUI
|
||||
super.installDefaults();
|
||||
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
|
||||
// use component font and foreground for HTML text
|
||||
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
||||
@@ -80,4 +101,17 @@ public class FlatEditorPaneUI
|
||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||
return size;
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JFileChooser}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatFileChooserUI
|
||||
extends MetalFileChooserUI
|
||||
{
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatFileChooserUI( (JFileChooser) c );
|
||||
}
|
||||
|
||||
public FlatFileChooserUI( JFileChooser filechooser ) {
|
||||
super( filechooser );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return UIScale.scale( super.getPreferredSize( c ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
return UIScale.scale( super.getMinimumSize( c ) );
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,26 @@ import javax.swing.plaf.ComponentUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JFormattedTextField}.
|
||||
*
|
||||
* <!-- BasicTextFieldUI -->
|
||||
*
|
||||
* @uiDefault FormattedTextField.font Font
|
||||
* @uiDefault FormattedTextField.background Color
|
||||
* @uiDefault FormattedTextField.foreground Color also used if not editable
|
||||
* @uiDefault FormattedTextField.caretForeground Color
|
||||
* @uiDefault FormattedTextField.selectionBackground Color
|
||||
* @uiDefault FormattedTextField.selectionForeground Color
|
||||
* @uiDefault FormattedTextField.disabledBackground Color used if not enabled
|
||||
* @uiDefault FormattedTextField.inactiveBackground Color used if not editable
|
||||
* @uiDefault FormattedTextField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault FormattedTextField.border Border
|
||||
* @uiDefault FormattedTextField.margin Insets
|
||||
* @uiDefault FormattedTextField.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatTextFieldUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatFormattedTextFieldUI
|
||||
|
||||
@@ -33,10 +33,15 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JLabel}.
|
||||
*
|
||||
* <!-- BasicLabelUI -->
|
||||
*
|
||||
* @uiDefault Label.font Font
|
||||
* @uiDefault Label.background Color only used if opaque
|
||||
* @uiDefault Label.foreground Color
|
||||
*
|
||||
* <!-- FlatLabelUI -->
|
||||
*
|
||||
* @uiDefault Label.disabledForeground Color
|
||||
* @uiDefault Label.font Font
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,27 @@ import javax.swing.plaf.basic.BasicListUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JList}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicListUI -->
|
||||
*
|
||||
* @uiDefault List.font Font
|
||||
* @uiDefault List.background Color
|
||||
* @uiDefault List.foreground Color
|
||||
* @uiDefault List.selectionBackground Color
|
||||
* @uiDefault List.selectionForeground Color
|
||||
* @uiDefault List.dropLineColor Color
|
||||
* @uiDefault List.border Border
|
||||
* @uiDefault List.cellRenderer ListCellRenderer
|
||||
* @uiDefault FileChooser.listFont Font used if client property List.isFileList is true
|
||||
*
|
||||
* <!-- DefaultListCellRenderer -->
|
||||
*
|
||||
* @uiDefault List.cellNoFocusBorder Border
|
||||
* @uiDefault List.focusCellHighlightBorder Border
|
||||
* @uiDefault List.focusSelectedCellHighlightBorder Border
|
||||
* @uiDefault List.dropCellBackground Color
|
||||
* @uiDefault List.dropCellForeground Color
|
||||
*
|
||||
* <!-- FlatListUI -->
|
||||
*
|
||||
* @uiDefault List.selectionInactiveBackground Color
|
||||
* @uiDefault List.selectionInactiveForeground Color
|
||||
|
||||
@@ -23,6 +23,13 @@ import javax.swing.plaf.basic.BasicMenuBarUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
||||
*
|
||||
* <!-- BasicMenuBarUI -->
|
||||
*
|
||||
* @uiDefault MenuBar.font Font
|
||||
* @uiDefault MenuBar.background Color
|
||||
* @uiDefault MenuBar.foreground Color
|
||||
* @uiDefault MenuBar.border Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuBarUI
|
||||
|
||||
@@ -25,6 +25,26 @@ import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuItem}.
|
||||
*
|
||||
* <!-- BasicMenuItemUI -->
|
||||
*
|
||||
* @uiDefault MenuItem.font Font
|
||||
* @uiDefault MenuItem.background Color
|
||||
* @uiDefault MenuItem.foreground Color
|
||||
* @uiDefault MenuItem.disabledForeground Color
|
||||
* @uiDefault MenuItem.selectionBackground Color
|
||||
* @uiDefault MenuItem.selectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorForeground Color
|
||||
* @uiDefault MenuItem.acceleratorSelectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||
* @uiDefault MenuItem.border Border
|
||||
* @uiDefault MenuItem.borderPainted boolean
|
||||
* @uiDefault MenuItem.margin Insets
|
||||
* @uiDefault MenuItem.arrowIcon Icon
|
||||
* @uiDefault MenuItem.checkIcon Icon
|
||||
* @uiDefault MenuItem.opaque boolean
|
||||
* @uiDefault MenuItem.evenHeight boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuItemUI
|
||||
|
||||
@@ -25,6 +25,29 @@ import javax.swing.plaf.basic.BasicMenuUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenu}.
|
||||
*
|
||||
* <!-- BasicMenuUI -->
|
||||
*
|
||||
* @uiDefault Menu.font Font
|
||||
* @uiDefault Menu.background Color
|
||||
* @uiDefault Menu.foreground Color
|
||||
* @uiDefault Menu.disabledForeground Color
|
||||
* @uiDefault Menu.selectionBackground Color
|
||||
* @uiDefault Menu.selectionForeground Color
|
||||
* @uiDefault Menu.acceleratorForeground Color
|
||||
* @uiDefault Menu.acceleratorSelectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||
* @uiDefault Menu.border Border
|
||||
* @uiDefault Menu.borderPainted boolean
|
||||
* @uiDefault Menu.margin Insets
|
||||
* @uiDefault Menu.arrowIcon Icon
|
||||
* @uiDefault Menu.checkIcon Icon
|
||||
* @uiDefault Menu.opaque boolean
|
||||
* @uiDefault Menu.evenHeight boolean
|
||||
* @uiDefault Menu.crossMenuMnemonic boolean default is false
|
||||
* @uiDefault Menu.useMenuBarBackgroundForTopLevel boolean default is false
|
||||
* @uiDefault MenuBar.background Color used if Menu.useMenuBarBackgroundForTopLevel is true
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatMenuUI
|
||||
|
||||
@@ -19,10 +19,15 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.plaf.basic.BasicOptionPaneUI;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
@@ -30,6 +35,9 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JOptionPane}.
|
||||
*
|
||||
* @uiDefault OptionPane.font Font unused
|
||||
* @uiDefault OptionPane.background Color
|
||||
* @uiDefault OptionPane.foreground Color unused
|
||||
* @uiDefault OptionPane.border Border
|
||||
* @uiDefault OptionPane.messageAreaBorder Border
|
||||
* @uiDefault OptionPane.buttonAreaBorder Border
|
||||
@@ -77,6 +85,13 @@ public class FlatOptionPaneUI
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
super.installComponents();
|
||||
|
||||
updateChildPanels( optionPane );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumOptionPaneSize() {
|
||||
return UIScale.scale( super.getMinimumOptionPaneSize() );
|
||||
@@ -130,6 +145,26 @@ public class FlatOptionPaneUI
|
||||
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
|
||||
}
|
||||
|
||||
private void updateChildPanels( Container c ) {
|
||||
for( Component child : c.getComponents() ) {
|
||||
if( child instanceof JPanel ) {
|
||||
JPanel panel = (JPanel)child;
|
||||
|
||||
// make sub-panel non-opaque for OptionPane.background
|
||||
panel.setOpaque( false );
|
||||
|
||||
// use non-UIResource borders to avoid that they are replaced when switching LaF
|
||||
Border border = panel.getBorder();
|
||||
if( border instanceof UIResource )
|
||||
panel.setBorder( new NonUIResourceBorder( border ) );
|
||||
}
|
||||
|
||||
if( child instanceof Container ) {
|
||||
updateChildPanels( (Container) child );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Component findByName( Container c, String name ) {
|
||||
for( Component child : c.getComponents() ) {
|
||||
if( name.equals( child.getName() ) )
|
||||
@@ -143,4 +178,31 @@ public class FlatOptionPaneUI
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//---- class NonUIResourceBorder ------------------------------------------
|
||||
|
||||
private static class NonUIResourceBorder
|
||||
implements Border
|
||||
{
|
||||
private final Border delegate;
|
||||
|
||||
NonUIResourceBorder( Border delegate ) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
delegate.paintBorder( c, g, x, y, width, height );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c ) {
|
||||
return delegate.getBorderInsets( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return delegate.isBorderOpaque();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,27 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicPasswordFieldUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault PasswordField.font Font
|
||||
* @uiDefault PasswordField.background Color
|
||||
* @uiDefault PasswordField.foreground Color also used if not editable
|
||||
* @uiDefault PasswordField.caretForeground Color
|
||||
* @uiDefault PasswordField.selectionBackground Color
|
||||
* @uiDefault PasswordField.selectionForeground Color
|
||||
* @uiDefault PasswordField.disabledBackground Color used if not enabled
|
||||
* @uiDefault PasswordField.inactiveBackground Color used if not editable
|
||||
* @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault PasswordField.border Border
|
||||
* @uiDefault PasswordField.margin Insets
|
||||
* @uiDefault PasswordField.echoChar character
|
||||
* @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatPasswordFieldUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -42,6 +59,7 @@ public class FlatPasswordFieldUI
|
||||
{
|
||||
protected int focusWidth;
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
|
||||
private FocusListener focusListener;
|
||||
|
||||
@@ -59,6 +77,7 @@ public class FlatPasswordFieldUI
|
||||
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
|
||||
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
||||
|
||||
@@ -90,7 +109,7 @@ public class FlatPasswordFieldUI
|
||||
|
||||
@Override
|
||||
protected void paintSafely( Graphics g ) {
|
||||
FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth );
|
||||
FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
|
||||
super.paintSafely( g );
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,17 @@ import javax.swing.plaf.ComponentUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu.Separator}.
|
||||
*
|
||||
* <!-- BasicSeparatorUI -->
|
||||
*
|
||||
* @uiDefault PopupMenuSeparator.background Color unused
|
||||
* @uiDefault PopupMenuSeparator.foreground Color
|
||||
*
|
||||
* <!-- FlatSeparatorUI -->
|
||||
*
|
||||
* @uiDefault PopupMenuSeparator.height int height (or width) of the component; may be larger than stripe
|
||||
* @uiDefault PopupMenuSeparator.stripeWidth int width of the stripe
|
||||
* @uiDefault PopupMenuSeparator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatPopupMenuSeparatorUI
|
||||
|
||||
@@ -23,6 +23,13 @@ import javax.swing.plaf.basic.BasicPopupMenuUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu}.
|
||||
*
|
||||
* <!-- BasicPopupMenuUI -->
|
||||
*
|
||||
* @uiDefault PopupMenu.font Font
|
||||
* @uiDefault PopupMenu.background Color
|
||||
* @uiDefault PopupMenu.foreground Color
|
||||
* @uiDefault PopupMenu.border Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatPopupMenuUI
|
||||
|
||||
@@ -31,6 +31,19 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JProgressBar}.
|
||||
*
|
||||
* <!-- BasicProgressBarUI -->
|
||||
*
|
||||
* @uiDefault ProgressBar.font Font
|
||||
* @uiDefault ProgressBar.background Color
|
||||
* @uiDefault ProgressBar.foreground Color
|
||||
* @uiDefault ProgressBar.selectionBackground Color
|
||||
* @uiDefault ProgressBar.selectionForeground Color
|
||||
* @uiDefault ProgressBar.border Border
|
||||
* @uiDefault ProgressBar.horizontalSize Dimension default is 146,12
|
||||
* @uiDefault ProgressBar.verticalSize Dimension default is 12,146
|
||||
* @uiDefault ProgressBar.repaintInterval int default is 50 milliseconds
|
||||
* @uiDefault ProgressBar.cycleTime int default is 3000 milliseconds
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatProgressBarUI
|
||||
|
||||
@@ -25,6 +25,26 @@ import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButtonMenuItem}.
|
||||
*
|
||||
* <!-- BasicRadioButtonMenuItemUI -->
|
||||
*
|
||||
* @uiDefault RadioButtonMenuItem.font Font
|
||||
* @uiDefault RadioButtonMenuItem.background Color
|
||||
* @uiDefault RadioButtonMenuItem.foreground Color
|
||||
* @uiDefault RadioButtonMenuItem.disabledForeground Color
|
||||
* @uiDefault RadioButtonMenuItem.selectionBackground Color
|
||||
* @uiDefault RadioButtonMenuItem.selectionForeground Color
|
||||
* @uiDefault RadioButtonMenuItem.acceleratorForeground Color
|
||||
* @uiDefault RadioButtonMenuItem.acceleratorSelectionForeground Color
|
||||
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||
* @uiDefault RadioButtonMenuItem.border Border
|
||||
* @uiDefault RadioButtonMenuItem.borderPainted boolean
|
||||
* @uiDefault RadioButtonMenuItem.margin Insets
|
||||
* @uiDefault RadioButtonMenuItem.arrowIcon Icon
|
||||
* @uiDefault RadioButtonMenuItem.checkIcon Icon
|
||||
* @uiDefault RadioButtonMenuItem.opaque boolean
|
||||
* @uiDefault RadioButtonMenuItem.evenHeight boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatRadioButtonMenuItemUI
|
||||
|
||||
@@ -21,19 +21,31 @@ import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicRadioButtonUI;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButton}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault Button.iconTextGap int
|
||||
* @uiDefault Button.disabledText Color
|
||||
* @uiDefault RadioButton.font Font
|
||||
* @uiDefault RadioButton.background Color
|
||||
* @uiDefault RadioButton.foreground Color
|
||||
* @uiDefault RadioButton.border Border
|
||||
* @uiDefault RadioButton.margin Insets
|
||||
* @uiDefault RadioButton.rollover boolean
|
||||
* @uiDefault RadioButton.icon Icon
|
||||
*
|
||||
* <!-- FlatRadioButtonUI -->
|
||||
*
|
||||
* @uiDefault RadioButton.iconTextGap int
|
||||
* @uiDefault RadioButton.disabledText Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -80,6 +92,21 @@ public class FlatRadioButtonUI
|
||||
defaults_initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
// fill background even if opaque if
|
||||
// - used as cell renderer (because of selection background)
|
||||
// - if background was explicitly set to a non-UIResource color
|
||||
if( !c.isOpaque() &&
|
||||
(c.getParent() instanceof CellRendererPane || !(c.getBackground() instanceof UIResource)) )
|
||||
{
|
||||
g.setColor( c.getBackground() );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
}
|
||||
|
||||
super.paint( g, c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
||||
FlatButtonUI.paintText( g, b, textRect, text, b.isEnabled() ? b.getForeground() : disabledText );
|
||||
|
||||
@@ -22,27 +22,41 @@ import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollBar}.
|
||||
*
|
||||
* <!-- BasicScrollBarUI -->
|
||||
*
|
||||
* @uiDefault ScrollBar.background Color
|
||||
* @uiDefault ScrollBar.foreground Color
|
||||
* @uiDefault ScrollBar.track Color
|
||||
* @uiDefault ScrollBar.thumb Color
|
||||
* @uiDefault ScrollBar.hoverTrackColor Color
|
||||
* @uiDefault ScrollBar.hoverThumbColor Color
|
||||
* @uiDefault ScrollBar.width int
|
||||
* @uiDefault ScrollBar.minimumThumbSize Insets
|
||||
* @uiDefault ScrollBar.maximumThumbSize Insets
|
||||
* @uiDefault ScrollBar.minimumThumbSize Dimension
|
||||
* @uiDefault ScrollBar.maximumThumbSize Dimension
|
||||
* @uiDefault ScrollBar.allowsAbsolutePositioning boolean
|
||||
*
|
||||
* <!-- FlatScrollBarUI -->
|
||||
*
|
||||
* @uiDefault ScrollBar.hoverTrackColor Color
|
||||
* @uiDefault ScrollBar.hoverThumbColor Color
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault ScrollBar.showButtons boolean
|
||||
* @uiDefault ScrollBar.buttonArrowColor Color
|
||||
* @uiDefault ScrollBar.buttonDisabledArrowColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatScrollBarUI
|
||||
@@ -51,6 +65,11 @@ public class FlatScrollBarUI
|
||||
protected Color hoverTrackColor;
|
||||
protected Color hoverThumbColor;
|
||||
|
||||
protected boolean showButtons;
|
||||
protected String arrowType;
|
||||
protected Color buttonArrowColor;
|
||||
protected Color buttonDisabledArrowColor;
|
||||
|
||||
private MouseAdapter hoverListener;
|
||||
private boolean hoverTrack;
|
||||
private boolean hoverThumb;
|
||||
@@ -83,6 +102,11 @@ public class FlatScrollBarUI
|
||||
|
||||
hoverTrackColor = UIManager.getColor( "ScrollBar.hoverTrackColor" );
|
||||
hoverThumbColor = UIManager.getColor( "ScrollBar.hoverThumbColor" );
|
||||
|
||||
showButtons = UIManager.getBoolean( "ScrollBar.showButtons" );
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
buttonArrowColor = UIManager.getColor( "ScrollBar.buttonArrowColor" );
|
||||
buttonDisabledArrowColor = UIManager.getColor( "ScrollBar.buttonDisabledArrowColor" );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,6 +115,24 @@ public class FlatScrollBarUI
|
||||
|
||||
hoverTrackColor = null;
|
||||
hoverThumbColor = null;
|
||||
|
||||
buttonArrowColor = null;
|
||||
buttonDisabledArrowColor = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyChangeListener createPropertyChangeListener() {
|
||||
return new BasicScrollBarUI.PropertyChangeHandler() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
|
||||
if( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS.equals( e.getPropertyName() ) ) {
|
||||
scrollbar.revalidate();
|
||||
scrollbar.repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,24 +142,50 @@ public class FlatScrollBarUI
|
||||
|
||||
@Override
|
||||
protected JButton createDecreaseButton( int orientation ) {
|
||||
return createInvisibleButton();
|
||||
return createArrowButton( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JButton createIncreaseButton( int orientation ) {
|
||||
return createInvisibleButton();
|
||||
return createArrowButton( orientation );
|
||||
}
|
||||
|
||||
private JButton createInvisibleButton() {
|
||||
JButton button = new JButton();
|
||||
button.setMinimumSize( new Dimension() );
|
||||
button.setMaximumSize( new Dimension() );
|
||||
button.setPreferredSize( new Dimension() );
|
||||
private JButton createArrowButton( int orientation ) {
|
||||
FlatArrowButton button = new FlatArrowButton( orientation,
|
||||
arrowType, buttonArrowColor, buttonDisabledArrowColor, null, hoverTrackColor )
|
||||
{
|
||||
@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;
|
||||
}
|
||||
|
||||
private boolean isShowButtons() {
|
||||
Object showButtons = scrollbar.getClientProperty( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS );
|
||||
if( showButtons == null && scrollbar.getParent() instanceof JScrollPane )
|
||||
showButtons = ((JScrollPane)scrollbar.getParent()).getClientProperty( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS );
|
||||
return (showButtons != null) ? Objects.equals( showButtons, true ) : this.showButtons;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintDecreaseHighlight( Graphics g ) {
|
||||
// do not paint
|
||||
|
||||
@@ -24,17 +24,28 @@ import java.awt.event.ContainerListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
|
||||
*
|
||||
* <!-- BasicScrollPaneUI -->
|
||||
*
|
||||
* @uiDefault ScrollPane.font Font unused
|
||||
* @uiDefault ScrollPane.background Color
|
||||
* @uiDefault ScrollPane.foreground Color unused
|
||||
* @uiDefault ScrollPane.border Border
|
||||
* @uiDefault ScrollPane.viewportBorder Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatScrollPaneUI
|
||||
@@ -79,6 +90,29 @@ public class FlatScrollPaneUI
|
||||
handler = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyChangeListener createPropertyChangeListener() {
|
||||
return new BasicScrollPaneUI.PropertyChangeHandler() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
|
||||
if( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS.equals( e.getPropertyName() ) ) {
|
||||
JScrollBar vsb = scrollpane.getVerticalScrollBar();
|
||||
JScrollBar hsb = scrollpane.getHorizontalScrollBar();
|
||||
if( vsb != null ) {
|
||||
vsb.revalidate();
|
||||
vsb.repaint();
|
||||
}
|
||||
if( hsb != null ) {
|
||||
hsb.revalidate();
|
||||
hsb.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Handler getHandler() {
|
||||
if( handler == null )
|
||||
handler = new Handler();
|
||||
|
||||
@@ -30,8 +30,13 @@ import javax.swing.plaf.basic.BasicSeparatorUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSeparator}.
|
||||
*
|
||||
* <!-- BasicSeparatorUI -->
|
||||
*
|
||||
* @uiDefault Separator.background Color unused
|
||||
* @uiDefault Separator.foreground Color
|
||||
*
|
||||
* <!-- FlatSeparatorUI -->
|
||||
*
|
||||
* @uiDefault Separator.height int height (or width) of the component; may be larger than stripe
|
||||
* @uiDefault Separator.stripeWidth int width of the stripe
|
||||
* @uiDefault Separator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component
|
||||
|
||||
@@ -34,21 +34,27 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSlider}.
|
||||
*
|
||||
* <!-- BasicSliderUI -->
|
||||
*
|
||||
* @uiDefault Slider.font Font
|
||||
* @uiDefault Slider.background Color
|
||||
* @uiDefault Slider.foreground Color unused
|
||||
* @uiDefault Slider.disabledForeground Color used for track and thumb if disabled
|
||||
* @uiDefault Slider.trackColor Color
|
||||
* @uiDefault Slider.thumbColor Color
|
||||
* @uiDefault Slider.tickColor Color
|
||||
* @uiDefault Slider.focusedColor Color
|
||||
* @uiDefault Slider.hoverColor Color optional; defaults to Slider.focusedColor
|
||||
* @uiDefault Slider.trackWidth int
|
||||
* @uiDefault Slider.thumbWidth int
|
||||
* @uiDefault Slider.horizontalSize Dimension preferred horizontal size; height is ignored; computed slider height is used
|
||||
* @uiDefault Slider.verticalSize Dimension preferred vertical size; width is ignored; computed slider width is used
|
||||
* @uiDefault Slider.minimumHorizontalSize Dimension height is ignored; computed slider height is used
|
||||
* @uiDefault Slider.minimumVerticalSize Dimension width is ignored; computed slider width is used
|
||||
* @uiDefault Slider.border Border
|
||||
*
|
||||
* <!-- FlatSliderUI -->
|
||||
*
|
||||
* @uiDefault Slider.trackWidth int
|
||||
* @uiDefault Slider.thumbWidth int
|
||||
* @uiDefault Slider.trackColor Color
|
||||
* @uiDefault Slider.thumbColor Color
|
||||
* @uiDefault Slider.focusedColor Color optional; defaults to Component.focusColor
|
||||
* @uiDefault Slider.hoverColor Color optional; defaults to Slider.focusedColor
|
||||
* @uiDefault Slider.disabledForeground Color used for track and thumb is disabled
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -104,7 +110,7 @@ public class FlatSliderUI
|
||||
|
||||
trackColor = UIManager.getColor( "Slider.trackColor" );
|
||||
thumbColor = UIManager.getColor( "Slider.thumbColor" );
|
||||
focusColor = UIManager.getColor( "Slider.focusedColor" );
|
||||
focusColor = FlatUIUtils.getUIColor( "Slider.focusedColor", "Component.focusColor" );
|
||||
hoverColor = FlatUIUtils.getUIColor( "Slider.hoverColor", focusColor );
|
||||
disabledForeground = UIManager.getColor( "Slider.disabledForeground" );
|
||||
}
|
||||
@@ -195,7 +201,7 @@ public class FlatSliderUI
|
||||
}
|
||||
|
||||
if( coloredTrack != null ) {
|
||||
g.setColor( slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor) );
|
||||
FlatUIUtils.setColor( g, slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor), thumbColor );
|
||||
((Graphics2D)g).fill( coloredTrack );
|
||||
}
|
||||
|
||||
@@ -205,9 +211,10 @@ public class FlatSliderUI
|
||||
|
||||
@Override
|
||||
public void paintThumb( Graphics g ) {
|
||||
g.setColor( slider.isEnabled()
|
||||
FlatUIUtils.setColor( g, slider.isEnabled()
|
||||
? (slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor))
|
||||
: disabledForeground );
|
||||
: disabledForeground,
|
||||
thumbColor );
|
||||
|
||||
if( isRoundThumb() )
|
||||
g.fillOval( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height );
|
||||
|
||||
@@ -44,12 +44,23 @@ import javax.swing.plaf.basic.BasicSpinnerUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSpinner}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicSpinnerUI -->
|
||||
*
|
||||
* @uiDefault Spinner.font Font
|
||||
* @uiDefault Spinner.background Color
|
||||
* @uiDefault Spinner.foreground Color
|
||||
* @uiDefault Spinner.border Border
|
||||
* @uiDefault Spinner.disableOnBoundaryValues boolean default is false
|
||||
* @uiDefault Spinner.editorAlignment int 0=center, 2=left, 4=right, 10=leading, 11=trailing
|
||||
* @uiDefault Spinner.editorBorderPainted boolean paint inner editor border; defaults to false
|
||||
*
|
||||
* <!-- FlatSpinnerUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.arc int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Spinner.disabledBackground Color
|
||||
@@ -71,6 +82,7 @@ public class FlatSpinnerUI
|
||||
protected int arc;
|
||||
protected int minimumWidth;
|
||||
protected String arrowType;
|
||||
protected boolean isIntelliJTheme;
|
||||
protected Color borderColor;
|
||||
protected Color disabledBorderColor;
|
||||
protected Color disabledBackground;
|
||||
@@ -95,6 +107,7 @@ public class FlatSpinnerUI
|
||||
arc = UIManager.getInt( "Component.arc" );
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
|
||||
@@ -251,7 +264,9 @@ public class FlatSpinnerUI
|
||||
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
|
||||
|
||||
// paint background
|
||||
g2.setColor( enabled ? c.getBackground() : disabledBackground );
|
||||
g2.setColor( enabled
|
||||
? c.getBackground()
|
||||
: (isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground) );
|
||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
||||
|
||||
// paint arrow buttons background
|
||||
|
||||
@@ -31,14 +31,19 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSplitPane}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* <!-- BasicSplitPaneUI -->
|
||||
*
|
||||
* @uiDefault SplitPane.background Color
|
||||
* @uiDefault SplitPane.foreground Color unused
|
||||
* @uiDefault SplitPane.dividerSize int
|
||||
* @uiDefault SplitPane.continuousLayout boolean
|
||||
* @uiDefault SplitPane.border Border
|
||||
* @uiDefault SplitPaneDivider.border Border
|
||||
* @uiDefault SplitPaneDivider.draggingColor Color only used if continuousLayout is false
|
||||
*
|
||||
* <!-- FlatSplitPaneUI -->
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault SplitPane.continuousLayout boolean
|
||||
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color
|
||||
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color
|
||||
*
|
||||
|
||||
@@ -36,7 +36,13 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.table.JTableHeader}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicTableHeaderUI -->
|
||||
*
|
||||
* @uiDefault TableHeader.font Font
|
||||
* @uiDefault TableHeader.background Color
|
||||
* @uiDefault TableHeader.foreground Color
|
||||
*
|
||||
* <!-- FlatTableHeaderUI -->
|
||||
*
|
||||
* @uiDefault TableHeader.separatorColor Color
|
||||
* @uiDefault TableHeader.bottomSeparatorColor Color
|
||||
@@ -75,8 +81,10 @@ public class FlatTableHeaderUI
|
||||
@Override
|
||||
public void paint( Graphics g, JComponent c ) {
|
||||
// do not paint borders if JTableHeader.setDefaultRenderer() was used
|
||||
boolean paintBorders = header.getDefaultRenderer().getClass().getName().equals(
|
||||
"sun.swing.table.DefaultTableCellHeaderRenderer" );
|
||||
String rendererClassName = header.getDefaultRenderer().getClass().getName();
|
||||
boolean paintBorders =
|
||||
rendererClassName.equals( "sun.swing.table.DefaultTableCellHeaderRenderer" ) ||
|
||||
rendererClassName.equals( "sun.swing.FilePane$AlignableTableHeaderRenderer" );
|
||||
|
||||
if( paintBorders )
|
||||
paintColumnBorders( g, c );
|
||||
|
||||
@@ -29,7 +29,30 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTable}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicTableUI -->
|
||||
*
|
||||
* @uiDefault Table.font Font
|
||||
* @uiDefault Table.background Color
|
||||
* @uiDefault Table.foreground Color
|
||||
* @uiDefault Table.selectionBackground Color
|
||||
* @uiDefault Table.selectionForeground Color
|
||||
* @uiDefault Table.gridColor Color
|
||||
* @uiDefault Table.scrollPaneBorder Border
|
||||
* @uiDefault Table.dropLineColor Color
|
||||
* @uiDefault Table.dropLineShortColor Color
|
||||
*
|
||||
* <!-- DefaultTableCellRenderer -->
|
||||
*
|
||||
* @uiDefault Table.cellNoFocusBorder Border
|
||||
* @uiDefault Table.focusCellHighlightBorder Border
|
||||
* @uiDefault Table.focusSelectedCellHighlightBorder Border
|
||||
* @uiDefault Table.dropCellBackground Color
|
||||
* @uiDefault Table.dropCellForeground Color
|
||||
* @uiDefault Table.alternateRowColor Color
|
||||
* @uiDefault Table.focusCellBackground Color
|
||||
* @uiDefault Table.focusCellForeground Color
|
||||
*
|
||||
* <!-- FlatTableUI -->
|
||||
*
|
||||
* @uiDefault Table.rowHeight int
|
||||
* @uiDefault Table.selectionInactiveBackground Color
|
||||
|
||||
@@ -31,11 +31,25 @@ import javax.swing.text.JTextComponent;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextArea}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicTextAreaUI -->
|
||||
*
|
||||
* @uiDefault TextArea.font Font
|
||||
* @uiDefault TextArea.background Color
|
||||
* @uiDefault TextArea.foreground Color also used if not editable
|
||||
* @uiDefault TextArea.caretForeground Color
|
||||
* @uiDefault TextArea.selectionBackground Color
|
||||
* @uiDefault TextArea.selectionForeground Color
|
||||
* @uiDefault TextArea.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault TextArea.border Border
|
||||
* @uiDefault TextArea.margin Insets
|
||||
* @uiDefault TextArea.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatTextAreaUI -->
|
||||
*
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault TextArea.disabledBackground Color
|
||||
* @uiDefault TextArea.inactiveBackground Color
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault TextArea.disabledBackground Color used if not enabled
|
||||
* @uiDefault TextArea.inactiveBackground Color used if not editable
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -43,6 +57,7 @@ public class FlatTextAreaUI
|
||||
extends BasicTextAreaUI
|
||||
{
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
protected Color disabledBackground;
|
||||
protected Color inactiveBackground;
|
||||
|
||||
@@ -55,6 +70,7 @@ public class FlatTextAreaUI
|
||||
super.installDefaults();
|
||||
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
|
||||
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
|
||||
}
|
||||
@@ -74,9 +90,11 @@ public class FlatTextAreaUI
|
||||
Color background = c.getBackground();
|
||||
g.setColor( !(background instanceof UIResource)
|
||||
? background
|
||||
: (!c.isEnabled()
|
||||
? disabledBackground
|
||||
: (!c.isEditable() ? inactiveBackground : background)) );
|
||||
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
|
||||
? FlatUIUtils.getParentBackground( c )
|
||||
: (!c.isEnabled()
|
||||
? disabledBackground
|
||||
: (!c.isEditable() ? inactiveBackground : background))) );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -29,16 +30,33 @@ import javax.swing.JTextField;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicTextFieldUI -->
|
||||
*
|
||||
* @uiDefault TextField.font Font
|
||||
* @uiDefault TextField.background Color
|
||||
* @uiDefault TextField.foreground Color also used if not editable
|
||||
* @uiDefault TextField.caretForeground Color
|
||||
* @uiDefault TextField.selectionBackground Color
|
||||
* @uiDefault TextField.selectionForeground Color
|
||||
* @uiDefault TextField.disabledBackground Color used if not enabled
|
||||
* @uiDefault TextField.inactiveBackground Color used if not editable
|
||||
* @uiDefault TextField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault TextField.border Border
|
||||
* @uiDefault TextField.margin Insets
|
||||
* @uiDefault TextField.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatTextFieldUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -47,6 +65,7 @@ public class FlatTextFieldUI
|
||||
{
|
||||
protected int focusWidth;
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
|
||||
private FocusListener focusListener;
|
||||
|
||||
@@ -60,6 +79,7 @@ public class FlatTextFieldUI
|
||||
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
|
||||
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
||||
|
||||
@@ -91,7 +111,7 @@ public class FlatTextFieldUI
|
||||
|
||||
@Override
|
||||
protected void paintSafely( Graphics g ) {
|
||||
paintBackground( g, getComponent(), focusWidth );
|
||||
paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
|
||||
super.paintSafely( g );
|
||||
}
|
||||
|
||||
@@ -100,7 +120,7 @@ public class FlatTextFieldUI
|
||||
// background is painted elsewhere
|
||||
}
|
||||
|
||||
static void paintBackground( Graphics g, JTextComponent c, int focusWidth ) {
|
||||
static void paintBackground( Graphics g, JTextComponent c, int focusWidth, boolean isIntelliJTheme ) {
|
||||
// do not paint background if:
|
||||
// - not opaque and
|
||||
// - border is not a flat border and
|
||||
@@ -120,7 +140,12 @@ public class FlatTextFieldUI
|
||||
|
||||
float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0;
|
||||
|
||||
g2.setColor( c.getBackground() );
|
||||
Color background = c.getBackground();
|
||||
g2.setColor( !(background instanceof UIResource)
|
||||
? background
|
||||
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
|
||||
? FlatUIUtils.getParentBackground( c )
|
||||
: background) );
|
||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
|
||||
@@ -18,18 +18,37 @@ package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextPaneUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicTextPaneUI -->
|
||||
*
|
||||
* @uiDefault TextPane.font Font
|
||||
* @uiDefault TextPane.background Color
|
||||
* @uiDefault TextPane.foreground Color also used if not editable
|
||||
* @uiDefault TextPane.caretForeground Color
|
||||
* @uiDefault TextPane.selectionBackground Color
|
||||
* @uiDefault TextPane.selectionForeground Color
|
||||
* @uiDefault TextPane.disabledBackground Color used if not enabled
|
||||
* @uiDefault TextPane.inactiveBackground Color used if not editable
|
||||
* @uiDefault TextPane.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||
* @uiDefault TextPane.border Border
|
||||
* @uiDefault TextPane.margin Insets
|
||||
* @uiDefault TextPane.caretBlinkRate int default is 500 milliseconds
|
||||
*
|
||||
* <!-- FlatTextPaneUI -->
|
||||
*
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -37,6 +56,7 @@ public class FlatTextPaneUI
|
||||
extends BasicTextPaneUI
|
||||
{
|
||||
protected int minimumWidth;
|
||||
protected boolean isIntelliJTheme;
|
||||
|
||||
private Object oldHonorDisplayProperties;
|
||||
|
||||
@@ -49,6 +69,7 @@ public class FlatTextPaneUI
|
||||
super.installDefaults();
|
||||
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||
|
||||
// use component font and foreground for HTML text
|
||||
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
||||
@@ -80,4 +101,17 @@ public class FlatTextPaneUI
|
||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||
return size;
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,17 +26,33 @@ import javax.swing.plaf.ComponentUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToggleButton}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicButtonUI -->
|
||||
*
|
||||
* @uiDefault ToggleButton.font Font
|
||||
* @uiDefault ToggleButton.background Color
|
||||
* @uiDefault ToggleButton.foreground Color
|
||||
* @uiDefault ToggleButton.border Border
|
||||
* @uiDefault ToggleButton.margin Insets
|
||||
* @uiDefault ToggleButton.rollover boolean
|
||||
*
|
||||
* <!-- FlatButtonUI -->
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault ToggleButton.arc int
|
||||
* @uiDefault ToggleButton.minimumWidth int
|
||||
* @uiDefault ToggleButton.iconTextGap int
|
||||
* @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.disabledText Color
|
||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||
*
|
||||
* <!-- FlatToggleButtonUI -->
|
||||
*
|
||||
* @uiDefault ToggleButton.selectedBackground Color
|
||||
* @uiDefault ToggleButton.selectedForeground Color
|
||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||
*
|
||||
*
|
||||
|
||||
@@ -33,6 +33,8 @@ import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar.Separator}.
|
||||
*
|
||||
* <!-- FlatToolBarSeparatorUI -->
|
||||
*
|
||||
* @uiDefault ToolBar.separatorWidth int
|
||||
* @uiDefault ToolBar.separatorColor Color
|
||||
*
|
||||
|
||||
@@ -33,7 +33,19 @@ import javax.swing.plaf.basic.BasicToolBarUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
|
||||
*
|
||||
* TODO document used UI defaults of superclass
|
||||
* <!-- BasicToolBarUI -->
|
||||
*
|
||||
* @uiDefault ToolBar.font Font
|
||||
* @uiDefault ToolBar.background Color
|
||||
* @uiDefault ToolBar.foreground Color
|
||||
* @uiDefault ToolBar.border Border
|
||||
* @uiDefault ToolBar.dockingBackground Color
|
||||
* @uiDefault ToolBar.dockingForeground Color
|
||||
* @uiDefault ToolBar.floatingBackground Color
|
||||
* @uiDefault ToolBar.floatingForeground Color
|
||||
* @uiDefault ToolBar.isRollover boolean
|
||||
*
|
||||
* <!-- FlatToolBarUI -->
|
||||
*
|
||||
* @uiDefault ToolBar.buttonMargins Insets
|
||||
*
|
||||
|
||||
@@ -27,11 +27,21 @@ import javax.swing.JToolTip;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicToolTipUI;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolTip}.
|
||||
*
|
||||
* <!-- BasicToolTipUI -->
|
||||
*
|
||||
* @uiDefault ToolTip.font Font
|
||||
* @uiDefault ToolTip.background Color
|
||||
* @uiDefault ToolTip.foreground Color
|
||||
* @uiDefault ToolTip.backgroundInactive Color
|
||||
* @uiDefault ToolTip.foregroundInactive Color
|
||||
* @uiDefault ToolTip.border Border
|
||||
* @uiDefault ToolTip.borderInactive Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatToolTipUI
|
||||
@@ -51,7 +61,7 @@ public class FlatToolTipUI
|
||||
FontMetrics fm = c.getFontMetrics( c.getFont() );
|
||||
Insets insets = c.getInsets();
|
||||
|
||||
List<String> lines = FlatLaf.split( ((JToolTip)c).getTipText(), '\n' );
|
||||
List<String> lines = StringUtils.split( ((JToolTip)c).getTipText(), '\n' );
|
||||
int width = 0;
|
||||
int height = fm.getHeight() * Math.max( lines.size(), 1 );
|
||||
for( String line : lines )
|
||||
@@ -71,7 +81,7 @@ public class FlatToolTipUI
|
||||
FlatUIUtils.setRenderingHints( (Graphics2D) g );
|
||||
g.setColor( c.getForeground() );
|
||||
|
||||
List<String> lines = FlatLaf.split( ((JToolTip)c).getTipText(), '\n' );
|
||||
List<String> lines = StringUtils.split( ((JToolTip)c).getTipText(), '\n' );
|
||||
|
||||
int x = insets.left;
|
||||
int x2 = c.getWidth() - insets.right;
|
||||
|
||||
@@ -91,6 +91,11 @@ public class FlatUIUtils
|
||||
return (color != null) ? color : defaultColor;
|
||||
}
|
||||
|
||||
public static Color getUIColor( String key, String defaultKey ) {
|
||||
Color color = UIManager.getColor( key );
|
||||
return (color != null) ? color : UIManager.getColor( defaultKey );
|
||||
}
|
||||
|
||||
public static int getUIInt( String key, int defaultValue ) {
|
||||
Object value = UIManager.get( key );
|
||||
return (value instanceof Integer) ? (Integer) value : defaultValue;
|
||||
@@ -163,6 +168,16 @@ public class FlatUIUtils
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the background color of the first opaque parent.
|
||||
*/
|
||||
public static Color getParentBackground( JComponent c ) {
|
||||
Container parent = findOpaqueParent( c );
|
||||
return (parent != null)
|
||||
? parent.getBackground()
|
||||
: UIManager.getColor( "Panel.background" ); // fallback, probably never used
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first parent that is opaque.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,12 @@ import javax.swing.plaf.basic.BasicViewportUI;
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JViewport}.
|
||||
*
|
||||
* <!-- BasicViewportUI -->
|
||||
*
|
||||
* @uiDefault Viewport.font Font unused
|
||||
* @uiDefault Viewport.background Color
|
||||
* @uiDefault Viewport.foreground Color unused
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatViewportUI
|
||||
|
||||
@@ -312,7 +312,7 @@ public class HSLColor
|
||||
*
|
||||
* @param hsl an array containing the 3 HSL values
|
||||
*
|
||||
* @returns the RGB Color object
|
||||
* @return the RGB Color object
|
||||
*/
|
||||
public static Color toRGB(float[] hsl)
|
||||
{
|
||||
@@ -328,7 +328,7 @@ public class HSLColor
|
||||
* @param hsl an array containing the 3 HSL values
|
||||
* @param alpha the alpha value between 0 - 1
|
||||
*
|
||||
* @returns the RGB Color object
|
||||
* @return the RGB Color object
|
||||
*/
|
||||
public static Color toRGB(float[] hsl, float alpha)
|
||||
{
|
||||
@@ -342,7 +342,7 @@ public class HSLColor
|
||||
* @param s Saturation is specified as a percentage in the range 1 - 100.
|
||||
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
||||
*
|
||||
* @returns the RGB Color object
|
||||
* @return the RGB Color object
|
||||
*/
|
||||
public static Color toRGB(float h, float s, float l)
|
||||
{
|
||||
@@ -357,7 +357,7 @@ public class HSLColor
|
||||
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
||||
* @param alpha the alpha value between 0 - 1
|
||||
*
|
||||
* @returns the RGB Color object
|
||||
* @return the RGB Color object
|
||||
*/
|
||||
public static Color toRGB(float h, float s, float l, float alpha)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility methods for strings.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class StringUtils
|
||||
{
|
||||
public static String removeLeading( String string, String leading ) {
|
||||
return string.startsWith( leading )
|
||||
? string.substring( leading.length() )
|
||||
: string;
|
||||
}
|
||||
|
||||
public static String removeTrailing( String string, String trailing ) {
|
||||
return string.endsWith( trailing )
|
||||
? string.substring( 0, string.length() - trailing.length() )
|
||||
: string;
|
||||
}
|
||||
|
||||
public static List<String> split( String str, char delim ) {
|
||||
ArrayList<String> strs = new ArrayList<>();
|
||||
int delimIndex = str.indexOf( delim );
|
||||
int index = 0;
|
||||
while( delimIndex >= 0 ) {
|
||||
strs.add( str.substring( index, delimIndex ) );
|
||||
index = delimIndex + 1;
|
||||
delimIndex = str.indexOf( delim, index );
|
||||
}
|
||||
strs.add( str.substring( index ) );
|
||||
|
||||
return strs;
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,16 @@
|
||||
|
||||
#---- variables ----
|
||||
|
||||
@background=3c3f41
|
||||
@foreground=bbbbbb
|
||||
@selectionBackground=4B6EAF
|
||||
@background=#3c3f41
|
||||
@foreground=#bbbbbb
|
||||
@selectionBackground=#4B6EAF
|
||||
@selectionForeground=@foreground
|
||||
@selectionInactiveBackground=0D293E
|
||||
@selectionInactiveBackground=#0D293E
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=777777
|
||||
@textComponentBackground=45494A
|
||||
@cellFocusColor=000000
|
||||
@icon=adadad
|
||||
@disabledText=#777777
|
||||
@textComponentBackground=#45494A
|
||||
@cellFocusColor=#000000
|
||||
@icon=#adadad
|
||||
|
||||
# Button
|
||||
@buttonHoverBackground=lighten(3%,autoInverse)
|
||||
@@ -50,78 +50,79 @@
|
||||
*.disabledBackground=@background
|
||||
*.disabledForeground=@disabledText
|
||||
*.disabledText=@disabledText
|
||||
*.acceleratorForeground=bbbbbb
|
||||
*.acceleratorForeground=#bbbbbb
|
||||
*.acceleratorSelectionForeground=@selectionForeground
|
||||
|
||||
|
||||
#---- system ----
|
||||
#---- system colors ----
|
||||
|
||||
control=@background
|
||||
controlText=@foreground
|
||||
infoText=@foreground
|
||||
text=@foreground
|
||||
textText=@foreground
|
||||
window=@background
|
||||
activeCaption=#434E60
|
||||
inactiveCaption=#393C3D
|
||||
controlHighlight=#616669
|
||||
controlLtHighlight=#303234
|
||||
controlShadow=#afb3b5
|
||||
controlDkShadow=#d7d9da
|
||||
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.background=4c5052
|
||||
Button.background=#4c5052
|
||||
Button.hoverBackground=@buttonHoverBackground
|
||||
Button.pressedBackground=@buttonPressedBackground
|
||||
|
||||
Button.borderColor=5e6060
|
||||
Button.disabledBorderColor=5e6060
|
||||
Button.focusedBorderColor=466d94
|
||||
Button.borderColor=#5e6060
|
||||
Button.disabledBorderColor=#5e6060
|
||||
Button.focusedBorderColor=#466d94
|
||||
Button.hoverBorderColor=@@Button.focusedBorderColor
|
||||
|
||||
Button.default.background=365880
|
||||
Button.default.foreground=bbbbbb
|
||||
Button.default.background=#365880
|
||||
Button.default.foreground=#bbbbbb
|
||||
Button.default.hoverBackground=@buttonHoverBackground
|
||||
Button.default.pressedBackground=@buttonPressedBackground
|
||||
Button.default.borderColor=4c708c
|
||||
Button.default.hoverBorderColor=537699
|
||||
Button.default.focusedBorderColor=537699
|
||||
Button.default.focusColor=43688c
|
||||
Button.default.borderColor=#4c708c
|
||||
Button.default.hoverBorderColor=#537699
|
||||
Button.default.focusedBorderColor=#537699
|
||||
Button.default.focusColor=#43688c
|
||||
Button.default.boldText=true
|
||||
|
||||
Button.toolbar.hoverBackground=4c5052
|
||||
Button.toolbar.pressedBackground=555a5d
|
||||
Button.toolbar.hoverBackground=#4c5052
|
||||
Button.toolbar.pressedBackground=#555a5d
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
CheckBox.icon.borderColor=6B6B6B
|
||||
CheckBox.icon.disabledBorderColor=545556
|
||||
CheckBox.icon.selectedBorderColor=6B6B6B
|
||||
CheckBox.icon.focusedBorderColor=466D94
|
||||
CheckBox.icon.borderColor=#6B6B6B
|
||||
CheckBox.icon.disabledBorderColor=#545556
|
||||
CheckBox.icon.selectedBorderColor=#6B6B6B
|
||||
CheckBox.icon.focusedBorderColor=#466D94
|
||||
CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
|
||||
CheckBox.icon.selectedFocusedBorderColor=466D94
|
||||
CheckBox.icon.background=43494A
|
||||
CheckBox.icon.selectedFocusedBorderColor=#466D94
|
||||
CheckBox.icon.background=#43494A
|
||||
CheckBox.icon.disabledBackground=@background
|
||||
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
||||
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
||||
CheckBox.icon.selectedBackground=43494A
|
||||
CheckBox.icon.checkmarkColor=A7A7A7
|
||||
CheckBox.icon.disabledCheckmarkColor=606060
|
||||
CheckBox.icon.selectedBackground=#43494A
|
||||
CheckBox.icon.checkmarkColor=#A7A7A7
|
||||
CheckBox.icon.disabledCheckmarkColor=#606060
|
||||
|
||||
|
||||
#---- ComboBox ----
|
||||
|
||||
ComboBox.background=@textComponentBackground
|
||||
ComboBox.buttonBackground=@textComponentBackground
|
||||
ComboBox.buttonEditableBackground=404445
|
||||
ComboBox.buttonArrowColor=9A9DA1
|
||||
ComboBox.buttonDisabledArrowColor=585858
|
||||
ComboBox.buttonHoverArrowColor=bbbbbb
|
||||
ComboBox.buttonEditableBackground=#404445
|
||||
ComboBox.buttonArrowColor=#9A9DA1
|
||||
ComboBox.buttonDisabledArrowColor=#585858
|
||||
ComboBox.buttonHoverArrowColor=#bbbbbb
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
Component.borderColor=646464
|
||||
Component.disabledBorderColor=646464
|
||||
Component.focusedBorderColor=466d94
|
||||
Component.focusColor=3d6185
|
||||
Component.borderColor=#646464
|
||||
Component.disabledBorderColor=#646464
|
||||
Component.focusedBorderColor=#466d94
|
||||
Component.focusColor=#3d6185
|
||||
Component.linkColor=#589df6
|
||||
|
||||
|
||||
#---- List ----
|
||||
@@ -131,111 +132,101 @@ List.background=@textComponentBackground
|
||||
|
||||
#---- Menu ----
|
||||
|
||||
Menu.icon.arrowColor=A7A7A7
|
||||
Menu.icon.disabledArrowColor=606060
|
||||
Menu.icon.arrowColor=#A7A7A7
|
||||
Menu.icon.disabledArrowColor=#606060
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=515151
|
||||
MenuBar.borderColor=#515151
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
|
||||
MenuItemCheckBox.icon.checkmarkColor=A7A7A7
|
||||
MenuItemCheckBox.icon.disabledCheckmarkColor=606060
|
||||
|
||||
|
||||
#---- OptionPane ----
|
||||
|
||||
OptionPane.icon.errorColor=C75450
|
||||
OptionPane.icon.informationColor=3592C4
|
||||
OptionPane.icon.questionColor=3592C4
|
||||
OptionPane.icon.warningColor=F0A732
|
||||
OptionPane.icon.foreground=null
|
||||
MenuItemCheckBox.icon.checkmarkColor=#A7A7A7
|
||||
MenuItemCheckBox.icon.disabledCheckmarkColor=#606060
|
||||
|
||||
|
||||
#---- PopupMenu ----
|
||||
|
||||
PopupMenu.borderColor=515151
|
||||
PopupMenu.borderColor=#515151
|
||||
|
||||
|
||||
#---- ProgressBar ----
|
||||
|
||||
ProgressBar.background=555555
|
||||
ProgressBar.foreground=a0a0a0
|
||||
ProgressBar.background=#555555
|
||||
ProgressBar.foreground=#a0a0a0
|
||||
ProgressBar.selectionForeground=@background
|
||||
ProgressBar.selectionBackground=@foreground
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.track=3F4244
|
||||
ScrollBar.thumb=5B5E5F
|
||||
ScrollBar.hoverTrackColor=434647
|
||||
ScrollBar.hoverThumbColor=666868
|
||||
ScrollBar.track=#3F4244
|
||||
ScrollBar.thumb=#5B5E5F
|
||||
ScrollBar.hoverTrackColor=#434647
|
||||
ScrollBar.hoverThumbColor=#666868
|
||||
|
||||
|
||||
#---- Separator ----
|
||||
|
||||
Separator.foreground=515151
|
||||
Separator.foreground=#515151
|
||||
|
||||
|
||||
#---- Slider ----
|
||||
|
||||
Slider.trackColor=646464
|
||||
Slider.thumbColor=A6A6A6
|
||||
Slider.tickColor=888888
|
||||
Slider.focusedColor=@@Component.focusColor
|
||||
Slider.hoverColor=888888
|
||||
Slider.disabledForeground=4c5052
|
||||
Slider.trackColor=#646464
|
||||
Slider.thumbColor=#A6A6A6
|
||||
Slider.tickColor=#888888
|
||||
Slider.hoverColor=darken(15%,autoInverse)
|
||||
Slider.disabledForeground=#4c5052
|
||||
|
||||
|
||||
#---- SplitPane ----
|
||||
|
||||
SplitPaneDivider.draggingColor=646464
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=7A7D81
|
||||
SplitPaneDivider.draggingColor=#646464
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=#7A7D81
|
||||
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.disabledForeground=777777
|
||||
TabbedPane.underlineColor=4A88C7
|
||||
TabbedPane.disabledUnderlineColor=7a7a7a
|
||||
TabbedPane.hoverColor=2e3133
|
||||
TabbedPane.focusColor=3d4b5c
|
||||
TabbedPane.contentAreaColor=323232
|
||||
TabbedPane.disabledForeground=#777777
|
||||
TabbedPane.underlineColor=#4A88C7
|
||||
TabbedPane.disabledUnderlineColor=#7a7a7a
|
||||
TabbedPane.hoverColor=#2e3133
|
||||
TabbedPane.focusColor=#3d4b5c
|
||||
TabbedPane.contentAreaColor=#323232
|
||||
|
||||
|
||||
#---- Table ----
|
||||
|
||||
Table.background=@textComponentBackground
|
||||
Table.gridColor=4F5152
|
||||
Table.gridColor=#4F5152
|
||||
|
||||
|
||||
#---- TableHeader ----
|
||||
|
||||
TableHeader.background=45494A
|
||||
TableHeader.separatorColor=585858
|
||||
TableHeader.bottomSeparatorColor=585858
|
||||
TableHeader.background=#45494A
|
||||
TableHeader.separatorColor=#585858
|
||||
TableHeader.bottomSeparatorColor=#585858
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=64696C
|
||||
ToggleButton.selectedBackground=#64696C
|
||||
ToggleButton.selectedForeground=@foreground
|
||||
ToggleButton.disabledSelectedBackground=525658
|
||||
ToggleButton.disabledSelectedBackground=#525658
|
||||
|
||||
ToggleButton.toolbar.selectedBackground=5c6164
|
||||
ToggleButton.toolbar.selectedBackground=#5c6164
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.border=4,6,4,6
|
||||
ToolTip.background=1e2123
|
||||
ToolTip.background=#1e2123
|
||||
|
||||
|
||||
#---- Tree ----
|
||||
|
||||
Tree.background=@textComponentBackground
|
||||
Tree.hash=505355
|
||||
Tree.hash=#505355
|
||||
|
||||
@@ -22,27 +22,25 @@
|
||||
|
||||
Button.focusedBackground=null
|
||||
|
||||
Button.default.background=4A86C7
|
||||
Button.default.foreground=f0f0f0
|
||||
Button.default.background=#4A86C7
|
||||
Button.default.foreground=#f0f0f0
|
||||
Button.default.focusedBackground=null
|
||||
Button.default.hoverBackground=5B91CC
|
||||
Button.default.pressedBackground=6E9ED2
|
||||
Button.default.borderColor=3167ad
|
||||
Button.default.hoverBorderColor=a8cef6
|
||||
Button.default.focusedBorderColor=a8cef6
|
||||
Button.default.focusColor=97c3f3
|
||||
Button.default.borderColor=#3167ad
|
||||
Button.default.hoverBorderColor=#a8cef6
|
||||
Button.default.focusedBorderColor=#a8cef6
|
||||
Button.default.focusColor=#97c3f3
|
||||
Button.default.boldText=true
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
CheckBox.icon.selectedBorderColor=4982CC
|
||||
CheckBox.icon.selectedFocusedBorderColor=ACCFF7
|
||||
CheckBox.icon.selectedBackground=4D89C9
|
||||
CheckBox.icon.checkmarkColor=FFFFFF
|
||||
CheckBox.icon.selectedBorderColor=#4982CC
|
||||
CheckBox.icon.selectedFocusedBorderColor=#ACCFF7
|
||||
CheckBox.icon.selectedBackground=#4D89C9
|
||||
CheckBox.icon.checkmarkColor=#FFFFFF
|
||||
|
||||
CheckBox.icon.selectedHoverBackground=5E94CE
|
||||
CheckBox.icon.selectedPressedBackground=72A1D4
|
||||
CheckBox.icon.selectedHoverBackground=#5E94CE
|
||||
CheckBox.icon.selectedPressedBackground=#72A1D4
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
@@ -22,6 +22,7 @@ CheckBoxMenuItemUI=com.formdev.flatlaf.ui.FlatCheckBoxMenuItemUI
|
||||
ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI
|
||||
ComboBoxUI=com.formdev.flatlaf.ui.FlatComboBoxUI
|
||||
EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI
|
||||
FileChooserUI=com.formdev.flatlaf.ui.FlatFileChooserUI
|
||||
FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI
|
||||
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
|
||||
ListUI=com.formdev.flatlaf.ui.FlatListUI
|
||||
@@ -60,6 +61,30 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
|
||||
@textComponentMargin=2,6,2,6
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
|
||||
desktop=@textComponentBackground
|
||||
activeCaptionText=@foreground
|
||||
activeCaptionBorder=@@activeCaption
|
||||
inactiveCaptionText=@foreground
|
||||
inactiveCaptionBorder=@@inactiveCaption
|
||||
window=@background
|
||||
windowBorder=@foreground
|
||||
windowText=@foreground
|
||||
menu=@background
|
||||
menuText=@foreground
|
||||
text=@textComponentBackground
|
||||
textText=@foreground
|
||||
textHighlight=@selectionBackground
|
||||
textHighlightText=@selectionForeground
|
||||
textInactiveText=@disabledText
|
||||
control=@background
|
||||
controlText=@foreground
|
||||
scrollbar=@@ScrollBar.track
|
||||
info=@@ToolTip.background
|
||||
infoText=@foreground
|
||||
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
||||
@@ -128,12 +153,6 @@ FileChooser.homeFolderIcon=com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIc
|
||||
FileChooser.detailsViewIcon=com.formdev.flatlaf.icons.FlatFileChooserDetailsViewIcon
|
||||
FileChooser.listViewIcon=com.formdev.flatlaf.icons.FlatFileChooserListViewIcon
|
||||
|
||||
FileChooser.icon.newFolderColor=@icon
|
||||
FileChooser.icon.upFolderColor=@icon
|
||||
FileChooser.icon.homeFolderColor=@icon
|
||||
FileChooser.icon.detailsViewColor=@icon
|
||||
FileChooser.icon.listViewColor=@icon
|
||||
|
||||
|
||||
#---- FileView ----
|
||||
|
||||
@@ -143,12 +162,6 @@ FileView.computerIcon=com.formdev.flatlaf.icons.FlatFileViewComputerIcon
|
||||
FileView.hardDriveIcon=com.formdev.flatlaf.icons.FlatFileViewHardDriveIcon
|
||||
FileView.floppyDriveIcon=com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon
|
||||
|
||||
FileView.icon.directoryColor=@icon
|
||||
FileView.icon.fileColor=@icon
|
||||
FileView.icon.computerColor=@icon
|
||||
FileView.icon.hardDriveColor=@icon
|
||||
FileView.icon.floppyDriveColor=@icon
|
||||
|
||||
|
||||
#---- FormattedTextField ----
|
||||
|
||||
@@ -217,6 +230,7 @@ OptionPane.buttonMinimumWidth={scaledNumber}72
|
||||
OptionPane.sameSizeButtons=true
|
||||
OptionPane.setButtonMargin=false
|
||||
OptionPane.buttonOrientation=4
|
||||
[mac]OptionPane.isYesLast=true
|
||||
|
||||
OptionPane.errorIcon=com.formdev.flatlaf.icons.FlatOptionPaneErrorIcon
|
||||
OptionPane.informationIcon=com.formdev.flatlaf.icons.FlatOptionPaneInformationIcon
|
||||
@@ -272,6 +286,10 @@ RadioButtonMenuItem.margin=2,2,2,2
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.width=10
|
||||
ScrollBar.showButtons=false
|
||||
ScrollBar.squareButtons=false
|
||||
ScrollBar.buttonArrowColor=@@ComboBox.buttonArrowColor
|
||||
ScrollBar.buttonDisabledArrowColor=@@ComboBox.buttonDisabledArrowColor
|
||||
|
||||
|
||||
#---- ScrollPane ----
|
||||
@@ -350,7 +368,7 @@ Table.selectionInactiveForeground=@selectionInactiveForeground
|
||||
#---- TableHeader ----
|
||||
|
||||
TableHeader.height=25
|
||||
TableHeader.cellBorder=2,2,2,2
|
||||
TableHeader.cellBorder=2,3,2,3
|
||||
|
||||
|
||||
#---- TextArea ----
|
||||
@@ -422,7 +440,7 @@ ToolTip.foregroundInactive=@disabledText
|
||||
Tree.border=1,1,1,1
|
||||
Tree.selectionInactiveBackground=@selectionInactiveBackground
|
||||
Tree.selectionInactiveForeground=@selectionInactiveForeground
|
||||
Tree.textBackground=@@Tree.background
|
||||
Tree.textBackground=null
|
||||
Tree.selectionBorderColor=@cellFocusColor
|
||||
Tree.rendererMargins=1,2,1,2
|
||||
Tree.paintLines=false
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
|
||||
#---- variables ----
|
||||
|
||||
@background=f2f2f2
|
||||
@foreground=000000
|
||||
@selectionBackground=4A6EB7
|
||||
@selectionForeground=ffffff
|
||||
@selectionInactiveBackground=d4d4d4
|
||||
@background=#f2f2f2
|
||||
@foreground=#000000
|
||||
@selectionBackground=#4A6EB7
|
||||
@selectionForeground=#ffffff
|
||||
@selectionInactiveBackground=#d4d4d4
|
||||
@selectionInactiveForeground=@foreground
|
||||
@disabledText=999999
|
||||
@textComponentBackground=ffffff
|
||||
@cellFocusColor=000000
|
||||
@icon=afafaf
|
||||
@disabledText=#999999
|
||||
@textComponentBackground=#ffffff
|
||||
@cellFocusColor=#000000
|
||||
@icon=#afafaf
|
||||
|
||||
# Button
|
||||
@buttonHoverBackground=darken(3%,autoInverse)
|
||||
@@ -40,40 +40,40 @@
|
||||
|
||||
*.background=@background
|
||||
*.foreground=@foreground
|
||||
*.textBackground=cccccc
|
||||
*.textBackground=#cccccc
|
||||
*.textForeground=@foreground
|
||||
*.caretForeground=@foreground
|
||||
*.inactiveBackground=@background
|
||||
*.inactiveForeground=777777
|
||||
*.inactiveForeground=#777777
|
||||
*.selectionBackground=@selectionBackground
|
||||
*.selectionForeground=@selectionForeground
|
||||
*.disabledBackground=@background
|
||||
*.disabledForeground=@disabledText
|
||||
*.disabledText=@disabledText
|
||||
*.acceleratorForeground=505050
|
||||
*.acceleratorForeground=#505050
|
||||
*.acceleratorSelectionForeground=@selectionForeground
|
||||
|
||||
|
||||
#---- system ----
|
||||
#---- system colors ----
|
||||
|
||||
control=e0e0e0
|
||||
controlText=@foreground
|
||||
infoText=@foreground
|
||||
text=@foreground
|
||||
textText=@foreground
|
||||
window=@background
|
||||
activeCaption=#99b4d1
|
||||
inactiveCaption=#bfcddb
|
||||
controlHighlight=#e3e3e3
|
||||
controlLtHighlight=#fff
|
||||
controlShadow=#a0a0a0
|
||||
controlDkShadow=#696969
|
||||
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.background=ffffff
|
||||
Button.focusedBackground=e3f1fa
|
||||
Button.background=#ffffff
|
||||
Button.focusedBackground=#e3f1fa
|
||||
Button.hoverBackground=@buttonHoverBackground
|
||||
Button.pressedBackground=@buttonPressedBackground
|
||||
|
||||
Button.borderColor=bfbfbf
|
||||
Button.disabledBorderColor=cfcfcf
|
||||
Button.focusedBorderColor=87afda
|
||||
Button.borderColor=#bfbfbf
|
||||
Button.disabledBorderColor=#cfcfcf
|
||||
Button.focusedBorderColor=#87afda
|
||||
Button.hoverBorderColor=@@Button.focusedBorderColor
|
||||
|
||||
Button.default.background=@@Button.background
|
||||
@@ -81,54 +81,55 @@ Button.default.foreground=@foreground
|
||||
Button.default.focusedBackground=@@Button.focusedBackground
|
||||
Button.default.hoverBackground=@buttonHoverBackground
|
||||
Button.default.pressedBackground=@buttonPressedBackground
|
||||
Button.default.borderColor=4D89C9
|
||||
Button.default.borderColor=#4D89C9
|
||||
Button.default.hoverBorderColor=@@Button.hoverBorderColor
|
||||
Button.default.focusedBorderColor=@@Button.focusedBorderColor
|
||||
Button.default.focusColor=@@Component.focusColor
|
||||
Button.default.borderWidth=2
|
||||
|
||||
Button.toolbar.hoverBackground=dfdfdf
|
||||
Button.toolbar.pressedBackground=d8d8d8
|
||||
Button.toolbar.hoverBackground=#dfdfdf
|
||||
Button.toolbar.pressedBackground=#d8d8d8
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
CheckBox.icon.borderColor=878787
|
||||
CheckBox.icon.disabledBorderColor=BDBDBD
|
||||
CheckBox.icon.selectedBorderColor=878787
|
||||
CheckBox.icon.focusedBorderColor=7B9FC7
|
||||
CheckBox.icon.borderColor=#878787
|
||||
CheckBox.icon.disabledBorderColor=#BDBDBD
|
||||
CheckBox.icon.selectedBorderColor=#878787
|
||||
CheckBox.icon.focusedBorderColor=#7B9FC7
|
||||
CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
|
||||
CheckBox.icon.background=FFFFFF
|
||||
CheckBox.icon.background=#FFFFFF
|
||||
CheckBox.icon.disabledBackground=@background
|
||||
CheckBox.icon.focusedBackground=@@Button.focusedBackground
|
||||
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
||||
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
||||
CheckBox.icon.selectedBackground=FFFFFF
|
||||
CheckBox.icon.checkmarkColor=4D89C9
|
||||
CheckBox.icon.disabledCheckmarkColor=ABABAB
|
||||
CheckBox.icon.selectedBackground=#FFFFFF
|
||||
CheckBox.icon.checkmarkColor=#4D89C9
|
||||
CheckBox.icon.disabledCheckmarkColor=#ABABAB
|
||||
|
||||
|
||||
#---- ComboBox ----
|
||||
|
||||
ComboBox.background=@textComponentBackground
|
||||
ComboBox.buttonBackground=@textComponentBackground
|
||||
ComboBox.buttonEditableBackground=fafafa
|
||||
ComboBox.buttonArrowColor=666666
|
||||
ComboBox.buttonDisabledArrowColor=ABABAB
|
||||
ComboBox.buttonHoverArrowColor=999999
|
||||
ComboBox.buttonEditableBackground=#fafafa
|
||||
ComboBox.buttonArrowColor=#666666
|
||||
ComboBox.buttonDisabledArrowColor=#ABABAB
|
||||
ComboBox.buttonHoverArrowColor=#999999
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
Component.borderColor=c4c4c4
|
||||
Component.disabledBorderColor=cfcfcf
|
||||
Component.focusedBorderColor=87afda
|
||||
Component.focusColor=97c3f3
|
||||
Component.borderColor=#c4c4c4
|
||||
Component.disabledBorderColor=#cfcfcf
|
||||
Component.focusedBorderColor=#87afda
|
||||
Component.focusColor=#97c3f3
|
||||
Component.linkColor=#4a78c2
|
||||
|
||||
|
||||
#---- HelpButton ----
|
||||
|
||||
HelpButton.questionMarkColor=4D89C9
|
||||
HelpButton.questionMarkColor=#4D89C9
|
||||
|
||||
|
||||
#---- List ----
|
||||
@@ -138,110 +139,100 @@ List.background=@textComponentBackground
|
||||
|
||||
#---- Menu ----
|
||||
|
||||
Menu.icon.arrowColor=666666
|
||||
Menu.icon.disabledArrowColor=ABABAB
|
||||
Menu.icon.arrowColor=#666666
|
||||
Menu.icon.disabledArrowColor=#ABABAB
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.borderColor=cdcdcd
|
||||
MenuBar.borderColor=#cdcdcd
|
||||
|
||||
|
||||
#---- MenuItemCheckBox ----
|
||||
|
||||
MenuItemCheckBox.icon.checkmarkColor=4D89C9
|
||||
MenuItemCheckBox.icon.disabledCheckmarkColor=ABABAB
|
||||
|
||||
|
||||
#---- OptionPane ----
|
||||
|
||||
OptionPane.icon.errorColor=DB5860
|
||||
OptionPane.icon.informationColor=389FD6
|
||||
OptionPane.icon.questionColor=389FD6
|
||||
OptionPane.icon.warningColor=EDA200
|
||||
OptionPane.icon.foreground=null
|
||||
MenuItemCheckBox.icon.checkmarkColor=#4D89C9
|
||||
MenuItemCheckBox.icon.disabledCheckmarkColor=#ABABAB
|
||||
|
||||
|
||||
#---- PopupMenu ----
|
||||
|
||||
PopupMenu.borderColor=cdcdcd
|
||||
PopupMenu.borderColor=#cdcdcd
|
||||
|
||||
|
||||
#---- ProgressBar ----
|
||||
|
||||
ProgressBar.background=c4c4c4
|
||||
ProgressBar.foreground=808080
|
||||
ProgressBar.background=#c4c4c4
|
||||
ProgressBar.foreground=#808080
|
||||
ProgressBar.selectionForeground=@textComponentBackground
|
||||
ProgressBar.selectionBackground=@foreground
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.track=F5F5F5
|
||||
ScrollBar.thumb=DBDBDB
|
||||
ScrollBar.hoverTrackColor=e6e6e6
|
||||
ScrollBar.hoverThumbColor=c6c6c6
|
||||
ScrollBar.track=#F5F5F5
|
||||
ScrollBar.thumb=#DBDBDB
|
||||
ScrollBar.hoverTrackColor=#e6e6e6
|
||||
ScrollBar.hoverThumbColor=#c6c6c6
|
||||
|
||||
|
||||
#---- Separator ----
|
||||
|
||||
Separator.foreground=cdcdcd
|
||||
Separator.foreground=#cdcdcd
|
||||
|
||||
|
||||
#---- Slider ----
|
||||
|
||||
Slider.trackColor=c4c4c4
|
||||
Slider.thumbColor=6e6e6e
|
||||
Slider.tickColor=888888
|
||||
Slider.focusedColor=@@Component.focusColor
|
||||
Slider.hoverColor=999999
|
||||
Slider.disabledForeground=c0c0c0
|
||||
Slider.trackColor=#c4c4c4
|
||||
Slider.thumbColor=#6e6e6e
|
||||
Slider.tickColor=#888888
|
||||
Slider.hoverColor=lighten(15%,autoInverse)
|
||||
Slider.disabledForeground=#c0c0c0
|
||||
|
||||
|
||||
#---- SplitPane ----
|
||||
|
||||
SplitPaneDivider.draggingColor=c4c4c4
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=333333
|
||||
SplitPaneDivider.draggingColor=#c4c4c4
|
||||
SplitPaneDivider.oneTouchHoverArrowColor=#333333
|
||||
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.disabledForeground=999999
|
||||
TabbedPane.underlineColor=4083C9
|
||||
TabbedPane.disabledUnderlineColor=ababab
|
||||
TabbedPane.hoverColor=d9d9d9
|
||||
TabbedPane.focusColor=dae4ed
|
||||
TabbedPane.contentAreaColor=bfbfbf
|
||||
TabbedPane.disabledForeground=#999999
|
||||
TabbedPane.underlineColor=#4083C9
|
||||
TabbedPane.disabledUnderlineColor=#ababab
|
||||
TabbedPane.hoverColor=#d9d9d9
|
||||
TabbedPane.focusColor=#dae4ed
|
||||
TabbedPane.contentAreaColor=#bfbfbf
|
||||
|
||||
|
||||
#---- Table ----
|
||||
|
||||
Table.background=@textComponentBackground
|
||||
Table.gridColor=F7F7F7
|
||||
Table.gridColor=#F7F7F7
|
||||
|
||||
|
||||
#---- TableHeader ----
|
||||
|
||||
TableHeader.background=ffffff
|
||||
TableHeader.separatorColor=e5e5e5
|
||||
TableHeader.bottomSeparatorColor=e5e5e5
|
||||
TableHeader.background=#ffffff
|
||||
TableHeader.separatorColor=#e5e5e5
|
||||
TableHeader.bottomSeparatorColor=#e5e5e5
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=cfcfcf
|
||||
ToggleButton.selectedBackground=#cfcfcf
|
||||
ToggleButton.selectedForeground=@foreground
|
||||
ToggleButton.disabledSelectedBackground=dfdfdf
|
||||
ToggleButton.disabledSelectedBackground=#dfdfdf
|
||||
|
||||
ToggleButton.toolbar.selectedBackground=cfcfcf
|
||||
ToggleButton.toolbar.selectedBackground=#cfcfcf
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.background=fafafa
|
||||
ToolTip.background=#fafafa
|
||||
|
||||
|
||||
#---- Tree ----
|
||||
|
||||
Tree.background=@textComponentBackground
|
||||
Tree.hash=E6E6E6
|
||||
Tree.hash=#E6E6E6
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.hoverBorderColor=null
|
||||
Button.default.hoverBorderColor=null
|
||||
|
||||
|
||||
#---- HelpButton ----
|
||||
|
||||
HelpButton.hoverBorderColor=null
|
||||
4
flatlaf-demo/README.md
Normal file
4
flatlaf-demo/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
FlatLaf Demo
|
||||
============
|
||||
|
||||
This sub-project contains the FlatLaf Demo source code.
|
||||
@@ -23,19 +23,20 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
implementation( project( ":flatlaf-extras" ) )
|
||||
implementation( "com.miglayout:miglayout-swing:5.2" )
|
||||
implementation( "com.jgoodies:jgoodies-forms:1.9.0" )
|
||||
implementation( "com.formdev:svgSalamander:1.1.2.1" )
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
tasks {
|
||||
jar {
|
||||
dependsOn( ":flatlaf-core:jar" )
|
||||
dependsOn( ":flatlaf-extras:jar" )
|
||||
|
||||
manifest {
|
||||
attributes( "Main-Class" to "com.formdev.flatlaf.demo.FlatLafDemo" )
|
||||
|
||||
@@ -40,6 +40,9 @@ class BasicComponentsPanel
|
||||
JButton button3 = new JButton();
|
||||
JButton button4 = new JButton();
|
||||
JButton button13 = new JButton();
|
||||
JButton button14 = new JButton();
|
||||
JButton button15 = new JButton();
|
||||
JButton button16 = new JButton();
|
||||
JLabel checkBoxLabel = new JLabel();
|
||||
JCheckBox checkBox1 = new JCheckBox();
|
||||
JCheckBox checkBox2 = new JCheckBox();
|
||||
@@ -174,6 +177,18 @@ class BasicComponentsPanel
|
||||
button13.setIcon(UIManager.getIcon("Tree.closedIcon"));
|
||||
add(button13, "cell 5 1");
|
||||
|
||||
//---- button14 ----
|
||||
button14.setText("...");
|
||||
add(button14, "cell 5 1");
|
||||
|
||||
//---- button15 ----
|
||||
button15.setText("\u2026");
|
||||
add(button15, "cell 5 1");
|
||||
|
||||
//---- button16 ----
|
||||
button16.setText("#");
|
||||
add(button16, "cell 5 1");
|
||||
|
||||
//---- checkBoxLabel ----
|
||||
checkBoxLabel.setText("JCheckBox");
|
||||
add(checkBoxLabel, "cell 0 2");
|
||||
|
||||
@@ -75,6 +75,24 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button14"
|
||||
"text": "..."
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button15"
|
||||
"text": "…"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button16"
|
||||
"text": "#"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "checkBoxLabel"
|
||||
"text": "JCheckBox"
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import javax.swing.*;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||
import com.formdev.flatlaf.*;
|
||||
@@ -43,11 +44,11 @@ class ControlBar
|
||||
initComponents();
|
||||
|
||||
// initialize look and feels combo box
|
||||
DefaultComboBoxModel<LafInfo> lafModel = new DefaultComboBoxModel<>();
|
||||
lafModel.addElement( new LafInfo( "Flat Light (F1)", FlatLightLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat Dark (F2)", FlatDarkLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat Darcula (F4)", FlatDarculaLaf.class.getName() ) );
|
||||
DefaultComboBoxModel<LookAndFeelInfo> lafModel = new DefaultComboBoxModel<>();
|
||||
lafModel.addElement( new LookAndFeelInfo( "Flat Light (F1)", FlatLightLaf.class.getName() ) );
|
||||
lafModel.addElement( new LookAndFeelInfo( "Flat Dark (F2)", FlatDarkLaf.class.getName() ) );
|
||||
lafModel.addElement( new LookAndFeelInfo( "Flat IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
|
||||
lafModel.addElement( new LookAndFeelInfo( "Flat Darcula (F4)", FlatDarculaLaf.class.getName() ) );
|
||||
|
||||
UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels();
|
||||
for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) {
|
||||
@@ -66,18 +67,9 @@ class ControlBar
|
||||
else if( className.equals( NimbusLookAndFeel.class.getName() ) )
|
||||
name += " (F11)";
|
||||
|
||||
lafModel.addElement( new LafInfo( name, className ) );
|
||||
lafModel.addElement( new LookAndFeelInfo( name, className ) );
|
||||
}
|
||||
|
||||
LookAndFeel activeLaf = UIManager.getLookAndFeel();
|
||||
String activeLafClassName = activeLaf.getClass().getName();
|
||||
int sel = lafModel.getIndexOf( new LafInfo( null, activeLafClassName ) );
|
||||
if( sel < 0 ) {
|
||||
lafModel.addElement( new LafInfo( activeLaf.getName(), activeLafClassName ) );
|
||||
sel = lafModel.getSize() - 1;
|
||||
}
|
||||
lafModel.setSelectedItem( lafModel.getElementAt( sel ) );
|
||||
|
||||
lookAndFeelComboBox.setModel( lafModel );
|
||||
|
||||
UIManager.addPropertyChangeListener( e -> {
|
||||
@@ -161,26 +153,21 @@ class ControlBar
|
||||
}
|
||||
|
||||
private void selectLookAndFeel( String lafClassName ) {
|
||||
DefaultComboBoxModel<LafInfo> lafModel = (DefaultComboBoxModel<LafInfo>) lookAndFeelComboBox.getModel();
|
||||
int sel = lafModel.getIndexOf( new LafInfo( null, lafClassName ) );
|
||||
if( sel >= 0 )
|
||||
lookAndFeelComboBox.setSelectedIndex( sel );
|
||||
lookAndFeelComboBox.setSelectedLookAndFeel( lafClassName );
|
||||
}
|
||||
|
||||
private void lookAndFeelChanged() {
|
||||
LafInfo newLaf = (LafInfo) lookAndFeelComboBox.getSelectedItem();
|
||||
if( newLaf == null )
|
||||
String lafClassName = lookAndFeelComboBox.getSelectedLookAndFeel();
|
||||
if( lafClassName == null )
|
||||
return;
|
||||
|
||||
if( newLaf.className.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
if( lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
return;
|
||||
|
||||
FlatLafDemo.prefs.put( FlatLafDemo.KEY_LAF, newLaf.className );
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
try {
|
||||
// change look and feel
|
||||
UIManager.setLookAndFeel( newLaf.className );
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
|
||||
// update all components
|
||||
FlatLaf.updateUI();
|
||||
@@ -250,7 +237,7 @@ class ControlBar
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
separator1 = new JSeparator();
|
||||
lookAndFeelComboBox = new JComboBox<>();
|
||||
lookAndFeelComboBox = new LookAndFeelsComboBox();
|
||||
rightToLeftCheckBox = new JCheckBox();
|
||||
enabledCheckBox = new JCheckBox();
|
||||
infoLabel = new JLabel();
|
||||
@@ -300,33 +287,10 @@ class ControlBar
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JSeparator separator1;
|
||||
private JComboBox<LafInfo> lookAndFeelComboBox;
|
||||
private LookAndFeelsComboBox lookAndFeelComboBox;
|
||||
private JCheckBox rightToLeftCheckBox;
|
||||
private JCheckBox enabledCheckBox;
|
||||
private JLabel infoLabel;
|
||||
private JButton closeButton;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
//---- class LafInfo ------------------------------------------------------
|
||||
|
||||
static class LafInfo
|
||||
{
|
||||
final String name;
|
||||
final String className;
|
||||
|
||||
LafInfo( String name, String className ) {
|
||||
this.name = name;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object obj ) {
|
||||
return obj instanceof LafInfo && className.equals( ((LafInfo)obj).className );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,8 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
add( new FormComponent( "com.formdev.flatlaf.demo.LookAndFeelsComboBox" ) {
|
||||
name: "lookAndFeelComboBox"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "LafInfo"
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "lookAndFeelChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.formdev.flatlaf.demo;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -28,7 +30,7 @@ class DemoFrame
|
||||
extends JFrame
|
||||
{
|
||||
DemoFrame() {
|
||||
int tabIndex = FlatLafDemo.prefs.getInt( FlatLafDemo.KEY_TAB, 0 );
|
||||
int tabIndex = DemoPrefs.getState().getInt( FlatLafDemo.KEY_TAB, 0 );
|
||||
|
||||
initComponents();
|
||||
controlBar.initialize( this, tabbedPane );
|
||||
@@ -46,7 +48,7 @@ class DemoFrame
|
||||
}
|
||||
|
||||
private void selectedTabChanged() {
|
||||
FlatLafDemo.prefs.putInt( FlatLafDemo.KEY_TAB, tabbedPane.getSelectedIndex() );
|
||||
DemoPrefs.getState().putInt( FlatLafDemo.KEY_TAB, tabbedPane.getSelectedIndex() );
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
@@ -87,6 +89,7 @@ class DemoFrame
|
||||
TabsPanel tabsPanel = new TabsPanel();
|
||||
OptionPanePanel optionPanePanel = new OptionPanePanel();
|
||||
controlBar = new ControlBar();
|
||||
IJThemesPanel themesPanel = new IJThemesPanel();
|
||||
|
||||
//======== this ========
|
||||
setTitle("FlatLaf Demo");
|
||||
@@ -262,6 +265,7 @@ class DemoFrame
|
||||
}
|
||||
contentPane.add(contentPanel, BorderLayout.CENTER);
|
||||
contentPane.add(controlBar, BorderLayout.SOUTH);
|
||||
contentPane.add(themesPanel, BorderLayout.EAST);
|
||||
|
||||
//---- buttonGroup1 ----
|
||||
ButtonGroup buttonGroup1 = new ButtonGroup();
|
||||
@@ -270,20 +274,20 @@ class DemoFrame
|
||||
buttonGroup1.add(radioButtonMenuItem3);
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
|
||||
undoMenuItem.setIcon( new ScaledSVGIcon( "icons/undo.svg" ) );
|
||||
redoMenuItem.setIcon( new ScaledSVGIcon( "icons/redo.svg" ) );
|
||||
undoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/undo.svg" ) );
|
||||
redoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/redo.svg" ) );
|
||||
|
||||
cutMenuItem.setIcon( new ScaledSVGIcon( "icons/menu-cut.svg" ) );
|
||||
copyMenuItem.setIcon( new ScaledSVGIcon( "icons/copy.svg" ) );
|
||||
pasteMenuItem.setIcon( new ScaledSVGIcon( "icons/menu-paste.svg" ) );
|
||||
cutMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-cut.svg" ) );
|
||||
copyMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/copy.svg" ) );
|
||||
pasteMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-paste.svg" ) );
|
||||
|
||||
backButton.setIcon( new ScaledSVGIcon( "icons/back.svg" ) );
|
||||
forwardButton.setIcon( new ScaledSVGIcon( "icons/forward.svg" ) );
|
||||
cutButton.setIcon( new ScaledSVGIcon( "icons/menu-cut.svg" ) );
|
||||
copyButton.setIcon( new ScaledSVGIcon( "icons/copy.svg" ) );
|
||||
pasteButton.setIcon( new ScaledSVGIcon( "icons/menu-paste.svg" ) );
|
||||
refreshButton.setIcon( new ScaledSVGIcon( "icons/refresh.svg" ) );
|
||||
showToggleButton.setIcon( new ScaledSVGIcon( "icons/show.svg" ) );
|
||||
backButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/back.svg" ) );
|
||||
forwardButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/forward.svg" ) );
|
||||
cutButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-cut.svg" ) );
|
||||
copyButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/copy.svg" ) );
|
||||
pasteButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-paste.svg" ) );
|
||||
refreshButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/refresh.svg" ) );
|
||||
showToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/show.svg" ) );
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
|
||||
@@ -107,6 +107,11 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "South"
|
||||
} )
|
||||
add( new FormComponent( "com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel" ) {
|
||||
name: "themesPanel"
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "East"
|
||||
} )
|
||||
menuBar: 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 ) ) {
|
||||
@@ -220,7 +225,7 @@ new FormModel {
|
||||
}
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 800, 710 )
|
||||
"size": new java.awt.Dimension( 935, 710 )
|
||||
} )
|
||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||
name: "buttonGroup1"
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class DemoPrefs
|
||||
{
|
||||
public static final String KEY_LAF = "laf";
|
||||
public static final String KEY_LAF_INTELLIJ_THEME = "lafIntelliJTheme";
|
||||
|
||||
public static final String RESOURCE_PREFIX = "res:";
|
||||
public static final String FILE_PREFIX = "file:";
|
||||
|
||||
public static final String INTELLIJ_THEME_UI_KEY = "__FlatLaf.demo.intelliJTheme";
|
||||
|
||||
private static Preferences state;
|
||||
|
||||
public static Preferences getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public static void init( String rootPath ) {
|
||||
state = Preferences.userRoot().node( rootPath );
|
||||
}
|
||||
|
||||
public static void initLaf( String[] args ) {
|
||||
// set look and feel
|
||||
try {
|
||||
if( args.length > 0 )
|
||||
UIManager.setLookAndFeel( args[0] );
|
||||
else {
|
||||
String lafClassName = state.get( KEY_LAF, FlatLightLaf.class.getName() );
|
||||
if( IntelliJTheme.ThemeLaf.class.getName().equals( lafClassName ) ) {
|
||||
String intelliJTheme = state.get( KEY_LAF_INTELLIJ_THEME, "" );
|
||||
if( intelliJTheme.startsWith( RESOURCE_PREFIX ) )
|
||||
IntelliJTheme.install( IJThemesPanel.class.getResourceAsStream( intelliJTheme.substring( RESOURCE_PREFIX.length() ) ) );
|
||||
else if( intelliJTheme.startsWith( FILE_PREFIX ) )
|
||||
FlatLaf.install( IntelliJTheme.createLaf( new FileInputStream( intelliJTheme.substring( FILE_PREFIX.length() ) ) ) );
|
||||
else
|
||||
FlatLightLaf.install();
|
||||
|
||||
if( !intelliJTheme.isEmpty() )
|
||||
UIManager.getLookAndFeelDefaults().put( INTELLIJ_THEME_UI_KEY, intelliJTheme );
|
||||
} else
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
}
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
|
||||
// fallback
|
||||
FlatLightLaf.install();
|
||||
}
|
||||
|
||||
// remember active look and feel
|
||||
UIManager.addPropertyChangeListener( e -> {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
state.put( KEY_LAF, UIManager.getLookAndFeel().getClass().getName() );
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -27,29 +24,14 @@ import com.formdev.flatlaf.FlatLightLaf;
|
||||
public class FlatLafDemo
|
||||
{
|
||||
static final String PREFS_ROOT_PATH = "/flatlaf-demo";
|
||||
static final String KEY_LAF = "laf";
|
||||
static final String KEY_TAB = "tab";
|
||||
|
||||
static Preferences prefs;
|
||||
|
||||
public static void main( String[] args ) {
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
|
||||
DemoPrefs.init( PREFS_ROOT_PATH );
|
||||
|
||||
// set look and feel
|
||||
try {
|
||||
if( args.length > 0 )
|
||||
UIManager.setLookAndFeel( args[0] );
|
||||
else {
|
||||
String lafClassName = prefs.get( KEY_LAF, FlatLightLaf.class.getName() );
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
}
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
|
||||
// fallback
|
||||
FlatLightLaf.install();
|
||||
}
|
||||
DemoPrefs.initLaf( args );
|
||||
|
||||
// create frame
|
||||
DemoFrame frame = new DemoFrame();
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.MutableComboBoxModel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class LookAndFeelsComboBox
|
||||
extends JComboBox<UIManager.LookAndFeelInfo>
|
||||
{
|
||||
private final PropertyChangeListener lafListener = this::lafChanged;
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public LookAndFeelsComboBox() {
|
||||
setRenderer( new BasicComboBoxRenderer() {
|
||||
@Override
|
||||
@SuppressWarnings( "rawtypes" )
|
||||
public Component getListCellRendererComponent( JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus )
|
||||
{
|
||||
value = (value != null)
|
||||
? ((LookAndFeelInfo)value).getName()
|
||||
: UIManager.getLookAndFeel().getName();
|
||||
return super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public void addLookAndFeel( String name, String className ) {
|
||||
getMutableModel().addElement( new LookAndFeelInfo( name, className ) );
|
||||
}
|
||||
|
||||
public String getSelectedLookAndFeel() {
|
||||
Object sel = getSelectedItem();
|
||||
return (sel instanceof LookAndFeelInfo) ? ((LookAndFeelInfo)sel).getClassName() : null;
|
||||
}
|
||||
|
||||
public void setSelectedLookAndFeel( String className ) {
|
||||
setSelectedIndex( getIndexOfLookAndFeel( className ) );
|
||||
}
|
||||
|
||||
public void selectedCurrentLookAndFeel() {
|
||||
setSelectedLookAndFeel( UIManager.getLookAndFeel().getClass().getName() );
|
||||
}
|
||||
|
||||
public void removeLookAndFeel( String className ) {
|
||||
int index = getIndexOfLookAndFeel( className );
|
||||
if( index >= 0 )
|
||||
getMutableModel().removeElementAt( index );
|
||||
}
|
||||
|
||||
public int getIndexOfLookAndFeel( String className ) {
|
||||
ComboBoxModel<LookAndFeelInfo> model = getModel();
|
||||
int size = model.getSize();
|
||||
for( int i = 0; i < size; i++ ) {
|
||||
if( className.equals( model.getElementAt( i ).getClassName() ) )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private MutableComboBoxModel<LookAndFeelInfo> getMutableModel() {
|
||||
return (MutableComboBoxModel<LookAndFeelInfo>) getModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
selectedCurrentLookAndFeel();
|
||||
UIManager.addPropertyChangeListener( lafListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
UIManager.removePropertyChangeListener( lafListener );
|
||||
}
|
||||
|
||||
void lafChanged( PropertyChangeEvent e ) {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
selectedCurrentLookAndFeel();
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,8 @@ class MoreComponentsPanel
|
||||
JPanel panel1 = new JPanel();
|
||||
JScrollBar scrollBar2 = new JScrollBar();
|
||||
JScrollBar scrollBar3 = new JScrollBar();
|
||||
JScrollBar scrollBar7 = new JScrollBar();
|
||||
JScrollBar scrollBar8 = new JScrollBar();
|
||||
JSeparator separator2 = new JSeparator();
|
||||
JSlider slider2 = new JSlider();
|
||||
JSlider slider4 = new JSlider();
|
||||
@@ -60,6 +62,8 @@ class MoreComponentsPanel
|
||||
JLabel scrollBarLabel = new JLabel();
|
||||
JScrollBar scrollBar1 = new JScrollBar();
|
||||
JScrollBar scrollBar4 = new JScrollBar();
|
||||
JScrollBar scrollBar5 = new JScrollBar();
|
||||
JScrollBar scrollBar6 = new JScrollBar();
|
||||
JLabel separatorLabel = new JLabel();
|
||||
JSeparator separator1 = new JSeparator();
|
||||
JPanel panel2 = new JPanel();
|
||||
@@ -102,6 +106,8 @@ class MoreComponentsPanel
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- scrollPaneLabel ----
|
||||
@@ -121,20 +127,29 @@ class MoreComponentsPanel
|
||||
scrollPane13.setViewportView(panel1);
|
||||
}
|
||||
add(scrollPane13, "cell 1 0,grow,width 70,height 70");
|
||||
add(scrollBar2, "cell 2 0 1 4,growy");
|
||||
add(scrollBar2, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar3 ----
|
||||
scrollBar3.setEnabled(false);
|
||||
add(scrollBar3, "cell 2 0 1 4,growy");
|
||||
add(scrollBar3, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar7 ----
|
||||
scrollBar7.putClientProperty("JScrollBar.showButtons", true);
|
||||
add(scrollBar7, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar8 ----
|
||||
scrollBar8.setEnabled(false);
|
||||
scrollBar8.putClientProperty("JScrollBar.showButtons", true);
|
||||
add(scrollBar8, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- separator2 ----
|
||||
separator2.setOrientation(SwingConstants.VERTICAL);
|
||||
add(separator2, "cell 2 0 1 4,growy");
|
||||
add(separator2, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- slider2 ----
|
||||
slider2.setOrientation(SwingConstants.VERTICAL);
|
||||
slider2.setValue(30);
|
||||
add(slider2, "cell 2 0 1 4,growy");
|
||||
add(slider2, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- slider4 ----
|
||||
slider4.setMinorTickSpacing(10);
|
||||
@@ -143,19 +158,19 @@ class MoreComponentsPanel
|
||||
slider4.setPaintLabels(true);
|
||||
slider4.setOrientation(SwingConstants.VERTICAL);
|
||||
slider4.setValue(30);
|
||||
add(slider4, "cell 2 0 1 4,growy");
|
||||
add(slider4, "cell 2 0 1 6,growy");
|
||||
add(scrollPane14, "cell 3 0,grow");
|
||||
|
||||
//---- progressBar3 ----
|
||||
progressBar3.setOrientation(SwingConstants.VERTICAL);
|
||||
progressBar3.setValue(50);
|
||||
add(progressBar3, "cell 4 0 1 4,growy");
|
||||
add(progressBar3, "cell 4 0 1 6,growy");
|
||||
|
||||
//---- progressBar4 ----
|
||||
progressBar4.setOrientation(SwingConstants.VERTICAL);
|
||||
progressBar4.setValue(55);
|
||||
progressBar4.setStringPainted(true);
|
||||
add(progressBar4, "cell 4 0 1 4,growy");
|
||||
add(progressBar4, "cell 4 0 1 6,growy");
|
||||
|
||||
//======== toolBar2 ========
|
||||
{
|
||||
@@ -178,7 +193,7 @@ class MoreComponentsPanel
|
||||
toggleButton7.setIcon(UIManager.getIcon("Tree.closedIcon"));
|
||||
toolBar2.add(toggleButton7);
|
||||
}
|
||||
add(toolBar2, "cell 4 0 1 4,growy");
|
||||
add(toolBar2, "cell 4 0 1 6,growy");
|
||||
|
||||
//---- scrollBarLabel ----
|
||||
scrollBarLabel.setText("JScrollBar:");
|
||||
@@ -193,30 +208,41 @@ class MoreComponentsPanel
|
||||
scrollBar4.setEnabled(false);
|
||||
add(scrollBar4, "cell 1 2,growx");
|
||||
|
||||
//---- scrollBar5 ----
|
||||
scrollBar5.setOrientation(Adjustable.HORIZONTAL);
|
||||
scrollBar5.putClientProperty("JScrollBar.showButtons", true);
|
||||
add(scrollBar5, "cell 1 3,growx");
|
||||
|
||||
//---- scrollBar6 ----
|
||||
scrollBar6.setOrientation(Adjustable.HORIZONTAL);
|
||||
scrollBar6.setEnabled(false);
|
||||
scrollBar6.putClientProperty("JScrollBar.showButtons", true);
|
||||
add(scrollBar6, "cell 1 4,growx");
|
||||
|
||||
//---- separatorLabel ----
|
||||
separatorLabel.setText("JSeparator:");
|
||||
add(separatorLabel, "cell 0 3");
|
||||
add(separator1, "cell 1 3,growx");
|
||||
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 3,grow");
|
||||
add(panel2, "cell 3 5,grow");
|
||||
|
||||
//---- sliderLabel ----
|
||||
sliderLabel.setText("JSlider:");
|
||||
add(sliderLabel, "cell 0 4");
|
||||
add(sliderLabel, "cell 0 6");
|
||||
|
||||
//---- slider1 ----
|
||||
slider1.setValue(30);
|
||||
add(slider1, "cell 1 4 3 1,aligny top,grow 100 0");
|
||||
add(slider1, "cell 1 6 3 1,aligny top,grow 100 0");
|
||||
|
||||
//---- slider6 ----
|
||||
slider6.setEnabled(false);
|
||||
slider6.setValue(30);
|
||||
add(slider6, "cell 1 4 3 1,aligny top,growy 0");
|
||||
add(slider6, "cell 1 6 3 1,aligny top,growy 0");
|
||||
|
||||
//---- slider3 ----
|
||||
slider3.setMinorTickSpacing(10);
|
||||
@@ -224,7 +250,7 @@ class MoreComponentsPanel
|
||||
slider3.setMajorTickSpacing(50);
|
||||
slider3.setPaintLabels(true);
|
||||
slider3.setValue(30);
|
||||
add(slider3, "cell 1 5 3 1,aligny top,grow 100 0");
|
||||
add(slider3, "cell 1 7 3 1,aligny top,grow 100 0");
|
||||
|
||||
//---- slider5 ----
|
||||
slider5.setMinorTickSpacing(10);
|
||||
@@ -233,41 +259,41 @@ class MoreComponentsPanel
|
||||
slider5.setPaintLabels(true);
|
||||
slider5.setEnabled(false);
|
||||
slider5.setValue(30);
|
||||
add(slider5, "cell 1 5 3 1,aligny top,growy 0");
|
||||
add(slider5, "cell 1 7 3 1,aligny top,growy 0");
|
||||
|
||||
//---- progressBarLabel ----
|
||||
progressBarLabel.setText("JProgressBar:");
|
||||
add(progressBarLabel, "cell 0 6");
|
||||
add(progressBarLabel, "cell 0 8");
|
||||
|
||||
//---- progressBar1 ----
|
||||
progressBar1.setValue(50);
|
||||
add(progressBar1, "cell 1 6 3 1,growx");
|
||||
add(progressBar1, "cell 1 8 3 1,growx");
|
||||
|
||||
//---- progressBar2 ----
|
||||
progressBar2.setStringPainted(true);
|
||||
progressBar2.setValue(55);
|
||||
add(progressBar2, "cell 1 6 3 1,growx");
|
||||
add(progressBar2, "cell 1 8 3 1,growx");
|
||||
|
||||
//---- indeterminateCheckBox ----
|
||||
indeterminateCheckBox.setText("indeterminate");
|
||||
indeterminateCheckBox.addActionListener(e -> indeterminateCheckBoxActionPerformed());
|
||||
add(indeterminateCheckBox, "cell 4 6");
|
||||
add(indeterminateCheckBox, "cell 4 8");
|
||||
|
||||
//---- toolTipLabel ----
|
||||
toolTipLabel.setText("JToolTip:");
|
||||
add(toolTipLabel, "cell 0 7");
|
||||
add(toolTipLabel, "cell 0 9");
|
||||
|
||||
//---- toolTip1 ----
|
||||
toolTip1.setTipText("Some text in tool tip.");
|
||||
add(toolTip1, "cell 1 7 3 1");
|
||||
add(toolTip1, "cell 1 9 3 1");
|
||||
|
||||
//---- toolTip2 ----
|
||||
toolTip2.setTipText("Tool tip with\nmultiple\nlines.");
|
||||
add(toolTip2, "cell 1 7 3 1");
|
||||
add(toolTip2, "cell 1 9 3 1");
|
||||
|
||||
//---- toolBarLabel ----
|
||||
toolBarLabel.setText("JToolBar:");
|
||||
add(toolBarLabel, "cell 0 8");
|
||||
add(toolBarLabel, "cell 0 10");
|
||||
|
||||
//======== toolBar1 ========
|
||||
{
|
||||
@@ -297,7 +323,7 @@ class MoreComponentsPanel
|
||||
toggleButton6.setSelected(true);
|
||||
toolBar1.add(toggleButton6);
|
||||
}
|
||||
add(toolBar1, "cell 1 8 3 1,growx");
|
||||
add(toolBar1, "cell 1 10 3 1,growx");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$columnConstraints": "[][][][][][]"
|
||||
"$rowConstraints": "[][][][][][][][][]"
|
||||
"$rowConstraints": "[][][][][][][][][][][]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -32,26 +32,39 @@ new FormModel {
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar2"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 4,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar3"
|
||||
"enabled": false
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 4,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar7"
|
||||
"$client.JScrollBar.showButtons": true
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar8"
|
||||
"enabled": false
|
||||
"$client.JScrollBar.showButtons": true
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSeparator" ) {
|
||||
name: "separator2"
|
||||
"orientation": 1
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 4,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider2"
|
||||
"orientation": 1
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 4,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider4"
|
||||
@@ -62,7 +75,7 @@ new FormModel {
|
||||
"orientation": 1
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0 1 4,growy"
|
||||
"value": "cell 2 0 1 6,growy"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane14"
|
||||
@@ -77,7 +90,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 4,growy"
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar4"
|
||||
@@ -88,7 +101,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 4,growy"
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||
name: "toolBar2"
|
||||
@@ -113,7 +126,7 @@ new FormModel {
|
||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0 1 4,growy"
|
||||
"value": "cell 4 0 1 6,growy"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "scrollBarLabel"
|
||||
@@ -134,41 +147,56 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 2,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar5"
|
||||
"orientation": 0
|
||||
"$client.JScrollBar.showButtons": true
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 3,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar6"
|
||||
"orientation": 0
|
||||
"enabled": false
|
||||
"$client.JScrollBar.showButtons": true
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 4,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "separatorLabel"
|
||||
"text": "JSeparator:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 3"
|
||||
"value": "cell 0 5"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSeparator" ) {
|
||||
name: "separator1"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 3,growx"
|
||||
"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 3,grow"
|
||||
"value": "cell 3 5,grow"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "sliderLabel"
|
||||
"text": "JSlider:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4"
|
||||
"value": "cell 0 6"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider1"
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 4 3 1,aligny top,grow 100 0"
|
||||
"value": "cell 1 6 3 1,aligny top,grow 100 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider6"
|
||||
"enabled": false
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 4 3 1,aligny top,growy 0"
|
||||
"value": "cell 1 6 3 1,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider3"
|
||||
@@ -178,7 +206,7 @@ new FormModel {
|
||||
"paintLabels": true
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 5 3 1,aligny top,grow 100 0"
|
||||
"value": "cell 1 7 3 1,aligny top,grow 100 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider5"
|
||||
@@ -189,13 +217,13 @@ new FormModel {
|
||||
"enabled": false
|
||||
"value": 30
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 5 3 1,aligny top,growy 0"
|
||||
"value": "cell 1 7 3 1,aligny top,growy 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "progressBarLabel"
|
||||
"text": "JProgressBar:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 6"
|
||||
"value": "cell 0 8"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar1"
|
||||
@@ -204,7 +232,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 6 3 1,growx"
|
||||
"value": "cell 1 8 3 1,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar2"
|
||||
@@ -214,7 +242,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 6 3 1,growx"
|
||||
"value": "cell 1 8 3 1,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "indeterminateCheckBox"
|
||||
@@ -224,31 +252,31 @@ new FormModel {
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "indeterminateCheckBoxActionPerformed", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 6"
|
||||
"value": "cell 4 8"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "toolTipLabel"
|
||||
"text": "JToolTip:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 7"
|
||||
"value": "cell 0 9"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JToolTip" ) {
|
||||
name: "toolTip1"
|
||||
"tipText": "Some text in tool tip."
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 7 3 1"
|
||||
"value": "cell 1 9 3 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JToolTip" ) {
|
||||
name: "toolTip2"
|
||||
"tipText": "Tool tip with\nmultiple\nlines."
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 7 3 1"
|
||||
"value": "cell 1 9 3 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "toolBarLabel"
|
||||
"text": "JToolBar:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 8"
|
||||
"value": "cell 0 10"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||
name: "toolBar1"
|
||||
@@ -282,7 +310,7 @@ new FormModel {
|
||||
"selected": true
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 8 3 1,growx"
|
||||
"value": "cell 1 10 3 1,growx"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
|
||||
@@ -296,7 +296,7 @@ class OptionPanePanel
|
||||
private JOptionPane optionPane;
|
||||
|
||||
ShowDialogLinkLabel() {
|
||||
setText( "<html><a href=\"#\" color=\"#589df6\">Show dialog</a></html>" );
|
||||
setText( "<html><a href=\"#\">Show dialog</a></html>" );
|
||||
|
||||
addMouseListener( new MouseAdapter() {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo.intellijthemes;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class IJThemeInfo
|
||||
{
|
||||
final String name;
|
||||
final String resourceName;
|
||||
final String license;
|
||||
final String licenseFile;
|
||||
final String sourceCodeUrl;
|
||||
final String sourceCodePath;
|
||||
final File themeFile;
|
||||
final String lafClassName;
|
||||
|
||||
IJThemeInfo( String name, String resourceName,
|
||||
String license, String licenseFile,
|
||||
String sourceCodeUrl, String sourceCodePath,
|
||||
File themeFile, String lafClassName )
|
||||
{
|
||||
this.name = name;
|
||||
this.resourceName = resourceName;
|
||||
this.license = license;
|
||||
this.licenseFile = licenseFile;
|
||||
this.sourceCodeUrl = sourceCodeUrl;
|
||||
this.sourceCodePath = sourceCodePath;
|
||||
this.themeFile = themeFile;
|
||||
this.lafClassName = lafClassName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo.intellijthemes;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.formdev.flatlaf.json.Json;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class IJThemesManager
|
||||
{
|
||||
final List<IJThemeInfo> bundledThemes = new ArrayList<>();
|
||||
final List<IJThemeInfo> moreThemes = new ArrayList<>();
|
||||
private final Map<File,Long> lastModifiedMap = new HashMap<>();
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
void loadBundledThemes() {
|
||||
bundledThemes.clear();
|
||||
|
||||
// load themes.json
|
||||
Map<String, Object> json;
|
||||
try( Reader reader = new InputStreamReader( getClass().getResourceAsStream( "themes.json" ), StandardCharsets.UTF_8 ) ) {
|
||||
json = (Map<String, Object>) Json.parse( reader );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
// add info about bundled themes
|
||||
for( Map.Entry<String, Object> e : json.entrySet() ) {
|
||||
String resourceName = e.getKey();
|
||||
Map<String, String> value = (Map<String, String>) e.getValue();
|
||||
String name = value.get( "name" );
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void loadThemesFromDirectory() {
|
||||
// get current working directory
|
||||
File directory = new File( "" ).getAbsoluteFile();
|
||||
|
||||
File[] themeFiles = directory.listFiles( (dir, name) -> name.endsWith( ".theme.json" ) );
|
||||
if( themeFiles == null )
|
||||
return;
|
||||
|
||||
lastModifiedMap.clear();
|
||||
lastModifiedMap.put( directory, directory.lastModified() );
|
||||
|
||||
moreThemes.clear();
|
||||
for( File f : themeFiles ) {
|
||||
String name = StringUtils.removeTrailing( f.getName(), ".theme.json" );
|
||||
moreThemes.add( new IJThemeInfo( name, null, null, null, null, null, f, null ) );
|
||||
lastModifiedMap.put( f, f.lastModified() );
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasThemesFromDirectoryChanged() {
|
||||
for( Map.Entry<File, Long> e : lastModifiedMap.entrySet() ) {
|
||||
if( e.getKey().lastModified() != e.getValue().longValue() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo.intellijthemes;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.event.*;
|
||||
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||
import com.formdev.flatlaf.FlatDarkLaf;
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
import com.formdev.flatlaf.demo.DemoPrefs;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class IJThemesPanel
|
||||
extends JPanel
|
||||
{
|
||||
private final IJThemesManager themesManager = new IJThemesManager();
|
||||
private final List<IJThemeInfo> themes = new ArrayList<>();
|
||||
private final HashMap<Integer, String> categories = new HashMap<>();
|
||||
private final PropertyChangeListener lafListener = this::lafChanged;
|
||||
private final WindowListener windowListener = new WindowAdapter() {
|
||||
@Override
|
||||
public void windowActivated( WindowEvent e ) {
|
||||
IJThemesPanel.this.windowActivated();
|
||||
}
|
||||
};
|
||||
private Window window;
|
||||
|
||||
private File lastDirectory;
|
||||
|
||||
public IJThemesPanel() {
|
||||
initComponents();
|
||||
|
||||
saveButton.setEnabled( false );
|
||||
sourceCodeButton.setEnabled( false );
|
||||
saveButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/download.svg" ) );
|
||||
sourceCodeButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/github.svg" ) );
|
||||
|
||||
// create renderer
|
||||
themesList.setCellRenderer( new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent( JList<?> list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus )
|
||||
{
|
||||
String title = categories.get( index );
|
||||
String name = ((IJThemeInfo)value).name;
|
||||
int sep = name.indexOf( '/' );
|
||||
if( sep >= 0 )
|
||||
name = name.substring( sep + 1 ).trim();
|
||||
|
||||
JComponent c = (JComponent) super.getListCellRendererComponent( list, name, index, isSelected, cellHasFocus );
|
||||
c.setToolTipText( buildToolTip( (IJThemeInfo) value ) );
|
||||
if( title != null )
|
||||
c.setBorder( new CompoundBorder( new ListCellTitledBorder( themesList, title ), c.getBorder() ) );
|
||||
return c;
|
||||
}
|
||||
|
||||
private String buildToolTip( IJThemeInfo ti ) {
|
||||
if( ti.themeFile != null )
|
||||
return ti.themeFile.getPath();
|
||||
if( ti.resourceName == null )
|
||||
return ti.name;
|
||||
|
||||
return "Name: " + ti.name
|
||||
+ "\nLicense: " + ti.license
|
||||
+ "\nSource Code: " + ti.sourceCodeUrl;
|
||||
}
|
||||
} );
|
||||
|
||||
updateThemesList();
|
||||
}
|
||||
|
||||
private void updateThemesList() {
|
||||
// load theme infos
|
||||
themesManager.loadBundledThemes();
|
||||
themesManager.loadThemesFromDirectory();
|
||||
|
||||
// sort themes by name
|
||||
Comparator<? super IJThemeInfo> comparator = (t1, t2) -> t1.name.compareToIgnoreCase( t2.name );
|
||||
themesManager.bundledThemes.sort( comparator );
|
||||
themesManager.moreThemes.sort( comparator );
|
||||
|
||||
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() ) );
|
||||
|
||||
// add uncategorized bundled themes
|
||||
categories.put( themes.size(), "IntelliJ Themes" );
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
if( !ti.name.contains( "/" ) )
|
||||
themes.add( ti );
|
||||
}
|
||||
|
||||
// add categorized bundled themes
|
||||
String lastCategory = null;
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
int sep = ti.name.indexOf( '/' );
|
||||
if( sep < 0 )
|
||||
continue;
|
||||
|
||||
String category = ti.name.substring( 0, sep ).trim();
|
||||
if( !Objects.equals( lastCategory, category ) ) {
|
||||
lastCategory = category;
|
||||
categories.put( themes.size(), category );
|
||||
}
|
||||
|
||||
themes.add( ti );
|
||||
}
|
||||
|
||||
// add themes from directory
|
||||
categories.put( themes.size(), "Current Directory" );
|
||||
themes.addAll( themesManager.moreThemes );
|
||||
|
||||
// remember selection
|
||||
IJThemeInfo oldSel = themesList.getSelectedValue();
|
||||
|
||||
// fill themes list
|
||||
themesList.setModel( new AbstractListModel<IJThemeInfo>() {
|
||||
@Override
|
||||
public int getSize() {
|
||||
return themes.size();
|
||||
}
|
||||
@Override
|
||||
public IJThemeInfo getElementAt( int index ) {
|
||||
return themes.get( index );
|
||||
}
|
||||
} );
|
||||
|
||||
// restore selection
|
||||
if( oldSel != null ) {
|
||||
for( int i = 0; i < themes.size(); i++ ) {
|
||||
IJThemeInfo theme = themes.get( i );
|
||||
if( oldSel.name.equals( theme.name ) &&
|
||||
Objects.equals( oldSel.resourceName, theme.resourceName ) &&
|
||||
Objects.equals( oldSel.themeFile, theme.themeFile ) &&
|
||||
Objects.equals( oldSel.lafClassName, theme.lafClassName ) )
|
||||
{
|
||||
themesList.setSelectedIndex( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void themesListValueChanged( ListSelectionEvent e ) {
|
||||
if( e.getValueIsAdjusting() )
|
||||
return;
|
||||
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
boolean bundledTheme = (themeInfo != null && themeInfo.resourceName != null);
|
||||
saveButton.setEnabled( bundledTheme );
|
||||
sourceCodeButton.setEnabled( bundledTheme );
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
setTheme( themeInfo );
|
||||
} );
|
||||
}
|
||||
|
||||
private void setTheme( IJThemeInfo themeInfo ) {
|
||||
if( themeInfo == null )
|
||||
return;
|
||||
|
||||
// change look and feel
|
||||
if( themeInfo.lafClassName != null ) {
|
||||
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
return;
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel( themeInfo.lafClassName );
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
|
||||
}
|
||||
} else if( themeInfo.themeFile != null ) {
|
||||
try {
|
||||
FlatLaf.install( IntelliJTheme.createLaf( new FileInputStream( themeInfo.themeFile ) ) );
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_INTELLIJ_THEME, DemoPrefs.FILE_PREFIX + themeInfo.themeFile );
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
|
||||
}
|
||||
} else {
|
||||
IntelliJTheme.install( getClass().getResourceAsStream( themeInfo.resourceName ) );
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_INTELLIJ_THEME, DemoPrefs.RESOURCE_PREFIX + themeInfo.resourceName );
|
||||
}
|
||||
|
||||
// update all components
|
||||
FlatLaf.updateUI();
|
||||
}
|
||||
|
||||
private void saveTheme() {
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
if( themeInfo == null || themeInfo.resourceName == null )
|
||||
return;
|
||||
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setSelectedFile( new File( lastDirectory, themeInfo.resourceName ) );
|
||||
if( fileChooser.showSaveDialog( SwingUtilities.windowForComponent( this ) ) != JFileChooser.APPROVE_OPTION )
|
||||
return;
|
||||
|
||||
File file = fileChooser.getSelectedFile();
|
||||
lastDirectory = file.getParentFile();
|
||||
|
||||
// save theme
|
||||
try {
|
||||
Files.copy( getClass().getResourceAsStream( themeInfo.resourceName ),
|
||||
file.toPath(), StandardCopyOption.REPLACE_EXISTING );
|
||||
} catch( IOException ex ) {
|
||||
showInformationDialog( "Failed to save theme to '" + file + "'.", ex );
|
||||
return;
|
||||
}
|
||||
|
||||
// save license
|
||||
if( themeInfo.licenseFile != null ) {
|
||||
try {
|
||||
File licenseFile = new File( file.getParentFile(),
|
||||
StringUtils.removeTrailing( file.getName(), ".theme.json" ) +
|
||||
themeInfo.licenseFile.substring( themeInfo.licenseFile.indexOf( '.' ) ) );
|
||||
Files.copy( getClass().getResourceAsStream( themeInfo.licenseFile ),
|
||||
licenseFile.toPath(), StandardCopyOption.REPLACE_EXISTING );
|
||||
} catch( IOException ex ) {
|
||||
showInformationDialog( "Failed to save theme license to '" + file + "'.", ex );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void browseSourceCode() {
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
if( themeInfo == null || themeInfo.resourceName == null )
|
||||
return;
|
||||
|
||||
String themeUrl = (themeInfo.sourceCodeUrl + '/' + themeInfo.sourceCodePath).replace( " ", "%20" );
|
||||
try {
|
||||
Desktop.getDesktop().browse( new URI( themeUrl ) );
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
showInformationDialog( "Failed to browse '" + themeUrl + "'.", ex );
|
||||
}
|
||||
}
|
||||
|
||||
private void showInformationDialog( String message, Exception ex ) {
|
||||
JOptionPane.showMessageDialog( SwingUtilities.windowForComponent( this ),
|
||||
message + "\n\n" + ex.getMessage(),
|
||||
"FlatLaf", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
selectedCurrentLookAndFeel();
|
||||
UIManager.addPropertyChangeListener( lafListener );
|
||||
|
||||
window = SwingUtilities.windowForComponent( this );
|
||||
if( window != null )
|
||||
window.addWindowListener( windowListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
UIManager.removePropertyChangeListener( lafListener );
|
||||
|
||||
if( window != null ) {
|
||||
window.removeWindowListener( windowListener );
|
||||
window = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void lafChanged( PropertyChangeEvent e ) {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
selectedCurrentLookAndFeel();
|
||||
}
|
||||
|
||||
private void windowActivated() {
|
||||
// refresh themes list on window activation
|
||||
if( themesManager.hasThemesFromDirectoryChanged() )
|
||||
updateThemesList();
|
||||
}
|
||||
|
||||
private void selectedCurrentLookAndFeel() {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
String intelliJTheme = UIManager.getLookAndFeelDefaults().getString( DemoPrefs.INTELLIJ_THEME_UI_KEY );
|
||||
|
||||
if( intelliJTheme == null && lookAndFeel instanceof IntelliJTheme.ThemeLaf )
|
||||
return;
|
||||
|
||||
Predicate<IJThemeInfo> test;
|
||||
if( intelliJTheme != null && intelliJTheme.startsWith( DemoPrefs.RESOURCE_PREFIX ) ) {
|
||||
String resourceName = intelliJTheme.substring( DemoPrefs.RESOURCE_PREFIX.length() );
|
||||
test = ti -> Objects.equals( ti.resourceName, resourceName );
|
||||
} else if( intelliJTheme != null && intelliJTheme.startsWith( DemoPrefs.FILE_PREFIX ) ) {
|
||||
File themeFile = new File( intelliJTheme.substring( DemoPrefs.FILE_PREFIX.length() ) );
|
||||
test = ti -> Objects.equals( ti.themeFile, themeFile );
|
||||
} else {
|
||||
String lafClassName = lookAndFeel.getClass().getName();
|
||||
test = ti -> Objects.equals( ti.lafClassName, lafClassName );
|
||||
}
|
||||
|
||||
int newSel = -1;
|
||||
for( int i = 0; i < themes.size(); i++ ) {
|
||||
if( test.test( themes.get( i ) ) ) {
|
||||
newSel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( newSel >= 0 ) {
|
||||
if( newSel != themesList.getSelectedIndex() )
|
||||
themesList.setSelectedIndex( newSel );
|
||||
} else
|
||||
themesList.clearSelection();
|
||||
}
|
||||
|
||||
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();
|
||||
themesScrollPane = new JScrollPane();
|
||||
themesList = new JList<>();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[grow,fill]",
|
||||
// rows
|
||||
"[]3" +
|
||||
"[grow,fill]"));
|
||||
|
||||
//---- themesLabel ----
|
||||
themesLabel.setText("Themes:");
|
||||
add(themesLabel, "cell 0 0");
|
||||
|
||||
//======== toolBar ========
|
||||
{
|
||||
toolBar.setFloatable(false);
|
||||
|
||||
//---- saveButton ----
|
||||
saveButton.setToolTipText("Save .theme.json of selected IntelliJ theme to file.");
|
||||
saveButton.addActionListener(e -> saveTheme());
|
||||
toolBar.add(saveButton);
|
||||
|
||||
//---- sourceCodeButton ----
|
||||
sourceCodeButton.setToolTipText("Opens the source code repository of selected IntelliJ theme in the browser.");
|
||||
sourceCodeButton.addActionListener(e -> browseSourceCode());
|
||||
toolBar.add(sourceCodeButton);
|
||||
}
|
||||
add(toolBar, "cell 0 0,alignx right,growx 0");
|
||||
|
||||
//======== themesScrollPane ========
|
||||
{
|
||||
|
||||
//---- themesList ----
|
||||
themesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
themesList.addListSelectionListener(e -> themesListValueChanged(e));
|
||||
themesScrollPane.setViewportView(themesList);
|
||||
}
|
||||
add(themesScrollPane, "cell 0 1");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JToolBar toolBar;
|
||||
private JButton saveButton;
|
||||
private JButton sourceCodeButton;
|
||||
private JScrollPane themesScrollPane;
|
||||
private JList<IJThemeInfo> themesList;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" 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": "[grow,fill]"
|
||||
"$rowConstraints": "[]3[grow,fill]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "themesLabel"
|
||||
"text": "Themes:"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": true
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||
name: "toolBar"
|
||||
"floatable": false
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "saveButton"
|
||||
"toolTipText": "Save .theme.json of selected IntelliJ theme to file."
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveTheme", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "sourceCodeButton"
|
||||
"toolTipText": "Opens the source code repository of selected IntelliJ theme in the browser."
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "browseSourceCode", 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" ) {
|
||||
name: "themesList"
|
||||
"selectionMode": 0
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "IJThemeInfo"
|
||||
}
|
||||
addEvent( new FormEvent( "javax.swing.event.ListSelectionListener", "valueChanged", "themesListValueChanged", true ) )
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 400, 300 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo.intellijthemes;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
/**
|
||||
* This tool updates all IntelliJ themes listed in themes.json by downloading
|
||||
* them from the source code repositories.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class IJThemesUpdater
|
||||
{
|
||||
public static void main( String[] args ) {
|
||||
IJThemesManager themesManager = new IJThemesManager();
|
||||
themesManager.loadBundledThemes();
|
||||
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
if( ti.sourceCodeUrl == null || ti.sourceCodePath == null )
|
||||
continue;
|
||||
|
||||
String fromUrl = ti.sourceCodeUrl + "/" + ti.sourceCodePath;
|
||||
if( fromUrl.contains( "github.com" ) )
|
||||
fromUrl += "?raw=true";
|
||||
else if( fromUrl.contains( "gitlab.com" ) )
|
||||
fromUrl = fromUrl.replace( "/blob/", "/raw/" );
|
||||
|
||||
String toPath = "src/main/resources/com/formdev/flatlaf/demo/intellijthemes/" + ti.resourceName;
|
||||
|
||||
download( fromUrl, toPath );
|
||||
}
|
||||
}
|
||||
|
||||
private static void download( String fromUrl, String toPath ) {
|
||||
System.out.println( "Download " + fromUrl );
|
||||
|
||||
Path out = new File( toPath ).toPath();
|
||||
try {
|
||||
URL url = new URL( fromUrl.replace( " ", "%20" ) );
|
||||
URLConnection con = url.openConnection();
|
||||
Files.copy( con.getInputStream(), out, StandardCopyOption.REPLACE_EXISTING );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user