changeset 1913:0669a0162b73

Update treemap tooltip This in another patch associated with the goal of backporting profiler treemap to 1.6. This combines, in order of application, head commits: http://icedtea.classpath.org/hg/thermostat/rev/846166fd27a6?revcount=480 http://icedtea.classpath.org/hg/thermostat/rev/972bc9886f7b?revcount=480 http://icedtea.classpath.org/hg/thermostat/rev/bcd37d6d4d4f?revcount=480 PR3008 Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019306.html
author James Aziz <jaziz@redhat.com>
date Tue, 14 Jun 2016 10:11:24 -0400
parents 45ec372ef040
children ec70d5d1cb75
files client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponent.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatter.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponentTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatterTest.java common/core/src/main/java/com/redhat/thermostat/common/Size.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java
diffstat 8 files changed, 75 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponent.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponent.java	Tue Jun 14 10:11:24 2016 -0400
@@ -70,6 +70,8 @@
 import javax.swing.border.LineBorder;
 
 import com.redhat.thermostat.client.swing.ThermostatSwingCursors;
+import com.redhat.thermostat.common.Size;
+import com.redhat.thermostat.common.Size.Unit;
 
 /**
  * This class allows to represent a hierarchical data structure as a TreeMap.
@@ -169,16 +171,19 @@
      */
     private List<TreeMapObserver> observers;
 
+    private ToolTipRenderer tooltipRenderer;
+
     /**
      * Constructor. It draw a TreeMap of the given tree in according to the 
      * {@Dimension} object in input.
      * 
      * @param tree the tree to represent as TreeMap.
      * @param d the dimension the TreeMap will fulfill.
-     * 
+     *
+     * @param renderer
      * @throws NullPointerException if one of the parameters is null
      */
-    public TreeMapComponent(TreeMapNode tree, Dimension d) {
+    public TreeMapComponent(TreeMapNode tree, Dimension d, ToolTipRenderer renderer) {
         super();
         Objects.requireNonNull(tree);
         Objects.requireNonNull(d);
@@ -187,6 +192,7 @@
         this.zoomStack = new Stack<>();
         this.zoomStack.push(this.tree);
         this.observers = new ArrayList<>();
+        this.tooltipRenderer = renderer;
 
         // assign a rectangle to the tree's root in order to process the tree.
         Rectangle2D.Double area = new Rectangle2D.Double(0, 0, d.width, d.height);
@@ -196,7 +202,7 @@
 
         drawTreeMap(tree); 
 
-        addResizeListener(this);        
+        addResizeListener(this);
         repaint();
     }
 
@@ -208,6 +214,10 @@
         return this.tree;
     }
 
+    public void setToolTipRenderer(ToolTipRenderer renderer) {
+        this.tooltipRenderer = renderer;
+    }
+
     /**
      * This method is responsible for the TreeMap drawing process.
      * @param tree the tree to represent as TreeMap.
@@ -666,8 +676,7 @@
         public void setNode(TreeMapNode node) {
             this.node = node;
             this.color = node.getColor();
-            ValueFormatter f = new ValueFormatter(this.node.getRealWeight());
-            this.setToolTipText(this.node.getLabel() + " - " + f.format());
+            this.setToolTipText(TreeMapComponent.this.tooltipRenderer.render(node));
         }
         
         public TreeMapNode getNode() {
@@ -777,6 +786,25 @@
             notifySelectionToObservers(node);
         }
     }
+
+    public static interface ToolTipRenderer {
+        public String render(TreeMapNode node);
+    }
+
+    public static class SimpleRenderer implements ToolTipRenderer {
+        @Override
+        public String render(TreeMapNode node) {
+            return node.getLabel();
+        }
+    }
+
+    public static class WeightAsSizeRenderer implements ToolTipRenderer {
+        @Override
+        public String render(TreeMapNode node) {
+            Size size = new Size(node.getRealWeight(), Unit.B);
+            return node.getLabel() + " - " + size.toString("%.2f");
+        }
+    }
 }
 
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatter.java	Tue Jun 14 12:27:21 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.components.experimental;
-
-public class ValueFormatter {
-    
-    private double value;
-    
-    public ValueFormatter(double val) {
-        this.value = val;
-    }
-    
-    /**
-     * This method returns the node value calculating it in bytes, KB or MB. 
-     * 
-     * i.e. if node's weight = 200 it returns: "200 bytes" <br>
-     * if weight = 20152: "20.15 KB"  <br>
-     * if weight = 2015248: "2.01 MB"  <br>
-     * 
-     * Note that float values are approximated to the second decimal digit.
-     */
-    public String format() {
-        int KB = 1000;
-        int MB = 1000000;
-        String unit = "Bytes";
-        
-        if (value >= KB && value < MB) {
-            value /= KB;
-            unit = "KBytes";
-        } else if (value >= MB) {
-            value /= MB;
-            unit = "MBytes";
-        }
-        // show 2 decimal digits 
-        String formattedValue = String.format("%.2f", value);
-        return formattedValue + " " + unit;
-    }
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponentTest.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponentTest.java	Tue Jun 14 10:11:24 2016 -0400
@@ -80,13 +80,13 @@
                 boolean catched = false;
 
                 try {
-                    treeMap = new TreeMapComponent(tree, dim);
+                    treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
                     // pass
                  } catch(NullPointerException e) {
                     Assert.fail("Didn't expect exception.");
                  }
                 try {
-                    treeMap = new TreeMapComponent(null, null);
+                    treeMap = new TreeMapComponent(null, null, new TreeMapComponent.WeightAsSizeRenderer());
                 } catch(NullPointerException e) {
                     catched = true;
                 }
