List and Tree: Hide cell focus indicator (black rectangle) by default. Can be enabled with List.showCellFocusIndicator=true / Tree.showCellFocusIndicator=true, but then the cell focus indicator is shown only if more than one item is selected.

Table: Hide cell focus indicator (black rectangle) by default if none of the selected cells is editable. Can be show always with `Table.showCellFocusIndicator=true`.
This commit is contained in:
Karl Tauber
2019-12-30 16:31:51 +01:00
parent 269075657d
commit 9c470d77cb
7 changed files with 169 additions and 19 deletions

View File

@@ -4,12 +4,17 @@ FlatLaf Change Log
## Unreleased ## Unreleased
- 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 matches
platform colors. platform colors.
- Tree: Support wide selection (enabled by default). - Tree: Support wide selection (enabled by default).
- Table: Hide grid and changed intercell spacing to zero. - Table: Hide grid and changed intercell spacing to zero.
- List and Tree: Paint cell focus indicator (black rectangle) only if more than - List and Tree: Hide cell focus indicator (black rectangle) by default. Can be
one item is selected. enabled with `List.showCellFocusIndicator=true` /
`Tree.showCellFocusIndicator=true`, but then the cell focus indicator is shown
only if more than one item is selected.
- Table: Hide cell focus indicator (black rectangle) by default if none of the
selected cells is editable. Can be show always with
`Table.showCellFocusIndicator=true`.
- Support basic color functions in `.properties` files: `rgb(red,green,blue)`, - Support basic color functions in `.properties` files: `rgb(red,green,blue)`,
`rgba(red,green,blue,alpha)`, `hsl(hue,saturation,lightness)`, `rgba(red,green,blue,alpha)`, `hsl(hue,saturation,lightness)`,
`hsla(hue,saturation,lightness,alpha)`, `lighten(color,amount[,options])` and `hsla(hue,saturation,lightness,alpha)`, `lighten(color,amount[,options])` and

View File

@@ -23,8 +23,9 @@ import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
/** /**
* Cell border for {@link javax.swing.DefaultListCellRenderer}. * Cell border for {@link javax.swing.DefaultListCellRenderer}
* * (used by {@link javax.swing.JList}).
* <p>
* Uses separate cell margins from UI defaults to allow easy customizing. * Uses separate cell margins from UI defaults to allow easy customizing.
* *
* @author Karl Tauber * @author Karl Tauber
@@ -32,23 +33,31 @@ import javax.swing.UIManager;
public class FlatListCellBorder public class FlatListCellBorder
extends FlatLineBorder extends FlatLineBorder
{ {
final boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" );
protected FlatListCellBorder() { protected FlatListCellBorder() {
super( UIManager.getInsets( "List.cellMargins" ), UIManager.getColor( "List.cellFocusColor" ) ); super( UIManager.getInsets( "List.cellMargins" ), UIManager.getColor( "List.cellFocusColor" ) );
} }
//---- class Default ------------------------------------------------------ //---- class Default ------------------------------------------------------
/**
* Border for unselected cell that uses margins, but does not paint focus indicator border.
*/
public static class Default public static class Default
extends FlatListCellBorder extends FlatListCellBorder
{ {
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
// do not paint border // do not paint focus indicator border
} }
} }
//---- class Focused ------------------------------------------------------ //---- class Focused ------------------------------------------------------
/**
* Border for focused unselected cell that uses margins and paints focus indicator border.
*/
public static class Focused public static class Focused
extends FlatListCellBorder extends FlatListCellBorder
{ {
@@ -56,12 +65,19 @@ public class FlatListCellBorder
//---- class Selected ----------------------------------------------------- //---- class Selected -----------------------------------------------------
/**
* Border for selected cell that uses margins and paints focus indicator border
* if enabled (List.showCellFocusIndicator=true) and exactly one item is selected.
*/
public static class Selected public static class Selected
extends FlatListCellBorder extends FlatListCellBorder
{ {
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
// paint border only if exactly one item is selected if( !showCellFocusIndicator )
return;
// paint focus indicator border only if exactly one item is selected
JList<?> list = (JList<?>) SwingUtilities.getAncestorOfClass( JList.class, c ); JList<?> list = (JList<?>) SwingUtilities.getAncestorOfClass( JList.class, c );
if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() ) if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() )
return; return;

View File

@@ -56,6 +56,7 @@ import javax.swing.plaf.basic.BasicListUI;
* *
* @uiDefault List.cellMargins Insets * @uiDefault List.cellMargins Insets
* @uiDefault List.cellFocusColor Color * @uiDefault List.cellFocusColor Color
* @uiDefault List.showCellFocusIndicator boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */

View File

@@ -0,0 +1,115 @@
/*
* 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.
*/
package com.formdev.flatlaf.ui;
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
* Cell border for {@link javax.swing.table.DefaultTableCellRenderer}
* (used by {@link javax.swing.JTable}).
* <p>
* Uses separate cell margins from UI defaults to allow easy customizing.
*
* @author Karl Tauber
*/
public class FlatTableCellBorder
extends FlatLineBorder
{
final boolean showCellFocusIndicator = UIManager.getBoolean( "Table.showCellFocusIndicator" );
protected FlatTableCellBorder() {
super( UIManager.getInsets( "Table.cellMargins" ), UIManager.getColor( "Table.cellFocusColor" ) );
}
//---- class Default ------------------------------------------------------
/**
* Border for unselected cell that uses margins, but does not paint focus indicator border.
*/
public static class Default
extends FlatTableCellBorder
{
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
// do not paint focus indicator border
}
}
//---- class Focused ------------------------------------------------------
/**
* Border for focused unselected cell that uses margins and paints focus indicator border.
*/
public static class Focused
extends FlatTableCellBorder
{
}
//---- class Selected -----------------------------------------------------
/**
* Border for selected cell that uses margins and paints focus indicator border
* if enabled (Table.showCellFocusIndicator=true) or at least one selected cell is editable.
*/
public static class Selected
extends FlatTableCellBorder
{
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( !showCellFocusIndicator ) {
JTable table = (JTable) SwingUtilities.getAncestorOfClass( JTable.class, c );
if( table != null && !isSelectionEditable( table ) )
return;
}
super.paintBorder( c, g, x, y, width, height );
}
/**
* Checks whether at least one selected cell is editable.
*/
private boolean isSelectionEditable( JTable table ) {
if( table.getRowSelectionAllowed() ) {
int columnCount = table.getColumnCount();
int[] selectedRows = table.getSelectedRows();
for( int selectedRow : selectedRows ) {
for( int column = 0; column < columnCount; column++ ) {
if( table.isCellEditable( selectedRow, column ) )
return true;
}
}
}
if( table.getColumnSelectionAllowed() ) {
int rowCount = table.getRowCount();
int[] selectedColumns = table.getSelectedColumns();
for( int selectedColumn : selectedColumns ) {
for( int row = 0; row < rowCount; row++ ) {
if( table.isCellEditable( row, selectedColumn ) )
return true;
}
}
}
return false;
}
}
}

