From a3d65089bdf21dcc0c83d4cf6b1e99b8fa6f4628 Mon Sep 17 00:00:00 2001 From: xylu Date: Fri, 21 Feb 2014 15:10:40 +0100 Subject: [PATCH] added chart datestamp setting on model loading --- .../tagtraum/perf/gcviewer/GCDocument.java | 13 +++ .../tagtraum/perf/gcviewer/GCPreferences.java | 84 +++++++++++-------- .../tagtraum/perf/gcviewer/ModelChart.java | 5 ++ .../perf/gcviewer/ModelChartImpl.java | 36 ++++++-- .../perf/gcviewer/ModelChartImplTest.java | 79 +++++++++++++++++ 5 files changed, 173 insertions(+), 44 deletions(-) create mode 100644 src/test/java/com/tagtraum/perf/gcviewer/ModelChartImplTest.java diff --git a/src/main/java/com/tagtraum/perf/gcviewer/GCDocument.java b/src/main/java/com/tagtraum/perf/gcviewer/GCDocument.java index 45927617..573d2f71 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/GCDocument.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/GCDocument.java @@ -587,6 +587,19 @@ public void resetPolygonCache() { } } + @Override + public void setShowDateStamp(boolean showDateStamp) { + for (ChartPanelView chartPanelView : chartPanelViews) { + chartPanelView.getModelChart().setShowDateStamp(showDateStamp); + } + } + + @Override + public boolean isShowDateStamp() { + if (chartPanelViews.isEmpty()) return false; + return chartPanelViews.get(0).getModelChart().isShowDateStamp(); + + } } private class ScrollBarMaximumChangeListener implements ChangeListener { diff --git a/src/main/java/com/tagtraum/perf/gcviewer/GCPreferences.java b/src/main/java/com/tagtraum/perf/gcviewer/GCPreferences.java index fc0114de..a259bada 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/GCPreferences.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/GCPreferences.java @@ -14,7 +14,7 @@ /** * Stores preferences of GCViewer in a file. - * + * * @author Joerg Wuethrich *

created on: 20.11.2011

*/ @@ -32,34 +32,35 @@ public class GCPreferences { public static final String INITIAL_MARK_LEVEL = "initialmarklevel"; public static final String CONCURRENT_COLLECTION_BEGIN_END = "concurrentcollectionbeginend"; public static final String ANTI_ALIAS = "antialias"; - + public static final String SHOW_DATA_PANEL = "showdatapanel"; - + public static final String SHOW_DATE_STAMP = "showdatestamp"; + private static final String GC_LINE_PREFIX = "view."; - + private static final String WINDOW_WIDTH = "window.width"; private static final String WINDOW_HEIGHT = "window.height"; private static final String WINDOW_X = "window.x"; private static final String WINDOW_Y = "window.y"; private static final String LASTFILE = "lastfile"; private static final String RECENT_FILE_PREFIX = "recent."; - + private static final int WINDOW_WIDTH_DEFAULT = 800; private static final int WINDOW_HEIGHT_DEFAULT = 600; private static final int WINDOW_X_DEFAULT = 0; private static final int WINDOW_Y_DEFAULT = 0; - + private static final Logger LOGGER = Logger.getLogger(GCPreferences.class.getName()); private Properties properties = new Properties(); - private boolean propertiesLoaded = false; - + private boolean propertiesLoaded = false; + public GCPreferences() { super(); - + load(); } - + public void store() { try (BufferedWriter writer = new BufferedWriter(new FileWriter(getPreferencesFile()))) { properties.store(writer, "GCViewer preferences"); @@ -70,13 +71,13 @@ public void store() { } } } - + public void load() { if (getPreferencesFile().exists()) { try (BufferedReader reader = new BufferedReader(new FileReader(getPreferencesFile()))) { propertiesLoaded = true; properties.load(reader); - } + } catch (IOException e) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning("could not load preferences (" + e.toString() + ")"); @@ -84,66 +85,66 @@ public void load() { } } } - + public boolean isPropertiesLoaded() { return propertiesLoaded; } - + public boolean getBooleanProperty(String key) { return getBooleanValue(key, true); } - + public void setBooleanProperty(String key, boolean value) { properties.setProperty(key, Boolean.toString(value)); } - + public int getWindowWidth() { return getIntValue(WINDOW_WIDTH, WINDOW_WIDTH_DEFAULT); } - + public void setWindowWidth(int value) { properties.setProperty(WINDOW_WIDTH, Integer.toString(value)); } - + public int getWindowHeight() { return getIntValue(WINDOW_HEIGHT, WINDOW_HEIGHT_DEFAULT); } - + public void setWindowHeight(int value) { properties.setProperty(WINDOW_HEIGHT, Integer.toString(value)); } - + public int getWindowX() { return getIntValue(WINDOW_X, WINDOW_X_DEFAULT); } - + public void setWindowX(int value) { properties.setProperty(WINDOW_X, Integer.toString(value)); } - + public int getWindowY() { return getIntValue(WINDOW_Y, WINDOW_Y_DEFAULT); } - + public void setWindowY(int value) { properties.setProperty(WINDOW_Y, Integer.toString(value)); } - + public void setLastFile(String filename) { properties.setProperty(LASTFILE, filename); } - + public String getLastFile() { return properties.getProperty(LASTFILE); } - + public void setRecentFiles(List fileNames) { int i = 0; for (String fileName : fileNames) { properties.setProperty(RECENT_FILE_PREFIX + i++, fileName); } } - + public List getRecentFiles() { List recentFiles = new LinkedList(); String filename; @@ -154,22 +155,26 @@ public List getRecentFiles() { recentFiles.add(filename); } } while (filename != null); - + return recentFiles; } - + public boolean getGcLineProperty(String key) { return getBooleanValue(GC_LINE_PREFIX + key, true); } - + + public boolean getGcLineProperty(String key, boolean defaultValue) { + return getBooleanValue(GC_LINE_PREFIX + key, defaultValue); + } + public void setGcLineProperty(String key, boolean value) { properties.setProperty(GC_LINE_PREFIX + key, Boolean.toString(value)); } - + private boolean getBooleanValue(String key, boolean defaultValue) { return Boolean.parseBoolean(properties.getProperty(key, Boolean.toString(defaultValue))); } - + private int getIntValue(String key, int defaultValue) { int result = defaultValue; try { @@ -178,20 +183,29 @@ private int getIntValue(String key, int defaultValue) { catch (NumberFormatException e) { e.printStackTrace(); } - + return result; } private File getPreferencesFile() { return new File(System.getProperty("user.home") + "/gcviewer.properties"); } - + public void setShowDataPanel(boolean showDataPanel) { setBooleanProperty(GC_LINE_PREFIX + SHOW_DATA_PANEL, showDataPanel); } - + public boolean isShowDataPanel() { return getBooleanProperty(GC_LINE_PREFIX + SHOW_DATA_PANEL); } + public boolean isShowDateStamp() { + return getBooleanProperty(GC_LINE_PREFIX + SHOW_DATE_STAMP); + } + + public void setShowDateStamp(boolean showDateStamp) { + setBooleanProperty(GC_LINE_PREFIX + SHOW_DATE_STAMP, showDateStamp); + } + + } diff --git a/src/main/java/com/tagtraum/perf/gcviewer/ModelChart.java b/src/main/java/com/tagtraum/perf/gcviewer/ModelChart.java index 1aac3523..e05d6760 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/ModelChart.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/ModelChart.java @@ -75,4 +75,9 @@ public interface ModelChart { void setAntiAlias(boolean antiAlias); void resetPolygonCache(); + + void setShowDateStamp(boolean showDateStamp); + + boolean isShowDateStamp(); + } diff --git a/src/main/java/com/tagtraum/perf/gcviewer/ModelChartImpl.java b/src/main/java/com/tagtraum/perf/gcviewer/ModelChartImpl.java index a33ec29e..83bb9b9a 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/ModelChartImpl.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/ModelChartImpl.java @@ -57,7 +57,7 @@ public ModelChartImpl() { this.chart.setPreferredSize(new Dimension(0, 0)); setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); - + // order of the renderers determines what is painted first and last // we start with what's painted last GridBagConstraints gridBagConstraints = new GridBagConstraints(); @@ -103,7 +103,7 @@ public ModelChartImpl() { horizontalScrollBar = getHorizontalScrollBar(); horizontalScrollBar.setUnitIncrement(50); horizontalScrollBar.setBlockIncrement(getViewport().getWidth()); - + JPanel rowHeaderPanel = new JPanel(); GridBagLayout layout = new GridBagLayout(); rowHeaderPanel.setLayout(layout); @@ -154,6 +154,7 @@ public void actionPerformed(ActionEvent e) { } }; timeOffsetPanel.setOkAction(setOffsetAction); + timeOffsetPanel.setOffsetSet(timestampRuler.getOffset() != 0); this.timestampRuler.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e) { maybePopup(e); @@ -198,7 +199,7 @@ public void invalidate() { public void resetPolygonCache() { chart.resetPolygons(); } - + public double getScaleFactor() { return scaleFactor; } @@ -215,7 +216,7 @@ public void setScaleFactor(double scaleFactor) { memoryRuler.setSize((int)memoryRuler.getPreferredSize().getWidth(), getViewport().getHeight()); pauseRuler.setSize((int)pauseRuler.getPreferredSize().getWidth(), getViewport().getHeight()); timestampRuler.setSize((int)(getViewport().getWidth()*getScaleFactor()), (int)timestampRuler.getPreferredSize().getHeight()); - + repaint(); } @@ -237,7 +238,7 @@ public boolean isShowTenured() { @Override public void setShowTenured(boolean showTenured) { totalTenuredRenderer.setVisible(showTenured); - + // reset cache because young generation needs to be repainted resetPolygonCache(); } @@ -341,12 +342,28 @@ public void setShowInitialMarkLevel(boolean showInitialMarkLevel) { public boolean isShowInitialMarkLevel() { return initialMarkLevelRenderer.isVisible(); } - + @Override public void setShowConcurrentCollectionBeginEnd(boolean showConcurrentCollectionBeginEnd) { concurrentGcLineRenderer.setVisible(showConcurrentCollectionBeginEnd); } + @Override + public void setShowDateStamp(boolean showDateStamp) { + if (showDateStamp && model.hasDateStamp()) { + timeOffsetPanel.setDate(model.getFirstDateStamp()); + timestampRuler.setOffset(timeOffsetPanel.getDate().getTime() / 1000); + timeOffsetPanel.setOffsetSet(true); + timestampRuler.revalidate(); + timestampRuler.repaint(); + } + } + @Override + public boolean isShowDateStamp(){ + return timeOffsetPanel.isOffsetSet(); + } + + @Override public boolean isShowConcurrentCollectionBeginEnd() { return concurrentGcLineRenderer.isVisible(); @@ -354,10 +371,10 @@ public boolean isShowConcurrentCollectionBeginEnd() { public void setModel(GCModel model, GCPreferences preferences) { this.model = model; - + applyPreferences(preferences); } - + private void applyPreferences(GCPreferences preferences) { setAntiAlias(preferences.getGcLineProperty(GCPreferences.ANTI_ALIAS)); setShowTenured(preferences.getGcLineProperty(GCPreferences.TENURED_MEMORY)); @@ -372,6 +389,7 @@ private void applyPreferences(GCPreferences preferences) { setShowUsedYoungMemoryLine(preferences.getGcLineProperty(GCPreferences.USED_YOUNG_MEMORY)); setShowInitialMarkLevel(preferences.getGcLineProperty(GCPreferences.INITIAL_MARK_LEVEL)); setShowConcurrentCollectionBeginEnd(preferences.getGcLineProperty(GCPreferences.CONCURRENT_COLLECTION_BEGIN_END)); + setShowDateStamp(preferences.getGcLineProperty(GCPreferences.SHOW_DATE_STAMP, false)); } public GCModel getModel() { @@ -423,7 +441,7 @@ public Dimension getPreferredSize() { private int scaleX(double d) { return (int) (d * getScaleFactor()); } - + /** * Reset the cached polygons of all {@link PolygonChartRenderer}s stored in this chart. */ diff --git a/src/test/java/com/tagtraum/perf/gcviewer/ModelChartImplTest.java b/src/test/java/com/tagtraum/perf/gcviewer/ModelChartImplTest.java new file mode 100644 index 00000000..a81a6b1d --- /dev/null +++ b/src/test/java/com/tagtraum/perf/gcviewer/ModelChartImplTest.java @@ -0,0 +1,79 @@ +package com.tagtraum.perf.gcviewer; + +import com.tagtraum.perf.gcviewer.model.GCModel; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; +import org.mockito.Mockito; + +import java.util.Date; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +@RunWith(Theories.class) +public class ModelChartImplTest { + + @DataPoint + public static TestCase HAS_DATE_STAMP_DATE_STAMP_TURNED_ON_IN_PREF = new TestCase().withDateStamp(true).withShowDateStamp(true).withExpectedShowDateStamp(true); + @DataPoint + public static TestCase HAS_DATE_STAMP_DATE_STAMP_TURNED_OFF_IN_PREF = new TestCase().withDateStamp(true).withShowDateStamp(false).withExpectedShowDateStamp(false); + @DataPoint + public static TestCase NO_DATE_STAMP_DATE_STAMP_TURNED_ON_IN_PREF = new TestCase().withDateStamp(false).withShowDateStamp(true).withExpectedShowDateStamp(false); + @DataPoint + public static TestCase NO_DATE_STAMP_DATE_STAMP_TURNED_OFF_IN_PREF = new TestCase().withDateStamp(false).withShowDateStamp(false).withExpectedShowDateStamp(false); + + + @Theory + public void shouldShowOrNotDateStampAccordingToModelAndSettings(TestCase testCase) throws Exception { + //given + ModelChartImpl modelChart = new ModelChartImpl(); + GCPreferences preferences = new GCPreferences(); + GCModel gcModel = Mockito.mock(GCModel.class); + Mockito.when(gcModel.hasDateStamp()).thenReturn(testCase.hasDateStamp()); + Mockito.when(gcModel.getFirstDateStamp()).thenReturn(new Date()); + preferences.setShowDateStamp(testCase.isShowDateStamp()); + + //when + modelChart.setModel(gcModel, preferences); + + //then + assertThat(modelChart.isShowDateStamp(), equalTo(testCase.isExpectedShowDateStamp())); + + } + + private static class TestCase { + private boolean hasDateStamp; + private boolean showDateStamp; + private boolean expectedShowDateStamp; + + public TestCase withDateStamp(boolean hasDateStamp) { + this.hasDateStamp = hasDateStamp; + return this; + } + + public TestCase withShowDateStamp(boolean showDateStamp) { + this.showDateStamp = showDateStamp; + return this; + } + + + public TestCase withExpectedShowDateStamp(boolean expectedShowDateStamp) { + this.expectedShowDateStamp = expectedShowDateStamp; + return this; + } + + private boolean hasDateStamp() { + return hasDateStamp; + } + + private boolean isShowDateStamp() { + return showDateStamp; + } + + private boolean isExpectedShowDateStamp() { + return expectedShowDateStamp; + } + } +}