@@ -94,7 +94,7 @@
                 catched = false;
 
                 try {
-                    treeMap = new TreeMapComponent(tree, null);
+                    treeMap = new TreeMapComponent(tree, null, new TreeMapComponent.WeightAsSizeRenderer());
                 } catch(NullPointerException e) {
                     catched = true;
                 }
@@ -102,7 +102,7 @@
                 catched = false;
 
                 try {
-                    treeMap = new TreeMapComponent(null, dim);
+                    treeMap = new TreeMapComponent(null, dim, new TreeMapComponent.WeightAsSizeRenderer());
                 } catch(NullPointerException e) {
                     catched = true;
                 }
@@ -117,7 +117,7 @@
 
             @Override
             public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
                 assertEquals(tree, treeMap.getTreeMapRoot());
             }
         });
@@ -128,7 +128,7 @@
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override
             public void run() {
-                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
+                TreeMapComponent treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 assertFalse("Should not be able to zoom in on null", treeMap.isZoomInEnabled(null));
                 assertFalse("Should not be able to zoom in on root", treeMap.isZoomInEnabled(tree));
@@ -144,7 +144,7 @@
 
             @Override
             public void run() {
-                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
+                TreeMapComponent treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 treeMap.zoomIn(node1);
                 assertEquals(node1, treeMap.getTreeMapRoot());
@@ -161,7 +161,7 @@
 
             @Override
             public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 treeMap.zoomOut();
                 assertEquals(tree, treeMap.getTreeMapRoot());
@@ -183,7 +183,7 @@
 
             @Override
             public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 treeMap.zoomIn(node2);
                 treeMap.zoomFull();
@@ -199,7 +199,7 @@
 
             @Override
             public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 // the root is always in the stack
                 assertEquals(1, treeMap.getZoomCallsStack().size());
@@ -223,7 +223,7 @@
 
             @Override
             public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
 
                 treeMap.clearZoomCallsStack();
                 assertEquals(1, treeMap.getZoomCallsStack().size());
@@ -271,7 +271,7 @@
                 TreeMapNode grandchild = new TreeMapNode(1);
                 child.addChild(grandchild);
 
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
                 treeMap.register(observer);
                 
                 treeMap.zoomIn(child);
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbarTest.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbarTest.java	Tue Jun 14 10:11:24 2016 -0400
@@ -68,7 +68,7 @@
                 
                 tree = new TreeMapNode(1);
                 dim = new Dimension(500, 500);
-                treeMap = new TreeMapComponent(tree, dim);
+                treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
                 
                 boolean catched = false;
                 try {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBarTest.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBarTest.java	Tue Jun 14 10:11:24 2016 -0400
@@ -81,7 +81,7 @@
                 }
                 assertTrue(catched);
                 try {
-                    treeMap = new TreeMapComponent(tree, dim);
+                    treeMap = new TreeMapComponent(tree, dim, new TreeMapComponent.WeightAsSizeRenderer());
                     zoomBar = new TreeMapZoomBar(treeMap);
                 } catch (NullPointerException e) {
                     Assert.fail("Should not throw any exception.");
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatterTest.java	Tue Jun 14 12:27:21 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.components.experimental;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ValueFormatterTest {
-
-    private ValueFormatter formatter;
-
-    @Test
-    public final void getFormattedWeight() {
-        formatter = new ValueFormatter(2);
-        assertEquals("2.00 Bytes", formatter.format());
-
-        formatter = new ValueFormatter(2222);
-        assertEquals("2.22 KBytes", formatter.format());
-
-        formatter = new ValueFormatter(2222222);
-        assertEquals("2.22 MBytes", formatter.format());
-    }
-}
\ No newline at end of file
--- a/common/core/src/main/java/com/redhat/thermostat/common/Size.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/Size.java	Tue Jun 14 10:11:24 2016 -0400
@@ -147,28 +147,49 @@
      */
     @Override
     public String toString() {
-        String[] parts = toStringParts();
+        String[] parts = toStringParts(DOUBLE_FORMAT_STRING);
+        return translator.localize(LocaleResources.VALUE_AND_UNIT, parts[0], parts[1]).getContents();
+    }
+
+    /**
+     * Returns a simplified and human-readable version of this Size
+     *
+     * @param valueFormatString indicates how to format the value (such as {@code "%.2f"}).
+     */
+    public String toString(String valueFormatString) {
+        String[] parts = toStringParts(valueFormatString);
         return translator.localize(LocaleResources.VALUE_AND_UNIT, parts[0], parts[1]).getContents();
     }
 
     /**
      * Returns a human-readable version of this Size, appropriate for localization.
      *
-     * @return a two-element string array. The first element is the amount. The second element is the unit.
+     * @return a two-element string array. The first element is the value. The second element is the unit.
      */
     public String[] toStringParts() {
+        return toStringParts(DOUBLE_FORMAT_STRING);
+    }
+
+    /**
+     * Returns a human-readable version of this Size, appropriate for localization.
+     *
+     * @param valueFormatString indicates how to format the value (such as {@code "%.2f"}).
+     *
+     * @return a two-element string array. The first element is the value. The second element is the unit.
+     */
+    public String[] toStringParts(String valueFormatString) {
         long amountInBytes = (long) (amount * unit.getNumBytes());
         if (amountInBytes < BYTES_IN_KiB) {
             // No decimal units in plain bytes
             return new String[] { String.valueOf(amountInBytes), Unit.B.name() };
         } else if (amountInBytes < BYTES_IN_MiB) {
-            return new String[] { String.format(DOUBLE_FORMAT_STRING, (double) amountInBytes / BYTES_IN_KiB), Unit.KiB.name() };
+            return new String[] { String.format(valueFormatString, (double) amountInBytes / BYTES_IN_KiB), Unit.KiB.name() };
         } else if (amountInBytes < BYTES_IN_GiB) {
-            return new String[] { String.format(DOUBLE_FORMAT_STRING, (double) amountInBytes / BYTES_IN_MiB), Unit.MiB.name() };
+            return new String[] { String.format(valueFormatString, (double) amountInBytes / BYTES_IN_MiB), Unit.MiB.name() };
         } else if (amountInBytes < BYTES_IN_TiB) {
-            return new String[] { String.format(DOUBLE_FORMAT_STRING, (double) amountInBytes / BYTES_IN_GiB), Unit.GiB.name() };
+            return new String[] { String.format(valueFormatString, (double) amountInBytes / BYTES_IN_GiB), Unit.GiB.name() };
         } else {
-            return new String[] { String.format(DOUBLE_FORMAT_STRING, (double) amountInBytes / BYTES_IN_TiB), Unit.TiB.name() };
+            return new String[] { String.format(valueFormatString, (double) amountInBytes / BYTES_IN_TiB), Unit.TiB.name() };
         }
     }
 
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java	Tue Jun 14 12:27:21 2016 +0200
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java	Tue Jun 14 10:11:24 2016 -0400
@@ -61,7 +61,7 @@
 
     @Override
     public void display(ObjectHistogram histogram) {
-        treeMap = new TreeMapComponent(HistogramConverter.convertToTreeMap(histogram), new Dimension());
+        treeMap = new TreeMapComponent(HistogramConverter.convertToTreeMap(histogram), new Dimension(), new TreeMapComponent.WeightAsSizeRenderer());
         panel.add(treeMap, BorderLayout.CENTER);
         panel.add(new TreeMapToolbar(treeMap), BorderLayout.NORTH);
     }