View File

@@ -55,11 +55,17 @@ import com.formdev.flatlaf.util.UIScale;
* *
* <!-- FlatTableUI --> * <!-- FlatTableUI -->
* *
* @uiDefault Table.rowHeight int * @uiDefault Table.rowHeight int
* @uiDefault Table.showGrid boolean * @uiDefault Table.showGrid boolean
* @uiDefault Table.intercellSpacing Dimension * @uiDefault Table.intercellSpacing Dimension
* @uiDefault Table.selectionInactiveBackground Color * @uiDefault Table.selectionInactiveBackground Color
* @uiDefault Table.selectionInactiveForeground Color * @uiDefault Table.selectionInactiveForeground Color
*
* <!-- FlatTableCellBorder -->
*
* @uiDefault Table.cellMargins Insets
* @uiDefault Table.cellFocusColor Color
* @uiDefault Table.showCellFocusIndicator boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */

View File

@@ -83,6 +83,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Tree.selectionInactiveBackground Color * @uiDefault Tree.selectionInactiveBackground Color
* @uiDefault Tree.selectionInactiveForeground Color * @uiDefault Tree.selectionInactiveForeground Color
* @uiDefault Tree.wideSelection boolean * @uiDefault Tree.wideSelection boolean
* @uiDefault Tree.showCellFocusIndicator boolean
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -95,6 +96,7 @@ public class FlatTreeUI
protected Color selectionInactiveForeground; protected Color selectionInactiveForeground;
protected Color selectionBorderColor; protected Color selectionBorderColor;
protected boolean wideSelection; protected boolean wideSelection;
protected boolean showCellFocusIndicator;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatTreeUI(); return new FlatTreeUI();
@@ -112,6 +114,7 @@ public class FlatTreeUI
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" ); wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
// scale // scale
int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 ); int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 );
@@ -217,9 +220,7 @@ public class FlatTreeUI
protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, protected void paintRow( 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 )
{ {
if( editingComponent != null && editingRow == row ) boolean isEditing = (editingComponent != null && editingRow == row);
return;
boolean hasFocus = tree.hasFocus(); boolean hasFocus = tree.hasFocus();
boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow()); boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());
boolean isSelected = tree.isRowSelected( row ); boolean isSelected = tree.isRowSelected( row );
@@ -240,6 +241,9 @@ public class FlatTreeUI
} }
} }
if( isEditing )
return;
// 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 );
@@ -262,10 +266,10 @@ public class FlatTreeUI
rendererComponent.setForeground( selectionInactiveForeground ); rendererComponent.setForeground( selectionInactiveForeground );
} }
// remove selection border if exactly one item is selected // remove focus selection border if exactly one item is selected
Color oldBorderSelectionColor = null; Color oldBorderSelectionColor = null;
if( isSelected && hasFocus && if( isSelected && hasFocus &&
tree.getMinSelectionRow() == tree.getMaxSelectionRow() && (!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) &&
rendererComponent instanceof DefaultTreeCellRenderer ) rendererComponent instanceof DefaultTreeCellRenderer )
{ {
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent; DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;

View File

@@ -375,8 +375,11 @@ Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder
Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon
Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon
Table.sortIconColor=@icon Table.sortIconColor=@icon
Table.cellNoFocusBorder=2,3,2,3 Table.cellMargins=2,3,2,3
Table.focusSelectedCellHighlightBorder=2,3,2,3,@cellFocusColor Table.cellFocusColor=@cellFocusColor
Table.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Default
Table.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Focused
Table.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Selected
Table.selectionInactiveBackground=@selectionInactiveBackground Table.selectionInactiveBackground=@selectionInactiveBackground
Table.selectionInactiveForeground=@selectionInactiveForeground Table.selectionInactiveForeground=@selectionInactiveForeground
Table.dropCellBackground=@dropCellBackground Table.dropCellBackground=@dropCellBackground