package com.ibm.nmon.gui.main; import java.awt.BorderLayout; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.tree.TreePath; import com.ibm.nmon.gui.tree.TreePathParser; import javax.swing.JFileChooser; import javax.swing.JPanel; import com.ibm.nmon.data.DataSet; import com.ibm.nmon.data.DataType; import com.ibm.nmon.gui.analysis.SummaryTablePanel; import com.ibm.nmon.gui.chart.BaseChartPanel; import com.ibm.nmon.gui.chart.annotate.AnnotationCache; import com.ibm.nmon.gui.chart.annotate.AnnotationListener; import com.ibm.nmon.gui.file.GUIFileChooser; import com.ibm.nmon.gui.Styles; /** * Central JPanel responsible for managing what is currently viewed in the UI. Listens for * <code>chartsDisplayed</code> property changes to display either charts or * {@link SummaryTablePanel}. The chart view will be one of {@link SummaryView}, {@link DataSetView} * or {@link DataTypeView} depending on the current tree path selected. */ public final class ViewManager extends JPanel implements PropertyChangeListener, TreeSelectionListener, AnnotationListener { private static final long serialVersionUID = 1411425971480047253L; private final NMONVisualizerGui gui; private final SummaryView summaryView; private final DataSetView dataSetView; private final DataTypeView dataTypeView; private final JPanel blank; private final SummaryTablePanel tablePanel; private final PathParser pathParser; private TreePath currentPath; private ChartSplitPane currentView; // if adding an annotation, ignore events from AnnotationCache private boolean addingAnnotation = false; // single use flag to make sure the ChartSplitPane is setup correctly // see PathParser.onReturn() private boolean displayedOnce = false; ViewManager(NMONVisualizerGui gui) { super(new BorderLayout()); this.gui = gui; this.pathParser = new PathParser(); summaryView = new SummaryView(gui); dataSetView = new DataSetView(gui); dataTypeView = new DataTypeView(gui); summaryView.addPropertyChangeListener("annotation", this); dataSetView.addPropertyChangeListener("annotation", this); dataTypeView.addPropertyChangeListener("annotation", this); summaryView.addPropertyChangeListener("chart", this); dataSetView.addPropertyChangeListener("chart", this); dataTypeView.addPropertyChangeListener("chart", this); blank = new JPanel(); blank.setBackground(java.awt.Color.WHITE); blank.setBorder(Styles.createTopLineBorder(this)); tablePanel = new SummaryTablePanel(gui, gui.getMainFrame()); tablePanel.setEnabled(false); gui.addPropertyChangeListener("chartsDisplayed", this); AnnotationCache.addAnnotationListener(this); add(blank); } void displayTableColumnChooser() { if (currentView != null) { currentView.displayTableColumnChooser(); } } private void showNothing() { if (getComponent(0) != blank) { remove(0); add(blank); summaryView.setEnabled(false); dataSetView.setEnabled(false); dataTypeView.setEnabled(false); tablePanel.setEnabled(false); updateDividerLocation(); currentView = null; } } private void showSummaryView() { if (currentView != summaryView) { remove(0); add(summaryView); summaryView.setEnabled(true); dataSetView.setEnabled(false); dataTypeView.setEnabled(false); tablePanel.setEnabled(false); updateDividerLocation(); currentView = summaryView; } } private void showDataSetView() { if (currentView != dataSetView) { remove(0); add(dataSetView); summaryView.setEnabled(false); dataSetView.setEnabled(true); dataTypeView.setEnabled(false); tablePanel.setEnabled(false); updateDividerLocation(); currentView = dataSetView; } } private void showDataTypeView() { if (currentView != dataTypeView) { remove(0); add(dataTypeView); summaryView.setEnabled(false); dataSetView.setEnabled(false); dataTypeView.setEnabled(true); tablePanel.setEnabled(false); updateDividerLocation(); currentView = dataTypeView; } } private void showTable() { if (getComponent(0) != tablePanel) { remove(0); add(tablePanel); summaryView.setEnabled(false); dataSetView.setEnabled(false); dataTypeView.setEnabled(false); tablePanel.setEnabled(true); updateDividerLocation(); currentView = null; } } private void updateDividerLocation() { if (currentView != null) { int location = currentView.getDividerLocation(); summaryView.setDividerLocation(location); dataSetView.setDividerLocation(location); dataTypeView.setDividerLocation(location); } } public void saveCharts() { if (currentView != null) { // note title here is consistent with BaseChartPanel.doSaveAs() // this dialog however only allows selecting the directory to save and uses the default // file names rather than allowing the user to specify a file name since a view may // contain multiple charts (i.e. a ReportPanel) GUIFileChooser chooser = new GUIFileChooser(gui, "Select Save Location"); chooser.setFileSelectionMode(GUIFileChooser.DIRECTORIES_ONLY); if (chooser.showDialog(gui.getMainFrame(), "Save") == JFileChooser.APPROVE_OPTION) { String directory = chooser.getSelectedFile().getAbsolutePath(); currentView.saveCharts(directory); } } } @Override public void propertyChange(PropertyChangeEvent evt) { if ("chartsDisplayed".equals(evt.getPropertyName())) { if ((Boolean) evt.getNewValue()) { pathParser.parse(currentPath); } else { showTable(); // disabling the chart menu will be handled in MainMenu.propertyChange() } } else if ("chart".equals(evt.getPropertyName())) { if (AnnotationCache.hasAnnotations()) { if (evt.getNewValue() != null) { addingAnnotation = true; ((BaseChartPanel) evt.getNewValue()).addAnnotations(AnnotationCache.getAnnotations()); ((BaseChartPanel) evt.getNewValue()).addMarkers(AnnotationCache.getMarkers()); addingAnnotation = false; } } } else if ("annotation".equals(evt.getPropertyName())) { if ((evt.getNewValue() != null) && !addingAnnotation) { addingAnnotation = true; AnnotationCache.add(evt.getNewValue()); addingAnnotation = false; } } } @Override public void annotationAdded() { annotationsCleared(); } @Override public void annotationRemoved() { annotationsCleared(); } @Override public void annotationsCleared() { if (!addingAnnotation) { if (currentView != null) { BaseChartPanel currentChart = currentView.getChartPanel(); if (currentChart != null) { addingAnnotation = true; currentChart.addAnnotations(AnnotationCache.getAnnotations()); currentChart.addMarkers(AnnotationCache.getMarkers()); addingAnnotation = false; } } } } @Override public void valueChanged(TreeSelectionEvent e) { currentPath = e.getNewLeadSelectionPath(); pathParser.parse(currentPath); } private final class PathParser extends TreePathParser { @Override protected void onNullPath() { if (gui.getBooleanProperty("chartsDisplayed")) { showNothing(); enableChartMenu(false); } } @Override protected void onRootPath() { if (gui.getBooleanProperty("chartsDisplayed")) { if (gui.getDataSetCount() == 0) { showNothing(); } else { showSummaryView(); enableChartMenu(true); } } } @Override protected void onDataSetPath(DataSet data) { dataSetView.setData(data); if (gui.getBooleanProperty("chartsDisplayed")) { showDataSetView(); dataSetView.setEnabled(true); enableChartMenu(true); } } @Override protected void onProcessPath(DataSet data) { if (gui.getBooleanProperty("chartsDisplayed")) { showNothing(); enableChartMenu(false); } } @Override protected void onTypePath(DataSet data, DataType type) { dataTypeView.setData(data, type); if (gui.getBooleanProperty("chartsDisplayed")) { showDataTypeView(); enableChartMenu(true); } } @Override protected void onFieldPath(DataSet data, DataType type, String field) { dataTypeView.setData(data, type, field); if (gui.getBooleanProperty("chartsDisplayed")) { showDataTypeView(); enableChartMenu(true); } } @Override protected Object onReturn(DataSet data, DataType type, String field) { // the first time a chart view is displayed, // set the proportional size of the scroll pane if (!displayedOnce && (currentView != null)) { // force layout to ensure currentView has a defined size // or setDividerLocation will not work doLayout(); currentView.setDividerLocation(.75); displayedOnce = true; } repaint(); return super.onReturn(data, type, field); } private void enableChartMenu(boolean enabled) { MainMenu menu = (MainMenu) gui.getMainFrame().getJMenuBar(); menu.enableChartSubMenu(enabled); } } }