# HG changeset patch # User Mario Torre # Date 1487318662 -3600 # Node ID 748eff6a152c5c42880ace2bd706bc59894b46e4 # Parent 097340ee0fec43fceccc5912bbb092de42e03a70 Memory plugin UI tweaks review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-February/022160.html reviewed-by: jkang diff -r 097340ee0fec -r 748eff6a152c vm-memory/client-core/pom.xml --- a/vm-memory/client-core/pom.xml Mon Feb 13 11:59:54 2017 +0100 +++ b/vm-memory/client-core/pom.xml Fri Feb 17 09:04:22 2017 +0100 @@ -123,5 +123,11 @@ ${project.version} test + + com.redhat.thermostat + thermostat-client-swing + ${project.version} + test + diff -r 097340ee0fec -r 748eff6a152c vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryMeter.java --- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryMeter.java Mon Feb 13 11:59:54 2017 +0100 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryMeter.java Fri Feb 17 09:04:22 2017 +0100 @@ -55,11 +55,14 @@ import javax.swing.JComponent; import javax.swing.plaf.ColorUIResource; +import com.redhat.thermostat.client.ui.Palette; import sun.swing.SwingUtilities2; @SuppressWarnings({ "restriction", "serial" }) public class MemoryMeter extends JComponent { - + + private static final int BORDER_RADIUS = 6; + // TODO the font should be customizable private static final Font font = new Font("SansSerif", Font.PLAIN, 10); @@ -69,14 +72,10 @@ private static final int MAIN_BAR_HEIGHT = 20; private static final ColorUIResource MAIN_GRADIENT_TOP = new ColorUIResource(0xf1f3f1); - private static final ColorUIResource MAIN_BORDER_COLOR = new ColorUIResource(0xa8aca8); + private static final ColorUIResource MAIN_BORDER_COLOR = new ColorUIResource(Palette.EARL_GRAY.getColor()); - private static final ColorUIResource MAIN_BAR_BASE_COLOR_TOP = new ColorUIResource(0xbcd5ef); private static final ColorUIResource MAIN_BAR_BASE_COLOR = new ColorUIResource(0x4A90D9); - //private static final ColorUIResource STATS_BG = new ColorUIResource(0xF8F8F8); - private static final ColorUIResource STATS_BG = new ColorUIResource(0xFFFFFF); - private ColorUIResource tickColor; private RangeModel primary; @@ -106,6 +105,23 @@ public void setStats(StatsModel primaryStats) { this.primaryStats = primaryStats; } + public void setMemoryGraphProperties(Payload region) { + + getPrimaryModel().setMinimum(0); + getPrimaryModel().setMaximum(region.getMaxUsed()); + getPrimaryModel().setValue(region.getUsed()); + + getSecondaryModel().setMinimum(0); + getSecondaryModel().setMaximum(region.getMaxCapacity()); + getSecondaryModel().setValue(region.getCapacity()); + + setToolTipText(region.getTooltip()); + + setPrimaryScaleUnit(region.getUsedUnit().toString()); + setSecondayScaleUnit(region.getCapacityUnit().toString()); + + setStats(region.getModel()); + } public MemoryMeter() { @@ -157,46 +173,27 @@ bounds.width - boundInsets.right, bounds.height - boundInsets.bottom); } - + /** - * paint the outher frame, including the light border sorrounding - */ - protected void paintOuterFrame(Graphics2D graphics, Rectangle bounds) { - - RoundRectangle2D frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height, 6, 6); - - Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, getHeight(), getBackground()); - graphics.setPaint(paint); - graphics.fill(frame); - - paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, 0, getHeight(), getBackground()); - graphics.setPaint(paint); - frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width -1, bounds.height, 6, 6); - graphics.draw(frame); - } - - /** - * paint the track sorrounding the main bar + * paint the track surrounding the main bar */ protected void paintMainBarTrackFill(Graphics2D graphics, Rectangle bounds) { Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, bounds.height, Color.WHITE); graphics.setPaint(paint); - RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width, bounds.height, 6, 6); + RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width, bounds.height, BORDER_RADIUS, BORDER_RADIUS); graphics.fill(frame); } /** */ protected void paintMainBarTrackBorder(Graphics2D graphics, Rectangle bounds) { - Paint paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, getWidth(), 0, getBackground()); - graphics.setPaint(paint); - - RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width - 1, bounds.height, 6, 6); + + graphics.setPaint(MAIN_BORDER_COLOR); + RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width - 1, bounds.height, BORDER_RADIUS, BORDER_RADIUS); graphics.draw(frame); } - /** * this is the main bar, will it up to what is defined by the model */ @@ -294,47 +291,52 @@ protected void drawStrings(Graphics2D graphics, int top, int bottom, int right) { - // now draw the min/max values of both side of markers - // top bar min value - FontMetrics fm = SwingUtilities2.getFontMetrics(this, font); - - String value = String.format("%.2f", getPrimaryModel().getMinimum()) + " " + primaryUnit; - int height = top + fm.getAscent()/2; - SwingUtilities2.drawString(this, graphics, value, 1, height); - - value = String.format("%.2f", getSecondaryModel().getMinimum()) + " " + secondaryUnit; - height = bottom; - SwingUtilities2.drawString(this, graphics, value, 1, height); - - value = String.format("%.2f", getPrimaryModel().getMaximum()) + " " + primaryUnit; - height = top + fm.getAscent()/2; + // now draw the min/max values of both side of markers + // top bar min value + FontMetrics fm = SwingUtilities2.getFontMetrics(this, font); + + String value = String.format("%.2f", getPrimaryModel().getMinimum()) + " " + primaryUnit; + int height = top + fm.getAscent()/2; + SwingUtilities2.drawString(this, graphics, value, 1, height); + + value = String.format("%.2f", getSecondaryModel().getMinimum()) + " " + secondaryUnit; + height = bottom; + SwingUtilities2.drawString(this, graphics, value, 1, height); + + value = String.format("%.2f", getPrimaryModel().getMaximum()) + " " + primaryUnit; + height = top + fm.getAscent()/2; - int width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - - value = String.format("%.2f", getSecondaryModel().getMaximum()) + " " + secondaryUnit; - height = bottom; - width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - - // now draw the actual value for the bottom bar, the top bar is drawn in - // its fill method - value = String.format("%.2f", getSecondaryModel().getValue()) + " " + secondaryUnit; - width = right/2; - Rectangle2D bounds = font.getStringBounds(value, graphics.getFontRenderContext()); - width = (int) (width - bounds.getWidth()/2) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - RoundRectangle2D frame = new RoundRectangle2D.Double(width - 2, height - bounds.getHeight(), + int width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; + SwingUtilities2.drawString(this, graphics, value, width, height); + + value = String.format("%.2f", getSecondaryModel().getMaximum()) + " " + secondaryUnit; + height = bottom; + width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; + SwingUtilities2.drawString(this, graphics, value, width, height); + + // now draw the actual value for the bottom bar, the top bar is drawn in + // its fill method + value = String.format("%.2f", getSecondaryModel().getValue()) + " " + secondaryUnit; + width = right/2; + Rectangle2D bounds = font.getStringBounds(value, graphics.getFontRenderContext()); + width = (int) (width - bounds.getWidth()/2) - 1; + RoundRectangle2D frame = new RoundRectangle2D.Double(width - 2, height - bounds.getHeight(), bounds.getWidth() + 4, bounds.getHeight() + 4, 4, 4); - graphics.draw(frame); + + Paint paint = new GradientPaint(0, 0, Palette.DARK_GRAY.getColor(), 0, height, Palette.LIGHT_GRAY.getColor()); + graphics.setPaint(paint); + graphics.fill(frame); + + graphics.setPaint(MAIN_BAR_BASE_COLOR); + SwingUtilities2.drawString(this, graphics, value, width, height); + + graphics.setPaint(MAIN_BORDER_COLOR); + graphics.draw(frame); } protected void paintSecondaryBarFill(Graphics2D graphics, Rectangle bounds) { - - graphics.setPaint(MAIN_BAR_BASE_COLOR_TOP); - graphics.drawLine(1, bounds.height, getSecondaryModel().getValueNormalized() - 1, bounds.height); - + graphics.setPaint(MAIN_BAR_BASE_COLOR); graphics.fillRect(1, bounds.height + 1, getSecondaryModel().getValueNormalized(), 2); } @@ -349,11 +351,11 @@ StatsModel stats = getStats(); drawStats(graphics, stats, bounds.x, bounds.y, imageWidth, bounds.height); } - + private void drawStats(Graphics2D graphics, StatsModel stats, int x, int y, int imageWidth, int height) { if (stats != null) { - BufferedImage image = stats.getChart(imageWidth, height, STATS_BG, - new ColorUIResource(getForeground())); + BufferedImage image = stats.getChart(imageWidth, height, new ColorUIResource(getBackground()), + MAIN_BAR_BASE_COLOR); paintStatsLabel(graphics, image, stats.getName()); graphics.drawImage(image, x, y, null); @@ -395,9 +397,6 @@ resetModels(0, innerBounds.width); - // some eye candy - paintOuterFrame(graphics, outerBounds); - // paint the usage stats paintStats(graphics, statsBound); @@ -428,7 +427,7 @@ @Override @Transient public Dimension getPreferredSize() { - return new Dimension(850, 150); + return new Dimension(280, 150); } } diff -r 097340ee0fec -r 748eff6a152c vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/MemoryMeterDemo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/MemoryMeterDemo.java Fri Feb 17 09:04:22 2017 +0100 @@ -0,0 +1,89 @@ +/* + * Copyright 2012-2017 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.memory.client.core; + +import com.redhat.thermostat.common.Size.Unit; + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.awt.Dimension; + +import com.redhat.thermostat.client.swing.components.ThermostatScrollPane; + +public class MemoryMeterDemo { + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setMinimumSize(new Dimension(200, 200)); + + MemoryMeter meter = new MemoryMeter(); + + JPanel graphPanel = new JPanel(); + graphPanel.setLayout(new BoxLayout(graphPanel, BoxLayout.Y_AXIS)); + + graphPanel.add(meter); + + Payload payload = new Payload(); + payload.setName("Test"); + payload.setUsedUnit(Unit.KiB); + payload.setCapacityUnit(Unit.KiB); + payload.setCapacity(1.7); + payload.setMaxCapacity(2.0); + meter.setMemoryGraphProperties(payload); + + meter = new MemoryMeter(); + graphPanel.add(meter); + + payload = new Payload(); + payload.setName("Test2"); + payload.setUsedUnit(Unit.KiB); + payload.setCapacityUnit(Unit.KiB); + meter.setMemoryGraphProperties(payload); + + ThermostatScrollPane scrollPane = new ThermostatScrollPane(graphPanel); + frame.setContentPane(scrollPane); + + frame.setVisible(true); + } + }); + } +} \ No newline at end of file diff -r 097340ee0fec -r 748eff6a152c vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryGraphPanel.java --- a/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryGraphPanel.java Mon Feb 13 11:59:54 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2017 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.memory.client.swing.internal; - -import java.awt.Dimension; -import java.beans.Transient; - -import javax.swing.BoxLayout; -import javax.swing.JPanel; - -import com.redhat.thermostat.vm.memory.client.core.MemoryMeter; -import com.redhat.thermostat.vm.memory.client.core.Payload; - -@SuppressWarnings("serial") -class MemoryGraphPanel extends JPanel { - - private MemoryMeter meter; - - /** - * Create the panel. - */ - public MemoryGraphPanel() { - setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); - meter = new MemoryMeter(); - add(meter); - } - - public void setMemoryGraphProperties(Payload region) { - - meter.getPrimaryModel().setMinimum(0); - meter.getPrimaryModel().setMaximum(region.getMaxUsed()); - meter.getPrimaryModel().setValue(region.getUsed()); - - meter.getSecondaryModel().setMinimum(0); - meter.getSecondaryModel().setMaximum(region.getMaxCapacity()); - meter.getSecondaryModel().setValue(region.getCapacity()); - - meter.setToolTipText(region.getTooltip()); - - meter.setPrimaryScaleUnit(region.getUsedUnit().toString()); - meter.setSecondayScaleUnit(region.getCapacityUnit().toString()); - - meter.setStats(region.getModel()); - } - - @Override - @Transient - public Dimension getPreferredSize() { - return meter.getPreferredSize(); - } -} - diff -r 097340ee0fec -r 748eff6a152c vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java --- a/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java Mon Feb 13 11:59:54 2017 +0100 +++ b/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java Fri Feb 17 09:04:22 2017 +0100 @@ -57,6 +57,7 @@ import com.redhat.thermostat.client.swing.components.HeaderPanel; import com.redhat.thermostat.client.swing.components.MultiChartPanel; import com.redhat.thermostat.client.swing.components.MultiChartPanel.DataGroup; +import com.redhat.thermostat.client.swing.components.ThermostatScrollPane; import com.redhat.thermostat.client.swing.components.ThermostatTabbedPane; import com.redhat.thermostat.client.swing.components.experimental.RecentTimeControlPanel; import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier; @@ -69,6 +70,7 @@ import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.model.DiscreteTimeData; +import com.redhat.thermostat.vm.memory.client.core.MemoryMeter; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsView; import com.redhat.thermostat.vm.memory.client.core.Payload; import com.redhat.thermostat.vm.memory.client.locale.LocaleResources; @@ -87,11 +89,11 @@ private JPanel contentPanel; private JPanel tlabPanel; - private final Map regions; + private final Map regions; private ToolbarGCButton toolbarButton; private RequestGCAction toolbarButtonAction; - + private Dimension preferredSize; private ActionNotifier userActionNotifier = new ActionNotifier<>(this); @@ -100,13 +102,15 @@ private DataGroup numberGroup; private DataGroup bytesGroup; + private ThermostatScrollPane scrollPane; + public MemoryStatsViewImpl(Duration duration) { super(); visiblePanel = new HeaderPanel(); regions = new HashMap<>(); - + preferredSize = new Dimension(0, 0); - + visiblePanel.setHeader(t.localize(LocaleResources.MEMORY_REGIONS_HEADER)); new ComponentVisibilityNotifier().initialize(visiblePanel, notifier); @@ -114,10 +118,12 @@ graphPanel = new JPanel(); graphPanel.setLayout(new BoxLayout(graphPanel, BoxLayout.Y_AXIS)); + scrollPane = new ThermostatScrollPane(graphPanel); + contentPanel = new JPanel(); contentPanel.setLayout(new BorderLayout()); - contentPanel.add(graphPanel, BorderLayout.CENTER); + contentPanel.add(scrollPane, BorderLayout.CENTER); RecentTimeControlPanel recentTimeControlPanel = new RecentTimeControlPanel(duration); recentTimeControlPanel.addPropertyChangeListener(RecentTimeControlPanel.PROPERTY_VISIBLE_TIME_RANGE, new PropertyChangeListener() { @@ -174,13 +180,13 @@ public Dimension getPreferredSize() { return new Dimension(preferredSize); } - + @Override public void updateRegion(final Payload region) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - MemoryGraphPanel memoryGraphPanel = regions.get(region.getName()); + MemoryMeter memoryGraphPanel = regions.get(region.getName()); memoryGraphPanel.setMemoryGraphProperties(region); } }); @@ -212,19 +218,18 @@ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - MemoryGraphPanel memoryGraphPanel = new MemoryGraphPanel(); + MemoryMeter meter = new MemoryMeter(); - graphPanel.add(memoryGraphPanel); + graphPanel.add(meter); graphPanel.add(Box.createRigidArea(new Dimension(5, 5))); - regions.put(region.getName(), memoryGraphPanel); - + regions.put(region.getName(), meter); + // components are stacked up vertically in this panel - Dimension memoryGraphPanelMinSize = memoryGraphPanel.getMinimumSize(); + Dimension memoryGraphPanelMinSize = meter.getMinimumSize(); preferredSize.height += memoryGraphPanelMinSize.height + 5; if (preferredSize.width < (memoryGraphPanelMinSize.width + 5)) { preferredSize.width = memoryGraphPanelMinSize.width + 5; } - updateRegion(region); graphPanel.revalidate(); graphPanel.repaint();