IDEA-178054: extract getRowX calculation to TreeUtil

This commit is contained in:
Sergey Malenkov
2019-03-29 19:41:17 +03:00
parent 5f84bc352f
commit 1ddc118160
5 changed files with 40 additions and 101 deletions
@@ -34,6 +34,7 @@ import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import java.util.function.Consumer;
@@ -41,6 +42,7 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static com.intellij.util.ReflectionUtil.getDeclaredMethod;
import static java.util.stream.Collectors.toList;
public final class TreeUtil {
@@ -1060,6 +1062,33 @@ public final class TreeUtil {
}
}
public static int getNodeDepth(@NotNull JTree tree, @NotNull TreePath path) {
int depth = path.getPathCount();
if (!tree.isRootVisible()) depth--;
if (!tree.getShowsRootHandles()) depth--;
return depth;
}
private static final class LazyRowX {
static final Method METHOD = getDeclaredMethod(BasicTreeUI.class, "getRowX", int.class, int.class);
}
public static int getNodeRowX(@NotNull JTree tree, int row) {
Method method = LazyRowX.METHOD;
if (method == null) return -1; // system error
TreePath path = tree.getPathForRow(row);
if (path == null) return -1; // path does not exist
int depth = getNodeDepth(tree, path);
if (depth < 0) return -1; // root is not visible
try {
return (Integer)method.invoke(tree.getUI(), row, depth);
}
catch (Exception exception) {
LOG.error(exception);
return -1; // unexpected
}
}
@NotNull
public static RelativePoint getPointForSelection(@NotNull JTree aTree) {
final int[] rows = aTree.getSelectionRows();
@@ -22,7 +22,6 @@ import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.QuickList;
import com.intellij.openapi.actionSystem.impl.ActionMenu;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.keymap.KeyMapBundle;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapUtil;
@@ -50,19 +49,17 @@ import org.jetbrains.annotations.Nullable;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import static com.intellij.util.ui.UIUtil.useSafely;
import static com.intellij.util.ui.tree.TreeUtil.getNodeRowX;
public class ActionsTree {
private static final Logger LOG = Logger.getInstance(ActionsTree.class);
private static final Icon EMPTY_ICON = EmptyIcon.ICON_18;
private static final Icon CLOSE_ICON = AllIcons.Nodes.Folder;
@@ -592,8 +589,7 @@ public class ActionsTree {
icon = link.getIcon();
setIcon(getEvenIcon(link.getIcon()));
Rectangle treeVisibleRect = tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? getRowX((BasicTreeUI)tree.getUI(), row, path.getPathCount() - 1) : 0;
int rowX = getNodeRowX(tree, row);
setupLinkDimensions(treeVisibleRect, rowX);
}
else {
@@ -814,29 +810,6 @@ public class ActionsTree {
config.restore();
}
private static Method ourGetRowXMethod = null;
private static int getRowX(BasicTreeUI ui, int row, int depth) {
if (ourGetRowXMethod == null) {
try {
ourGetRowXMethod = BasicTreeUI.class.getDeclaredMethod("getRowX", int.class, int.class);
ourGetRowXMethod.setAccessible(true);
}
catch (NoSuchMethodException e) {
LOG.error(e);
}
}
if (ourGetRowXMethod != null) {
try {
return (Integer)ourGetRowXMethod.invoke(ui, row, depth);
}
catch (Exception e) {
LOG.error(e);
}
}
return 0;
}
private static class MyColoredTreeCellRenderer extends ColoredTreeCellRenderer {
private int myHeight;
@@ -6,6 +6,7 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ui.MouseEventAdapter;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,13 +42,6 @@ public final class DefaultTreeUI extends BasicTreeUI {
return false;
}
private static int getDepth(@NotNull JTree tree, @NotNull TreePath path) {
int depth = path.getPathCount();
if (!tree.isRootVisible()) depth--;
if (!tree.getShowsRootHandles()) depth--;
return depth;
}
@NotNull
private static Control.Painter getPainter(@NotNull JTree tree) {
Object property = tree.getClientProperty(Control.Painter.class);
@@ -182,7 +176,7 @@ public final class DefaultTreeUI extends BasicTreeUI {
if (bounds == null) break;
bounds.y += insets.top;
int depth = getDepth(tree, path);
int depth = TreeUtil.getNodeDepth(tree, path);
boolean leaf = isLeaf(path.getLastPathComponent());
boolean expanded = !leaf && cache.getExpandedState(path);
boolean selected = tree.isRowSelected(row);
@@ -237,7 +231,7 @@ public final class DefaultTreeUI extends BasicTreeUI {
protected boolean isLocationInExpandControl(TreePath path, int mouseX, int mouseY) {
JTree tree = getTree();
if (tree == null || path == null || isLeaf(path.getLastPathComponent())) return false;
int depth = getDepth(tree, path);
int depth = TreeUtil.getNodeDepth(tree, path);
Control.Painter painter = getPainter(tree);
Insets insets = tree.getInsets();
if (insets != null) mouseX -= insets.left;
@@ -250,7 +244,7 @@ public final class DefaultTreeUI extends BasicTreeUI {
if (tree == null) return 0;
TreePath path = getPathForRow(tree, row);
if (path == null) return 0;
return getPainter(tree).getRendererOffset(control, getDepth(tree, path), isLeaf(path.getLastPathComponent()));
return getPainter(tree).getRendererOffset(control, TreeUtil.getNodeDepth(tree, path), isLeaf(path.getLastPathComponent()));
}
@Override
@@ -1,7 +1,6 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredTreeCellRenderer;
@@ -18,18 +17,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;
import static com.intellij.util.ui.tree.TreeUtil.getNodeRowX;
/**
* @author nik
*/
class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
private static final Logger LOG = Logger.getInstance(XDebuggerTreeRenderer.class);
private final MyColoredTreeCellRenderer myLink = new MyColoredTreeCellRenderer();
private boolean myHaveLink;
private int myLinkOffset;
@@ -57,8 +53,7 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
setIcon(node.getIcon());
Rectangle treeVisibleRect = tree.getParent() instanceof JViewport ? ((JViewport)tree.getParent()).getViewRect() : tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? getRowX((BasicTreeUI)tree.getUI(), row, path.getPathCount() - 1) : 0;
int rowX = getNodeRowX(tree, row);
if (myHaveLink) {
setupLinkDimensions(treeVisibleRect, rowX);
@@ -86,29 +81,6 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
putClientProperty(ExpandableItemsHandler.RENDERER_DISABLED, myHaveLink);
}
private static Method ourGetRowXMethod = null;
private static int getRowX(BasicTreeUI ui, int row, int depth) {
if (ourGetRowXMethod == null) {
try {
ourGetRowXMethod = BasicTreeUI.class.getDeclaredMethod("getRowX", int.class, int.class);
ourGetRowXMethod.setAccessible(true);
}
catch (NoSuchMethodException e) {
LOG.error(e);
}
}
if (ourGetRowXMethod != null) {
try {
return (Integer)ourGetRowXMethod.invoke(ui, row, depth);
}
catch (Exception e) {
LOG.error(e);
}
}
return 0;
}
private void setupLinkDimensions(Rectangle treeVisibleRect, int rowX) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;
@@ -1,7 +1,6 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.streams.ui.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredTreeCellRenderer;
@@ -19,20 +18,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;
import static com.intellij.util.ui.UIUtil.useSafely;
import static com.intellij.util.ui.tree.TreeUtil.getNodeRowX;
/**
* @author Vitaliy.Bibaev
*/
public class TraceTreeCellRenderer extends ColoredTreeCellRenderer {
private static final Logger LOG = Logger.getInstance(TraceTreeCellRenderer.class);
private final MyColoredTreeCellRenderer myLink = new MyColoredTreeCellRenderer();
private boolean myHaveLink;
private int myLinkOffset;
@@ -60,8 +55,7 @@ public class TraceTreeCellRenderer extends ColoredTreeCellRenderer {
setIcon(node.getIcon());
Rectangle treeVisibleRect = tree.getParent() instanceof JViewport ? ((JViewport)tree.getParent()).getViewRect() : tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? getRowX((BasicTreeUI)tree.getUI(), row, path.getPathCount() - 1) : 0;
int rowX = getNodeRowX(tree, row);
if (myHaveLink) {
setupLinkDimensions(treeVisibleRect, rowX);
@@ -89,29 +83,6 @@ public class TraceTreeCellRenderer extends ColoredTreeCellRenderer {
putClientProperty(ExpandableItemsHandler.RENDERER_DISABLED, myHaveLink);
}
private static Method ourGetRowXMethod = null;
private static int getRowX(BasicTreeUI ui, int row, int depth) {
if (ourGetRowXMethod == null) {
try {
ourGetRowXMethod = BasicTreeUI.class.getDeclaredMethod("getRowX", int.class, int.class);
ourGetRowXMethod.setAccessible(true);
}
catch (NoSuchMethodException e) {
LOG.error(e);
}
}
if (ourGetRowXMethod != null) {
try {
return (Integer)ourGetRowXMethod.invoke(ui, row, depth);
}
catch (Exception e) {
LOG.error(e);
}
}
return 0;
}
private void setupLinkDimensions(Rectangle treeVisibleRect, int rowX) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;