Tree: support wide selection (enabled by default)

This commit is contained in:
Karl Tauber
2019-12-22 00:07:08 +01:00
parent 56c161fea0
commit 4960b30cfb
3 changed files with 68 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ FlatLaf Change Log
- Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from - Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from
"IntelliJ Light Theme", which provides blue coloring that better match "IntelliJ Light Theme", which provides blue coloring that better match
platform colors. platform colors.
- Tree: Support wide selection (enabled by default).
- List and Tree: Paint cell focus indicator (black rectangle) only if more than - List and Tree: Paint cell focus indicator (black rectangle) only if more than
one item is selected. one item is selected.
- Fixed link color (in HTML text) and separator color in IntelliJ platform - Fixed link color (in HTML text) and separator color in IntelliJ platform

View File

@@ -21,8 +21,11 @@ import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
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.MouseListener;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.plaf.basic.BasicTreeUI;
@@ -75,6 +78,7 @@ 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.wideSelection boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -86,6 +90,7 @@ public class FlatTreeUI
protected Color selectionInactiveBackground; protected Color selectionInactiveBackground;
protected Color selectionInactiveForeground; protected Color selectionInactiveForeground;
protected Color selectionBorderColor; protected Color selectionBorderColor;
protected boolean wideSelection;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatTreeUI(); return new FlatTreeUI();
@@ -102,6 +107,7 @@ 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" );
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
// scale // scale
int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 ); int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 );
@@ -124,6 +130,53 @@ public class FlatTreeUI
selectionBorderColor = null; selectionBorderColor = null;
} }
@Override
protected MouseListener createMouseListener() {
if( !wideSelection )
return super.createMouseListener();
return new BasicTreeUI.MouseHandler() {
@Override
public void mousePressed( MouseEvent e ) {
super.mousePressed( handleWideMouseEvent( e ) );
}
@Override
public void mouseReleased( MouseEvent e ) {
super.mouseReleased( handleWideMouseEvent( e ) );
}
@Override
public void mouseDragged( MouseEvent e ) {
super.mouseDragged( handleWideMouseEvent( e ) );
}
private MouseEvent handleWideMouseEvent( MouseEvent e ) {
if( !tree.isEnabled() || !SwingUtilities.isLeftMouseButton( e ) || e.isConsumed() )
return e;
int x = e.getX();
int y = e.getY();
TreePath path = getClosestPathForLocation( tree, x, y );
if( path == null || isLocationInExpandControl( path, x, y ) )
return e;
Rectangle bounds = getPathBounds( tree, path );
if( bounds == null || y < bounds.y || y >= (bounds.y + bounds.height) )
return e;
int newX = Math.max( bounds.x, Math.min( x, bounds.x + bounds.width - 1 ) );
if( newX == x )
return e;
// clone mouse event, but with new X coordinate
return new MouseEvent( e.getComponent(), e.getID(), e.getWhen(),
e.getModifiers() | e.getModifiersEx(), newX, e.getY(),
e.getClickCount(), e.isPopupTrigger(), e.getButton() );
}
};
}
/** /**
* Same as super.paintRow(), but uses inactive selection background/foreground if tree is not focused. * Same as super.paintRow(), but uses inactive selection background/foreground if tree is not focused.
*/ */
@@ -138,6 +191,19 @@ public class FlatTreeUI
boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow()); boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());
boolean isSelected = tree.isRowSelected( row ); boolean isSelected = tree.isRowSelected( row );
// wide selection background
if( wideSelection && isSelected ) {
// fill background
g.setColor( hasFocus ? selectionBackground : selectionInactiveBackground );
g.fillRect( 0, bounds.y, clipBounds.width, bounds.height );
// paint expand/collapse icon
if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) {
paintExpandControl( g, clipBounds, insets, bounds,
path, row, isExpanded, hasBeenExpanded, isLeaf );
}
}
// get renderer component // get renderer component
Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree, Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree,
path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus ); path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus );

View File

@@ -454,6 +454,7 @@ Tree.selectionInactiveForeground=@selectionInactiveForeground
Tree.textBackground=null Tree.textBackground=null
Tree.selectionBorderColor=@cellFocusColor Tree.selectionBorderColor=@cellFocusColor
Tree.rendererMargins=1,2,1,2 Tree.rendererMargins=1,2,1,2
Tree.wideSelection=true
Tree.paintLines=false Tree.paintLines=false
Tree.leftChildIndent=7 Tree.leftChildIndent=7
Tree.rightChildIndent=11 Tree.rightChildIndent=11