Fill the selected tree row across its whole width

The cell renderer paints the selection only behind the label, which now
looks short next to the full-width hover outline and the full-line hit
area. The tree fills the selected rows itself, in the renderer's own
selection colour so the two meet seamlessly, which means it can no
longer clear its background as an opaque component would.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 19:16:06 +00:00
parent 9ba0982f25
commit fa99cadc44

View File

@@ -71,6 +71,9 @@ final class DropIndicatorTree extends JTree {
addMouseMotionListener(hover); addMouseMotionListener(hover);
addMouseListener(hover); addMouseListener(hover);
addMouseWheelListener(hover); addMouseWheelListener(hover);
// The selected row is filled across the full width below, before the rows
// themselves are drawn, so this component must not clear its own background.
setOpaque(false);
} }
/** /**
@@ -129,6 +132,10 @@ final class DropIndicatorTree extends JTree {
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
Rectangle clip = g.getClipBounds();
g.setColor(getBackground());
g.fillRect(clip.x, clip.y, clip.width, clip.height);
paintSelection(g);
super.paintComponent(g); super.paintComponent(g);
paintBadges(g); paintBadges(g);
paintHover(g); paintHover(g);
@@ -154,6 +161,22 @@ final class DropIndicatorTree extends JTree {
g2.dispose(); g2.dispose();
} }
/**
* Fills the selected row across the full width, in the colour the cell renderer
* puts behind the label itself, so the selection covers the whole line rather
* than stopping where the name ends.
*/
private void paintSelection(Graphics g) {
int[] rows = getSelectionRows();
if (rows == null) return;
Rectangle visible = getVisibleRect();
g.setColor(Theme.TREE_SELECTION);
for (int row : rows) {
Rectangle bounds = getRowBounds(row);
if (bounds != null) g.fillRect(visible.x, bounds.y, visible.width, bounds.height);
}
}
/** /**
* Outlines the row under the pointer, across the full width the row occupies — * Outlines the row under the pointer, across the full width the row occupies —
* the same area a click on it acts on. Spacers, which nothing can be done with, * the same area a click on it acts on. Spacers, which nothing can be done with,