mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 15:07:11 -06:00
Extras: FlatInspector: show class hierarchies when pressing Alt key and prettified class names (dimmed package name)
This commit is contained in:
@@ -30,6 +30,8 @@ FlatLaf Change Log
|
|||||||
- Use mapper function in color filter to dynamically map colors. (PR #303)
|
- Use mapper function in color filter to dynamically map colors. (PR #303)
|
||||||
- Color filter supports light and dark themes.
|
- Color filter supports light and dark themes.
|
||||||
- Getters for icon name, classloader, etc.
|
- Getters for icon name, classloader, etc.
|
||||||
|
- Extras: UI Inspector: Show class hierarchies when pressing <kbd>Alt</kbd> key
|
||||||
|
and prettified class names (dimmed package name).
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import javax.swing.Popup;
|
|||||||
import javax.swing.PopupFactory;
|
import javax.swing.PopupFactory;
|
||||||
import javax.swing.RootPaneContainer;
|
import javax.swing.RootPaneContainer;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.border.LineBorder;
|
import javax.swing.border.LineBorder;
|
||||||
@@ -90,7 +91,11 @@ public class FlatInspector
|
|||||||
{
|
{
|
||||||
private static final Integer HIGHLIGHT_LAYER = JLayeredPane.POPUP_LAYER - 1;
|
private static final Integer HIGHLIGHT_LAYER = JLayeredPane.POPUP_LAYER - 1;
|
||||||
|
|
||||||
private static final int KEY_MODIFIERS_MASK = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK;
|
private static final int KEY_MODIFIERS_MASK =
|
||||||
|
InputEvent.CTRL_DOWN_MASK |
|
||||||
|
InputEvent.SHIFT_DOWN_MASK |
|
||||||
|
InputEvent.ALT_DOWN_MASK |
|
||||||
|
InputEvent.META_DOWN_MASK;
|
||||||
|
|
||||||
private final JRootPane rootPane;
|
private final JRootPane rootPane;
|
||||||
private final MouseMotionListener mouseMotionListener;
|
private final MouseMotionListener mouseMotionListener;
|
||||||
@@ -104,7 +109,8 @@ public class FlatInspector
|
|||||||
private int lastX;
|
private int lastX;
|
||||||
private int lastY;
|
private int lastY;
|
||||||
private int inspectParentLevel;
|
private int inspectParentLevel;
|
||||||
private boolean wasCtrlOrShiftKeyPressed;
|
private boolean wasModifierKeyPressed;
|
||||||
|
private boolean showClassHierarchy;
|
||||||
|
|
||||||
private JComponent highlightFigure;
|
private JComponent highlightFigure;
|
||||||
private Popup popup;
|
private Popup popup;
|
||||||
@@ -161,9 +167,9 @@ public class FlatInspector
|
|||||||
if( id == KeyEvent.KEY_PRESSED ) {
|
if( id == KeyEvent.KEY_PRESSED ) {
|
||||||
// this avoids that the inspection level is changed when UI inspector
|
// this avoids that the inspection level is changed when UI inspector
|
||||||
// is enabled with keyboard shortcut (e.g. Ctrl+Shift+Alt+X)
|
// is enabled with keyboard shortcut (e.g. Ctrl+Shift+Alt+X)
|
||||||
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT )
|
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT )
|
||||||
wasCtrlOrShiftKeyPressed = true;
|
wasModifierKeyPressed = true;
|
||||||
} else if( id == KeyEvent.KEY_RELEASED && wasCtrlOrShiftKeyPressed ) {
|
} else if( id == KeyEvent.KEY_RELEASED && wasModifierKeyPressed ) {
|
||||||
if( keyCode == KeyEvent.VK_CONTROL ) {
|
if( keyCode == KeyEvent.VK_CONTROL ) {
|
||||||
inspectParentLevel++;
|
inspectParentLevel++;
|
||||||
int parentLevel = inspect( lastX, lastY );
|
int parentLevel = inspect( lastX, lastY );
|
||||||
@@ -180,6 +186,9 @@ public class FlatInspector
|
|||||||
inspectParentLevel = Math.max( parentLevel - 1, 0 );
|
inspectParentLevel = Math.max( parentLevel - 1, 0 );
|
||||||
inspect( lastX, lastY );
|
inspect( lastX, lastY );
|
||||||
}
|
}
|
||||||
|
} else if( keyCode == KeyEvent.VK_ALT && lastComponent != null) {
|
||||||
|
showClassHierarchy = !showClassHierarchy;
|
||||||
|
showToolTip( lastComponent, lastX, lastY, inspectParentLevel );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +411,7 @@ public class FlatInspector
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
JToolTip tip = new JToolTip();
|
JToolTip tip = new JToolTip();
|
||||||
tip.setTipText( buildToolTipText( c, parentLevel ) );
|
tip.setTipText( buildToolTipText( c, parentLevel, showClassHierarchy ) );
|
||||||
tip.putClientProperty( FlatClientProperties.POPUP_FORCE_HEAVY_WEIGHT, true );
|
tip.putClientProperty( FlatClientProperties.POPUP_FORCE_HEAVY_WEIGHT, true );
|
||||||
|
|
||||||
Point pt = new Point( x, y );
|
Point pt = new Point( x, y );
|
||||||
@@ -428,16 +437,13 @@ public class FlatInspector
|
|||||||
popup.show();
|
popup.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildToolTipText( Component c, int parentLevel ) {
|
private static String buildToolTipText( Component c, int parentLevel, boolean classHierarchy ) {
|
||||||
StringBuilder buf = new StringBuilder( 1500 );
|
StringBuilder buf = new StringBuilder( 1500 );
|
||||||
buf.append( "<html><style>" );
|
buf.append( "<html><style>" );
|
||||||
buf.append( "td { padding: 0 10 0 0; }" );
|
buf.append( "td { padding: 0 10 0 0; }" );
|
||||||
buf.append( "</style><table>" );
|
buf.append( "</style><table>" );
|
||||||
|
|
||||||
String name = c.getClass().getName();
|
appendRow( buf, "Class", toString( c.getClass(), classHierarchy ) );
|
||||||
name = name.substring( name.lastIndexOf( '.' ) + 1 );
|
|
||||||
Package pkg = c.getClass().getPackage();
|
|
||||||
appendRow( buf, "Class", name + " (" + (pkg != null ? pkg.getName() : "-") + ")" );
|
|
||||||
appendRow( buf, "Size", c.getWidth() + ", " + c.getHeight() + " @ " + c.getX() + ", " + c.getY() );
|
appendRow( buf, "Size", c.getWidth() + ", " + c.getHeight() + " @ " + c.getX() + ", " + c.getY() );
|
||||||
|
|
||||||
if( c instanceof Container )
|
if( c instanceof Container )
|
||||||
@@ -464,7 +470,7 @@ public class FlatInspector
|
|||||||
appendRow( buf, "Max size", maxSize.width + ", " + maxSize.height );
|
appendRow( buf, "Max size", maxSize.width + ", " + maxSize.height );
|
||||||
|
|
||||||
if( c instanceof JComponent )
|
if( c instanceof JComponent )
|
||||||
appendRow( buf, "Border", toString( ((JComponent)c).getBorder() ) );
|
appendRow( buf, "Border", toString( ((JComponent)c).getBorder(), classHierarchy ) );
|
||||||
|
|
||||||
appendRow( buf, "Background", toString( c.getBackground() ) );
|
appendRow( buf, "Background", toString( c.getBackground() ) );
|
||||||
appendRow( buf, "Foreground", toString( c.getForeground() ) );
|
appendRow( buf, "Foreground", toString( c.getForeground() ) );
|
||||||
@@ -475,7 +481,7 @@ public class FlatInspector
|
|||||||
Field f = JComponent.class.getDeclaredField( "ui" );
|
Field f = JComponent.class.getDeclaredField( "ui" );
|
||||||
f.setAccessible( true );
|
f.setAccessible( true );
|
||||||
Object ui = f.get( c );
|
Object ui = f.get( c );
|
||||||
appendRow( buf, "UI", (ui != null ? ui.getClass().getName() : "null") );
|
appendRow( buf, "UI", (ui != null ? toString( ui.getClass(), classHierarchy ) : "null") );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
@@ -484,7 +490,7 @@ public class FlatInspector
|
|||||||
if( c instanceof Container ) {
|
if( c instanceof Container ) {
|
||||||
LayoutManager layout = ((Container)c).getLayout();
|
LayoutManager layout = ((Container)c).getLayout();
|
||||||
if( layout != null )
|
if( layout != null )
|
||||||
appendRow( buf, "Layout", layout.getClass().getName() );
|
appendRow( buf, "Layout", toString( layout.getClass(), classHierarchy ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
appendRow( buf, "Enabled", String.valueOf( c.isEnabled() ) );
|
appendRow( buf, "Enabled", String.valueOf( c.isEnabled() ) );
|
||||||
@@ -494,16 +500,23 @@ public class FlatInspector
|
|||||||
appendRow( buf, "ContentAreaFilled", String.valueOf( ((AbstractButton)c).isContentAreaFilled() ) );
|
appendRow( buf, "ContentAreaFilled", String.valueOf( ((AbstractButton)c).isContentAreaFilled() ) );
|
||||||
appendRow( buf, "Focusable", String.valueOf( c.isFocusable() ) );
|
appendRow( buf, "Focusable", String.valueOf( c.isFocusable() ) );
|
||||||
appendRow( buf, "Left-to-right", String.valueOf( c.getComponentOrientation().isLeftToRight() ) );
|
appendRow( buf, "Left-to-right", String.valueOf( c.getComponentOrientation().isLeftToRight() ) );
|
||||||
appendRow( buf, "Parent", (c.getParent() != null ? c.getParent().getClass().getName() : "null") );
|
appendRow( buf, "Parent", (c.getParent() != null ? toString( c.getParent().getClass(), classHierarchy ) : "null") );
|
||||||
|
|
||||||
|
// append parent level
|
||||||
buf.append( "<tr><td colspan=\"2\">" );
|
buf.append( "<tr><td colspan=\"2\">" );
|
||||||
if( parentLevel > 0 )
|
if( parentLevel > 0 )
|
||||||
buf.append( "<br>Parent level: " + parentLevel );
|
buf.append( "<br>Parent level: " + parentLevel );
|
||||||
|
|
||||||
if( parentLevel > 0 )
|
// append modifier keys hint
|
||||||
buf.append( "<br>(press Ctrl/Shift to increase/decrease level)" );
|
buf.append( "<br>(" )
|
||||||
else
|
.append( (parentLevel > 0)
|
||||||
buf.append( "<br>(press Ctrl key to inspect parent)" );
|
? "press <b>Ctrl/Shift</b> to increase/decrease level"
|
||||||
|
: "press <b>Ctrl</b> key to inspect parent" )
|
||||||
|
.append( "; " )
|
||||||
|
.append( classHierarchy
|
||||||
|
? "press <b>Alt</b> key to hide class hierarchy"
|
||||||
|
: "press <b>Alt</b> key to show class hierarchy" )
|
||||||
|
.append( ')' );
|
||||||
|
|
||||||
buf.append( "</td></tr>" );
|
buf.append( "</td></tr>" );
|
||||||
buf.append( "</table></html>" );
|
buf.append( "</table></html>" );
|
||||||
@@ -512,13 +525,43 @@ public class FlatInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void appendRow( StringBuilder buf, String key, String value ) {
|
private static void appendRow( StringBuilder buf, String key, String value ) {
|
||||||
buf.append( "<tr><td>" )
|
buf.append( "<tr><td valign=\"top\">" )
|
||||||
.append( key )
|
.append( key )
|
||||||
.append( ":</td><td>" )
|
.append( ":</td><td>" )
|
||||||
.append( value )
|
.append( value )
|
||||||
.append( "</td></tr>" );
|
.append( "</td></tr>" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String toString( Class<?> cls, boolean classHierarchy ) {
|
||||||
|
StringBuilder buf = new StringBuilder( 100 );
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
while( cls != null ) {
|
||||||
|
if( level > 0 ) {
|
||||||
|
if( cls == Object.class )
|
||||||
|
break;
|
||||||
|
buf.append( "<br> " );
|
||||||
|
for( int i = 1; i < level; i++ )
|
||||||
|
buf.append( " " );
|
||||||
|
buf.append( "\u2570 " );
|
||||||
|
}
|
||||||
|
level++;
|
||||||
|
|
||||||
|
String name = cls.getName();
|
||||||
|
int dot = name.lastIndexOf( '.' );
|
||||||
|
String pkg = (dot >= 0) ? name.substring( 0, dot ) : "-";
|
||||||
|
String simpleName = (dot >= 0) ? name.substring( dot + 1 ) : name;
|
||||||
|
buf.append( simpleName ).append( ' ' ).append( toDimmedText( "(" + pkg + ")" ) );
|
||||||
|
|
||||||
|
if( !classHierarchy )
|
||||||
|
break;
|
||||||
|
|
||||||
|
cls = cls.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private static String toString( Insets insets ) {
|
private static String toString( Insets insets ) {
|
||||||
if( insets == null )
|
if( insets == null )
|
||||||
return "null";
|
return "null";
|
||||||
@@ -564,11 +607,11 @@ public class FlatInspector
|
|||||||
+ (f instanceof UIResource ? " UI" : "");
|
+ (f instanceof UIResource ? " UI" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toString( Border b ) {
|
private static String toString( Border b, boolean classHierarchy ) {
|
||||||
if( b == null )
|
if( b == null )
|
||||||
return "null";
|
return "null";
|
||||||
|
|
||||||
String s = b.getClass().getName();
|
String s = toString( b.getClass(), classHierarchy );
|
||||||
|
|
||||||
if( b instanceof EmptyBorder )
|
if( b instanceof EmptyBorder )
|
||||||
s += '(' + toString( ((EmptyBorder)b).getBorderInsets() ) + ')';
|
s += '(' + toString( ((EmptyBorder)b).getBorderInsets() ) + ')';
|
||||||
@@ -578,4 +621,14 @@ public class FlatInspector
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String toDimmedText( String text ) {
|
||||||
|
Color color = UIManager.getColor( "Label.disabledForeground" );
|
||||||
|
if( color == null )
|
||||||
|
color = UIManager.getColor( "Label.disabledText" );
|
||||||
|
if( color == null )
|
||||||
|
color = Color.GRAY;
|
||||||
|
return String.format( "<span color=\"#%06x\">%s</span>",
|
||||||
|
color.getRGB() & 0xffffff, text );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user