package com.ibm.nmon.gui.tree; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.datatransfer.StringSelection; import java.io.IOException; import java.io.StringWriter; import java.util.List; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.tree.TreePath; import com.ibm.nmon.gui.main.NMONVisualizerGui; import com.ibm.nmon.gui.data.RemoveAllDataSetsAction; import com.ibm.nmon.gui.file.FileLoadAction; import com.ibm.nmon.gui.data.MergeDataSetDialog; import com.ibm.nmon.gui.info.MetadataInfoDialog; import com.ibm.nmon.gui.info.ProcessInfoDialog; import com.ibm.nmon.gui.info.SystemInfoDialog; import com.ibm.nmon.gui.file.CSVFileChooser; import com.ibm.nmon.util.CSVWriter; import com.ibm.nmon.data.DataSet; import com.ibm.nmon.data.SystemDataSet; import com.ibm.nmon.data.DataType; import com.ibm.nmon.data.ProcessDataType; final class TreeMouseListener extends TreePathParser implements MouseListener { protected final NMONVisualizerGui gui; protected final JTree tree; protected MouseEvent event; protected TreeMouseListener(NMONVisualizerGui gui, JTree tree) { this.gui = gui; this.tree = tree; } @Override public final void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { // right click only // use getClosestRow to allow users to click to the left and right of nodes... int row = tree.getClosestRowForLocation(e.getX(), e.getY()); TreePath selectionPath = null; // but check if the click is actually below the tree // this will happen on the last node in the tree, in which case the file load menu // should popup instead if ((row != -1) && (tree.getRowBounds(row).getMaxY() >= e.getY())) { selectionPath = tree.getPathForRow(row); } if (selectionPath != null) { // set selected node on right click; not the default behavior tree.setSelectionPath(selectionPath); } event = e; parse(selectionPath); event = null; } } @Override protected final void onNullPath() { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem("Load Files.."); item.addActionListener(new FileLoadAction(gui)); menu.add(item); item = new JMenuItem("Remove All"); item.addActionListener(new RemoveAllDataSetsAction(gui, gui.getMainFrame())); menu.add(item); menu.show(event.getComponent(), event.getX(), event.getY()); } @Override protected void onRootPath() { if (gui.getDataSetCount() > 0) { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem("Save Summary Charts..."); item.addActionListener(saveChartsAction); menu.add(item); menu.show(event.getComponent(), event.getX(), event.getY()); } } @Override protected final void onDataSetPath(DataSet data) { buildDataSetMenu(data).show(event.getComponent(), event.getX(), event.getY()); } @Override protected void onTypePath(DataSet data, DataType type) { buildTypeMenu(data, type, type.getFields()).show(event.getComponent(), event.getX(), event.getY()); } @Override protected void onFieldPath(DataSet data, DataType type, String field) { buildTypeMenu(data, type, java.util.Collections.singletonList(field)).show(event.getComponent(), event.getX(), event.getY()); } private JPopupMenu buildDataSetMenu(final DataSet data) { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem("Save to CSV..."); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new CSVFileChooser(gui, data, null, null).saveToCSV(); } }); menu.add(item); item = new JMenuItem("Save Charts..."); item.addActionListener(saveChartsAction); menu.add(item); menu.addSeparator(); if (data.getClass().equals(SystemDataSet.class)) { SystemDataSet systemData = (SystemDataSet) data; boolean needsSeparator = false; if (systemData.getMetadataCount() > 0) { item = new JMenuItem("Parsed File Info"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new MetadataInfoDialog(gui, (SystemDataSet) data).setVisible(true); } }); menu.add(item); needsSeparator = true; } if (systemData.getSystemInfoCount() > 0) { item = new JMenuItem("System Info"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new SystemInfoDialog(gui, (SystemDataSet) data).setVisible(true); } }); menu.add(item); needsSeparator = true; } if (needsSeparator) { menu.addSeparator(); } item = new JMenuItem("Merge..."); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new MergeDataSetDialog(gui, (SystemDataSet) data).setVisible(true); }; }); menu.add(item); } item = new JMenuItem("Remove"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { gui.removeDataSet(data); } }); menu.add(item); return menu; } private JPopupMenu buildTypeMenu(final DataSet data, final DataType type, final List<String> fields) { JPopupMenu menu = new JPopupMenu(); if (type.getClass().equals(ProcessDataType.class)) { final ProcessDataType processType = (ProcessDataType) type; // not aggregated process data if (processType.getProcess().getId() != -1) { JMenuItem item = new JMenuItem("Process Info"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new ProcessInfoDialog(gui, tree, processType.getProcess()).setVisible(true); } }); menu.add(item); menu.addSeparator(); } } JMenuItem item = new JMenuItem("Copy"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StringWriter writer = new StringWriter(4096); try { CSVWriter.write(data, type, fields, gui.getIntervalManager().getCurrentInterval(), writer); } catch (IOException ioe) { ioe.printStackTrace(); return; } gui.getMainFrame().getToolkit().getSystemClipboard() .setContents(new StringSelection(writer.toString()), null); } }); menu.add(item); menu.addSeparator(); item = new JMenuItem("Save to CSV..."); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new CSVFileChooser(gui, data, type, fields).saveToCSV(); } }); menu.add(item); item = new JMenuItem("Save Chart..."); item.addActionListener(saveChartsAction); menu.add(item); return menu; } @Override public final void mouseClicked(MouseEvent e) {} @Override public final void mousePressed(MouseEvent e) { mouseReleased(e); } @Override public final void mouseEntered(MouseEvent e) {} @Override public final void mouseExited(MouseEvent e) {} private final ActionListener saveChartsAction = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { gui.getViewManager().saveCharts(); } }; }