package com.ibm.nmon.gui.main; import java.awt.BorderLayout; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.ActionListener; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.KeyStroke; import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingConstants; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.plot.CategoryPlot; import com.ibm.nmon.data.DataSet; import com.ibm.nmon.interval.Interval; import com.ibm.nmon.interval.IntervalListener; import com.ibm.nmon.report.ReportCache; import com.ibm.nmon.gui.Styles; import com.ibm.nmon.gui.chart.BaseChartPanel; import com.ibm.nmon.gui.chart.builder.ChartBuilderPlugin; import com.ibm.nmon.gui.report.ReportPanel; /** * ChartSplitPane showing summary charts for either all defined intervals or a single interval. The * choice is determined by a check box. * * @see ReportPanel */ final class SummaryView extends ChartSplitPane implements IntervalListener { private static final long serialVersionUID = 3407771704687182117L; private final ReportPanel singleIntervalReport; private final ReportPanel allIntervalsReport; private final JCheckBox allIntervals; private String lastCommonTabName; public SummaryView(NMONVisualizerGui gui) { super(gui, gui.getMainFrame()); singleIntervalReport = new ReportPanel(gui, ReportCache.DEFAULT_SUMMARY_CHARTS_KEY); singleIntervalReport.setBorder(null); // make consistent with addBorderIfNecessary singleIntervalReport.addPlugin(new ChartBuilderPlugin() { @Override public void configureChart(JFreeChart chart) { if (chart.getPlot() instanceof CategoryPlot) { // assume bar names will usually be hostnames // draw them on the chart at a 45 degree angle CategoryPlot plot = (CategoryPlot) chart.getPlot(); plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45); } } }); allIntervalsReport = new ReportPanel(gui, ReportCache.DEFAULT_INTERVAL_CHARTS_KEY); allIntervalsReport.setBorder(null); // make consistent with addBorderIfNecessary allIntervals = new JCheckBox("Graph All Intervals"); allIntervals.setEnabled(false); allIntervals.setSelected(false); allIntervals.setFont(Styles.LABEL); allIntervals.setHorizontalAlignment(SwingConstants.RIGHT); allIntervals.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); allIntervals.setBorderPainted(true); allIntervals.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { toggleReports(); } }); setTopComponent(singleIntervalReport); addBorderIfNecessary(); setEnabled(false); gui.addDataSetListener(this); gui.getIntervalManager().addListener(this); // assuming specific layout for NMONVisualizerGui JPanel right = (JPanel) ((javax.swing.JSplitPane) gui.getMainFrame().getContentPane()).getRightComponent(); JPanel top = (JPanel) right.getComponent(0); top.add(allIntervals, BorderLayout.LINE_START); ActionMap actions = allIntervals.getActionMap(); InputMap inputs = allIntervals.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); actions.put("allIntervals", new AbstractAction() { private static final long serialVersionUID = -442106516679509723L; @Override public void actionPerformed(ActionEvent e) { allIntervals.doClick(); } }); inputs.put(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), "allIntervals"); allIntervalsReport.addPropertyChangeListener("chart", summaryTable); allIntervalsReport.addPropertyChangeListener("highlightedLine", this); allIntervalsReport.addPropertyChangeListener("highlightedBar", this); allIntervalsReport.addPropertyChangeListener("highlightedIntervalLine", this); singleIntervalReport.addPropertyChangeListener("chart", summaryTable); singleIntervalReport.addPropertyChangeListener("highlightedLine", this); singleIntervalReport.addPropertyChangeListener("highlightedBar", this); // ensure ChartSplitPane forwards these events allIntervalsReport.addPropertyChangeListener("chart", this); allIntervalsReport.addPropertyChangeListener("annotation", this); singleIntervalReport.addPropertyChangeListener("chart", this); singleIntervalReport.addPropertyChangeListener("annotation", this); } @Override protected BaseChartPanel getChartPanel() { if (allIntervalsReport.isEnabled()) { return allIntervalsReport.getChartPanel(); } else { return singleIntervalReport.getChartPanel(); } } @Override public void setEnabled(boolean enabled) { if (enabled != isEnabled()) { super.setEnabled(enabled); if (enabled) { if (allIntervals.isSelected()) { allIntervalsReport.setEnabled(true); } else { singleIntervalReport.setEnabled(true); } if (gui.getIntervalManager().getIntervalCount() > 0) { allIntervals.setEnabled(true); } } else { allIntervalsReport.setEnabled(false); singleIntervalReport.setEnabled(false); allIntervals.setEnabled(false); } } } @Override protected void saveCharts(String directory) { if (allIntervalsReport.isEnabled()) { allIntervalsReport.saveAllCharts(directory); } else { singleIntervalReport.saveAllCharts(directory); } } @Override public void dataAdded(DataSet data) { singleIntervalReport.addData(data); allIntervalsReport.addData(data); int index = singleIntervalReport.getPreviousTab(); if (index != -1) { if (index >= singleIntervalReport.getTabCount()) { index = singleIntervalReport.getTabCount() - 1; } singleIntervalReport.setSelectedIndex(index); } else { singleIntervalReport.setSelectedIndex(0); } index = allIntervalsReport.getPreviousTab(); if (index != -1) { if (index >= allIntervalsReport.getTabCount()) { index = allIntervalsReport.getTabCount() - 1; } allIntervalsReport.setSelectedIndex(index); } else { allIntervalsReport.setSelectedIndex(0); } addBorderIfNecessary(); } @Override public void dataRemoved(DataSet data) { singleIntervalReport.removeData(data); allIntervalsReport.removeData(data); updateLastTab(); addBorderIfNecessary(); } @Override public void dataChanged(DataSet data) { singleIntervalReport.resetReport(); allIntervalsReport.resetReport(); } @Override public void dataCleared() { singleIntervalReport.clearData(); allIntervalsReport.clearData(); addBorderIfNecessary(); } public void intervalAdded(Interval interval) { if (isEnabled()) { allIntervals.setEnabled(true); } // else setEnabled() will handle enabling allIntervals if necessary } public void intervalRemoved(Interval interval) { if (gui.getIntervalManager().getIntervalCount() == 0) { intervalsCleared(); } } public void intervalsCleared() { if (isEnabled()) { allIntervals.setEnabled(false); allIntervals.setSelected(false); toggleReports(); } } public void currentIntervalChanged(Interval interval) {} public void intervalRenamed(Interval interval) {} private void toggleReports() { // keep the same divider location when changing the top component int location = getDividerLocation(); if (allIntervals.isSelected()) { singleIntervalReport.setEnabled(false); allIntervalsReport.setEnabled(true); updateLastTab(); setTopComponent(allIntervalsReport); } else { allIntervalsReport.setEnabled(false); singleIntervalReport.setEnabled(true); updateLastTab(); setTopComponent(singleIntervalReport); } setDividerLocation(location); revalidate(); } private void addBorderIfNecessary() { // ensure there is a separator line between the top panel and the report // if there are no tabs if (allIntervalsReport.getTabCount() == 0) { if (allIntervalsReport.getBorder() == null) { allIntervalsReport.setBorder(Styles.createTopLineBorder(this)); } } else { if (allIntervalsReport.getBorder() != null) { allIntervalsReport.setBorder(null); } } if (singleIntervalReport.getTabCount() == 0) { if (singleIntervalReport.getBorder() == null) { singleIntervalReport.setBorder(Styles.createTopLineBorder(this)); } } else { if (singleIntervalReport.getBorder() != null) { singleIntervalReport.setBorder(null); } } } private void updateLastTab() { ReportPanel currentReport = null; // this function is only called after selection is made // so get the previous report's selected index if (allIntervals.isSelected()) { currentReport = singleIntervalReport; } else { currentReport = allIntervalsReport; } int index = currentReport.getSelectedIndex(); String lastTabName = null; if (index != -1) { lastTabName = currentReport.getTitleAt(index); } // now update the _other_ report (the currently selected one) // this is the opposite of the above if if (allIntervals.isSelected()) { currentReport = allIntervalsReport; } else { currentReport = singleIntervalReport; } boolean found = false; // attempt to select the same tab that was selected on the previous report if (lastTabName != null) { for (int i = 0; i < currentReport.getTabCount(); i++) { if (currentReport.getTitleAt(i).equals(lastTabName)) { if (currentReport.getSelectedIndex() != i) { currentReport.setSelectedIndex(i); } lastCommonTabName = lastTabName; found = true; break; } } } // tab with same name not found, attempt to find the last common name if (!found) { for (int i = 0; i < currentReport.getTabCount(); i++) { if (currentReport.getTitleAt(i).equals(lastCommonTabName)) { if (currentReport.getSelectedIndex() != i) { currentReport.setSelectedIndex(i); } break; } } } // otherwise, the currently selected tab will not change } @Override protected String[] getDefaultColumns() { return new String[] { "Series Name", "Minimum", "Average", "Maximum", "Std Dev" }; } }