Merge PR #546: Tree: rounded selection

This commit is contained in:
Karl Tauber
2022-10-30 10:16:07 +01:00
11 changed files with 146 additions and 18 deletions

View File

@@ -6,6 +6,7 @@ FlatLaf Change Log
#### New features and improvements #### New features and improvements
- Menus: Support rounded selection. (PR #536) - Menus: Support rounded selection. (PR #536)
- Tree: Support rounded selection. (PR #546)
#### Fixed bugs #### Fixed bugs

View File

@@ -369,15 +369,11 @@ debug*/
/** @since 3 */ /** @since 3 */
protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) { protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) {
Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( menuItem.getSize() ), scale( selectionInsets ) ); float arc = scale( selectionArc / 2f );
g.setColor( deriveBackground( selectionBackground ) ); g.setColor( deriveBackground( selectionBackground ) );
if( selectionArc > 0 ) { FlatUIUtils.paintSelection( (Graphics2D) g, 0, 0, menuItem.getWidth(), menuItem.getHeight(),
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g ); scale( selectionInsets ), arc, arc, arc, arc, 0 );
FlatUIUtils.paintComponentBackground( (Graphics2D) g, r.x, r.y, r.width, r.height, 0, scale( selectionArc ) );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
} else
g.fillRect( r.x, r.y, r.width, r.height );
} }
/** @since 3 */ /** @since 3 */

View File

