package com.ibm.nmon.gui.file;
import java.util.Map;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.BorderLayout;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.ListSelectionModel;
import javax.swing.DefaultListSelectionModel;
import com.ibm.nmon.gui.GUIDialog;
import com.ibm.nmon.gui.GUITable;
import com.ibm.nmon.gui.Styles;
import com.ibm.nmon.gui.main.NMONVisualizerGui;
import com.ibm.nmon.gui.table.ReadOnlyTableModel;
import com.ibm.nmon.gui.util.LogViewerDialog;
import com.ibm.nmon.gui.util.ScrollingTableFix;
final class ParserErrorDialog extends GUIDialog {
private static final long serialVersionUID = -9140024700542269099L;
private final Map<String, String> errors;
private final JSplitPane splitPane;
private final GUITable errorList;
private final JTextArea errorText;
private final JButton ok;
public ParserErrorDialog(NMONVisualizerGui gui, Map<String, String> fileErrors) {
super(gui, gui.getMainFrame(), "Parsing Errors");
setModal(true);
setIconImage(LogViewerDialog.LOG_ICON.getImage());
this.errors = fileErrors;
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setBorder(Styles.LOWER_LINE_BORDER);
ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
JButton copy = new JButton("Copy");
copy.setIcon(Styles.COPY_ICON);
copy.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ReadOnlyTableModel model = (ReadOnlyTableModel) errorList.getModel();
String filename = (String) model.getValueAt(errorList.getSelectedRow(), 0);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(filename + ':' + '\n' + errorText.getText()), null);
}
});
JButton copyAll = new JButton("Copy All");
copyAll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StringBuilder allErrors = new StringBuilder(errors.size() * 256);
ReadOnlyTableModel model = (ReadOnlyTableModel) errorList.getModel();
for (int i = 0; i < model.getRowCount(); i++) {
if (i != 0) {
allErrors.append('\n');
}
String filename = (String) model.getValueAt(i, 0);
allErrors.append(filename);
allErrors.append(':');
allErrors.append('\n');
allErrors.append(errors.get(filename));
}
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(allErrors.toString()), null);
}
});
errorList = new GUITable(gui, new ReadOnlyTableModel());
errorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// only one column, no need for a header
errorList.setTableHeader(null);
errorList.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
dispose();
e.consume();
}
}
});
// still need to add the column or the data will not show up
((ReadOnlyTableModel) errorList.getModel()).addColumn("");
for (String filename : errors.keySet()) {
((ReadOnlyTableModel) errorList.getModel()).addRow(new Object[] { filename });
}
errorText = new JTextArea();
errorText.setColumns(75);
errorText.setRows(15);
errorText.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
errorText.setEditable(false);
((DefaultListSelectionModel) errorList.getSelectionModel())
.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
String filename = (String) errorList.getModel().getValueAt(errorList.getSelectedRow(), 0);
errorText.setText(errors.get(filename));
}
}
});
JScrollPane scroller = new JScrollPane(errorList);
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroller.setBorder(null);
scroller.addComponentListener(new ScrollingTableFix(errorList, scroller));
scroller.setColumnHeaderView(null);
splitPane.setTopComponent(scroller);
scroller = new JScrollPane(errorText);
scroller.setBorder(null);
splitPane.setBottomComponent(scroller);
add(splitPane, BorderLayout.CENTER);
JPanel footer = new JPanel(new BorderLayout());
// temp panel so button does not expand
JPanel temp = new JPanel();
temp.add(ok);
// footer.setBorder(Styles.CONTENT_BORDER);
footer.add(temp, BorderLayout.LINE_END);
temp = new JPanel();
temp.add(copy);
temp.add(copyAll);
footer.add(temp, BorderLayout.LINE_START);
add(footer, BorderLayout.PAGE_END);
// 3/4 the height and 1/2 the width
setPreferredSize(new java.awt.Dimension((int) (gui.getMainFrame().getWidth() * .75), (int) (gui.getMainFrame()
.getHeight() * .5)));
addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
// divider location must be set when the window is visible
// because this dialog is modal, it cannot be done in setVisible() since
// super.setVisible() has not been called
splitPane.setDividerLocation(.25);
}
});
}
@Override
public void setVisible(boolean b) {
if (b) {
// used for visual effect only
// does not do anything since table intercepts the Enter key press
// added KeyListener recreates the correct behavior
getRootPane().setDefaultButton(ok);
// select the first error
errorList.getSelectionModel().setSelectionInterval(0, 0);
}
super.setVisible(b);
}
}