diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestTreeRenderer.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestTreeRenderer.java index fa8757dd23ed..006da0bebf9c 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestTreeRenderer.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestTreeRenderer.java @@ -15,16 +15,25 @@ */ package com.intellij.execution.testframework.sm.runner.ui; +import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.runner.SMTRunnerNodeDescriptor; import com.intellij.execution.testframework.sm.runner.SMTestProxy; +import com.intellij.execution.testframework.ui.BaseTestProxyNodeDescriptor; +import com.intellij.openapi.ui.GraphicsConfig; +import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.ExpandableItemsHandler; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.GraphicsUtil; +import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; /** * @author: Roman Chernyatchik @@ -34,6 +43,9 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer { private final TestConsoleProperties myConsoleProperties; private SMRootTestProxyFormatter myAdditionalRootFormatter; + private int myDurationWidth = 20; + private int myRow; + private Object myProperty; public TestTreeRenderer(final TestConsoleProperties consoleProperties) { myConsoleProperties = consoleProperties; @@ -46,6 +58,7 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer { final boolean leaf, final int row, final boolean hasFocus) { + myRow = row; final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; final Object userObj = node.getUserObject(); if (userObj instanceof SMTRunnerNodeDescriptor) { @@ -65,6 +78,16 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer { } else { TestsPresentationUtil.formatTestProxy(testProxy, this); } + + String durationString = testProxy.getDurationString(); + if (durationString != null) { + durationString = " [" + durationString + "]"; + myDurationWidth = tree.getFontMetrics(tree.getFont()).stringWidth(durationString); + myProperty = tree.getClientProperty(ExpandableItemsHandler.EXPANDED_RENDERER); + if (myProperty != null) { + append(durationString); + } + } //Done return; } @@ -75,6 +98,13 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer { append(text != null ? text : SPACE_STRING, SimpleTextAttributes.GRAYED_ATTRIBUTES); } + @NotNull + @Override + public Dimension getPreferredSize() { + final Dimension preferredSize = super.getPreferredSize(); + return myProperty != null ? preferredSize : JBUI.size(preferredSize.width + myDurationWidth, preferredSize.height); + } + public TestConsoleProperties getConsoleProperties() { return myConsoleProperties; } @@ -86,4 +116,44 @@ public class TestTreeRenderer extends ColoredTreeCellRenderer { public void removeAdditionalRootFormatter() { myAdditionalRootFormatter = null; } + + + @Override + protected void doPaint(Graphics2D g) { + + super.doPaint(g); + if (Registry.is("tests_view_inline_statistics") && myRow >= 0) { + Rectangle visibleRect = myTree.getVisibleRect(); + final Rectangle bounds = getBounds(); + Object node = myTree.getPathForRow(myRow).getLastPathComponent(); + if (node instanceof DefaultMutableTreeNode) { + Object data = ((DefaultMutableTreeNode)node).getUserObject(); + if (data instanceof BaseTestProxyNodeDescriptor) { + final AbstractTestProxy testProxy = ((BaseTestProxyNodeDescriptor)data).getElement(); + final String durationString = testProxy.getDurationString(); + if (durationString != null) { + final Rectangle fullRowRect = + new Rectangle(visibleRect.x, visibleRect.y + bounds.y, visibleRect.width - bounds.x, bounds.height); + paintRowData(durationString, fullRowRect, (Graphics2D)g, myTree.isRowSelected(myRow)); + } + } + } + } + } + + private void paintRowData(String duration, Rectangle bounds, Graphics2D g, boolean isSelected) { + final Rectangle clipBounds = g.getClipBounds(); + final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); + final FontMetrics metrics = myTree.getFontMetrics(myTree.getFont()); + int totalWidth = metrics.stringWidth(duration); + int x = bounds.x + bounds.width - totalWidth; + g.setClip(x, clipBounds.y, bounds.width, clipBounds.height); + g.setColor(isSelected ? UIUtil.getTreeSelectionBackground(myTree.hasFocus()) : UIUtil.getTreeBackground()); + g.fillRect(0, 0, bounds.width, clipBounds.height); + g.setColor(isSelected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeForeground()); + g.drawString(duration, x, (int)metrics.getMaxCharBounds(g).getHeight()); + config.restore(); + g.setClip(clipBounds); + } + } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java index fec954f13c5b..ace77525a893 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java @@ -21,23 +21,18 @@ package com.intellij.execution.testframework; import com.intellij.execution.Location; -import com.intellij.execution.testframework.ui.BaseTestProxyNodeDescriptor; import com.intellij.ide.CopyProvider; import com.intellij.ide.actions.CopyReferenceAction; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiElement; import com.intellij.ui.PopupHandler; import com.intellij.ui.TreeSpeedSearch; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.EditSourceOnDoubleClickHandler; import com.intellij.util.containers.Convertor; -import com.intellij.util.ui.GraphicsUtil; -import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,7 +42,6 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreePath; -import java.awt.*; import java.awt.datatransfer.StringSelection; import java.util.ArrayList; import java.util.List; @@ -176,50 +170,4 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro TreeUtil.installActions(this); PopupHandler.installPopupHandler(this, IdeActions.GROUP_TESTTREE_POPUP, ActionPlaces.TESTTREE_VIEW_POPUP); } - - @Override - public void paint(Graphics g) { - super.paint(g); - if (Registry.is("tests_view_inline_statistics")) { - Rectangle visibleRect = getVisibleRect(); - Rectangle clip = g.getClipBounds(); - for (int row = 0; row < getRowCount(); row++) { - Rectangle rowBounds = getRowBounds(row); - rowBounds.x = 0; - rowBounds.width = Integer.MAX_VALUE; - - if (rowBounds.intersects(clip)) { - Object node = getPathForRow(row).getLastPathComponent(); - if (node instanceof DefaultMutableTreeNode) { - Object data = ((DefaultMutableTreeNode)node).getUserObject(); - if (data instanceof BaseTestProxyNodeDescriptor) { - final AbstractTestProxy testProxy = ((BaseTestProxyNodeDescriptor)data).getElement(); - final String durationString = testProxy.getDurationString(); - if (durationString != null) { - final Rectangle fullRowRect = new Rectangle(visibleRect.x, rowBounds.y, visibleRect.width, rowBounds.height); - paintRowData(this, durationString, fullRowRect, (Graphics2D)g, isRowSelected(row), hasFocus()); - } - } - } - } - } - } - } - - private static void paintRowData(Tree tree, String duration, Rectangle bounds, Graphics2D g, boolean isSelected, boolean hasFocus) { - final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); - final FontMetrics metrics = tree.getFontMetrics(tree.getFont()); - g.setFont(metrics.getFont().deriveFont(Font.ITALIC, UIUtil.getFontSize(UIUtil.FontSize.MINI))); - int totalWidth = metrics.stringWidth(duration); - int x = bounds.x + bounds.width - totalWidth; - g.setColor(isSelected ? UIUtil.getTreeSelectionBackground(hasFocus) : UIUtil.getTreeBackground()); - final int leftOffset = 5; - g.fillRect(x - leftOffset, bounds.y, totalWidth + leftOffset, bounds.height); - int fontHeight = (int)metrics.getMaxCharBounds(g).getHeight(); - g.translate(0, bounds.y - 1); - g.setColor(isSelected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeForeground()); - g.drawString(duration, x, fontHeight); - g.translate(0, -bounds.y + 1); - config.restore(); - } } \ No newline at end of file