Merge branch 'master' into branch 'custom-window-decorations'

# Conflicts:
#	flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRootPaneUI.java
This commit is contained in:
Karl Tauber
2020-06-02 16:13:35 +02:00
23 changed files with 205 additions and 55 deletions

View File

@@ -9,6 +9,7 @@ FlatLaf Change Log
for editable comboboxes). for editable comboboxes).
- ComboBox: Support custom borders in combobox editors. (issue #102) - ComboBox: Support custom borders in combobox editors. (issue #102)
- Ubuntu Linux: Fixed poorly rendered font. (issue #105) - Ubuntu Linux: Fixed poorly rendered font. (issue #105)
- macOS Catalina: Use Helvetica Neue font.
## 0.35 ## 0.35

View File

@@ -411,7 +411,10 @@ public abstract class FlatLaf
} else if( SystemInfo.IS_MAC ) { } else if( SystemInfo.IS_MAC ) {
String fontName; String fontName;
if( SystemInfo.IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER ) { if( SystemInfo.IS_MAC_OS_10_15_CATALINA_OR_LATER ) {
// use Helvetica Neue font
fontName = "Helvetica Neue";
} else if( SystemInfo.IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER ) {
// use San Francisco Text font // use San Francisco Text font
fontName = ".SF NS Text"; fontName = ".SF NS Text";
} else { } else {

View File

@@ -27,6 +27,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
/** /**
* Base class for internal frame icons. * Base class for internal frame icons.
* *
* @uiDefault InternalFrame.buttonSize Dimension
* @uiDefault InternalFrame.buttonHoverBackground Color * @uiDefault InternalFrame.buttonHoverBackground Color
* @uiDefault InternalFrame.buttonPressedBackground Color * @uiDefault InternalFrame.buttonPressedBackground Color
* *

View File

@@ -28,8 +28,11 @@ import com.formdev.flatlaf.ui.FlatButtonUI;
/** /**
* "close" icon for {@link javax.swing.JInternalFrame}. * "close" icon for {@link javax.swing.JInternalFrame}.
* *
* @uiDefault InternalFrame.buttonHoverBackground Color * @uiDefault InternalFrame.buttonSize Dimension
* @uiDefault InternalFrame.buttonPressedBackground Color * @uiDefault InternalFrame.closeHoverBackground Color
* @uiDefault InternalFrame.closePressedBackground Color
* @uiDefault InternalFrame.closeHoverForeground Color
* @uiDefault InternalFrame.closePressedForeground Color
* *
* @author Karl Tauber * @author Karl Tauber
*/ */

View File

@@ -24,14 +24,14 @@ import java.awt.geom.Rectangle2D;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
/** /**
* "minimize" (actually "restore") icon for {@link javax.swing.JInternalFrame}. * "restore" (or "minimize") icon for {@link javax.swing.JInternalFrame}.
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatInternalFrameMinimizeIcon public class FlatInternalFrameRestoreIcon
extends FlatInternalFrameAbstractIcon extends FlatInternalFrameAbstractIcon
{ {
public FlatInternalFrameMinimizeIcon() { public FlatInternalFrameRestoreIcon() {
} }
@Override @Override

View File

@@ -145,11 +145,21 @@ public class FlatArrowButton
int direction = getDirection(); int direction = getDirection();
boolean vert = (direction == NORTH || direction == SOUTH); boolean vert = (direction == NORTH || direction == SOUTH);
// compute width/height
int w = scale( arrowWidth + (chevron ? 0 : 1) ); int w = scale( arrowWidth + (chevron ? 0 : 1) );
int h = scale( (arrowWidth / 2) + (chevron ? 0 : 1) ); int h = scale( (arrowWidth / 2) + (chevron ? 0 : 1) );
// rotate width/height
int rw = vert ? w : h; int rw = vert ? w : h;
int rh = vert ? h : w; int rh = vert ? h : w;
// chevron lines end 1px outside of width/height
if( chevron ) {
// add 1px to width/height for position calculation only
rw++;
rh++;
}
// Adding -/+0.35 before rounding tends move up NORTH arrows and move down SOUTH arrows. // Adding -/+0.35 before rounding tends move up NORTH arrows and move down SOUTH arrows.
// This makes top margin of NORTH arrow equal to bottom margin of SOUTH arrow. // This makes top margin of NORTH arrow equal to bottom margin of SOUTH arrow.
float rd = 0.35f; float rd = 0.35f;
@@ -159,12 +169,6 @@ public class FlatArrowButton
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) + xrd ); int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) + xrd );
int y = Math.round( (height - rh) / 2f + scale( (float) yOffset ) + yrd ); int y = Math.round( (height - rh) / 2f + scale( (float) yOffset ) + yrd );
// optimization for small chevron arrows (e.g. OneTouchButtons in SplitPane)
if( x + rw >= width && x > 0 )
x--;
if( y + rh >= height && y > 0 )
y--;
// move arrow for round borders // move arrow for round borders
Container parent = getParent(); Container parent = getParent();
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) ) if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
@@ -176,7 +180,7 @@ public class FlatArrowButton
: disabledForeground ); : disabledForeground );
g.translate( x, y ); g.translate( x, y );
/*debug /*debug
debugPaint( g2, vert, w, h ); debugPaint( g2, vert, rw, rh );
debug*/ debug*/
Shape arrowShape = createArrowShape( direction, chevron, w, h ); Shape arrowShape = createArrowShape( direction, chevron, w, h );
if( chevron ) { if( chevron ) {
@@ -203,7 +207,7 @@ debug*/
private void debugPaint( Graphics g, boolean vert, int w, int h ) { private void debugPaint( Graphics g, boolean vert, int w, int h ) {
Color oldColor = g.getColor(); Color oldColor = g.getColor();
g.setColor( Color.red ); g.setColor( Color.red );
g.drawRect( 0, 0, (vert ? w : h) - 1, (vert ? h : w) - 1 ); g.drawRect( 0, 0, w - 1, h - 1 );
int xy1 = -2; int xy1 = -2;
int xy2 = h + 1; int xy2 = h + 1;

View File

@@ -16,6 +16,7 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
@@ -25,10 +26,14 @@ import java.awt.LayoutManager2;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.function.Function; import java.util.function.Function;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.JMenuBar; import javax.swing.JMenuBar;
import javax.swing.JRootPane; import javax.swing.JRootPane;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicRootPaneUI; import javax.swing.plaf.basic.BasicRootPaneUI;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
@@ -70,6 +75,23 @@ public class FlatRootPaneUI
rootPane = null; rootPane = null;
} }
@Override
protected void installDefaults( JRootPane c ) {
super.installDefaults( c );
// Update background color of JFrame or JDialog parent to avoid bad border
// on HiDPI screens when switching from light to dark Laf.
// The background of JFrame is initialized in JFrame.frameInit() and
// the background of JDialog in JDialog.dialogInit(),
// but it was not updated when switching Laf.
Container parent = c.getParent();
if( parent instanceof JFrame || parent instanceof JDialog ) {
Color background = parent.getBackground();
if( background == null || background instanceof UIResource )
parent.setBackground( UIManager.getColor( "control" ) );
}
}
private void installClientDecorations() { private void installClientDecorations() {
// install title pane // install title pane
setTitlePane( new FlatTitlePane( rootPane ) ); setTitlePane( new FlatTitlePane( rootPane ) );

View File

@@ -34,6 +34,7 @@ public class SystemInfo
// OS versions // OS versions
public static final boolean IS_WINDOWS_10_OR_LATER; public static final boolean IS_WINDOWS_10_OR_LATER;
public static final boolean IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER; public static final boolean IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER;
public static final boolean IS_MAC_OS_10_15_CATALINA_OR_LATER;
// Java versions // Java versions
public static final boolean IS_JAVA_9_OR_LATER; public static final boolean IS_JAVA_9_OR_LATER;
@@ -57,6 +58,7 @@ public class SystemInfo
long osVersion = scanVersion( System.getProperty( "os.version" ) ); long osVersion = scanVersion( System.getProperty( "os.version" ) );
IS_WINDOWS_10_OR_LATER = (IS_WINDOWS && osVersion >= toVersion( 10, 0, 0, 0 )); IS_WINDOWS_10_OR_LATER = (IS_WINDOWS && osVersion >= toVersion( 10, 0, 0, 0 ));
IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 11, 0, 0 )); IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 11, 0, 0 ));
IS_MAC_OS_10_15_CATALINA_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 15, 0, 0 ));
// Java versions // Java versions
long javaVersion = scanVersion( System.getProperty( "java.version" ) ); long javaVersion = scanVersion( System.getProperty( "java.version" ) );

View File

@@ -261,7 +261,7 @@ InternalFrame.buttonSize=24,24
InternalFrame.closeIcon=com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon InternalFrame.closeIcon=com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon
InternalFrame.iconifyIcon=com.formdev.flatlaf.icons.FlatInternalFrameIconifyIcon InternalFrame.iconifyIcon=com.formdev.flatlaf.icons.FlatInternalFrameIconifyIcon
InternalFrame.maximizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon InternalFrame.maximizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon
InternalFrame.minimizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMinimizeIcon InternalFrame.minimizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameRestoreIcon
InternalFrame.windowBindings=null InternalFrame.windowBindings=null
# drop shadow # drop shadow

View File

@@ -46,21 +46,21 @@
"license": "MIT", "license": "MIT",
"licenseFile": "Gradianto.LICENSE.txt", "licenseFile": "Gradianto.LICENSE.txt",
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto", "sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
"sourceCodePath": "blob/master/resources/Gradianto_dark_fuchsia.theme.json" "sourceCodePath": "blob/master/src/main/resources/Gradianto_dark_fuchsia.theme.json"
}, },
"Gradianto_deep_ocean.theme.json": { "Gradianto_deep_ocean.theme.json": {
"name": "Gradianto Deep Ocean", "name": "Gradianto Deep Ocean",
"license": "MIT", "license": "MIT",
"licenseFile": "Gradianto.LICENSE.txt", "licenseFile": "Gradianto.LICENSE.txt",
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto", "sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
"sourceCodePath": "blob/master/resources/Gradianto_deep_ocean.theme.json" "sourceCodePath": "blob/master/src/main/resources/Gradianto_deep_ocean.theme.json"
}, },
"Gradianto_midnight_blue.theme.json": { "Gradianto_midnight_blue.theme.json": {
"name": "Gradianto Midnight Blue", "name": "Gradianto Midnight Blue",
"license": "MIT", "license": "MIT",
"licenseFile": "Gradianto.LICENSE.txt", "licenseFile": "Gradianto.LICENSE.txt",
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto", "sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
"sourceCodePath": "blob/master/resources/Gradianto_midnight_blue.theme.json" "sourceCodePath": "blob/master/src/main/resources/Gradianto_midnight_blue.theme.json"
}, },
"Gray.theme.json": { "Gray.theme.json": {
"name": "Gray", "name": "Gray",

View File

@@ -159,6 +159,13 @@
"inactiveBackground": "#44475a" "inactiveBackground": "#44475a"
} }
}, },
"ScrollBar": {
"Mac": {
"Transparent": {
"hoverThumbColor": "#bd93f9"
}
}
},
"SearchEverywhere": { "SearchEverywhere": {
"SearchField": { "SearchField": {
"background": "#44475a" "background": "#44475a"

View File

@@ -1,7 +1,7 @@
{ {
"name": "Gradianto Dark Fuchsia", "name": "Gradianto Dark Fuchsia",
"dark": true, "dark": true,
"author": "", "author": "thvardhan",
"editorScheme": "/Gradianto_dark_fuchsia.xml", "editorScheme": "/Gradianto_dark_fuchsia.xml",
"ui": { "ui": {
"*": { "*": {

View File

@@ -1,7 +1,7 @@
{ {
"name": "Gradianto Deep Ocean", "name": "Gradianto Deep Ocean",
"dark": true, "dark": true,
"author": "", "author": "thvardhan",
"editorScheme": "/Gradianto_deep_ocean.xml", "editorScheme": "/Gradianto_deep_ocean.xml",
"ui": { "ui": {
"*": { "*": {
@@ -214,7 +214,7 @@
"tagBackground": "#3d445a", "tagBackground": "#3d445a",
"lightSelectionBackground": "#3c4b7e" "lightSelectionBackground": "#3c4b7e"
}, },
"EditorPane.inactiveBackground": "#040c25" "EditorPane.inactiveBackground": "#25334aff"
}, },
"icons": { "icons": {
"ColorPalette": { "ColorPalette": {

View File

@@ -1,7 +1,7 @@
{ {
"name": "Gradianto Midnight Blue", "name": "Gradianto Midnight Blue",
"dark": true, "dark": true,
"author": "", "author": "thvardhan",
"editorScheme": "/Gradianto_midnight_blue.xml", "editorScheme": "/Gradianto_midnight_blue.xml",
"ui": { "ui": {
"*": { "*": {
@@ -217,7 +217,7 @@
"tagBackground": "#40405a", "tagBackground": "#40405a",
"lightSelectionBackground": "#48387e" "lightSelectionBackground": "#48387e"
}, },
"EditorPane.inactiveBackground": "#1a0225" "EditorPane.inactiveBackground": "#414157ff"
}, },
"icons": { "icons": {
"ColorPalette": { "ColorPalette": {

View File

@@ -5,6 +5,7 @@
"editorScheme": "/gruvbox_dark_hard.xml", "editorScheme": "/gruvbox_dark_hard.xml",
"colors": { "colors": {
"bg0": "#282828", "bg0": "#282828",
"bg0_hh": "#101415",
"bg0_h": "#1d2021", "bg0_h": "#1d2021",
"bg0_s": "#32302f", "bg0_s": "#32302f",
"bg1": "#3c3836", "bg1": "#3c3836",
@@ -51,7 +52,7 @@
"selectionBackgroundInactive": "bg0_s", "selectionBackgroundInactive": "bg0_s",
"selectionInactiveBackground": "bg0_s", "selectionInactiveBackground": "bg0_s",
"selectedBackground": "bg0_h", "selectedBackground": "bg0_hh",
"selectedForeground": "fg0", "selectedForeground": "fg0",
"selectedInactiveBackground": "bg0_s", "selectedInactiveBackground": "bg0_s",
"selectedBackgroundInactive": "bg0_s", "selectedBackgroundInactive": "bg0_s",
@@ -59,7 +60,7 @@
"hoverBackground": "#28282866", "hoverBackground": "#28282866",
"borderColor": "bg2", "borderColor": "bg2",
"disabledBorderColor": "bg0_h", "disabledBorderColor": "bg0_hh",
"separatorColor": "bg2" "separatorColor": "bg2"
}, },
@@ -91,6 +92,7 @@
}, },
"EditorTabs": { "EditorTabs": {
"selectedBackground": "bg0_s", "selectedBackground": "bg0_s",
"underlinedTabBackground": "bg2",
"underlineColor": "blue1", "underlineColor": "blue1",
"inactiveMaskColor": "#28282866" "inactiveMaskColor": "#28282866"
}, },
@@ -101,8 +103,8 @@
}, },
"HeaderTab": { "HeaderTab": {
"selectedInactiveBackground": "bg0_h", "selectedInactiveBackground": "bg0_hh",
"hoverInactiveBackground": "bg0_h" "hoverInactiveBackground": "bg0_hh"
} }
}, },
"Table": { "Table": {

View File

@@ -91,6 +91,7 @@
}, },
"EditorTabs": { "EditorTabs": {
"selectedBackground": "bg0_s", "selectedBackground": "bg0_s",
"underlinedTabBackground": "bg2",
"underlineColor": "blue1", "underlineColor": "blue1",
"inactiveMaskColor": "#28282866" "inactiveMaskColor": "#28282866"
}, },

View File

@@ -91,6 +91,7 @@
}, },
"EditorTabs": { "EditorTabs": {
"selectedBackground": "bg0_s", "selectedBackground": "bg0_s",
"underlinedTabBackground": "bg2",
"underlineColor": "blue1", "underlineColor": "blue1",
"inactiveMaskColor": "#28282866" "inactiveMaskColor": "#28282866"
}, },

View File

@@ -1,5 +1,5 @@
{ {
"name": "Atom One Light", "name": "Atom One Light Contrast",
"dark": false, "dark": false,
"author": "Mallowigi", "author": "Mallowigi",
"editorScheme": "/colors/Atom One Light.xml", "editorScheme": "/colors/Atom One Light.xml",

View File

@@ -24,7 +24,7 @@
"errorForeground": "#cd3359", "errorForeground": "#cd3359",
"borderColor": "#46494f", "borderColor": "#333841",
"disabledBorderColor": "#2d3137", "disabledBorderColor": "#2d3137",
"focusColor": "#21252b", "focusColor": "#21252b",
"focusedBorderColor": "#568AF2", "focusedBorderColor": "#568AF2",
@@ -93,8 +93,6 @@
"foreground": "#abb2bf" "foreground": "#abb2bf"
}, },
"DebuggerPopup.borderColor": "#46494f",
"DefaultTabs": { "DefaultTabs": {
"underlineColor": "#568AF2", "underlineColor": "#568AF2",
"inactiveUnderlineColor": "#4269b9", "inactiveUnderlineColor": "#4269b9",
@@ -104,7 +102,7 @@
"DragAndDrop": { "DragAndDrop": {
"areaForeground": "#abb2bf", "areaForeground": "#abb2bf",
"areaBackground": "#323844", "areaBackground": "#323844",
"areaBorderColor": "#46494f" "areaBorderColor": "#333841"
}, },
"Editor": { "Editor": {
@@ -139,11 +137,6 @@
"visitedForeground": "#6494ed" "visitedForeground": "#6494ed"
}, },
"MenuBar.borderColor": "#46494f",
"Menu.borderColor": "#2d3137",
"NavBar.borderColor": "#46494f",
"Notification": { "Notification": {
"background": "#3d424b", "background": "#3d424b",
"borderColor": "#53565f", "borderColor": "#53565f",
@@ -312,8 +305,7 @@
"Header": { "Header": {
"background": "#414855", "background": "#414855",
"inactiveBackground": "#323844", "inactiveBackground": "#323844"
"borderColor": "#21252b"
}, },
"HeaderTab": { "HeaderTab": {

View File

@@ -28,15 +28,19 @@ import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.LayoutManager; import java.awt.LayoutManager;
import java.awt.MouseInfo;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -68,7 +72,10 @@ public class FlatInspector
private final JRootPane rootPane; private final JRootPane rootPane;
private final MouseMotionListener mouseMotionListener; private final MouseMotionListener mouseMotionListener;
private final AWTEventListener keyListener;
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this );
private boolean enabled;
private Component lastComponent; private Component lastComponent;
private int lastX; private int lastX;
private int lastY; private int lastY;
@@ -113,14 +120,40 @@ public class FlatInspector
public void mouseMoved( MouseEvent e ) { public void mouseMoved( MouseEvent e ) {
lastX = e.getX(); lastX = e.getX();
lastY = e.getY(); lastY = e.getY();
inspectParentLevel = (e.isControlDown() ? 1 : 0)
+ (e.isShiftDown() ? 2 : 0)
+ (e.isAltDown() ? 4 : 0);
inspect( lastX, lastY ); inspect( lastX, lastY );
} }
}; };
rootPane.getGlassPane().addMouseMotionListener( mouseMotionListener ); rootPane.getGlassPane().addMouseMotionListener( mouseMotionListener );
keyListener = e -> {
KeyEvent keyEvent = (KeyEvent) e;
int keyCode = keyEvent.getKeyCode();
if( e.getID() == KeyEvent.KEY_RELEASED ) {
if( keyCode == KeyEvent.VK_CONTROL ) {
inspectParentLevel++;
inspect( lastX, lastY );
} else if( keyCode == KeyEvent.VK_SHIFT && inspectParentLevel > 0 ) {
inspectParentLevel--;
inspect( lastX, lastY );
}
}
if( keyCode == KeyEvent.VK_ESCAPE ) {
// consume pressed and released ESC key events to e.g. avoid that dialog is closed
keyEvent.consume();
if( e.getID() == KeyEvent.KEY_PRESSED ) {
FlatInspector inspector = (FlatInspector) rootPane.getClientProperty( FlatInspector.class );
if( inspector == FlatInspector.this ) {
uninstall();
rootPane.putClientProperty( FlatInspector.class, null );
} else
setEnabled( false );
}
}
};
} }
private void uninstall() { private void uninstall() {
@@ -129,11 +162,43 @@ public class FlatInspector
rootPane.getGlassPane().removeMouseMotionListener( mouseMotionListener ); rootPane.getGlassPane().removeMouseMotionListener( mouseMotionListener );
} }
public void addPropertyChangeListener( PropertyChangeListener l ) {
propertyChangeSupport.addPropertyChangeListener( l );
}
public void removePropertyChangeListener( PropertyChangeListener l ) {
propertyChangeSupport.removePropertyChangeListener( l );
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled( boolean enabled ) { public void setEnabled( boolean enabled ) {
if( this.enabled == enabled )
return;
this.enabled = enabled;
rootPane.getGlassPane().setVisible( enabled ); rootPane.getGlassPane().setVisible( enabled );
if( !enabled ) { Toolkit toolkit = Toolkit.getDefaultToolkit();
if( enabled )
toolkit.addAWTEventListener( keyListener, AWTEvent.KEY_EVENT_MASK );
else
toolkit.removeAWTEventListener( keyListener );
if( enabled ) {
Point pt = new Point( MouseInfo.getPointerInfo().getLocation() );
SwingUtilities.convertPointFromScreen( pt, rootPane );
lastX = pt.x;
lastY = pt.y;
inspect( lastX, lastY );
} else {
lastComponent = null; lastComponent = null;
inspectParentLevel = 0;
if( highlightFigure != null ) if( highlightFigure != null )
highlightFigure.getParent().remove( highlightFigure ); highlightFigure.getParent().remove( highlightFigure );
@@ -143,6 +208,8 @@ public class FlatInspector
tip.getParent().remove( tip ); tip.getParent().remove( tip );
tip = null; tip = null;
} }
propertyChangeSupport.firePropertyChange( "enabled", !enabled, enabled );
} }
public void update() { public void update() {
@@ -157,11 +224,14 @@ public class FlatInspector
} }
private void inspect( int x, int y ) { private void inspect( int x, int y ) {
Container contentPane = rootPane.getContentPane(); Point pt = SwingUtilities.convertPoint( rootPane.getGlassPane(), x, y, rootPane );
Point pt = SwingUtilities.convertPoint( rootPane.getGlassPane(), x, y, contentPane ); Component c = getDeepestComponentAt( rootPane, pt.x, pt.y );
Component c = SwingUtilities.getDeepestComponentAt( contentPane, pt.x, pt.y );
for( int i = 0; i < inspectParentLevel && c != null; i++ ) { for( int i = 0; i < inspectParentLevel && c != null; i++ ) {
c = c.getParent(); Container parent = c.getParent();
if( parent == null )
break;
c = parent;
} }
if( c == lastComponent ) if( c == lastComponent )
@@ -173,6 +243,38 @@ public class FlatInspector
showToolTip( c, x, y ); showToolTip( c, x, y );
} }
private Component getDeepestComponentAt( Component parent, int x, int y ) {
if( !parent.contains( x, y ) )
return null;
if( parent instanceof Container ) {
for( Component child : ((Container)parent).getComponents() ) {
if( child == null || !child.isVisible() )
continue;
int cx = x - child.getX();
int cy = y - child.getY();
Component c = (child instanceof Container)
? getDeepestComponentAt( child, cx, cy )
: child.getComponentAt( cx, cy );
if( c == null || !c.isVisible() )
continue;
// ignore highlight figure and tooltip
if( c == highlightFigure || c == tip )
continue;
// ignore glass pane
if( c.getParent() instanceof JRootPane && c == ((JRootPane)c.getParent()).getGlassPane() )
continue;
return c;
}
}
return parent;
}
private void highlight( Component c ) { private void highlight( Component c ) {
if( highlightFigure == null ) { if( highlightFigure == null ) {
highlightFigure = createHighlightFigure(); highlightFigure = createHighlightFigure();
@@ -182,9 +284,9 @@ public class FlatInspector
highlightFigure.setVisible( c != null ); highlightFigure.setVisible( c != null );
if( c != null ) { if( c != null ) {
Rectangle bounds = c.getBounds(); highlightFigure.setBounds( new Rectangle(
Rectangle highlightBounds = SwingUtilities.convertRectangle( c.getParent(), bounds, rootPane ); SwingUtilities.convertPoint( c, 0, 0, rootPane ),
highlightFigure.setBounds( highlightBounds ); c.getSize() ) );
} }
} }
@@ -308,11 +410,16 @@ public class FlatInspector
text += "ContentAreaFilled: " + ((AbstractButton)c).isContentAreaFilled() + '\n'; text += "ContentAreaFilled: " + ((AbstractButton)c).isContentAreaFilled() + '\n';
text += "Focusable: " + c.isFocusable() + '\n'; text += "Focusable: " + c.isFocusable() + '\n';
text += "Left-to-right: " + c.getComponentOrientation().isLeftToRight() + '\n'; text += "Left-to-right: " + c.getComponentOrientation().isLeftToRight() + '\n';
text += "Parent: " + c.getParent().getClass().getName(); text += "Parent: " + (c.getParent() != null ? c.getParent().getClass().getName() : "null");
if( inspectParentLevel > 0 ) if( inspectParentLevel > 0 )
text += "\n\nParent level: " + inspectParentLevel; text += "\n\nParent level: " + inspectParentLevel;
if( inspectParentLevel > 0 )
text += "\n(press Ctrl/Shift to increase/decrease level)";
else
text += "\n\n(press Ctrl key to inspect parent)";
return text; return text;
} }

View File

@@ -455,8 +455,12 @@ public class FlatTestFrame
} }
private void inspectChanged() { private void inspectChanged() {
if( inspector == null ) if( inspector == null ) {
inspector = new FlatInspector( contentPanel ); inspector = new FlatInspector( getRootPane() );
inspector.addPropertyChangeListener( e -> {
inspectCheckBox.setSelected( inspector.isEnabled() );
} );
}
inspector.setEnabled( inspectCheckBox.isSelected() ); inspector.setEnabled( inspectCheckBox.isSelected() );
} }

View File

@@ -364,7 +364,7 @@ InternalFrame.inactiveDropShadowOpacity 0.75
InternalFrame.inactiveTitleBackground #303234 javax.swing.plaf.ColorUIResource [UI] InternalFrame.inactiveTitleBackground #303234 javax.swing.plaf.ColorUIResource [UI]
InternalFrame.inactiveTitleForeground #777777 javax.swing.plaf.ColorUIResource [UI] InternalFrame.inactiveTitleForeground #777777 javax.swing.plaf.ColorUIResource [UI]
InternalFrame.maximizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon [UI] InternalFrame.maximizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon [UI]
InternalFrame.minimizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMinimizeIcon [UI] InternalFrame.minimizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameRestoreIcon [UI]
InternalFrame.titleFont [active] $defaultFont [UI] InternalFrame.titleFont [active] $defaultFont [UI]

View File

@@ -366,7 +366,7 @@ InternalFrame.inactiveDropShadowOpacity 0.5
InternalFrame.inactiveTitleBackground #fafafa javax.swing.plaf.ColorUIResource [UI] InternalFrame.inactiveTitleBackground #fafafa javax.swing.plaf.ColorUIResource [UI]
InternalFrame.inactiveTitleForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI] InternalFrame.inactiveTitleForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI]
InternalFrame.maximizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon [UI] InternalFrame.maximizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon [UI]
InternalFrame.minimizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameMinimizeIcon [UI] InternalFrame.minimizeIcon [lazy] 24,24 com.formdev.flatlaf.icons.FlatInternalFrameRestoreIcon [UI]
InternalFrame.titleFont [active] $defaultFont [UI] InternalFrame.titleFont [active] $defaultFont [UI]