@@ -17,10 +17,10 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
@@ -36,6 +36,7 @@ import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.JTree.DropLocation; import javax.swing.JTree.DropLocation;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeCellRenderer;
@@ -96,6 +97,8 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Tree.selectionForeground Color * @uiDefault Tree.selectionForeground Color
* @uiDefault Tree.selectionInactiveBackground Color * @uiDefault Tree.selectionInactiveBackground Color
* @uiDefault Tree.selectionInactiveForeground Color * @uiDefault Tree.selectionInactiveForeground Color
* @uiDefault Tree.selectionInsets Insets
* @uiDefault Tree.selectionArc int
* @uiDefault Tree.wideSelection boolean * @uiDefault Tree.wideSelection boolean
* @uiDefault Tree.showCellFocusIndicator boolean * @uiDefault Tree.showCellFocusIndicator boolean
* *
@@ -132,6 +135,8 @@ public class FlatTreeUI
@Styleable protected Color selectionInactiveBackground; @Styleable protected Color selectionInactiveBackground;
@Styleable protected Color selectionInactiveForeground; @Styleable protected Color selectionInactiveForeground;
@Styleable protected Color selectionBorderColor; @Styleable protected Color selectionBorderColor;
/** @since 3 */ @Styleable protected Insets selectionInsets;
/** @since 3 */ @Styleable protected int selectionArc;
@Styleable protected boolean wideSelection; @Styleable protected boolean wideSelection;
@Styleable protected boolean showCellFocusIndicator; @Styleable protected boolean showCellFocusIndicator;
@@ -175,6 +180,8 @@ public class FlatTreeUI
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" ); selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" ); selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" ); selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
selectionInsets = UIManager.getInsets( "Tree.selectionInsets" );
selectionArc = UIManager.getInt( "Tree.selectionArc" );
wideSelection = UIManager.getBoolean( "Tree.wideSelection" ); wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" ); showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
@@ -295,6 +302,34 @@ public class FlatTreeUI
tree.repaint( 0, r.y, tree.getWidth(), r.height ); tree.repaint( 0, r.y, tree.getWidth(), r.height );
} }
@Override
protected TreeSelectionListener createTreeSelectionListener() {
TreeSelectionListener superListener = super.createTreeSelectionListener();
return e -> {
superListener.valueChanged( e );
// for united rounded selection, repaint parts of the rows that adjoin to the changed rows
TreePath[] changedPaths;
if( useUnitedRoundedSelection() &&
tree.getSelectionCount() > 1 &&
(changedPaths = e.getPaths()) != null )
{
if( changedPaths.length > 4 ) {
// same is done in BasicTreeUI.Handler.valueChanged()
tree.repaint();
} else {
int arcHeight = (int) Math.ceil( UIScale.scale( (float) selectionArc ) );
for( TreePath path : changedPaths ) {
Rectangle r = getPathBounds( tree, path );
if( r != null )
tree.repaint( r.x, r.y - arcHeight, r.width, r.height + (arcHeight * 2) );
}
}
}
};
}
@Override @Override
public Rectangle getPathBounds( JTree tree, TreePath path ) { public Rectangle getPathBounds( JTree tree, TreePath path ) {
Rectangle bounds = super.getPathBounds( tree, path ); Rectangle bounds = super.getPathBounds( tree, path );
@@ -347,7 +382,7 @@ public class FlatTreeUI
} }
/** /**
* Same as super.paintRow(), but supports wide selection and uses * Similar to super.paintRow(), but supports wide selection and uses
* inactive selection background/foreground if tree is not focused. * inactive selection background/foreground if tree is not focused.
*/ */
@Override @Override
@@ -428,7 +463,7 @@ public class FlatTreeUI
paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf ); paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
} else { } else {
// non-wide selection // non-wide selection
paintCellBackground( g, rendererComponent, bounds ); paintCellBackground( g, rendererComponent, bounds, row, true );
} }
// this is actually not necessary because renderer should always set color // this is actually not necessary because renderer should always set color
@@ -442,7 +477,7 @@ public class FlatTreeUI
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) { if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
Color oldColor = g.getColor(); Color oldColor = g.getColor();
g.setColor( bg ); g.setColor( bg );
paintCellBackground( g, rendererComponent, bounds ); paintCellBackground( g, rendererComponent, bounds, row, false );
g.setColor( oldColor ); g.setColor( oldColor );
} }
} }
@@ -497,7 +532,18 @@ public class FlatTreeUI
private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf ) TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
{ {
g.fillRect( 0, bounds.y, tree.getWidth(), bounds.height ); float arcTop, arcBottom;
arcTop = arcBottom = UIScale.scale( selectionArc / 2f );
if( useUnitedRoundedSelection() ) {
if( row > 0 && tree.isRowSelected( row - 1 ) )
arcTop = 0;
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
arcBottom = 0;
}
FlatUIUtils.paintSelection( (Graphics2D) g, 0, bounds.y, tree.getWidth(), bounds.height,
UIScale.scale( selectionInsets ), arcTop, arcTop, arcBottom, arcBottom, 0 );
// paint expand/collapse icon // paint expand/collapse icon
// (was already painted before, but painted over with wide selection) // (was already painted before, but painted over with wide selection)
@@ -507,7 +553,9 @@ public class FlatTreeUI
} }
} }
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds ) { private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds,
int row, boolean paintSelection )
{
int xOffset = 0; int xOffset = 0;
int imageOffset = 0; int imageOffset = 0;
@@ -520,7 +568,32 @@ public class FlatTreeUI
xOffset = label.getComponentOrientation().isLeftToRight() ? imageOffset : 0; xOffset = label.getComponentOrientation().isLeftToRight() ? imageOffset : 0;
} }
g.fillRect( bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height ); if( paintSelection ) {
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
if( useUnitedRoundedSelection() ) {
if( row > 0 && tree.isRowSelected( row - 1 ) ) {
Rectangle r = getPathBounds( tree, tree.getPathForRow( row - 1 ) );
arcTopLeft = Math.min( arcTopLeft, r.x - bounds.x );
arcTopRight = Math.min( arcTopRight, (bounds.x + bounds.width) - (r.x + r.width) );
}
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) ) {
Rectangle r = getPathBounds( tree, tree.getPathForRow( row + 1 ) );
arcBottomLeft = Math.min( arcBottomLeft, r.x - bounds.x );
arcBottomRight = Math.min( arcBottomRight, (bounds.x + bounds.width) - (r.x + r.width) );
}
}
FlatUIUtils.paintSelection( (Graphics2D) g, bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height,
UIScale.scale( selectionInsets ), arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight, 0 );
} else
g.fillRect( bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height );
}
private boolean useUnitedRoundedSelection() {
return selectionArc > 0 &&
(selectionInsets == null || (selectionInsets.top == 0 && selectionInsets.bottom == 0));
} }
/** /**

View File

@@ -443,9 +443,9 @@ public class FlatUIUtils
} }
/** /**
* Fills the background of a component with a round rectangle. * Fills the background of a component with a rounded rectangle.
* <p> * <p>
* The bounds of the painted round rectangle are * The bounds of the painted rounded rectangle are
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}. * {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}). * The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
* *
@@ -476,7 +476,7 @@ public class FlatUIUtils
* <p> * <p>
* *
* <strong>Background</strong>: * <strong>Background</strong>:
* The bounds of the filled round rectangle are * The bounds of the filled rounded rectangle are
* {@code [x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)]}. * {@code [x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)]}.
* The focus border and the border may paint over the background. * The focus border and the border may paint over the background.
* <p> * <p>
@@ -674,6 +674,50 @@ public class FlatUIUtils
} }
} }
/**
* Paints a selection.
* <p>
* The bounds of the painted selection (rounded) rectangle are
* {@code x + insets.left, y + insets.top, width - insets.left - insets.right, height - insets.top - insets.bottom}.
* The given arc radius refers to the painted rectangle (and not to {@code x,y,width,height}).
*
* @since 3
*/
public static void paintSelection( Graphics2D g, int x, int y, int width, int height, Insets insets,
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight, int flags )
{
if( insets != null ) {
x += insets.left;
y += insets.top;
width -= insets.left + insets.right;
height -= insets.top + insets.bottom;
}
if( arcTopLeft > 0 || arcTopRight > 0 || arcBottomLeft > 0 || arcBottomRight > 0 ) {
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
HiDPIUtils.paintAtScale1x( g, x, y, width, height,
(g2d, x2, y2, width2, height2, scaleFactor) -> {
paintRoundedSelectionImpl( g2d, x2, y2, width2, height2,
(float) (arcTopLeft * scaleFactor), (float) (arcTopRight * scaleFactor),
(float) (arcBottomLeft * scaleFactor), (float) (arcBottomRight * scaleFactor) );
} );
} else
paintRoundedSelectionImpl( g, x, y, width, height, arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight );
} else
g.fillRect( x, y, width, height );
}
private static void paintRoundedSelectionImpl( Graphics2D g, int x, int y, int width, int height,
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
{
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
g.fill( FlatUIUtils.createRoundRectanglePath( x, y, width, height, arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight ) );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
}
public static void paintGrip( Graphics g, int x, int y, int width, int height, public static void paintGrip( Graphics g, int x, int y, int width, int height,
boolean horizontal, int dotCount, int dotSize, int gap, boolean centerPrecise ) boolean horizontal, int dotCount, int dotSize, int gap, boolean centerPrecise )
{ {
@@ -765,7 +809,7 @@ public class FlatUIUtils
} }
/** /**
* Creates a not-filled rounded rectangle shape and allows specifying the line width and the radius or each corner. * Creates a not-filled rounded rectangle shape and allows specifying the line width and the radius of each corner.
*/ */
public static Path2D createRoundRectangle( float x, float y, float width, float height, public static Path2D createRoundRectangle( float x, float y, float width, float height,
float lineWidth, float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight ) float lineWidth, float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )

View File

@@ -889,6 +889,8 @@ Tree.dropCellForeground = @dropCellForeground
Tree.dropLineColor = @dropLineColor Tree.dropLineColor = @dropLineColor
Tree.rendererFillBackground = false Tree.rendererFillBackground = false
Tree.rendererMargins = 1,2,1,2 Tree.rendererMargins = 1,2,1,2
Tree.selectionInsets = 0,0,0,0
Tree.selectionArc = 0
Tree.wideSelection = true Tree.wideSelection = true
Tree.repaintWholeRow = true Tree.repaintWholeRow = true
Tree.paintLines = false Tree.paintLines = false

View File

@@ -939,6 +939,8 @@ public class TestFlatStyleableInfo
"selectionInactiveBackground", Color.class, "selectionInactiveBackground", Color.class,
"selectionInactiveForeground", Color.class, "selectionInactiveForeground", Color.class,
"selectionBorderColor", Color.class, "selectionBorderColor", Color.class,
"selectionInsets", Insets.class,
"selectionArc", int.class,
"wideSelection", boolean.class, "wideSelection", boolean.class,
"showCellFocusIndicator", boolean.class, "showCellFocusIndicator", boolean.class,

View File

@@ -1145,6 +1145,8 @@ public class TestFlatStyling
ui.applyStyle( "selectionInactiveBackground: #fff" ); ui.applyStyle( "selectionInactiveBackground: #fff" );
ui.applyStyle( "selectionInactiveForeground: #fff" ); ui.applyStyle( "selectionInactiveForeground: #fff" );
ui.applyStyle( "selectionBorderColor: #fff" ); ui.applyStyle( "selectionBorderColor: #fff" );
ui.applyStyle( "selectionInsets: 1,2,3,4" );
ui.applyStyle( "selectionArc: 8" );
ui.applyStyle( "wideSelection: true" ); ui.applyStyle( "wideSelection: true" );
ui.applyStyle( "showCellFocusIndicator: true" ); ui.applyStyle( "showCellFocusIndicator: true" );

View File

@@ -1386,11 +1386,13 @@ Tree.repaintWholeRow true
Tree.rightChildIndent 11 Tree.rightChildIndent 11
Tree.rowHeight 0 Tree.rowHeight 0
Tree.scrollsOnExpand true Tree.scrollsOnExpand true
Tree.selectionArc 0
Tree.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionBorderColor #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBorderColor #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] Tree.selectionForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveBackground #0f2a3d HSL 205 61 15 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveBackground #0f2a3d HSL 205 61 15 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
Tree.showCellFocusIndicator false Tree.showCellFocusIndicator false
Tree.textBackground #46494b HSL 204 3 28 javax.swing.plaf.ColorUIResource [UI] Tree.textBackground #46494b HSL 204 3 28 javax.swing.plaf.ColorUIResource [UI]
Tree.textForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] Tree.textForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -1391,11 +1391,13 @@ Tree.repaintWholeRow true
Tree.rightChildIndent 11 Tree.rightChildIndent 11
Tree.rowHeight 0 Tree.rowHeight 0
Tree.scrollsOnExpand true Tree.scrollsOnExpand true
Tree.selectionArc 0
Tree.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionBorderColor #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBorderColor #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] Tree.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveBackground #d3d3d3 HSL 0 0 83 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveBackground #d3d3d3 HSL 0 0 83 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
Tree.showCellFocusIndicator false Tree.showCellFocusIndicator false
Tree.textBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] Tree.textBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Tree.textForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] Tree.textForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -1437,11 +1437,13 @@ Tree.repaintWholeRow true
Tree.rightChildIndent 11 Tree.rightChildIndent 11
Tree.rowHeight 0 Tree.rowHeight 0
Tree.scrollsOnExpand true Tree.scrollsOnExpand true
Tree.selectionArc 0
Tree.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] Tree.selectionBorderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI] Tree.selectionForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveBackground #888888 HSL 0 0 53 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveBackground #888888 HSL 0 0 53 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] Tree.selectionInactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
Tree.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
Tree.showCellFocusIndicator false Tree.showCellFocusIndicator false
Tree.textBackground #fff0ff HSL 300 100 97 javax.swing.plaf.ColorUIResource [UI] Tree.textBackground #fff0ff HSL 300 100 97 javax.swing.plaf.ColorUIResource [UI]
Tree.textForeground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] Tree.textForeground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -1137,11 +1137,13 @@ Tree.repaintWholeRow
Tree.rightChildIndent Tree.rightChildIndent
Tree.rowHeight Tree.rowHeight
Tree.scrollsOnExpand Tree.scrollsOnExpand
Tree.selectionArc
Tree.selectionBackground Tree.selectionBackground
Tree.selectionBorderColor Tree.selectionBorderColor
Tree.selectionForeground Tree.selectionForeground
Tree.selectionInactiveBackground Tree.selectionInactiveBackground
Tree.selectionInactiveForeground Tree.selectionInactiveForeground
Tree.selectionInsets
Tree.showCellFocusIndicator Tree.showCellFocusIndicator
Tree.textBackground Tree.textBackground
Tree.textForeground Tree.textForeground