-
-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wide selection in trees paints over lines #598
Comments
The implementation of the // javac -cp flatlaf-2.6.jar WideSelectionLinesTest.java
// java -cp ".;flatlaf-2.6.jar" WideSelectionLinesTest
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.ui.FlatTreeUI;
import java.awt.*;
import java.util.Enumeration;
import javax.swing.*;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public final class WideSelectionLinesTest {
private Component makeUI() {
UIManager.put("Tree.paintLines", Boolean.TRUE);
UIManager.put("Tree.repaintWholeRow", Boolean.TRUE);
UIManager.put("Tree.hash", new Color(0x0));
JTree tree = new JTree();
tree.setUI(new FlatTreeUI() {
@Override
public void paint(Graphics g, JComponent c) {
// @see javax/swing/plaf/synth/SynthTreeUI#paint(SynthContext context, Graphics g)
if (tree != c) {
throw new InternalError("incorrect component");
}
// Should never happen if installed for a UI
if(treeState == null) {
return;
}
// paintContext = context;
// updateLeadSelectionRow();
Rectangle paintBounds = g.getClipBounds();
Insets insets = tree.getInsets();
TreePath initialPath = getClosestPathForLocation(tree, 0, paintBounds.y);
Enumeration<?> paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
int row = treeState.getRowForPath(initialPath);
int endY = paintBounds.y + paintBounds.height;
TreeModel treeModel = tree.getModel();
// SynthContext cellContext = getContext(tree, Region.TREE_CELL);
drawingCache.clear();
// setHashColor(context.getStyle().getColor(context, ColorType.FOREGROUND));
if(initialPath != null && paintingEnumerator != null) {
// First pass, draw the rows
boolean done = false;
boolean isExpanded;
boolean hasBeenExpanded;
boolean isLeaf;
// Rectangle rowBounds = new Rectangle(0, 0, tree.getWidth(),0);
Rectangle bounds;
TreePath path;
// TreeCellRenderer renderer = tree.getCellRenderer();
// DefaultTreeCellRenderer dtcr = null;
// if (renderer instanceof DefaultTreeCellRenderer) {
// dtcr = (DefaultTreeCellRenderer) renderer;
// }
// configureRenderer(cellContext);
while (!done && paintingEnumerator.hasMoreElements()) {
path = (TreePath) paintingEnumerator.nextElement();
bounds = getPathBounds(tree, path);
if (path != null && bounds != null) {
isLeaf = treeModel.isLeaf(path.getLastPathComponent());
if (isLeaf) {
isExpanded = hasBeenExpanded = false;
} else {
isExpanded = treeState.getExpandedState(path);
hasBeenExpanded = tree.hasBeenExpanded(path);
}
// rowBounds.y = bounds.y;
// rowBounds.height = bounds.height;
// paintRow(renderer, dtcr, context, cellContext, g,
// paintBounds, insets, bounds, rowBounds, path,
// row, isExpanded, hasBeenExpanded, isLeaf);
paintRow(
g, paintBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
if (bounds.y + bounds.height >= endY) {
done = true;
}
} else {
done = true;
}
row++;
}
// Draw the connecting lines and controls.
// Find each parent and have them draw a line to their last child
// boolean rootVisible = tree.isRootVisible();
TreePath parentPath = initialPath;
parentPath = parentPath.getParentPath();
while (parentPath != null) {
paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
drawingCache.put(parentPath, Boolean.TRUE);
parentPath = parentPath.getParentPath();
}
done = false;
paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
while (!done && paintingEnumerator.hasMoreElements()) {
path = (TreePath) paintingEnumerator.nextElement();
bounds = getPathBounds(tree, path);
if (path != null && bounds != null) {
isLeaf = treeModel.isLeaf(path.getLastPathComponent());
if (isLeaf) {
isExpanded = hasBeenExpanded = false;
} else {
isExpanded = treeState.getExpandedState(path);
hasBeenExpanded = tree.hasBeenExpanded(path);
}
// See if the vertical line to the parent has been drawn.
parentPath = path.getParentPath();
if (parentPath != null) {
if (drawingCache.get(parentPath) == null) {
paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
drawingCache.put(parentPath, Boolean.TRUE);
}
paintHorizontalPartOfLeg(
g, paintBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
} else if (tree.isRootVisible() && row == 0) {
paintHorizontalPartOfLeg(
g, paintBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
}
if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) {
paintExpandControl(
g, paintBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
}
if (bounds.y + bounds.height >= endY) {
done = true;
}
} else {
done = true;
}
row++;
}
}
paintDropLine(g);
// Empty out the renderer pane, allowing renderers to be gc'ed.
rendererPane.removeAll();
drawingCache.clear();
}
});
JPanel p = new JPanel(new GridLayout(1, 0));
p.add(new JScrollPane(new JTree()));
p.add(new JScrollPane(tree));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
FlatLightLaf.setup();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new WideSelectionLinesTest().makeUI());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
} |
Thanks for reporting. Fixed in main branch. Removed support for dashed tree lines because this does not scale well and it looks outdated. |
When painting tree lines with wide selection enabled, the selection is painted over the lines. The lines should be painted over the selection background like the disclosure control on the "sports" node in the image below.
This is a screenshot from the FlatLaf Demo app using the following theme customizations:
The text was updated successfully, but these errors were encountered: