diff --git a/CHANGELOG.md b/CHANGELOG.md index efcfcac3..aa4d2337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,17 @@ FlatLaf Change Log ## Unreleased - 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. - Tree: Support wide selection (enabled by default). - Table: Hide grid and changed intercell spacing to zero. -- List and Tree: Paint cell focus indicator (black rectangle) only if more than - one item is selected. +- 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`. - Support basic color functions in `.properties` files: `rgb(red,green,blue)`, `rgba(red,green,blue,alpha)`, `hsl(hue,saturation,lightness)`, `hsla(hue,saturation,lightness,alpha)`, `lighten(color,amount[,options])` and diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java index 823a448a..16d3a23d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListCellBorder.java @@ -23,8 +23,9 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; /** - * Cell border for {@link javax.swing.DefaultListCellRenderer}. - * + * Cell border for {@link javax.swing.DefaultListCellRenderer} + * (used by {@link javax.swing.JList}). + *
* Uses separate cell margins from UI defaults to allow easy customizing. * * @author Karl Tauber @@ -32,23 +33,31 @@ import javax.swing.UIManager; public class FlatListCellBorder extends FlatLineBorder { + final boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" ); + protected FlatListCellBorder() { super( UIManager.getInsets( "List.cellMargins" ), UIManager.getColor( "List.cellFocusColor" ) ); } //---- class Default ------------------------------------------------------ + /** + * Border for unselected cell that uses margins, but does not paint focus indicator border. + */ public static class Default extends FlatListCellBorder { @Override 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 ------------------------------------------------------ + /** + * Border for focused unselected cell that uses margins and paints focus indicator border. + */ public static class Focused extends FlatListCellBorder { @@ -56,12 +65,19 @@ public class FlatListCellBorder //---- 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 extends FlatListCellBorder { @Override 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 ); if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() ) return; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java index c5efd11f..329eca2b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatListUI.java @@ -56,6 +56,7 @@ import javax.swing.plaf.basic.BasicListUI; * * @uiDefault List.cellMargins Insets * @uiDefault List.cellFocusColor Color + * @uiDefault List.showCellFocusIndicator boolean * * @author Karl Tauber */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java new file mode 100644 index 00000000..05669edf --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableCellBorder.java @@ -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}). + *
+ * 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; + } + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java index 27d9553a..3e7c31bb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java @@ -55,11 +55,17 @@ import com.formdev.flatlaf.util.UIScale; * * * - * @uiDefault Table.rowHeight int - * @uiDefault Table.showGrid boolean - * @uiDefault Table.intercellSpacing Dimension - * @uiDefault Table.selectionInactiveBackground Color - * @uiDefault Table.selectionInactiveForeground Color + * @uiDefault Table.rowHeight int + * @uiDefault Table.showGrid boolean + * @uiDefault Table.intercellSpacing Dimension + * @uiDefault Table.selectionInactiveBackground Color + * @uiDefault Table.selectionInactiveForeground Color + * + * + * + * @uiDefault Table.cellMargins Insets + * @uiDefault Table.cellFocusColor Color + * @uiDefault Table.showCellFocusIndicator boolean * * @author Karl Tauber */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java index 57e719a3..59566495 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java @@ -83,6 +83,7 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault Tree.selectionInactiveBackground Color * @uiDefault Tree.selectionInactiveForeground Color * @uiDefault Tree.wideSelection boolean + * @uiDefault Tree.showCellFocusIndicator boolean * * @author Karl Tauber */ @@ -95,6 +96,7 @@ public class FlatTreeUI protected Color selectionInactiveForeground; protected Color selectionBorderColor; protected boolean wideSelection; + protected boolean showCellFocusIndicator; public static ComponentUI createUI( JComponent c ) { return new FlatTreeUI(); @@ -112,6 +114,7 @@ public class FlatTreeUI selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" ); selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" ); wideSelection = UIManager.getBoolean( "Tree.wideSelection" ); + showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" ); // scale 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, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf ) { - if( editingComponent != null && editingRow == row ) - return; - + boolean isEditing = (editingComponent != null && editingRow == row); boolean hasFocus = tree.hasFocus(); boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow()); boolean isSelected = tree.isRowSelected( row ); @@ -240,6 +241,9 @@ public class FlatTreeUI } } + if( isEditing ) + return; + // get renderer component Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree, path.getLastPathComponent(), isSelected, isExpanded, isLeaf, row, cellHasFocus ); @@ -262,10 +266,10 @@ public class FlatTreeUI 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; if( isSelected && hasFocus && - tree.getMinSelectionRow() == tree.getMaxSelectionRow() && + (!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) && rendererComponent instanceof DefaultTreeCellRenderer ) { DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent; diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 954275db..16426537 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -375,8 +375,11 @@ Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon Table.sortIconColor=@icon -Table.cellNoFocusBorder=2,3,2,3 -Table.focusSelectedCellHighlightBorder=2,3,2,3,@cellFocusColor +Table.cellMargins=2,3,2,3 +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.selectionInactiveForeground=@selectionInactiveForeground Table.dropCellBackground=@dropCellBackground