mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ac7867ae | ||
|
|
b6cd31b734 | ||
|
|
8806cc8e93 | ||
|
|
2da0ca736f | ||
|
|
5288e0f54e | ||
|
|
c87f5cb05f | ||
|
|
17074eb16d | ||
|
|
43429ddc39 | ||
|
|
7ef598ded6 | ||
|
|
37c70f6c9e | ||
|
|
26a2446a4d | ||
|
|
771c949d74 | ||
|
|
23d448d4fc | ||
|
|
86577c5fef | ||
|
|
3a69b41646 | ||
|
|
2d26b6fa94 | ||
|
|
144f79f0f9 | ||
|
|
8ea23fc533 | ||
|
|
ae714502fb | ||
|
|
07d6755ddb | ||
|
|
177996ee81 | ||
|
|
3847b14033 | ||
|
|
423805be3a |
@@ -5,6 +5,7 @@ jdk:
|
||||
- openjdk8
|
||||
- openjdk9
|
||||
- openjdk11
|
||||
- openjdk13
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
@@ -24,5 +25,5 @@ deploy:
|
||||
skip_cleanup: true # to upload artifacts created during the build
|
||||
on:
|
||||
branch: master
|
||||
jdk: openjdk8
|
||||
jdk: openjdk11
|
||||
tags: true
|
||||
|
||||
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,6 +1,25 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 0.10
|
||||
|
||||
- Use new chevron arrows in "Flat Light" and "Flat Dark" themes, but keep
|
||||
triangle arrows in "Flat IntelliJ" and "Flat Darcula" themes. (issue #7)
|
||||
- Use bold font for default buttons in "Flat IntelliJ" and "Flat Darcula"
|
||||
themes.
|
||||
- Hide label, button and tab mnemonics by default and show them only when
|
||||
<kbd>Alt</kbd> is pressed. (issue #4)
|
||||
- If a JButton has an icon and no text, then it does not get a minimum width
|
||||
(usually 72 pixel) and the left and right insets are same as top/bottom insets
|
||||
so that it becomes square (if the icon is square).
|
||||
- Changed styling of default button in "Flat Light" theme (wide blue border
|
||||
instead of blue background).
|
||||
- Added Java 9 module descriptor `module-info.class` to `flatlaf.jar` (in
|
||||
`META-INF/versions/9`). But FlatLaf remains Java 8 compatible. (issue #1)
|
||||
- Support specifying custom scale factor in system properties `flatlaf.uiScale`
|
||||
or `sun.java2d.uiScale`. E.g. `-Dflatlaf.uiScale=1.5`. (Java 8 only)
|
||||
|
||||
|
||||
## 0.9
|
||||
|
||||
- Initial release
|
||||
|
||||
18
README.md
18
README.md
@@ -4,8 +4,9 @@ FlatLaf - Flat Look and Feel
|
||||
**FlatLaf** is a modern open-source cross-platform Look and Feel for Java
|
||||
desktop applications.
|
||||
|
||||
It is mostly "flat" (no shadows or gradients), clean, simple and elegant. It
|
||||
comes with **Light** and **Dark** themes and is made for **HiDPI** displays.
|
||||
It looks mostly "flat" (no shadows or gradients), clean, simple and elegant.
|
||||
FlatLaf comes with **Light**, **Dark**, **IntelliJ** and **Darcula** themes,
|
||||
scales on **HiDPI** displays and runs on Java 8 or newer.
|
||||
|
||||
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
|
||||
IntelliJ IDEA 2019.2+ and uses mostly the same colors and icons.
|
||||
@@ -19,15 +20,22 @@ Demo
|
||||
----
|
||||
|
||||
Download
|
||||
[flatlaf-demo-0.1.jar](https://download.formdev.com/flatlaf/flatlaf-demo-0.1.jar)
|
||||
and run it with `java -jar flatlaf-demo-0.1.jar` (or double-click it). Requires
|
||||
[flatlaf-demo-0.10.jar](https://download.formdev.com/flatlaf/flatlaf-demo-0.10.jar)
|
||||
and run it with `java -jar flatlaf-demo-0.10.jar` (or double-click it). Requires
|
||||
Java 8 or newer.
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Coming soon
|
||||
[  ](https://bintray.com/jformdesigner/flatlaf/flatlaf-core/_latestVersion)
|
||||
|
||||
For Maven or Gradle use:
|
||||
|
||||
Repository: jcenter (https://jcenter.bintray.com/)
|
||||
Group Id: com.formdev.flatlaf
|
||||
Artifact Id: flatlaf-core
|
||||
Version: 0.10
|
||||
|
||||
|
||||
License
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
version = "0.9"
|
||||
version = "0.10"
|
||||
|
||||
// check required Java version
|
||||
if( JavaVersion.current() < JavaVersion.VERSION_1_8 )
|
||||
|
||||
@@ -26,6 +26,18 @@ repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
sourceSets {
|
||||
create( "module-info" ) {
|
||||
java {
|
||||
// include "src/main/java" here to get compile errors if classes are
|
||||
// used from other modules that are not specified in module dependencies
|
||||
setSrcDirs( listOf( "src/main/module-info", "src/main/java" ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation( "com.miglayout:miglayout-swing:5.2" )
|
||||
testImplementation( "com.jgoodies:jgoodies-forms:1.9.0" )
|
||||
@@ -37,8 +49,26 @@ java {
|
||||
}
|
||||
|
||||
tasks {
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||
named<JavaCompile>( "compileModuleInfoJava" ) {
|
||||
sourceCompatibility = "9"
|
||||
targetCompatibility = "9"
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
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 )
|
||||
include( "module-info.class" )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
|
||||
@@ -16,11 +16,18 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.AWTEventListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -29,7 +36,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIDefaults.LazyValue;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.DimensionUIResource;
|
||||
@@ -41,6 +53,7 @@ import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
import com.formdev.flatlaf.util.ScaledNumber;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* The base class for all Flat LaFs.
|
||||
@@ -57,6 +70,9 @@ public abstract class FlatLaf
|
||||
|
||||
private BasicLookAndFeel base;
|
||||
|
||||
private AWTEventListener mnemonicListener;
|
||||
private static boolean altKeyPressed;
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return getName();
|
||||
@@ -77,10 +93,23 @@ public abstract class FlatLaf
|
||||
getBase().initialize();
|
||||
|
||||
super.initialize();
|
||||
|
||||
// add mnemonic listener
|
||||
mnemonicListener = e -> {
|
||||
if( e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ALT )
|
||||
altKeyChanged( e.getID() == KeyEvent.KEY_PRESSED );
|
||||
};
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener( mnemonicListener, AWTEvent.KEY_EVENT_MASK );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninitialize() {
|
||||
// remove mnemonic listener
|
||||
if( mnemonicListener != null ) {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener( mnemonicListener );
|
||||
mnemonicListener = null;
|
||||
}
|
||||
|
||||
if( base != null )
|
||||
base.uninitialize();
|
||||
|
||||
@@ -159,6 +188,8 @@ public abstract class FlatLaf
|
||||
if( uiFont == null )
|
||||
return;
|
||||
|
||||
uiFont = UIScale.applyCustomScaleFactor( uiFont );
|
||||
|
||||
// override fonts
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && ((String)key).endsWith( ".font" ) )
|
||||
@@ -285,15 +316,15 @@ public abstract class FlatLaf
|
||||
key.endsWith( "Margins" ) || key.endsWith( "Insets" ) )
|
||||
return parseInsets( value );
|
||||
|
||||
// size
|
||||
if( key.endsWith( "Size" ) && !key.equals( "SplitPane.dividerSize" ))
|
||||
return parseSize( value );
|
||||
|
||||
// scaled number
|
||||
ScaledNumber scaledNumber = parseScaledNumber( key, value );
|
||||
if( scaledNumber != null )
|
||||
return scaledNumber;
|
||||
|
||||
// size
|
||||
if( key.endsWith( "Size" ) && !key.equals( "SplitPane.dividerSize" ))
|
||||
return parseSize( value );
|
||||
|
||||
// width, height
|
||||
if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
||||
return parseInteger( value, true );
|
||||
@@ -400,8 +431,10 @@ public abstract class FlatLaf
|
||||
}
|
||||
|
||||
private ScaledNumber parseScaledNumber( String key, String value ) {
|
||||
if( !key.equals( "OptionPane.buttonMinimumWidth" ) )
|
||||
return null; // not supported
|
||||
if( !key.equals( "OptionPane.buttonMinimumWidth" ) &&
|
||||
!key.equals( "SplitPane.oneTouchButtonSize" ) &&
|
||||
!key.equals( "SplitPane.oneTouchButtonOffset" ) )
|
||||
return null; // not supported
|
||||
|
||||
try {
|
||||
return new ScaledNumber( Integer.parseInt( value ) );
|
||||
@@ -424,4 +457,61 @@ public abstract class FlatLaf
|
||||
|
||||
return strs;
|
||||
}
|
||||
|
||||
public static boolean isShowMnemonics() {
|
||||
return altKeyPressed || !UIManager.getBoolean( "Component.hideMnemonics" );
|
||||
}
|
||||
|
||||
private static void altKeyChanged( boolean pressed ) {
|
||||
if( pressed == altKeyPressed )
|
||||
return;
|
||||
|
||||
altKeyPressed = pressed;
|
||||
|
||||
// check whether it is necessary to repaint
|
||||
if( !UIManager.getBoolean( "Component.hideMnemonics" ) )
|
||||
return;
|
||||
|
||||
// get focus owner
|
||||
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
if( focusOwner == null )
|
||||
return;
|
||||
|
||||
// get focused window
|
||||
Window window = SwingUtilities.windowForComponent( focusOwner );
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
// repaint components with mnemonics in focused window
|
||||
repaintMnemonics( window );
|
||||
}
|
||||
|
||||
private static void repaintMnemonics( Container container ) {
|
||||
for( Component c : container.getComponents() ) {
|
||||
if( hasMnemonic( c ) )
|
||||
c.repaint();
|
||||
|
||||
if( c instanceof Container )
|
||||
repaintMnemonics( (Container) c );
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasMnemonic( Component c ) {
|
||||
if( c instanceof JLabel && ((JLabel)c).getDisplayedMnemonicIndex() >= 0 )
|
||||
return true;
|
||||
|
||||
if( c instanceof AbstractButton && ((AbstractButton)c).getDisplayedMnemonicIndex() >= 0 )
|
||||
return true;
|
||||
|
||||
if( c instanceof JTabbedPane ) {
|
||||
JTabbedPane tabPane = (JTabbedPane) c;
|
||||
int tabCount = tabPane.getTabCount();
|
||||
for( int i = 0; i < tabCount; i++ ) {
|
||||
if( tabPane.getDisplayedMnemonicIndexAt( i ) >= 0 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
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.JMenu;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
@@ -26,6 +28,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "arrow" icon for {@link javax.swing.JMenu}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Menu.icon.arrowColor Color
|
||||
* @uiDefault Menu.icon.disabledArrowColor Color
|
||||
* @uiDefault Menu.selectionForeground Color
|
||||
@@ -35,12 +38,13 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatMenuArrowIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
protected final Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
|
||||
protected final Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
|
||||
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
|
||||
|
||||
public FlatMenuArrowIcon() {
|
||||
super( 5, 10, null );
|
||||
super( 6, 10, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +53,15 @@ public class FlatMenuArrowIcon
|
||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||
|
||||
g.setColor( getArrowColor( c ) );
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
|
||||
}
|
||||
}
|
||||
|
||||
private Color getArrowColor( Component c ) {
|
||||
|
||||
@@ -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,6 +25,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
/**
|
||||
* "collapsed" icon for {@link javax.swing.JTree}.
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Tree.icon.collapsedColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -31,15 +33,32 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatTreeCollapsedIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final boolean chevron;
|
||||
|
||||
public FlatTreeCollapsedIcon() {
|
||||
super( 11, 11, UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
||||
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
||||
}
|
||||
|
||||
FlatTreeCollapsedIcon( Color color ) {
|
||||
super( 11, 11, color );
|
||||
chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
rotate( c, g );
|
||||
|
||||
if( chevron ) {
|
||||
// chevron arrow
|
||||
g.fill( FlatUIUtils.createPath( 3,1, 3,2.5, 6,5.5, 3,8.5, 3,10, 4.5,10, 9,5.5, 4.5,1 ) );
|
||||
} else {
|
||||
// triangle arrow
|
||||
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void rotate( Component c, Graphics2D g ) {
|
||||
if( !c.getComponentOrientation().isLeftToRight() )
|
||||
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.formdev.flatlaf.icons;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "expanded" icon for {@link javax.swing.JTree}.
|
||||
@@ -29,14 +28,14 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatTreeExpandedIcon
|
||||
extends FlatAbstractIcon
|
||||
extends FlatTreeCollapsedIcon
|
||||
{
|
||||
public FlatTreeExpandedIcon() {
|
||||
super( 11, 11, UIManager.getColor( "Tree.icon.expandedColor" ) );
|
||||
super( UIManager.getColor( "Tree.icon.expandedColor" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
g.fill( FlatUIUtils.createPath( 1,2, 10,2, 5.5,10 ) );
|
||||
void rotate( Component c, Graphics2D g ) {
|
||||
g.rotate( Math.toRadians( 90 ), width / 2., height / 2. );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -37,6 +38,7 @@ public class FlatArrowButton
|
||||
extends BasicArrowButton
|
||||
implements UIResource
|
||||
{
|
||||
private final boolean chevron;
|
||||
private final Color foreground;
|
||||
private final Color disabledForeground;
|
||||
private final Color hoverForeground;
|
||||
@@ -47,11 +49,12 @@ public class FlatArrowButton
|
||||
|
||||
private boolean hover;
|
||||
|
||||
public FlatArrowButton( int direction, Color foreground, Color disabledForeground,
|
||||
public FlatArrowButton( int direction, String type, Color foreground, Color disabledForeground,
|
||||
Color hoverForeground, Color hoverBackground )
|
||||
{
|
||||
super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE );
|
||||
|
||||
this.chevron = "chevron".equals( type );
|
||||
this.foreground = foreground;
|
||||
this.disabledForeground = disabledForeground;
|
||||
this.hoverForeground = hoverForeground;
|
||||
@@ -77,6 +80,10 @@ public class FlatArrowButton
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isHover() {
|
||||
return hover;
|
||||
}
|
||||
|
||||
public int getXOffset() {
|
||||
return xOffset;
|
||||
}
|
||||
@@ -113,7 +120,7 @@ public class FlatArrowButton
|
||||
boolean enabled = isEnabled();
|
||||
|
||||
// paint hover background
|
||||
if( enabled && hover && hoverBackground != null ) {
|
||||
if( enabled && isHover() && hoverBackground != null ) {
|
||||
g.setColor( hoverBackground );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
}
|
||||
@@ -121,26 +128,41 @@ public class FlatArrowButton
|
||||
int direction = getDirection();
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
|
||||
int w = scale( 9 );
|
||||
int h = scale( 5 );
|
||||
int x = Math.round( (width - (vert ? w : h)) / 2f + scale( (float) xOffset ) );
|
||||
int y = Math.round( (height - (vert ? h : w)) / 2f + scale( (float) yOffset ) );
|
||||
int w = scale( chevron ? 8 : 9 );
|
||||
int h = scale( chevron ? 4 : 5 );
|
||||
int rw = vert ? w : h;
|
||||
int rh = vert ? h : w;
|
||||
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) );
|
||||
int y = Math.round( (height - rh) / 2f + scale( (float) yOffset ) );
|
||||
|
||||
// optimization for small chevron arrows (e.g. OneTouchButtons in SplitPane)
|
||||
if( x + rw >= width && x > 0 )
|
||||
x--;
|
||||
if( y + rh >= height && y > 0 )
|
||||
y--;
|
||||
|
||||
// paint arrow
|
||||
g.setColor( enabled
|
||||
? (hover && hoverForeground != null ? hoverForeground : foreground)
|
||||
? (isHover() && hoverForeground != null ? hoverForeground : foreground)
|
||||
: disabledForeground );
|
||||
g.translate( x, y );
|
||||
g2.fill( createArrowShape( direction, w, h ) );
|
||||
Shape arrowShape = createArrowShape( direction, chevron, w, h );
|
||||
if( chevron ) {
|
||||
g2.setStroke( new BasicStroke( scale( 1f ) ) );
|
||||
g2.draw( arrowShape );
|
||||
} else {
|
||||
// triangle
|
||||
g2.fill( arrowShape );
|
||||
}
|
||||
g.translate( -x, -y );
|
||||
}
|
||||
|
||||
public static Shape createArrowShape( int direction, int w, int h ) {
|
||||
public static Shape createArrowShape( int direction, boolean chevron, int w, int h ) {
|
||||
switch( direction ) {
|
||||
case NORTH: return FlatUIUtils.createPath( 0,h, w,h, (w / 2f),0 );
|
||||
case SOUTH: return FlatUIUtils.createPath( 0,0, w,0, (w / 2f),h );
|
||||
case WEST: return FlatUIUtils.createPath( h,0, h,w, 0,(w / 2f) );
|
||||
case EAST: return FlatUIUtils.createPath( 0,0, 0,w, h,(w / 2f) );
|
||||
case NORTH: return FlatUIUtils.createPath( !chevron, 0,h, (w / 2f),0, w,h );
|
||||
case SOUTH: return FlatUIUtils.createPath( !chevron, 0,0, (w / 2f),h, w,0 );
|
||||
case WEST: return FlatUIUtils.createPath( !chevron, h,0, 0,(w / 2f), h,w );
|
||||
case EAST: return FlatUIUtils.createPath( !chevron, 0,0, h,(w / 2f), 0,w );
|
||||
default: return new Path2D.Float();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import javax.swing.text.JTextComponent;
|
||||
* {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly.
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.innerFocusWidth int
|
||||
* @uiDefault Component.focusColor Color
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
@@ -59,6 +60,7 @@ public class FlatBorder
|
||||
extends BasicBorders.MarginBorder
|
||||
{
|
||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
protected final int innerFocusWidth = UIManager.getInt( "Component.innerFocusWidth" );
|
||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||
protected final Color borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
@@ -71,16 +73,17 @@ public class FlatBorder
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
|
||||
float focusWidth = getFocusWidth();
|
||||
float lineWidth = getLineWidth();
|
||||
float borderWidth = getBorderWidth( c );
|
||||
float arc = getArc();
|
||||
|
||||
if( isFocused( c ) ) {
|
||||
g2.setColor( getFocusColor( c ) );
|
||||
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth, lineWidth, arc );
|
||||
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth,
|
||||
getLineWidth() + scale( (float) innerFocusWidth ), arc );
|
||||
}
|
||||
|
||||
g2.setPaint( getBorderColor( c ) );
|
||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, lineWidth, arc );
|
||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
@@ -149,6 +152,10 @@ public class FlatBorder
|
||||
return scale( 1f );
|
||||
}
|
||||
|
||||
protected float getBorderWidth( Component c ) {
|
||||
return getLineWidth();
|
||||
}
|
||||
|
||||
protected float getArc() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,11 @@ import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Border for {@link javax.swing.JButton}.
|
||||
@@ -34,6 +37,7 @@ import javax.swing.UIManager;
|
||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||
* @uiDefault Button.default.focusedBorderColor Color
|
||||
* @uiDefault Button.default.focusColor Color
|
||||
* @uiDefault Button.default.borderWidth int
|
||||
* @uiDefault Button.arc int
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -49,6 +53,7 @@ public class FlatButtonBorder
|
||||
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
||||
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
||||
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
||||
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
|
||||
protected final int arc = UIManager.getInt( "Button.arc" );
|
||||
|
||||
@Override
|
||||
@@ -73,6 +78,22 @@ public class FlatButtonBorder
|
||||
null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
insets = super.getBorderInsets( c, insets );
|
||||
|
||||
// use smaller left and right insets for icon-only buttons (so that they are square)
|
||||
if( FlatButtonUI.isIconOnlyButton( c ) && ((JButton)c).getMargin() instanceof UIResource )
|
||||
insets.left = insets.right = Math.min( insets.top, insets.bottom );
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getBorderWidth( Component c ) {
|
||||
return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getArc() {
|
||||
return scale( (float) arc );
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
@@ -35,7 +36,9 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
|
||||
@@ -55,6 +58,7 @@ import javax.swing.plaf.basic.BasicButtonUI;
|
||||
* @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.toolbar.hoverBackground Color
|
||||
* @uiDefault Button.toolbar.pressedBackground Color
|
||||
*
|
||||
@@ -78,6 +82,7 @@ public class FlatButtonUI
|
||||
protected Color defaultFocusedBackground;
|
||||
protected Color defaultHoverBackground;
|
||||
protected Color defaultPressedBackground;
|
||||
protected boolean defaultBoldText;
|
||||
|
||||
protected Color toolbarHoverBackground;
|
||||
protected Color toolbarPressedBackground;
|
||||
@@ -116,6 +121,7 @@ public class FlatButtonUI
|
||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
||||
|
||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||
@@ -146,6 +152,13 @@ public class FlatButtonUI
|
||||
return c instanceof JButton && ((JButton)c).isDefaultButton();
|
||||
}
|
||||
|
||||
static boolean isIconOnlyButton( Component c ) {
|
||||
String text;
|
||||
return c instanceof JButton &&
|
||||
((JButton)c).getIcon() != null &&
|
||||
((text = ((JButton)c).getText()) == null || text.isEmpty());
|
||||
}
|
||||
|
||||
static boolean isHelpButton( Component c ) {
|
||||
return c instanceof JButton && clientPropertyEquals( (JButton) c, BUTTON_TYPE, BUTTON_TYPE_HELP );
|
||||
}
|
||||
@@ -191,12 +204,23 @@ public class FlatButtonUI
|
||||
if( isHelpButton( b ) )
|
||||
return;
|
||||
|
||||
if( defaultBoldText && isDefaultButton( b ) && b.getFont() instanceof UIResource ) {
|
||||
Font boldFont = g.getFont().deriveFont( Font.BOLD );
|
||||
g.setFont( boldFont );
|
||||
|
||||
int boldWidth = b.getFontMetrics( boldFont ).stringWidth( text );
|
||||
if( boldWidth > textRect.width ) {
|
||||
textRect.x -= (boldWidth - textRect.width) / 2;
|
||||
textRect.width = boldWidth;
|
||||
}
|
||||
}
|
||||
|
||||
paintText( g, b, textRect, text, b.isEnabled() ? getForeground( b ) : disabledText );
|
||||
}
|
||||
|
||||
static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||
int mnemonicIndex = b.getDisplayedMnemonicIndex();
|
||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||
|
||||
g.setColor( foreground );
|
||||
FlatUIUtils.drawStringUnderlineCharAt( b, g, text, mnemonicIndex,
|
||||
@@ -259,8 +283,11 @@ public class FlatButtonUI
|
||||
return new Dimension( helpButtonIcon.getIconWidth(), helpButtonIcon.getIconHeight() );
|
||||
|
||||
Dimension prefSize = super.getPreferredSize( c );
|
||||
if( !isToolBarButton( c ) )
|
||||
|
||||
// apply minimum width, if not in toolbar and not a icon-only button
|
||||
if( !isToolBarButton( c ) && !isIconOnlyButton( c ) )
|
||||
prefSize.width = Math.max( prefSize.width, scale( minimumWidth + (focusWidth * 2) ) );
|
||||
|
||||
return prefSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
@@ -57,6 +58,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
*
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.arc int
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault ComboBox.disabledBackground Color
|
||||
@@ -74,6 +76,7 @@ public class FlatComboBoxUI
|
||||
{
|
||||
protected int focusWidth;
|
||||
protected int arc;
|
||||
protected String arrowType;
|
||||
protected Color borderColor;
|
||||
protected Color disabledBorderColor;
|
||||
|
||||
@@ -86,16 +89,42 @@ public class FlatComboBoxUI
|
||||
protected Color buttonDisabledArrowColor;
|
||||
protected Color buttonHoverArrowColor;
|
||||
|
||||
private MouseListener hoverListener;
|
||||
private boolean hover;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
return new FlatComboBoxUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
hoverListener = new FlatUIUtils.HoverListener( null, h -> {
|
||||
if( !comboBox.isEditable() ) {
|
||||
hover = h;
|
||||
if( arrowButton != null )
|
||||
arrowButton.repaint();
|
||||
}
|
||||
} );
|
||||
comboBox.addMouseListener( hoverListener );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
|
||||
comboBox.removeMouseListener( hoverListener );
|
||||
hoverListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
arc = UIManager.getInt( "Component.arc" );
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
|
||||
@@ -224,8 +253,14 @@ public class FlatComboBoxUI
|
||||
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
return new FlatArrowButton( SwingConstants.SOUTH, buttonArrowColor,
|
||||
buttonDisabledArrowColor, buttonHoverArrowColor, null );
|
||||
return new FlatArrowButton( SwingConstants.SOUTH, arrowType, buttonArrowColor,
|
||||
buttonDisabledArrowColor, buttonHoverArrowColor, null )
|
||||
{
|
||||
@Override
|
||||
protected boolean isHover() {
|
||||
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -71,9 +72,16 @@ public class FlatLabelUI
|
||||
defaults_initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
||||
int mnemIndex = FlatLaf.isShowMnemonics() ? l.getDisplayedMnemonicIndex() : -1;
|
||||
g.setColor( l.getForeground() );
|
||||
FlatUIUtils.drawStringUnderlineCharAt( l, g, s, mnemIndex, textX, textY );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintDisabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
||||
int mnemIndex = l.getDisplayedMnemonicIndex();
|
||||
int mnemIndex = FlatLaf.isShowMnemonics() ? l.getDisplayedMnemonicIndex() : -1;
|
||||
g.setColor( disabledForeground );
|
||||
FlatUIUtils.drawStringUnderlineCharAt( l, g, s, mnemIndex, textX, textY );
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import javax.swing.plaf.basic.BasicSpinnerUI;
|
||||
* @uiDefault Component.focusWidth int
|
||||
* @uiDefault Component.arc int
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault Component.borderColor Color
|
||||
* @uiDefault Component.disabledBorderColor Color
|
||||
* @uiDefault Spinner.disabledBackground Color
|
||||
@@ -68,6 +69,7 @@ public class FlatSpinnerUI
|
||||
protected int focusWidth;
|
||||
protected int arc;
|
||||
protected int minimumWidth;
|
||||
protected String arrowType;
|
||||
protected Color borderColor;
|
||||
protected Color disabledBorderColor;
|
||||
protected Color disabledBackground;
|
||||
@@ -89,6 +91,7 @@ public class FlatSpinnerUI
|
||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||
arc = UIManager.getInt( "Component.arc" );
|
||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
|
||||
@@ -209,7 +212,7 @@ public class FlatSpinnerUI
|
||||
}
|
||||
|
||||
private Component createArrowButton( int direction, String name ) {
|
||||
FlatArrowButton button = new FlatArrowButton( direction, buttonArrowColor,
|
||||
FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor,
|
||||
buttonDisabledArrowColor, buttonHoverArrowColor, null );
|
||||
button.setName( name );
|
||||
button.setYOffset( (direction == SwingConstants.NORTH) ? 1 : -1 );
|
||||
|
||||
@@ -31,6 +31,7 @@ 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
|
||||
* @uiDefault SplitPane.background Color
|
||||
* @uiDefault SplitPane.foreground Color unused
|
||||
* @uiDefault SplitPane.dividerSize int
|
||||
@@ -46,6 +47,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public class FlatSplitPaneUI
|
||||
extends BasicSplitPaneUI
|
||||
{
|
||||
protected String arrowType;
|
||||
private Boolean continuousLayout;
|
||||
private Color oneTouchArrowColor;
|
||||
private Color oneTouchHoverArrowColor;
|
||||
@@ -56,6 +58,8 @@ public class FlatSplitPaneUI
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
arrowType = UIManager.getString( "Component.arrowType" );
|
||||
|
||||
// get one-touch colors before invoking super.installDefaults() because they are
|
||||
// used in there on LaF switching
|
||||
oneTouchArrowColor = UIManager.getColor( "SplitPaneDivider.oneTouchArrowColor" );
|
||||
@@ -108,7 +112,7 @@ public class FlatSplitPaneUI
|
||||
private final boolean left;
|
||||
|
||||
public FlatOneTouchButton( boolean left ) {
|
||||
super( SwingConstants.NORTH, oneTouchArrowColor, null, oneTouchHoverArrowColor, null );
|
||||
super( SwingConstants.NORTH, arrowType, oneTouchArrowColor, null, oneTouchHoverArrowColor, null );
|
||||
setCursor( Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ) );
|
||||
|
||||
this.left = left;
|
||||
|
||||
@@ -33,12 +33,14 @@ import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
import javax.swing.text.View;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTabbedPane}.
|
||||
*
|
||||
* @clientProperty JTabbedPane.hasFullBorder boolean
|
||||
*
|
||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||
* @uiDefault TabbedPane.font Font
|
||||
* @uiDefault TabbedPane.background Color
|
||||
* @uiDefault TabbedPane.foreground Color
|
||||
@@ -144,7 +146,8 @@ public class FlatTabbedPaneUI
|
||||
@Override
|
||||
protected JButton createScrollButton( int direction ) {
|
||||
// this method is invoked before installDefaults(), so we can not use color fields here
|
||||
return new FlatArrowButton( direction, UIManager.getColor("TabbedPane.shadow"),
|
||||
return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ),
|
||||
UIManager.getColor( "TabbedPane.shadow" ),
|
||||
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
|
||||
UIManager.getColor( "TabbedPane.hoverColor" ) );
|
||||
}
|
||||
@@ -261,7 +264,7 @@ public class FlatTabbedPaneUI
|
||||
} else
|
||||
color = disabledForeground;
|
||||
|
||||
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt( tabIndex );
|
||||
int mnemIndex = FlatLaf.isShowMnemonics() ? tabPane.getDisplayedMnemonicIndexAt( tabIndex ) : -1;
|
||||
|
||||
g.setColor( color );
|
||||
FlatUIUtils.drawStringUnderlineCharAt( tabPane, g, title, mnemIndex,
|
||||
|
||||
@@ -181,11 +181,16 @@ public class FlatUIUtils
|
||||
}
|
||||
|
||||
public static Path2D createPath( double... points ) {
|
||||
return createPath( true, points );
|
||||
}
|
||||
|
||||
public static Path2D createPath( boolean close, double... points ) {
|
||||
Path2D path = new Path2D.Float();
|
||||
path.moveTo( points[0], points[1] );
|
||||
for( int i = 2; i < points.length; i += 2 )
|
||||
path.lineTo( points[i], points[i + 1] );
|
||||
path.closePath();
|
||||
if( close )
|
||||
path.closePath();
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.lang.reflect.Method;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.DimensionUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
|
||||
@@ -65,7 +66,7 @@ public class UIScale
|
||||
|
||||
private static Boolean jreHiDPI;
|
||||
|
||||
private static boolean isJreHiDPIEnabled() {
|
||||
public static boolean isJreHiDPIEnabled() {
|
||||
if( jreHiDPI != null )
|
||||
return jreHiDPI;
|
||||
|
||||
@@ -103,8 +104,13 @@ public class UIScale
|
||||
//---- user scaling (Java 8) ----------------------------------------------
|
||||
|
||||
private static float scaleFactor = 1;
|
||||
private static boolean initialized;
|
||||
|
||||
private static void initialize() {
|
||||
if( initialized )
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
static {
|
||||
if( isEnabled() ) {
|
||||
// listener to update scale factor if LaF changed or if Label.font changed
|
||||
// (e.g. option "Override default fonts" in IntelliJ IDEA)
|
||||
@@ -138,6 +144,10 @@ public class UIScale
|
||||
// (e.g. can avoid large icons with small text)
|
||||
Font font = UIManager.getFont( "Label.font" );
|
||||
|
||||
setUserScaleFactor( computeScaleFactor( font ) );
|
||||
}
|
||||
|
||||
private static float computeScaleFactor( Font font ) {
|
||||
// default font size
|
||||
float fontSizeDivider = 12f;
|
||||
|
||||
@@ -152,7 +162,7 @@ public class UIScale
|
||||
fontSizeDivider = 15f;
|
||||
}
|
||||
|
||||
setUserScaleFactor( font.getSize() / fontSizeDivider );
|
||||
return font.getSize() / fontSizeDivider;
|
||||
}
|
||||
|
||||
private static boolean isEnabled() {
|
||||
@@ -164,7 +174,58 @@ public class UIScale
|
||||
return (hidpi != null) ? Boolean.parseBoolean( hidpi ) : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a custom scale factor given in system properties "flatlaf.uiScale"
|
||||
* or "sun.java2d.uiScale" to the given font.
|
||||
*/
|
||||
public static FontUIResource applyCustomScaleFactor( FontUIResource font ) {
|
||||
if( UIScale.isJreHiDPIEnabled() )
|
||||
return font;
|
||||
|
||||
String uiScale = System.getProperty( "flatlaf.uiScale" );
|
||||
if( uiScale == null )
|
||||
uiScale = System.getProperty( "sun.java2d.uiScale" );
|
||||
|
||||
float scaleFactor = parseScaleFactor( uiScale );
|
||||
if( scaleFactor <= 0 )
|
||||
return font;
|
||||
|
||||
float fontScaleFactor = computeScaleFactor( font );
|
||||
if( scaleFactor == fontScaleFactor )
|
||||
return font;
|
||||
|
||||
int newFontSize = Math.round( (font.getSize() / fontScaleFactor) * scaleFactor );
|
||||
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to sun.java2d.SunGraphicsEnvironment.getScaleFactor(String)
|
||||
*/
|
||||
private static float parseScaleFactor( String s ) {
|
||||
if( s == null )
|
||||
return -1;
|
||||
|
||||
float units = 1;
|
||||
if( s.endsWith( "x" ) )
|
||||
s = s.substring( 0, s.length() - 1 );
|
||||
else if( s.endsWith( "dpi" ) ) {
|
||||
units = 96;
|
||||
s = s.substring( 0, s.length() - 3 );
|
||||
} else if( s.endsWith( "%" ) ) {
|
||||
units = 100;
|
||||
s = s.substring( 0, s.length() - 1 );
|
||||
}
|
||||
|
||||
try {
|
||||
float scale = Float.parseFloat( s );
|
||||
return scale > 0 ? scale / units : -1;
|
||||
} catch( NumberFormatException ex ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static float getUserScaleFactor() {
|
||||
initialize();
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
@@ -181,10 +242,12 @@ public class UIScale
|
||||
}
|
||||
|
||||
public static float scale( float value ) {
|
||||
initialize();
|
||||
return (scaleFactor == 1) ? value : (value * scaleFactor);
|
||||
}
|
||||
|
||||
public static int scale( int value ) {
|
||||
initialize();
|
||||
return (scaleFactor == 1) ? value : Math.round( value * scaleFactor );
|
||||
}
|
||||
|
||||
@@ -192,23 +255,28 @@ public class UIScale
|
||||
* Similar as scale(int) but always "rounds down".
|
||||
*/
|
||||
public static int scale2( int value ) {
|
||||
initialize();
|
||||
return (scaleFactor == 1) ? value : (int) (value * scaleFactor);
|
||||
}
|
||||
|
||||
public static float unscale( float value ) {
|
||||
initialize();
|
||||
return (scaleFactor == 1f) ? value : (value / scaleFactor);
|
||||
}
|
||||
|
||||
public static int unscale( int value ) {
|
||||
initialize();
|
||||
return (scaleFactor == 1f) ? value : Math.round( value / scaleFactor );
|
||||
}
|
||||
|
||||
public static void scaleGraphics( Graphics2D g ) {
|
||||
initialize();
|
||||
if( scaleFactor != 1f )
|
||||
g.scale( scaleFactor, scaleFactor );
|
||||
}
|
||||
|
||||
public static Dimension scale( Dimension dimension ) {
|
||||
initialize();
|
||||
return (dimension == null || scaleFactor == 1f)
|
||||
? dimension
|
||||
: (dimension instanceof UIResource
|
||||
@@ -217,6 +285,7 @@ public class UIScale
|
||||
}
|
||||
|
||||
public static Insets scale( Insets insets ) {
|
||||
initialize();
|
||||
return (insets == null || scaleFactor == 1f)
|
||||
? insets
|
||||
: (insets instanceof UIResource
|
||||
|
||||
27
flatlaf-core/src/main/module-info/module-info.java
Normal file
27
flatlaf-core/src/main/module-info/module-info.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
module com.formdev.flatlaf {
|
||||
requires java.desktop;
|
||||
|
||||
exports com.formdev.flatlaf;
|
||||
exports com.formdev.flatlaf.icons;
|
||||
exports com.formdev.flatlaf.ui;
|
||||
exports com.formdev.flatlaf.util;
|
||||
}
|
||||
@@ -18,9 +18,16 @@
|
||||
# which is licensed under the Apache 2.0 license. Copyright 2000-2019 JetBrains s.r.o.
|
||||
# See: https://github.com/JetBrains/intellij-community/
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.default.boldText=true
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
Component.focusWidth=2
|
||||
Component.innerFocusWidth=0
|
||||
Component.arrowType=triangle
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
|
||||
@@ -79,6 +79,7 @@ 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
|
||||
|
||||
@@ -22,6 +22,17 @@
|
||||
|
||||
Button.focusedBackground=null
|
||||
|
||||
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.boldText=true
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
@@ -37,6 +48,8 @@ CheckBox.icon.selectedPressedBackground=72A1D4
|
||||
#---- Component ----
|
||||
|
||||
Component.focusWidth=2
|
||||
Component.innerFocusWidth=0
|
||||
Component.arrowType=triangle
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
|
||||
@@ -70,6 +70,8 @@ Button.iconTextGap=4
|
||||
Button.rollover=true
|
||||
Button.defaultButtonFollowsFocus=false
|
||||
|
||||
Button.default.borderWidth=1
|
||||
|
||||
|
||||
#---- CheckBox ----
|
||||
|
||||
@@ -103,8 +105,11 @@ ComboBox.padding=2,6,2,6
|
||||
#---- Component ----
|
||||
|
||||
Component.focusWidth=0
|
||||
Component.innerFocusWidth=0
|
||||
Component.arc=5
|
||||
Component.minimumWidth=64
|
||||
Component.arrowType=chevron
|
||||
Component.hideMnemonics=true
|
||||
|
||||
|
||||
#---- EditorPane ----
|
||||
@@ -306,6 +311,8 @@ SplitPane.dividerSize=5
|
||||
SplitPane.continuousLayout=true
|
||||
SplitPane.border=null
|
||||
SplitPane.centerOneTouchButtons=true
|
||||
SplitPane.oneTouchButtonSize=6
|
||||
SplitPane.oneTouchButtonOffset=2
|
||||
|
||||
SplitPaneDivider.border=null
|
||||
SplitPaneDivider.oneTouchArrowColor=@@ComboBox.buttonArrowColor
|
||||
|
||||
@@ -72,14 +72,16 @@ Button.disabledBorderColor=cfcfcf
|
||||
Button.focusedBorderColor=87afda
|
||||
Button.hoverBorderColor=@@Button.focusedBorderColor
|
||||
|
||||
Button.default.background=4A86C7
|
||||
Button.default.foreground=f0f0f0
|
||||
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.background=@@Button.background
|
||||
Button.default.foreground=@foreground
|
||||
Button.default.focusedBackground=@@Button.focusedBackground
|
||||
Button.default.hoverBackground=@@Button.hoverBackground
|
||||
Button.default.pressedBackground=@@Button.pressedBackground
|
||||
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
|
||||
|
||||
@@ -55,6 +55,7 @@ public class FlatComponentsTest
|
||||
FlatComponentsTest.TestDefaultButton button5 = new FlatComponentsTest.TestDefaultButton();
|
||||
JButton button3 = new JButton();
|
||||
JButton button12 = new JButton();
|
||||
JButton button13 = new JButton();
|
||||
JLabel toggleButtonLabel = new JLabel();
|
||||
JToggleButton toggleButton1 = new JToggleButton();
|
||||
JToggleButton toggleButton2 = new JToggleButton();
|
||||
@@ -246,6 +247,10 @@ public class FlatComponentsTest
|
||||
button12.setEnabled(false);
|
||||
add(button12, "cell 4 1");
|
||||
|
||||
//---- button13 ----
|
||||
button13.setIcon(UIManager.getIcon("Tree.closedIcon"));
|
||||
add(button13, "cell 5 1");
|
||||
|
||||
//---- toggleButtonLabel ----
|
||||
toggleButtonLabel.setText("JToggleButton:");
|
||||
add(toggleButtonLabel, "cell 0 2");
|
||||
|
||||
@@ -76,6 +76,12 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button13"
|
||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "toggleButtonLabel"
|
||||
"text": "JToggleButton:"
|
||||
|
||||
@@ -17,13 +17,19 @@
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -34,18 +40,28 @@ public class FlatTestFrame
|
||||
{
|
||||
private static final String PREFS_ROOT_PATH = "/flatlaf-test";
|
||||
private static final String KEY_LAF = "laf";
|
||||
private static final String KEY_SCALE_FACTOR = "scaleFactor";
|
||||
|
||||
private final String title;
|
||||
private JComponent content;
|
||||
private FlatInspector inspector;
|
||||
|
||||
public static FlatTestFrame create( String[] args, String title ) {
|
||||
Preferences prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
|
||||
|
||||
// set scale factor
|
||||
if( System.getProperty( "flatlaf.uiScale", System.getProperty( "sun.java2d.uiScale" ) ) == null ) {
|
||||
String scaleFactor = prefs.get( KEY_SCALE_FACTOR, null );
|
||||
if( scaleFactor != null )
|
||||
System.setProperty( "flatlaf.uiScale", scaleFactor );
|
||||
}
|
||||
|
||||
// set look and feel
|
||||
try {
|
||||
if( args.length > 0 )
|
||||
UIManager.setLookAndFeel( args[0] );
|
||||
else {
|
||||
String lafClassName = Preferences.userRoot().node( PREFS_ROOT_PATH )
|
||||
.get( KEY_LAF, FlatLightLaf.class.getName() );
|
||||
String lafClassName = prefs.get( KEY_LAF, FlatLightLaf.class.getName() );
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
}
|
||||
} catch( Exception ex ) {
|
||||
@@ -60,21 +76,21 @@ public class FlatTestFrame
|
||||
}
|
||||
|
||||
// create frame
|
||||
FlatTestFrame frame = new FlatTestFrame();
|
||||
frame.setTitle( title + " (Java " + System.getProperty( "java.version" ) + ")" );
|
||||
return frame;
|
||||
return new FlatTestFrame( title );
|
||||
}
|
||||
|
||||
private FlatTestFrame() {
|
||||
private FlatTestFrame( String title ) {
|
||||
this.title = title;
|
||||
|
||||
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 Test (F3)", FlatTestLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat IntelliJ (F4)", FlatIntelliJLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat Darcula (F5)", FlatDarculaLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat Darcula (F4)", FlatDarculaLaf.class.getName() ) );
|
||||
lafModel.addElement( new LafInfo( "Flat Test (F8)", FlatTestLaf.class.getName() ) );
|
||||
|
||||
UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels();
|
||||
for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) {
|
||||
@@ -106,12 +122,18 @@ public class FlatTestFrame
|
||||
|
||||
lookAndFeelComboBox.setModel( lafModel );
|
||||
|
||||
// register F1, F2 and F3 keys to switch to Light, Dark or Test LaF
|
||||
updateScaleFactorComboBox();
|
||||
String scaleFactor = System.getProperty( "flatlaf.uiScale", System.getProperty( "sun.java2d.uiScale" ) );
|
||||
if( scaleFactor != null )
|
||||
scaleFactorComboBox.setSelectedItem( scaleFactor );
|
||||
|
||||
// register F1, F2, ... keys to switch to Light, Dark or other LaFs
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F1, FlatLightLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F2, FlatDarkLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatTestLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatIntelliJLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F5, FlatDarculaLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatIntelliJLaf.class.getName() );
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatDarculaLaf.class.getName() );
|
||||
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F8, FlatTestLaf.class.getName() );
|
||||
|
||||
if( SystemInfo.IS_WINDOWS )
|
||||
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
|
||||
@@ -130,6 +152,35 @@ public class FlatTestFrame
|
||||
|
||||
// close frame
|
||||
closeButton.addActionListener(e -> dispose());
|
||||
|
||||
// update title
|
||||
addWindowListener( new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened( WindowEvent e ) {
|
||||
updateTitle();
|
||||
}
|
||||
} );
|
||||
|
||||
// update title when moved to another screen
|
||||
addComponentListener( new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentMoved( ComponentEvent e ) {
|
||||
updateTitle();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private void updateTitle() {
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( getGraphicsConfiguration() );
|
||||
float userScaleFactor = UIScale.getUserScaleFactor();
|
||||
String newTitle = title + " (Java " + System.getProperty( "java.version" )
|
||||
+ (systemScaleFactor != 1 ? ("; system scale factor " + systemScaleFactor) : "")
|
||||
+ (userScaleFactor != 1 ? ("; user scale factor " + userScaleFactor) : "")
|
||||
+ (systemScaleFactor == 1 && userScaleFactor == 1 ? "; no scaling" : "")
|
||||
+ ")";
|
||||
|
||||
if( !newTitle.equals( getTitle() ) )
|
||||
setTitle( newTitle );
|
||||
}
|
||||
|
||||
private void registerSwitchToLookAndFeel( int keyCode, String lafClassName ) {
|
||||
@@ -169,22 +220,54 @@ public class FlatTestFrame
|
||||
if( newLaf.className.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
return;
|
||||
|
||||
// hide popup to avoid occasional StackOverflowError when updating UI
|
||||
lookAndFeelComboBox.setPopupVisible( false );
|
||||
|
||||
Preferences.userRoot().node( PREFS_ROOT_PATH ).put( KEY_LAF, newLaf.className );
|
||||
|
||||
applyLookAndFeel( newLaf.className, false );
|
||||
}
|
||||
|
||||
private void applyLookAndFeel( String lafClassName, boolean pack ) {
|
||||
EventQueue.invokeLater( () -> {
|
||||
try {
|
||||
// change look and feel
|
||||
UIManager.setLookAndFeel( newLaf.className );
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
|
||||
// update title because user scale factor may change
|
||||
updateTitle();
|
||||
|
||||
// enable/disable scale factor combobox
|
||||
updateScaleFactorComboBox();
|
||||
|
||||
// update all components
|
||||
SwingUtilities.updateComponentTreeUI( this );
|
||||
|
||||
// increase size of frame if necessary
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
Dimension prefSize = getPreferredSize();
|
||||
if( prefSize.width > width || prefSize.height > height )
|
||||
setSize( Math.max( prefSize.width, width ), Math.max( prefSize.height, height ) );
|
||||
if( pack )
|
||||
pack();
|
||||
else {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
Dimension prefSize = getPreferredSize();
|
||||
if( prefSize.width > width || prefSize.height > height )
|
||||
setSize( Math.max( prefSize.width, width ), Math.max( prefSize.height, height ) );
|
||||
}
|
||||
|
||||
// limit frame size to screen size
|
||||
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
screenBounds = FlatUIUtils.subtractInsets( screenBounds, getToolkit().getScreenInsets( getGraphicsConfiguration() ) );
|
||||
Dimension frameSize = getSize();
|
||||
if( frameSize.width > screenBounds.width || frameSize.height > screenBounds.height )
|
||||
setSize( Math.min( frameSize.width, screenBounds.width ), Math.min( frameSize.height, screenBounds.height ) );
|
||||
|
||||
// move frame to left/top if necessary
|
||||
if( getX() + getWidth() > screenBounds.x + screenBounds.width ||
|
||||
getY() + getHeight() > screenBounds.y + screenBounds.height )
|
||||
{
|
||||
setLocation( Math.min( getX(), screenBounds.x + screenBounds.width - getWidth() ),
|
||||
Math.min( getY(), screenBounds.y + screenBounds.height - getHeight() ) );
|
||||
}
|
||||
|
||||
if( inspector != null )
|
||||
inspector.update();
|
||||
@@ -289,6 +372,31 @@ public class FlatTestFrame
|
||||
inspector.setEnabled( inspectCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void scaleFactorChanged() {
|
||||
String scaleFactor = (String) scaleFactorComboBox.getSelectedItem();
|
||||
if( "default".equals( scaleFactor ) )
|
||||
scaleFactor = null;
|
||||
|
||||
// hide popup to avoid occasional StackOverflowError when updating UI
|
||||
scaleFactorComboBox.setPopupVisible( false );
|
||||
|
||||
Preferences prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
|
||||
|
||||
if( scaleFactor != null ) {
|
||||
System.setProperty( "flatlaf.uiScale", scaleFactor );
|
||||
prefs.put( KEY_SCALE_FACTOR, scaleFactor );
|
||||
} else {
|
||||
System.clearProperty( "flatlaf.uiScale" );
|
||||
prefs.remove( KEY_SCALE_FACTOR );
|
||||
}
|
||||
|
||||
applyLookAndFeel( UIManager.getLookAndFeel().getClass().getName(), true );
|
||||
}
|
||||
|
||||
private void updateScaleFactorComboBox() {
|
||||
scaleFactorComboBox.setEnabled( !UIScale.isJreHiDPIEnabled() && UIManager.getLookAndFeel() instanceof FlatLaf );
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
dialogPane = new JPanel();
|
||||
@@ -299,6 +407,7 @@ public class FlatTestFrame
|
||||
rightToLeftCheckBox = new JCheckBox();
|
||||
enabledCheckBox = new JCheckBox();
|
||||
inspectCheckBox = new JCheckBox();
|
||||
scaleFactorComboBox = new JComboBox<>();
|
||||
closeButton = new JButton();
|
||||
|
||||
//======== this ========
|
||||
@@ -332,6 +441,7 @@ public class FlatTestFrame
|
||||
"[fill]" +
|
||||
"[fill]" +
|
||||
"[fill]" +
|
||||
"[fill]" +
|
||||
"[grow,fill]" +
|
||||
"[button,fill]",
|
||||
// rows
|
||||
@@ -366,9 +476,27 @@ public class FlatTestFrame
|
||||
inspectCheckBox.addActionListener(e -> inspectChanged());
|
||||
buttonBar.add(inspectCheckBox, "cell 4 0");
|
||||
|
||||
//---- scaleFactorComboBox ----
|
||||
scaleFactorComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"default",
|
||||
"1",
|
||||
"1.25",
|
||||
"1.5",
|
||||
"1.75",
|
||||
"2.0",
|
||||
"2.25",
|
||||
"2.5",
|
||||
"3",
|
||||
"3.5",
|
||||
"4"
|
||||
}));
|
||||
scaleFactorComboBox.setMaximumRowCount(20);
|
||||
scaleFactorComboBox.addActionListener(e -> scaleFactorChanged());
|
||||
buttonBar.add(scaleFactorComboBox, "cell 5 0");
|
||||
|
||||
//---- closeButton ----
|
||||
closeButton.setText("Close");
|
||||
buttonBar.add(closeButton, "cell 6 0");
|
||||
buttonBar.add(closeButton, "cell 7 0");
|
||||
}
|
||||
dialogPane.add(buttonBar, BorderLayout.SOUTH);
|
||||
}
|
||||
@@ -385,6 +513,7 @@ public class FlatTestFrame
|
||||
private JCheckBox rightToLeftCheckBox;
|
||||
private JCheckBox enabledCheckBox;
|
||||
private JCheckBox inspectCheckBox;
|
||||
private JComboBox<String> scaleFactorComboBox;
|
||||
private JButton closeButton;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ new FormModel {
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog"
|
||||
"$columnConstraints": "[fill][fill][fill][fill][fill][grow,fill][button,fill]"
|
||||
"$columnConstraints": "[fill][fill][fill][fill][fill][fill][grow,fill][button,fill]"
|
||||
"$rowSpecs": "[fill]"
|
||||
} ) {
|
||||
name: "buttonBar"
|
||||
@@ -67,11 +67,35 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "scaleFactorComboBox"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "default"
|
||||
addElement( "default" )
|
||||
addElement( "1" )
|
||||
addElement( "1.25" )
|
||||
addElement( "1.5" )
|
||||
addElement( "1.75" )
|
||||
addElement( "2.0" )
|
||||
addElement( "2.25" )
|
||||
addElement( "2.5" )
|
||||
addElement( "3" )
|
||||
addElement( "3.5" )
|
||||
addElement( "4" )
|
||||
}
|
||||
"maximumRowCount": 20
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "String"
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scaleFactorChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "closeButton"
|
||||
"text": "Close"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 6 0"
|
||||
"value": "cell 7 0"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "South"
|
||||
@@ -81,7 +105,7 @@ new FormModel {
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 510, 300 )
|
||||
"size": new java.awt.Dimension( 640, 300 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ tasks {
|
||||
attributes( "Main-Class" to "com.formdev.flatlaf.demo.FlatLafDemo" )
|
||||
}
|
||||
|
||||
exclude( "META-INF/versions/**" )
|
||||
|
||||
// include all dependencies in jar
|
||||
from( {
|
||||
configurations.runtimeClasspath.get().filter { it.name.endsWith( "jar" ) }.map { zipTree( it ) }
|
||||
|
||||
@@ -39,6 +39,7 @@ class BasicComponentsPanel
|
||||
JButton button2 = new JButton();
|
||||
JButton button3 = new JButton();
|
||||
JButton button4 = new JButton();
|
||||
JButton button13 = new JButton();
|
||||
JLabel checkBoxLabel = new JLabel();
|
||||
JCheckBox checkBox1 = new JCheckBox();
|
||||
JCheckBox checkBox2 = new JCheckBox();
|
||||
@@ -169,6 +170,10 @@ class BasicComponentsPanel
|
||||
button4.setEnabled(false);
|
||||
add(button4, "cell 4 1");
|
||||
|
||||
//---- button13 ----
|
||||
button13.setIcon(UIManager.getIcon("Tree.closedIcon"));
|
||||
add(button13, "cell 5 1");
|
||||
|
||||
//---- checkBoxLabel ----
|
||||
checkBoxLabel.setText("JCheckBox");
|
||||
add(checkBoxLabel, "cell 0 2");
|
||||
|
||||
@@ -69,6 +69,12 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button13"
|
||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.closedIcon" )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "checkBoxLabel"
|
||||
"text": "JCheckBox"
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
@@ -106,15 +108,19 @@ class ControlBar
|
||||
// make the "close" button the default button
|
||||
frame.getRootPane().setDefaultButton( closeButton );
|
||||
|
||||
// move focus to "close" button
|
||||
// update info label and move focus to "close" button
|
||||
frame.addWindowListener( new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened( WindowEvent e ) {
|
||||
updateInfoLabel();
|
||||
closeButton.requestFocusInWindow();
|
||||
}
|
||||
} );
|
||||
|
||||
// update info label when moved to another screen
|
||||
frame.addComponentListener( new ComponentAdapter() {
|
||||
@Override
|
||||
public void windowActivated( WindowEvent e ) {
|
||||
public void componentMoved( ComponentEvent e ) {
|
||||
updateInfoLabel();
|
||||
}
|
||||
} );
|
||||
@@ -123,11 +129,14 @@ class ControlBar
|
||||
private void updateInfoLabel() {
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( getGraphicsConfiguration() );
|
||||
float userScaleFactor = UIScale.getUserScaleFactor();
|
||||
infoLabel.setText( "(Java " + System.getProperty( "java.version" )
|
||||
String newInfo = "(Java " + System.getProperty( "java.version" )
|
||||
+ (systemScaleFactor != 1 ? ("; system scale factor " + systemScaleFactor) : "")
|
||||
+ (userScaleFactor != 1 ? ("; user scale factor " + userScaleFactor) : "")
|
||||
+ (systemScaleFactor == 1 && userScaleFactor == 1 ? "; no scaling" : "")
|
||||
+ ")" );
|
||||
+ ")";
|
||||
|
||||
if( !newInfo.equals( infoLabel.getText() ) )
|
||||
infoLabel.setText( newInfo );
|
||||
}
|
||||
|
||||
private void registerSwitchToLookAndFeel( int keyCode, String lafClassName ) {
|
||||
|
||||
Reference in New Issue
Block a user