/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration) * and Cosylab 2002, All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package alma.acs.logging.errorbrowser; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import alma.acs.gui.widgets.CheckList.CheckListTableEntry; import alma.acs.logging.table.LogEntryTableModelBase; import alma.acs.logging.table.renderer.DateRenderer; import alma.acs.logging.table.renderer.EntryTypeRenderer; import alma.acs.logging.table.renderer.InfoRenderer; import com.cosylab.logging.LoggingClient; import com.cosylab.logging.client.DetailedLogTable; import com.cosylab.logging.engine.log.ILogEntry; import com.cosylab.logging.engine.log.LogField; import com.cosylab.logging.settings.FieldChooserDialog; import com.cosylab.logging.settings.FieldChooserDialog.DialogExitAction; /** * The component in each error tab of the error browser dialog * * @author acaproni * */ public class ErrorTab extends JSplitPane implements ActionListener { /** * The worker thread to look for logs belonging to the error trace */ private Engine engine; /** * The table with the details of the log */ private DetailedLogTable detailedLogTable = new DetailedLogTable(); /** * The dialog to show the cols to display */ private FieldChooserDialog fieldChooser=null; /** * The table of logs */ private JTable table = new JTable(); /** * The table model */ private LogEntryTableModelBase model; /** * The popup menu to show the field chooser dialog */ private JPopupMenu popmenu; /** * The columns shown by the table for each field of the log * i.e. the array does not contain the column showing if there * are additional data */ private TableColumn[] columns = new TableColumn[LogField.values().length]; /** * Constructor * * @param sourceModel The model used by the engine to look for logs * @param stackID The <code>STACKID</code> of the logs in this error trace */ public ErrorTab(LogEntryTableModelBase sourceModel, String stackID, LoggingClient client) throws Exception { super(JSplitPane.HORIZONTAL_SPLIT); model = new LogEntryTableModelBase(client); table.setModel(model); model.start(); initialize(); // Instantiate the engine that push logs into the table engine = new Engine(sourceModel,stackID,model); } /** * Init the GUI */ private void initialize() { // Init the table table.createDefaultColumnsFromModel(); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setAutoCreateRowSorter(true); TableColumnModel tcm = table.getColumnModel(); TableColumn tc; // Setup the first col tc = tcm.getColumn(0); tc.setCellRenderer(new InfoRenderer()); tc.setWidth(18); tc.setMaxWidth(18); tc.setResizable(false); tc = tcm.getColumn(LogField.ENTRYTYPE.ordinal() + 1); tc.setCellRenderer(new EntryTypeRenderer(false)); tc = tcm.getColumn(LogField.TIMESTAMP.ordinal() + 1); tc.setCellRenderer(new DateRenderer(true)); for (int t=1; t<tcm.getColumnCount(); t++) { tc=tcm.getColumn(t); tc.setMinWidth(50); tc.setPreferredWidth(100); tc.setResizable(true); tc.setIdentifier(LogField.values()[t-1]); columns[t-1]=tc; } // Set the visible columns boolean[] visCols = new boolean[LogField.values().length]; for (int t=0; t<visCols.length; t++) { visCols[t]=false; } visCols[LogField.TIMESTAMP.ordinal()]=true; visCols[LogField.ENTRYTYPE.ordinal()]=true; visCols[LogField.SOURCEOBJECT.ordinal()]=true; visCols[LogField.LOGMESSAGE.ordinal()]=true; visCols[LogField.STACKLEVEL.ordinal()]=true; setupTableCols(visCols); // Add the tabs setRightComponent(new JScrollPane(detailedLogTable)); setLeftComponent(new JScrollPane(table)); setDividerLocation(table.getPreferredSize().width); // Init the popup menu JMenuItem menuItem=new JMenuItem("Select columns..."); menuItem.addActionListener(this); popmenu = new JPopupMenu(); popmenu.add(menuItem); // Add the listener to the table header table.getTableHeader().addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { popmenu.show(ErrorTab.this.table, e.getX(), e.getY()); } } }); // Add the listener to the table table.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (!e.isPopupTrigger()) { // Get the index of the row and the column below // the mouse pointer int row = ErrorTab.this.table.rowAtPoint(e.getPoint()); ILogEntry log=model.getVisibleLogEntry(table.convertRowIndexToModel(row)); ErrorTab.this.detailedLogTable.setupContent(log); } } }); } /** * Release all the resource */ public void close() { setVisible(false); if (engine!=null) { engine.close(); model.close(false); } if (fieldChooser!=null) { fieldChooser.dispose(); fieldChooser=null; } } /** * Show the dialog to set the visible columns * <P> * The first time this class is called, the dialog is created. */ private void showFieldChooser() { if (fieldChooser==null) { fieldChooser=new FieldChooserDialog(ErrorTab.this); } String[] colNames = new String[LogField.values().length]; boolean colVisible[] = new boolean[colNames.length]; for (int t=0; t<colNames.length; t++) { colNames[t]=LogField.values()[t].getName(); try { TableColumn tc = table.getColumn(LogField.values()[t]); colVisible[t]=true; } catch (IllegalArgumentException e) { colVisible[t]=false; } } fieldChooser.setupFields(colNames, colVisible); fieldChooser.setVisible(true); if (fieldChooser.getModalResult()==DialogExitAction.OK) { setupTableCols(fieldChooser.getFields()); } } /** * Show or hide the the columns of the table. * <P> * The array of boolean has one entry for each column that is * <code>true</code> if the column must be shown or <code>false</code> if * such a column must be hidden. * <BR> The methods checks if a column is already shown (or hidden) before adding * (or removing) a new column to the table. * <P> * The first column, i.e. the column showing if a log has additional data, * is not considered here and is not part of the parameter. * * @param cols The columns to show/hide */ private void setupTableCols(boolean[] cols) { if (cols==null || cols.length!=LogField.values().length) { throw new IllegalArgumentException("(nvalid parameter"); } for (int t=0; t<cols.length; t++) { // Check if the column is shown by the table TableColumn tc =null; try { tc = table.getColumn(LogField.values()[t]); } catch (IllegalArgumentException e) {} if (cols[t]) { // show a column if (tc==null) { table.getColumnModel().addColumn(columns[t]); } } else { // remove a column if (tc!=null) { table.getColumnModel().removeColumn(tc); } } } } /** * Override <code>setVisible</code> to hide the field chooser dialog * when the user closes the error browser dialog. */ @Override public void setVisible(boolean b) { if (b==false && fieldChooser!=null) { fieldChooser.setVisible(b); } super.setVisible(b); } @Override public void actionPerformed(ActionEvent e) { showFieldChooser(); } }