# HG changeset patch # User Mario Torre # Date 1370456804 -7200 # Node ID 9917555955a0f3ec4e568ff2a21efab8b3b37063 # Parent bb4bde056ead8a8c9a2aa215d8dbd25651a5ad40 Heap Dumper refactoring reviewed-by: vanaltj review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-June/006924.html diff -r bb4bde056ead -r 9917555955a0 client/core/src/main/java/com/redhat/thermostat/client/ui/Palette.java --- a/client/core/src/main/java/com/redhat/thermostat/client/ui/Palette.java Mon Jun 03 11:03:06 2013 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/Palette.java Wed Jun 05 20:26:44 2013 +0200 @@ -74,6 +74,10 @@ BLACK(Color.BLACK), WHITE(Color.WHITE), + DARK_BLUE(new Color(0x030A0C)), + ROYAL_BLUE(new Color(0x0A242D)), + ELEGANT_CYAN(new Color(0x39CAFF)), + /* END */ ; private Color color; diff -r bb4bde056ead -r 9917555955a0 client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GaussianBlur.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GaussianBlur.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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; + +import java.awt.image.BufferedImage; +import java.awt.image.ConvolveOp; +import java.awt.image.Kernel; + +/** + * Apply Gaussian Blur on images. + * + *

+ * + * The formula for Gaussian blur is: + * + *
+ * 
+ * G(x, y) = ({@link Math#E} ^ (-(x^2 + y^2) / (2 * SIGMA^2))) / sqrt(2 * {@link Math#PI} * SIGMA^2))
+ * 
+ * 
+ * + * Where {@code SIGMA} is the standard deviation, {@code x} and {@code y} + * represent the distance from the horizontal and vertical axis respectively. + * + * In this implementation {@code SIGMA} is always 1/3 of the radius of the + * applied filter. + * + *

+ * + * Since the Gaussian filter is separable, meaning that can be applied to a + * two-dimensional image as two independent one-dimensional calculations, + * so this filter will first create a {@link Kernel} for the horizontal + * direction and then a second {@link Kernel} for the vertical one. + */ +public class GaussianBlur { + + static ConvolveOp[] createFilters(int radius) { + ConvolveOp[] filters = new ConvolveOp[2]; + + double sigma = radius / 3.0; + double sigmaSquareDivisor = 2.0 * Math.pow(sigma, 2); + + double sqrtDivisor = Math.sqrt(sigmaSquareDivisor * Math.PI); + + float total = 0f; + float [] matrix = new float[radius * 2]; + for (int i = -radius; i < radius; i++) { + + double distance = -(i * i); + double midpoint = Math.exp(distance / sigmaSquareDivisor) / sqrtDivisor; + + matrix[i + radius] = (float) midpoint; + + // keep this to normalise the matrix to avoid a darkening or + // brightening of the image + total += (float) midpoint; + } + + // normalise the matrix now + for (int i = 0; i < matrix.length; i++) { + matrix[i] /= total; + } + + Kernel horizontalKernel = new Kernel(matrix.length, 1, matrix); + Kernel verticalKernel = new Kernel(1, matrix.length, matrix); + + filters[0] = new ConvolveOp(horizontalKernel, ConvolveOp.EDGE_NO_OP, null); + filters[1] = new ConvolveOp(verticalKernel, ConvolveOp.EDGE_NO_OP, null); + + return filters; + } + + public static BufferedImage applyFilter(int radius, BufferedImage src) { + ConvolveOp[] filters = GaussianBlur.createFilters(radius); + + src = filters[0].filter(src, null); + src = filters[1].filter(src, null); + + return src; + } +} diff -r bb4bde056ead -r 9917555955a0 client/swing/src/main/java/com/redhat/thermostat/client/swing/components/OverlayPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/OverlayPanel.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,298 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.KeyAdapter; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseMotionAdapter; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.image.BufferedImage; + +import javax.swing.JPanel; + +import com.redhat.thermostat.client.swing.GraphicsUtils; +import com.redhat.thermostat.client.ui.Palette; + +/** + * A panel meant to be stacked on top of existing components to display + * informations in an floating overlay. + * + *

+ * + * Note: By default, the panel is invisible even when the + * component it belongs sets all its children to be visible. + * For this reason, the {@link #setVisible(boolean)} + * method is a no-op when setting the panel visible and the user should + * only use {@link #setOverlayVisible(boolean)} to turn on and off the + * visibility of this panel. + */ +@SuppressWarnings("serial") +public class OverlayPanel extends JPanel { + + private JPanel content; + private JPanel titlePane; + + private ShadowLabel overlayTitle; + + private boolean displayArrow; + + /** + * Creates a new {@link OverlayPanel}, with an arrow facing upward. + */ + public OverlayPanel(String title) { + this(title, true); + } + + /** + * Creates a new {@link OverlayPanel}. The panel will display an up facing + * arrow if {@code displayArrow} is {@code true}. + */ + public OverlayPanel(String title, boolean displayArrow) { + + this.displayArrow = displayArrow; + + setOpaque(false); + setBorder(new OverlayBorder()); + setLayout(new BorderLayout(0, 10)); + + titlePane = new JPanel(); + titlePane.setOpaque(true); + + overlayTitle = new ShadowLabel(title); + + titlePane.setBorder(new TitleBorder()); + titlePane.setBackground(Palette.ROYAL_BLUE.getColor()); + overlayTitle.setForeground(Palette.WHITE.getColor()); + + titlePane.add(overlayTitle); + + content = new JPanel(); + content.setOpaque(false); + + super.add(titlePane, BorderLayout.NORTH); + super.add(content, BorderLayout.CENTER); + + // a bit more useful layout than the default + content.setLayout(new BorderLayout()); + + setOverlayVisible(false); + + // filter events, we don't want them to reach components below us + addMouseListener(new MouseAdapter() {}); + addMouseMotionListener(new MouseMotionAdapter() {}); + addKeyListener(new KeyAdapter() {}); + setFocusTraversalKeysEnabled(false); + } + + @Override + public Component add(Component comp) { + return content.add(comp); + } + + @Override + public void remove(Component comp) { + content.remove(comp); + } + + @Override + public void removeAll() { + content.removeAll(); + } + + @Override + protected void paintComponent(Graphics g) { + + GraphicsUtils utils = GraphicsUtils.getInstance(); + + Graphics2D graphics = utils.createAAGraphics(g); + graphics.setColor(utils.deriveWithAlpha(Palette.PALE_GRAY.getColor(), 200)); + + Rectangle clip = graphics.getClipBounds(); + Insets borderInsets = getBorder().getBorderInsets(this); + + clip.height = clip.height - borderInsets.bottom - borderInsets.top; + clip.width = clip.width - borderInsets.left - borderInsets.right; + + graphics.translate(borderInsets.left, borderInsets.top); + graphics.fillRect(clip.x, clip.y, clip.width, clip.height); + + graphics.dispose(); + } + + /** + * No-op when setting the panel visible. + * Please, use {@link #setOverlayVisible(boolean)} instead. + * + * @see #setOverlayVisible(boolean) + */ + @Override + public void setVisible(boolean visible) { + // no-op otherwise + if (!visible) { + setOverlayVisible(visible); + } + } + + /** + * Sets the visibility of this panel. + */ + public void setOverlayVisible(boolean visible) { + super.setVisible(visible); + } + + /** + * Paints the border of the TitlePane + */ + private class TitleBorder extends DebugBorder { + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(overlayTitle.getForeground()); + g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); + } + + @Override + public Insets getBorderInsets(Component c, Insets insets) { + + insets.top = 2; + insets.left = 2; + insets.right = 2; + insets.bottom = 2; + + return insets; + } + } + + /** + * Paints the drop shadow around the overlay. + */ + private class OverlayBorder extends DebugBorder { + + private BufferedImage buffer; + + private static final boolean DEBUG = false; + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + if (DEBUG) { + super.paintBorder(c, g, x, y, width, height); + return; + } + + if (buffer != null && buffer.getWidth() == getWidth() && buffer.getHeight() == getHeight()) { + g.drawImage(buffer, 0, 0, null); + return; + } + + GraphicsUtils utils = GraphicsUtils.getInstance(); + + buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics bufferGraphics = buffer.getGraphics(); + Graphics2D graphics = utils.createAAGraphics(bufferGraphics); + bufferGraphics.dispose(); + + Insets insets = getBorderInsets(c); + + Area clip = new Area(new Rectangle(x, y, width, height)); + BufferedImage dropShadow = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + + x = x + insets.left; + y = y + insets.top; + + width = width - insets.right - insets.left; + height = height - insets.top - insets.bottom; + + Area inside = new Area(new Rectangle(x, y, width, height)); + clip.subtract(inside); + graphics.setClip(clip); + + Graphics2D dropShadowGraphics = dropShadow.createGraphics(); + dropShadowGraphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + dropShadowGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + dropShadowGraphics.setColor(utils.deriveWithAlpha(Palette.BLACK.getColor(), 100)); + dropShadowGraphics.fillRoundRect(x - 5, y + 5, width + 10, height + 5, 15, 15); + dropShadowGraphics.dispose(); + + dropShadow = GaussianBlur.applyFilter(20, dropShadow); + + graphics.drawImage(dropShadow, 0, 0, null); + + if (displayArrow) { + int x1Points[] = {0, 4, 4, 8}; + int y1Points[] = {4, 0, 0, 4}; + + GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x1Points.length); + + polyline.moveTo(x1Points[0], y1Points[0]); + for (int index = 1; index < x1Points.length; index++) { + polyline.lineTo(x1Points[index], y1Points[index]); + }; + polyline.closePath(); + + graphics.setColor(Palette.BLACK.getColor()); + x += (width / 2) - 4; + y -= 4; + graphics.translate(x, y); + graphics.fill(polyline); + } + + graphics.dispose(); + + g.drawImage(buffer, 0, 0, null); + } + + @Override + public Insets getBorderInsets(Component c, Insets insets) { + + insets.top = 30; + insets.left = 50; + insets.right = 50; + insets.bottom = 50; + + return insets; + } + } +} diff -r bb4bde056ead -r 9917555955a0 client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java Mon Jun 03 11:03:06 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java Wed Jun 05 20:26:44 2013 +0200 @@ -67,7 +67,7 @@ protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { GraphicsUtils graphicsUtils = GraphicsUtils.getInstance(); Graphics2D graphics = graphicsUtils.createAAGraphics(g); - graphicsUtils.drawStringWithShadow(l, graphics, s, getForeground(), textX, textY); + graphicsUtils.drawStringWithShadow(l, graphics, s, ShadowLabel.this.getForeground(), textX, textY); } } } diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpListView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpListView.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.core; + +import java.util.List; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.core.views.UIComponent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ActionNotifier; +import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; + +/** + * + */ +public abstract class HeapDumpListView extends BasicView implements UIComponent { + public enum ListAction { + DUMP_SELECTED, + } + + protected final ActionNotifier listNotifier; + protected HeapDumpListView() { + listNotifier = new ActionNotifier(this); + } + + public void addListListener(ActionListener listener) { + listNotifier.addActionListener(listener); + } + + public void removeListListener(ActionListener listener) { + listNotifier.removeActionListener(listener); + } + + public abstract void setDumps(List dumps); +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpListViewProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpListViewProvider.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.core; + +import com.redhat.thermostat.annotations.ExtensionPoint; +import com.redhat.thermostat.client.core.views.ViewProvider; + +@ExtensionPoint +public interface HeapDumpListViewProvider extends ViewProvider { + + @Override + public HeapDumpListView createView(); +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java Wed Jun 05 20:26:44 2013 +0200 @@ -47,6 +47,7 @@ public class HeapIconResources { public static final String PIN_MASK = "com/redhat/thermostat/vm/heap/analysis/client/core/pin_mask.png"; + public static final String LIST_DUMPS = "com/redhat/thermostat/vm/heap/analysis/client/core/list_dumps.png"; private static Map icons = new HashMap<>(); diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java Wed Jun 05 20:26:44 2013 +0200 @@ -52,6 +52,7 @@ DUMP_REQUESTED, ANALYSE, REQUEST_ABORTED, + REQUEST_DISPLAY_DUMP_LIST, } public enum DumpDisabledReason { @@ -90,5 +91,6 @@ public abstract void displayWarning(LocalizedString string); + public abstract void openDumpListView(HeapDumpListView childView); } diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java Wed Jun 05 20:26:44 2013 +0200 @@ -53,6 +53,7 @@ import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumperService; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapViewProvider; @@ -77,7 +78,8 @@ HeapDumpDetailsViewProvider.class, HeapHistogramViewProvider.class, ObjectDetailsViewProvider.class, - ObjectRootsViewProvider.class + ObjectRootsViewProvider.class, + HeapDumpListViewProvider.class, }; tracker = new MultipleServiceTracker(context, deps, new Action() { @@ -106,10 +108,14 @@ .get(ObjectRootsViewProvider.class.getName()); Objects.requireNonNull(objectRootsViewProvider); + HeapDumpListViewProvider heapDumpListViewProvider = (HeapDumpListViewProvider) services + .get(HeapDumpListViewProvider.class.getName()); + HeapDumperService service = new HeapDumperServiceImpl(appSvc, vmInfoDao, vmMemoryStatDao, heapDao, viewProvider, detailsViewProvider, histogramViewProvider, - objectDetailsViewProvider, objectRootsViewProvider); + objectDetailsViewProvider, objectRootsViewProvider, + heapDumpListViewProvider); Dictionary properties = new Hashtable<>(); properties.put(Constants.GENERIC_SERVICE_CLASSNAME, VmRef.class.getName()); properties.put(InformationService.KEY_SERVICE_ID, HeapDumperService.SERVICE_ID); diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Wed Jun 05 20:26:44 2013 +0200 @@ -57,6 +57,7 @@ import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView.DumpDisabledReason; @@ -92,7 +93,7 @@ private HeapHistogramViewProvider histogramViewProvider; private ObjectDetailsViewProvider objectDetailsViewProvider; private ObjectRootsViewProvider objectRootsViewProvider; - + private HeapDumpListViewProvider heapDumpListViewProvider; public HeapDumpController(final VmMemoryStatDAO vmMemoryStatDao, final VmInfoDAO vmInfoDao, @@ -101,11 +102,12 @@ HeapDumpDetailsViewProvider detailsViewProvider, HeapHistogramViewProvider histogramProvider, ObjectDetailsViewProvider objectDetailsProvider, - ObjectRootsViewProvider objectRootsProvider) + ObjectRootsViewProvider objectRootsProvider, + HeapDumpListViewProvider heapDumpListViewProvider) { this(vmMemoryStatDao, vmInfoDao, heapDao, ref, appService, viewProvider, detailsViewProvider, histogramProvider, objectDetailsProvider, - objectRootsProvider, new HeapDumper(ref)); + objectRootsProvider, heapDumpListViewProvider, new HeapDumper(ref)); } HeapDumpController(final VmMemoryStatDAO vmMemoryStatDao, @@ -117,6 +119,7 @@ HeapHistogramViewProvider histogramProvider, ObjectDetailsViewProvider objectDetailsProvider, ObjectRootsViewProvider objectRootsProvider, + HeapDumpListViewProvider heapDumpListViewProvider, final HeapDumper heapDumper) { this.objectDetailsViewProvider = objectDetailsProvider; @@ -127,6 +130,7 @@ this.ref = ref; this.vmDao = vmMemoryStatDao; this.heapDAO = heapDao; + this.heapDumpListViewProvider = heapDumpListViewProvider; model = new OverviewChart( null, @@ -188,6 +192,11 @@ view.disableHeapDumping(DumpDisabledReason.DUMP_IN_PROGRESS); requestDump(heapDumper); break; + + case REQUEST_DISPLAY_DUMP_LIST: + openDumpList(); + break; + case ANALYSE: dump = (HeapDump) actionEvent.getPayload(); analyseDump(dump); @@ -204,6 +213,21 @@ } } + private void openDumpList() { + + appService.getApplicationExecutor().execute(new Runnable() { + @Override + public void run() { + List dumps = getHeapDumps(); + HeapDumpListController controller = + new HeapDumpListController(heapDumpListViewProvider, + HeapDumpController.this); + controller.setDumps(dumps); + view.openDumpListView(controller.getView()); + } + }); + } + private void requestDump(final HeapDumper heapDumper) { appService.getApplicationExecutor().execute(new Runnable() { @@ -220,9 +244,8 @@ }); } - private void analyseDump(final HeapDump dump) { + void analyseDump(final HeapDump dump) { appService.getApplicationExecutor().execute(new Runnable() { - @Override public void run() { showHeapDumpDetails(dump); @@ -253,6 +276,15 @@ return translator.localize(LocaleResources.HEAP_SECTION_TITLE); } + private List getHeapDumps() { + Collection heapInfos = heapDAO.getAllHeapInfo(ref); + List heapDumps = new ArrayList(heapInfos.size()); + for (HeapInfo heapInfo : heapInfos) { + heapDumps.add(new HeapDump(heapInfo, heapDAO)); + } + return heapDumps; + } + class HeapOverviewDataCollector implements Runnable { private long desiredUpdateTimeStamp = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1); @@ -264,12 +296,7 @@ } private void checkForHeapDumps() { - Collection heapInfos = heapDAO.getAllHeapInfo(ref); - List heapDumps = new ArrayList(heapInfos.size()); - for (HeapInfo heapInfo : heapInfos) { - heapDumps.add(new HeapDump(heapInfo, heapDAO)); - } - view.updateHeapDumpList(heapDumps); + view.updateHeapDumpList(getHeapDumps()); } private void updateMemoryChartAndDisplay() { diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpListController.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpListController.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.core.internal; + +import java.util.List; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView.ListAction; +import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; + +public class HeapDumpListController { + + private HeapDumpListView view; + + public HeapDumpListController(HeapDumpListViewProvider viewProvider, final HeapDumpController mainController) { + view = viewProvider.createView(); + view.addListListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + mainController.analyseDump((HeapDump) actionEvent.getPayload()); + } + }); + } + + public HeapDumpListView getView() { + return view; + } + + public void setDumps(List dumps) { + view.setDumps(dumps); + } +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumperServiceImpl.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumperServiceImpl.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumperServiceImpl.java Wed Jun 05 20:26:44 2013 +0200 @@ -43,6 +43,7 @@ import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumperService; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapViewProvider; @@ -67,13 +68,16 @@ private ObjectDetailsViewProvider objectDetailsViewProvider; private ObjectRootsViewProvider objectRootsViewProvider; + private HeapDumpListViewProvider heapDumpListViewProvider; + public HeapDumperServiceImpl(ApplicationService appService, VmInfoDAO vmInfoDao, VmMemoryStatDAO vmMemoryStatDao, HeapDAO heapDao, HeapViewProvider viewProvider, HeapDumpDetailsViewProvider detailsViewProvider, HeapHistogramViewProvider histogramViewProvider, ObjectDetailsViewProvider objectDetailsViewProvider, - ObjectRootsViewProvider objectRootsViewProvider) { + ObjectRootsViewProvider objectRootsViewProvider, + HeapDumpListViewProvider heapDumpListViewProvider) { this.vmInfoDao = vmInfoDao; this.vmMemoryStatDao = vmMemoryStatDao; this.heapDao = heapDao; @@ -83,12 +87,14 @@ this.histogramViewProvider = histogramViewProvider; this.objectDetailsViewProvider = objectDetailsViewProvider; this.objectRootsViewProvider = objectRootsViewProvider; + this.heapDumpListViewProvider = heapDumpListViewProvider; } @Override public InformationServiceController getInformationServiceController(VmRef ref) { return new HeapDumpController(vmMemoryStatDao, vmInfoDao, heapDao, ref, appService, - viewProvider, detailsViewProvider, histogramViewProvider, objectDetailsViewProvider, objectRootsViewProvider); + viewProvider, detailsViewProvider, histogramViewProvider, objectDetailsViewProvider, + objectRootsViewProvider, heapDumpListViewProvider); } @Override diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java Wed Jun 05 20:26:44 2013 +0200 @@ -71,6 +71,10 @@ TRIGGER_HEAP_DUMP, HEAP_DUMP_IN_PROGRESS, PROCESS_EXITED, + + DUMPS_LIST, + LIST_DUMPS_ACTION, + ; static final String RESOURCE_BUNDLE = "com.redhat.thermostat.vm.heap.analysis.client.locale.strings"; diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/core/list_dumps.png Binary file vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/core/list_dumps.png has changed diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/core/pin_mask.png Binary file vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/core/pin_mask.png has changed diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties --- a/vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties Wed Jun 05 20:26:44 2013 +0200 @@ -28,5 +28,7 @@ OBJECT_ROOTS_VIEW_TITLE = Object Roots TRIGGER_HEAP_DUMP = Heap Dump +LIST_DUMPS_ACTION = List Dumps +DUMPS_LIST = Available Dumps HEAP_DUMP_IN_PROGRESS = dumping... PROCESS_EXITED = Process exited. diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java --- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -48,6 +48,7 @@ import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsViewProvider; @@ -86,6 +87,7 @@ HeapHistogramViewProvider histogramViewProvider = mock(HeapHistogramViewProvider.class); ObjectDetailsViewProvider objectDetailsViewProvider = mock(ObjectDetailsViewProvider.class); ObjectRootsViewProvider objectRootsViewProvider = mock(ObjectRootsViewProvider.class); + HeapDumpListViewProvider heapDumpListViewProvider = mock(HeapDumpListViewProvider.class); context.registerService(VmInfoDAO.class, vmInfoDao, null); context.registerService(VmMemoryStatDAO.class, vmMemoryStatDAO, null); @@ -97,6 +99,7 @@ context.registerService(HeapHistogramViewProvider.class, histogramViewProvider, null); context.registerService(ObjectDetailsViewProvider.class, objectDetailsViewProvider, null); context.registerService(ObjectRootsViewProvider.class, objectRootsViewProvider, null); + context.registerService(HeapDumpListViewProvider.class, heapDumpListViewProvider, null); Activator activator = new Activator(); @@ -107,7 +110,7 @@ activator.stop(context); assertEquals(0, context.getServiceListeners().size()); - assertEquals(9, context.getAllServices().size()); + assertEquals(10, context.getAllServices().size()); } } diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java --- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -77,6 +77,7 @@ import com.redhat.thermostat.storage.model.VmInfo; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView; @@ -121,6 +122,8 @@ private ObjectDetailsViewProvider objectDetailsProvider; private ObjectRootsViewProvider objectRootsProvider; + private HeapDumpListViewProvider heapDumpListViewProvider; + @Before public void setUp() { heapDao = mock(HeapDAO.class); @@ -132,6 +135,8 @@ appService = mock(ApplicationService.class); heapDumper = mock(HeapDumper.class); + heapDumpListViewProvider = mock(HeapDumpListViewProvider.class); + setUpView(); } @@ -195,7 +200,8 @@ controller = new HeapDumpController(vmDao, vmInfoDao, heapDao, ref, appService, viewProvider, detailsViewProvider, histogramProvider, - objectDetailsProvider, objectRootsProvider, heapDumper); + objectDetailsProvider, objectRootsProvider, heapDumpListViewProvider, + heapDumper); } @After @@ -279,7 +285,8 @@ VmRef ref = mock(VmRef.class); controller = new HeapDumpController(vmDao, vmInfoDao, heapDao, ref, appService, viewProvider, detailsViewProvider, histogramProvider, - objectDetailsProvider, objectRootsProvider, heapDumper); + objectDetailsProvider, objectRootsProvider, heapDumpListViewProvider, + heapDumper); verify(view, times(1)).setChildView(any(HeapView.class)); verify(view, times(1)).openDumpView(); @@ -304,7 +311,8 @@ VmRef ref = mock(VmRef.class); controller = new HeapDumpController(vmDao, vmInfoDao, heapDao, ref, appService, viewProvider, detailsViewProvider, histogramProvider, - objectDetailsProvider, objectRootsProvider, heapDumper); + objectDetailsProvider, objectRootsProvider, heapDumpListViewProvider, + heapDumper); verify(view, times(0)).openDumpView(); } @@ -324,7 +332,8 @@ controller = new HeapDumpController(vmDao, vmInfoDao, heapDao, ref, appService, viewProvider, detailsViewProvider, histogramProvider, - objectDetailsProvider, objectRootsProvider, heapDumper); + objectDetailsProvider, objectRootsProvider, heapDumpListViewProvider, + heapDumper); verify(view).disableHeapDumping(DumpDisabledReason.PROCESS_DEAD); } diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpListControllerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpListControllerTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.core.internal; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView.ListAction; +import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.junit.Assert.assertNotNull; + +public class HeapDumpListControllerTest { + + private HeapDumpController mainController; + private HeapDumpListViewProvider provider; + private HeapDumpListView view; + + @Before + public void setUp() throws Exception { + provider = mock(HeapDumpListViewProvider.class); + view = mock(HeapDumpListView.class); + when(provider.createView()).thenReturn(view); + + mainController = mock(HeapDumpController.class); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testAnalyseDump() { + + HeapDump dump = mock(HeapDump.class); + + ArgumentCaptor viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class); + doNothing().when(view).addListListener(viewArgumentCaptor.capture()); + + HeapDumpListController controller = new HeapDumpListController(provider, mainController); + + ActionListener listener = viewArgumentCaptor.getValue(); + assertNotNull(listener); + + ActionEvent actionEvent = new ActionEvent(view, ListAction.DUMP_SELECTED); + actionEvent.setPayload(dump); + listener.actionPerformed(actionEvent); + + verify(mainController).analyseDump(dump); + verifyNoMoreInteractions(mainController); + } + + @Test + public void testSetDumps() { + + List dumps = mock(List.class); + + HeapDumpListController controller = new HeapDumpListController(provider, mainController); + + controller.setDumps(dumps); + + verify(view).setDumps(dumps); + } +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/Activator.java --- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/Activator.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/Activator.java Wed Jun 05 20:26:44 2013 +0200 @@ -40,6 +40,7 @@ import org.osgi.framework.BundleContext; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsViewProvider; @@ -60,6 +61,8 @@ context.registerService(ObjectDetailsViewProvider.class.getName(), objectDetailsViewProvider, null); ObjectRootsViewProvider objectRootsViewProvider = new SwingObjectRootsViewProvider(); context.registerService(ObjectRootsViewProvider.class.getName(), objectRootsViewProvider, null); + HeapDumpListViewProvider heapListViewProvider = new SwingHeapDumpListViewProvider(); + context.registerService(HeapDumpListViewProvider.class.getName(), heapListViewProvider, null); } @Override diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java --- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java Wed Jun 05 20:26:44 2013 +0200 @@ -45,26 +45,27 @@ import javax.swing.BoxLayout; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.OverlayLayout; import javax.swing.SwingUtilities; -import com.redhat.thermostat.shared.locale.LocalizedString; -import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapDumpListener; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapSelectionEvent; - -import org.jfree.chart.axis.DateAxis; -import org.jfree.chart.event.AxisChangeEvent; -import org.jfree.chart.event.AxisChangeListener; -import org.jfree.chart.plot.XYPlot; - import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.swing.ComponentVisibleListener; import com.redhat.thermostat.client.swing.SwingComponent; +import com.redhat.thermostat.client.swing.components.ActionToggleButton; import com.redhat.thermostat.client.swing.components.HeaderPanel; +import com.redhat.thermostat.client.swing.components.Icon; +import com.redhat.thermostat.client.swing.components.OverlayPanel; +import com.redhat.thermostat.shared.locale.LocalizedString; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView.ListAction; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapIconResources; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView; import com.redhat.thermostat.vm.heap.analysis.client.core.chart.OverviewChart; import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources; import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapChartPanel; +import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapDumpListener; +import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapSelectionEvent; import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.StatsPanel; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; @@ -78,6 +79,11 @@ private HeaderPanel overview; private JPanel visiblePane; + private OverlayPanel overlay; + + private ActionToggleButton showHeapListButton; + + private JPanel stack; public HeapSwingView() { stats = new StatsPanel(); @@ -102,9 +108,39 @@ heapDetailPanel = new HeapPanel(); overview = new HeaderPanel(translator.localize(LocaleResources.HEAP_OVERVIEW_TITLE).getContents()); - overview.setContent(stats); + + stack = new JPanel(); + stack.setLayout(new OverlayLayout(stack)); + + overlay = new OverlayPanel(translator.localize(LocaleResources.DUMPS_LIST).getContents()); + stack.add(overlay); + stack.add(stats); + stats.setOpaque(false); + + overlay.setAlignmentX(-1.f); + overlay.setAlignmentY(1.f); + + overview.setContent(stack); overview.addHierarchyListener(new ViewVisibleListener()); + Icon listDumpIcon = new Icon(HeapIconResources.getIcon(HeapIconResources.LIST_DUMPS)); + + showHeapListButton = new ActionToggleButton(listDumpIcon, translator.localize(LocaleResources.LIST_DUMPS_ACTION).getContents()); + showHeapListButton.setToolTipText(translator.localize(LocaleResources.LIST_DUMPS_ACTION).getContents()); + showHeapListButton.setName("LIST_DUMPS_ACTION"); + + showHeapListButton.getToolbarButton().addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (overlay.isVisible()) { + overlay.setOverlayVisible(false); + } else { + heapDumperNotifier.fireAction(HeapDumperAction.REQUEST_DISPLAY_DUMP_LIST); + } + } + }); + overview.addToolBarButton(showHeapListButton); + // at the beginning, only the overview is visible visiblePane.add(overview); } @@ -132,16 +168,6 @@ final HeapChartPanel charts = new HeapChartPanel(model.getChart()); - XYPlot plot = model.getChart().getXYPlot(); - DateAxis domainAxis = (DateAxis) plot.getDomainAxis(); - domainAxis.addChangeListener(new AxisChangeListener() { - @Override - public void axisChanged(AxisChangeEvent event) { - // somehow the chart panel doesn't see this - charts.revalidate(); - } - }); - /* * By default, ChartPanel scales itself instead of redrawing things when * it's re-sized. To have it resize automatically, we need to set minimum @@ -155,7 +181,9 @@ charts.setMaximumDrawHeight(Integer.MAX_VALUE); charts.setMaximumDrawWidth(Integer.MAX_VALUE); - + + charts.setOpaque(false); + stats.setChartPanel(charts); } }); @@ -277,5 +305,43 @@ public void displayWarning(LocalizedString string) { JOptionPane.showMessageDialog(visiblePane, string.getContents(), "Warning", JOptionPane.WARNING_MESSAGE); } + + private void closeDumpListView() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + showHeapListButton.getToolbarButton().doClick(); + } + }); + } + + @Override + public void openDumpListView(HeapDumpListView view) { + if (view instanceof SwingHeapDumpListView) { + SwingHeapDumpListView swingView = (SwingHeapDumpListView) view; + view.addListListener(new com.redhat.thermostat.common.ActionListener() { + @Override + public void actionPerformed(com.redhat.thermostat.common.ActionEvent actionEvent) { + switch (actionEvent.getActionId()) { + case DUMP_SELECTED: + closeDumpListView(); + break; + + default: + break; + } + } + }); + + final Component dumpListView = swingView.getUiComponent(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + overlay.removeAll(); + overlay.add(dumpListView); + overlay.setOverlayVisible(true); + } + }); + } + } } - diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListView.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.swing.internal; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListCellRenderer; +import javax.swing.SwingUtilities; + +import com.redhat.thermostat.client.swing.SwingComponent; +import com.redhat.thermostat.client.swing.components.ShadowLabel; +import com.redhat.thermostat.client.ui.Palette; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; + +public class SwingHeapDumpListView extends HeapDumpListView implements SwingComponent { + + private JPanel container; + private JScrollPane scrollPane; + private HeapDumpModel model; + private JList list; + + public SwingHeapDumpListView() { + container = new JPanel(); + container.setName(getClass().getName()); + container.setLayout(new BorderLayout(0, 0)); + container.setOpaque(false); + + model = new HeapDumpModel(); + list = new JList<>(model); + list.setName(getClass().getName() + "_LIST"); + list.setBorder(null); + list.setOpaque(false); + list.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent evt) { + if (evt.getClickCount() == 2) { + int index = list.locationToIndex(evt.getPoint()); + HeapDump dump = model.get(index); + listNotifier.fireAction(ListAction.DUMP_SELECTED, dump); + } + } + }); + + list.setCellRenderer(new HeapCellRenderer()); + + scrollPane = new JScrollPane(list); + scrollPane.setBorder(null); + scrollPane.setViewportBorder(null); + + scrollPane.getViewport().setOpaque(false); + scrollPane.setOpaque(false); + + container.add(scrollPane, BorderLayout.CENTER); + } + + @Override + public Component getUiComponent() { + return container; + } + + @Override + public void setDumps(List dumps) { + + final List _dumps = new ArrayList<>(dumps); + Collections.sort(_dumps, new DumpsComparator()); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + model.clear(); + for (HeapDump dump : _dumps) { + model.addElement(dump); + container.repaint(); + } + } + }); + } + + @SuppressWarnings("serial") + private class HeapDumpModel extends DefaultListModel {} + + private class DumpsComparator implements Comparator { + @Override + public int compare(HeapDump o1, HeapDump o2) { + // TODO: descending order only for now, we should allow the users + // to sort this via the UI though + int result = Long.compare(o1.getTimestamp(), o2.getTimestamp()); + return -result; + } + } + + private class HeapCellRenderer implements ListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, HeapDump value, int index, + boolean isSelected, boolean cellHasFocus) { + + ShadowLabel label = new ShadowLabel(value.toString()); + label.setForeground(Palette.ROYAL_BLUE.getColor()); + + if (!isSelected) { + label.setOpaque(false); + } else { + label.setOpaque(true); + label.setBackground(Palette.ELEGANT_CYAN.getColor()); + } + + return label; + } + + } +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListViewProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListViewProvider.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.swing.internal; + +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; + +public class SwingHeapDumpListViewProvider implements HeapDumpListViewProvider { + + @Override + public HeapDumpListView createView() { + return new SwingHeapDumpListView(); + } +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapChartPanel.java --- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapChartPanel.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapChartPanel.java Wed Jun 05 20:26:44 2013 +0200 @@ -51,8 +51,9 @@ public HeapChartPanel(JFreeChart chart) { super(chart); + setName(HeapChartPanel.class.getName()); - setName(HeapChartPanel.class.getName()); + setupChart(); setLayout(new HeapChartPanelLayout()); chart.addChangeListener(new ChartChangeListener() { @@ -63,6 +64,11 @@ }); } + private void setupChart() { + JFreeChart chart = getChart(); + chart.setBackgroundPaint(getBackground()); + } + @Override protected void paintChildren(Graphics g) { Rectangle2D area = getScreenDataArea(); diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java --- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java Wed Jun 05 20:26:44 2013 +0200 @@ -93,12 +93,8 @@ GraphicsUtils utils = GraphicsUtils.getInstance(); Graphics2D graphics = utils.createAAGraphics(g); - - Color up = utils.deriveWithAlpha(Palette.DARK_GRAY.getColor(), 200); - Color bottom = utils.deriveWithAlpha(Palette.BLACK.getColor(), 200); - Paint gradient = new GradientPaint(0, 0, up, 0, getIconHeight(), bottom); - graphics.setPaint(gradient); + graphics.setColor(utils.deriveWithAlpha(OverlayComponent.this.getForeground(), 200)); graphics.fillRect(x, y, getIconWidth(), getIconHeight()); @@ -120,6 +116,10 @@ super(""); + setOpaque(false); + + setForeground(Palette.ROYAL_BLUE.getColor()); + setName(OverlayComponent.class.getName()); Icon mask = new Icon(HeapIconResources.getIcon(HeapIconResources.PIN_MASK)); diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ActivatorTest.java --- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ActivatorTest.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ActivatorTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -43,6 +43,7 @@ import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsViewProvider; @@ -66,7 +67,9 @@ assertTrue(ctx.isServiceRegistered(HeapHistogramViewProvider.class.getName(), SwingHeapHistogramViewProvider.class)); assertTrue(ctx.isServiceRegistered(ObjectDetailsViewProvider.class.getName(), SwingObjectDetailsViewProvider.class)); assertTrue(ctx.isServiceRegistered(ObjectRootsViewProvider.class.getName(), SwingObjectRootsViewProvider.class)); - assertEquals(5, ctx.getAllServices().size()); + assertTrue(ctx.isServiceRegistered(HeapDumpListViewProvider.class.getName(), SwingHeapDumpListViewProvider.class)); + + assertEquals(6, ctx.getAllServices().size()); } } diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDumpListViewTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDumpListViewTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright 2012, 2013 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 + * . + * + * 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.vm.heap.analysis.client.swing.internal; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JFrame; + +import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; + +import org.fest.swing.annotation.GUITest; +import org.fest.swing.edt.FailOnThreadViolationRepaintManager; +import org.fest.swing.edt.GuiActionRunner; +import org.fest.swing.edt.GuiTask; +import org.fest.swing.fixture.FrameFixture; +import org.fest.swing.fixture.JListFixture; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView.ListAction; +import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; + +@RunWith(CacioFESTRunner.class) +public class HeapDumpListViewTest { + + private JFrame frame; + private FrameFixture frameFixture; + private SwingHeapDumpListView view; + + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } + + @Before + public void setUp() { + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + view = new SwingHeapDumpListView(); + frame = new JFrame(); + frame.add(view.getUiComponent()); + + } + }); + frameFixture = new FrameFixture(frame); + } + + @After + public void tearDown() { + frameFixture.cleanUp(); + frameFixture = null; + } + + @GUITest + @Test + public void testDumpSelectedFired() { + + final boolean [] result = new boolean[1]; + final HeapDump [] selectedHeap = new HeapDump[1]; + + view.addListListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + result[0] = true; + selectedHeap[0] = (HeapDump) actionEvent.getPayload(); + } + }); + + frameFixture.show(); + + HeapDump dump1 = mock(HeapDump.class); + when(dump1.getTimestamp()).thenReturn(1L); + + HeapDump dump2 = mock(HeapDump.class); + when(dump2.getTimestamp()).thenReturn(2L); + + List dumps = new ArrayList<>(); + dumps.add(dump1); + dumps.add(dump2); + + view.setDumps(dumps); + + verify(dump1).getTimestamp(); + verify(dump2).getTimestamp(); + + JListFixture list = frameFixture.list(SwingHeapDumpListView.class.getName() + "_LIST"); + list.item(0).doubleClick(); + + assertTrue(result[0]); + assertEquals(dump2, selectedHeap[0]); + + result[0] = false; + list.item(1).doubleClick(); + + assertTrue(result[0]); + assertEquals(dump1, selectedHeap[0]); + } +} diff -r bb4bde056ead -r 9917555955a0 vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingViewTest.java --- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingViewTest.java Mon Jun 03 11:03:06 2013 +0200 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingViewTest.java Wed Jun 05 20:26:44 2013 +0200 @@ -45,6 +45,7 @@ import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; +import org.fest.swing.annotation.GUITest; import org.fest.swing.edt.FailOnThreadViolationRepaintManager; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiTask; @@ -53,6 +54,7 @@ import org.fest.swing.fixture.JLabelFixture; import org.fest.swing.fixture.JPanelFixture; import org.fest.swing.fixture.JPopupMenuFixture; +import org.fest.swing.fixture.JToggleButtonFixture; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -61,6 +63,7 @@ import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView.HeapDumperAction; import com.redhat.thermostat.vm.heap.analysis.client.core.chart.OverviewChart; import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats.HeapChartPanel; @@ -111,6 +114,7 @@ view = null; } + @GUITest @Test public void testAddHeapDump() { final boolean [] result = new boolean[1]; @@ -151,6 +155,7 @@ assertEquals(1, resultTimes[0]); } + @GUITest @Test public void testActivateHeapDump() throws InterruptedException { final boolean [] result = new boolean[1]; @@ -220,5 +225,25 @@ assertTrue(result[0]); assertEquals(1, resultTimes[0]); } + + @GUITest + @Test + public void testHeapDumperActionFired() { + + final boolean [] result = new boolean[1]; + view.addDumperListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + result[0] = true; + } + }); + + frame.show(); + + JToggleButtonFixture listDupms = frame.toggleButton("LIST_DUMPS_ACTION"); + listDupms.click(); + + assertTrue(result[0]); + } }