mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
Tree and List: fixed painting of rounded drop backgrounds (issue #1023)
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 3.7-SNAPSHOT
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- Tree and List: Fixed painting of rounded drop backgrounds. (issue #1023)
|
||||
|
||||
|
||||
## 3.6.1
|
||||
|
||||
- Extras: Support JSVG 2.0.0. Minimum JSVG version is now 1.6.0. (issue #997)
|
||||
|
||||
@@ -302,6 +302,7 @@ public class FlatListUI
|
||||
ListModel dataModel, ListSelectionModel selModel, int leadIndex )
|
||||
{
|
||||
boolean isSelected = selModel.isSelectedIndex( row );
|
||||
boolean isDropRow = isDropRow( row );
|
||||
|
||||
// paint alternating rows
|
||||
if( alternateRowColor != null && row % 2 != 0 &&
|
||||
@@ -335,7 +336,7 @@ public class FlatListUI
|
||||
}
|
||||
|
||||
// rounded selection or selection insets
|
||||
if( isSelected &&
|
||||
if( (isSelected || isDropRow) &&
|
||||
!isFileList && // rounded selection is not supported for file list
|
||||
(rendererComponent instanceof DefaultListCellRenderer ||
|
||||
rendererComponent instanceof BasicComboBoxRenderer) &&
|
||||
@@ -376,7 +377,22 @@ public class FlatListUI
|
||||
this.getColor() == rendererComponent.getBackground() )
|
||||
{
|
||||
inPaintSelection = true;
|
||||
paintCellSelection( this, row, x, y, width, height );
|
||||
if( isDropRow ) {
|
||||
// for rounded drop background, it is necessary to first
|
||||
// paint selection background because may be not rounded on some corners
|
||||
if( isSelected ) {
|
||||
Color oldColor = getColor();
|
||||
setColor( list.getSelectionBackground() );
|
||||
paintCellSelection( this, row, x, y, width, height );
|
||||
setColor( oldColor );
|
||||
}
|
||||
|
||||
// paint drop background
|
||||
float arc = UIScale.scale( selectionArc / 2f );
|
||||
FlatUIUtils.paintSelection( this, x, y, width, height,
|
||||
UIScale.scale( selectionInsets ), arc, arc, arc, arc, 0 );
|
||||
} else
|
||||
paintCellSelection( this, row, x, y, width, height );
|
||||
inPaintSelection = false;
|
||||
} else
|
||||
super.fillRect( x, y, width, height );
|
||||
@@ -475,4 +491,15 @@ public class FlatListUI
|
||||
FlatListUI ui = (FlatListUI) list.getUI();
|
||||
ui.paintCellSelection( g, row, x, y, width, height );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether dropping on a row.
|
||||
* See DefaultListCellRenderer.getListCellRendererComponent().
|
||||
*/
|
||||
private boolean isDropRow( int row ) {
|
||||
JList.DropLocation dropLocation = list.getDropLocation();
|
||||
return dropLocation != null &&
|
||||
!dropLocation.isInsert() &&
|
||||
dropLocation.getIndex() == row;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +577,6 @@ public class FlatTreeUI
|
||||
boolean isEditing = (editingComponent != null && editingRow == row);
|
||||
boolean isSelected = tree.isRowSelected( row );
|
||||
boolean isDropRow = isDropRow( row );
|
||||
boolean needsSelectionPainting = (isSelected || isDropRow) && isPaintSelection();
|
||||
|
||||
// paint alternating rows
|
||||
if( alternateRowColor != null && row % 2 != 0 ) {
|
||||
@@ -608,7 +607,7 @@ public class FlatTreeUI
|
||||
if( isSelected && isWideSelection() ) {
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( selectionInactiveBackground );
|
||||
paintWideSelection( g, bounds, row );
|
||||
paintWideSelection( g, bounds, row, false );
|
||||
g.setColor( oldColor );
|
||||
}
|
||||
return;
|
||||
@@ -628,7 +627,7 @@ public class FlatTreeUI
|
||||
|
||||
// renderer background/foreground
|
||||
Color oldBackgroundSelectionColor = null;
|
||||
if( isSelected && !hasFocus && !isDropRow ) {
|
||||
if( isSelected && !hasFocus ) {
|
||||
// apply inactive selection background/foreground if tree is not focused
|
||||
oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionInactiveBackground );
|
||||
setRendererForeground( rendererComponent, selectionInactiveForeground );
|
||||
@@ -655,26 +654,12 @@ public class FlatTreeUI
|
||||
}
|
||||
|
||||
// paint selection background
|
||||
if( needsSelectionPainting ) {
|
||||
// set selection color
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( isDropRow
|
||||
? UIManager.getColor( "Tree.dropCellBackground" )
|
||||
: (rendererComponent instanceof DefaultTreeCellRenderer
|
||||
? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
|
||||
: (hasFocus ? selectionBackground : selectionInactiveBackground)) );
|
||||
if( isSelected && isPaintSelection() ) {
|
||||
Color selectionColor = rendererComponent instanceof DefaultTreeCellRenderer
|
||||
? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
|
||||
: (hasFocus ? selectionBackground : selectionInactiveBackground);
|
||||
|
||||
if( isWideSelection() ) {
|
||||
// wide selection
|
||||
paintWideSelection( g, bounds, row );
|
||||
} else {
|
||||
// non-wide selection
|
||||
paintCellBackground( g, rendererComponent, bounds, row, true );
|
||||
}
|
||||
|
||||
// this is actually not necessary because renderer should always set color
|
||||
// before painting, but doing anyway to avoid any side effect (in bad renderers)
|
||||
g.setColor( oldColor );
|
||||
paintRowSelection( g, selectionColor, rendererComponent, bounds, row, hasFocus, false );
|
||||
} else {
|
||||
// paint cell background if DefaultTreeCellRenderer.getBackgroundNonSelectionColor() is set
|
||||
if( rendererComponent instanceof DefaultTreeCellRenderer ) {
|
||||
@@ -683,12 +668,19 @@ public class FlatTreeUI
|
||||
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( bg );
|
||||
paintCellBackground( g, rendererComponent, bounds, row, false );
|
||||
paintCellBackground( g, rendererComponent, bounds, row, false, false );
|
||||
g.setColor( oldColor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// paint drop background
|
||||
// (this needs to be an extra step for rounded selection)
|
||||
if( isDropRow && isPaintSelection() ) {
|
||||
paintRowSelection( g, UIManager.getColor( "Tree.dropCellBackground" ),
|
||||
rendererComponent, bounds, row, hasFocus, true );
|
||||
}
|
||||
|
||||
// paint renderer
|
||||
rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
|
||||
|
||||
@@ -699,6 +691,26 @@ public class FlatTreeUI
|
||||
((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
|
||||
}
|
||||
|
||||
private void paintRowSelection( Graphics g, Color color, Component rendererComponent,
|
||||
Rectangle bounds, int row, boolean hasFocus, boolean paintDropSelection )
|
||||
{
|
||||
// set selection color
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( color );
|
||||
|
||||
if( isWideSelection() ) {
|
||||
// wide selection
|
||||
paintWideSelection( g, bounds, row, paintDropSelection );
|
||||
} else {
|
||||
// non-wide selection
|
||||
paintCellBackground( g, rendererComponent, bounds, row, true, paintDropSelection );
|
||||
}
|
||||
|
||||
// this is actually not necessary because renderer should always set color
|
||||
// before painting, but doing anyway to avoid any side effect (in bad renderers)
|
||||
g.setColor( oldColor );
|
||||
}
|
||||
|
||||
private Color setRendererBackgroundSelectionColor( Component rendererComponent, Color color ) {
|
||||
Color oldColor = null;
|
||||
|
||||
@@ -735,11 +747,11 @@ public class FlatTreeUI
|
||||
return oldColor;
|
||||
}
|
||||
|
||||
private void paintWideSelection( Graphics g, Rectangle bounds, int row ) {
|
||||
private void paintWideSelection( Graphics g, Rectangle bounds, int row, boolean paintDropSelection ) {
|
||||
float arcTop, arcBottom;
|
||||
arcTop = arcBottom = UIScale.scale( selectionArc / 2f );
|
||||
|
||||
if( useUnitedRoundedSelection() ) {
|
||||
if( useUnitedRoundedSelection() && !paintDropSelection ) {
|
||||
if( row > 0 && tree.isRowSelected( row - 1 ) )
|
||||
arcTop = 0;
|
||||
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
|
||||
@@ -751,7 +763,7 @@ public class FlatTreeUI
|
||||
}
|
||||
|
||||
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds,
|
||||
int row, boolean paintSelection )
|
||||
int row, boolean paintSelection, boolean paintDropSelection )
|
||||
{
|
||||
int xOffset = 0;
|
||||
int imageOffset = 0;
|
||||
@@ -769,7 +781,7 @@ public class FlatTreeUI
|
||||
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
|
||||
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
|
||||
|
||||
if( useUnitedRoundedSelection() ) {
|
||||
if( useUnitedRoundedSelection() && !paintDropSelection ) {
|
||||
if( row > 0 && tree.isRowSelected( row - 1 ) ) {
|
||||
Rectangle r = getPathBounds( tree, tree.getPathForRow( row - 1 ) );
|
||||
arcTopLeft = Math.min( arcTopLeft, r.x - bounds.x );
|
||||
|
||||
@@ -162,6 +162,11 @@ public class FlatComponents2Test
|
||||
|
||||
for( JTree tree : allTrees )
|
||||
expandTree( tree );
|
||||
|
||||
// drop mode
|
||||
dropModeComboBox.init( DropMode.class, false );
|
||||
dropModeComboBox.setSelectedItem( DropMode.ON_OR_INSERT );
|
||||
dropModeChanged();
|
||||
}
|
||||
|
||||
private void initTableEditors( JTable table ) {
|
||||
@@ -311,13 +316,6 @@ public class FlatComponents2Test
|
||||
xTable1.setDragEnabled( dnd );
|
||||
xTreeTable1.setDragEnabled( dnd );
|
||||
|
||||
DropMode dropMode = dnd ? DropMode.ON_OR_INSERT : DropMode.USE_SELECTION;
|
||||
list1.setDropMode( dropMode );
|
||||
tree1.setDropMode( dropMode );
|
||||
table1.setDropMode( dropMode );
|
||||
xTable1.setDropMode( dropMode );
|
||||
xTreeTable1.setDropMode( dropMode );
|
||||
|
||||
String key = "FlatLaf.oldTransferHandler";
|
||||
if( dnd ) {
|
||||
list1.putClientProperty( key, list1.getTransferHandler() );
|
||||
@@ -341,6 +339,32 @@ public class FlatComponents2Test
|
||||
}
|
||||
}
|
||||
|
||||
private void dropModeChanged() {
|
||||
DropMode dropMode = dropModeComboBox.getSelectedValue();
|
||||
DropMode dropMode2;
|
||||
switch( dropMode ) {
|
||||
case INSERT_ROWS:
|
||||
case INSERT_COLS:
|
||||
dropMode2 = DropMode.INSERT;
|
||||
break;
|
||||
|
||||
case ON_OR_INSERT_ROWS:
|
||||
case ON_OR_INSERT_COLS:
|
||||
dropMode2 = DropMode.ON_OR_INSERT;
|
||||
break;
|
||||
|
||||
default:
|
||||
dropMode2 = dropMode;
|
||||
break;
|
||||
}
|
||||
|
||||
list1.setDropMode( dropMode2 );
|
||||
tree1.setDropMode( dropMode2 );
|
||||
table1.setDropMode( dropMode );
|
||||
xTable1.setDropMode( dropMode );
|
||||
xTreeTable1.setDropMode( dropMode );
|
||||
}
|
||||
|
||||
private void tableHeaderButtonChanged() {
|
||||
tableHeaderButtonChanged( table1ScrollPane );
|
||||
tableHeaderButtonChanged( xTable1ScrollPane );
|
||||
@@ -618,6 +642,7 @@ public class FlatComponents2Test
|
||||
super.updateUI();
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
dropModeChanged();
|
||||
showHorizontalLinesChanged();
|
||||
showVerticalLinesChanged();
|
||||
intercellSpacingChanged();
|
||||
@@ -673,6 +698,7 @@ public class FlatComponents2Test
|
||||
leftSelectionInsetsCheckBox = new JCheckBox();
|
||||
rightSelectionInsetsCheckBox = new JCheckBox();
|
||||
dndCheckBox = new JCheckBox();
|
||||
dropModeComboBox = new FlatTestEnumComboBox<>();
|
||||
listOptionsPanel = new JPanel();
|
||||
JLabel listRendererLabel = new JLabel();
|
||||
listRendererComboBox = new JComboBox<>();
|
||||
@@ -963,6 +989,7 @@ public class FlatComponents2Test
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]rel" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- roundedSelectionCheckBox ----
|
||||
@@ -1004,6 +1031,10 @@ public class FlatComponents2Test
|
||||
dndCheckBox.setMnemonic('D');
|
||||
dndCheckBox.addActionListener(e -> dndChanged());
|
||||
generalOptionsPanel.add(dndCheckBox, "cell 0 4");
|
||||
|
||||
//---- dropModeComboBox ----
|
||||
dropModeComboBox.addActionListener(e -> dropModeChanged());
|
||||
generalOptionsPanel.add(dropModeComboBox, "cell 0 5");
|
||||
}
|
||||
add(generalOptionsPanel, "cell 0 4 4 1");
|
||||
|
||||
@@ -1272,6 +1303,7 @@ public class FlatComponents2Test
|
||||
private JCheckBox leftSelectionInsetsCheckBox;
|
||||
private JCheckBox rightSelectionInsetsCheckBox;
|
||||
private JCheckBox dndCheckBox;
|
||||
private FlatTestEnumComboBox<DropMode> dropModeComboBox;
|
||||
private JPanel listOptionsPanel;
|
||||
private JComboBox<String> listRendererComboBox;
|
||||
private JComboBox<String> listLayoutOrientationField;
|
||||
|
||||
@@ -299,7 +299,7 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets 8,hidemode 3"
|
||||
"$columnConstraints": "[left]"
|
||||
"$rowConstraints": "[][]0[]0[]rel[]"
|
||||
"$rowConstraints": "[][]0[]0[]rel[][]"
|
||||
} ) {
|
||||
name: "generalOptionsPanel"
|
||||
"border": new javax.swing.border.TitledBorder( "General Control" )
|
||||
@@ -379,6 +379,16 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4"
|
||||
} )
|
||||
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumComboBox" ) {
|
||||
name: "dropModeComboBox"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
"JavaCodeGenerator.typeParameters": "DropMode"
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dropModeChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 5"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4 4 1"
|
||||
} )
|
||||
|
||||
Reference in New Issue
Block a user