19 package org.sleuthkit.autopsy.ingest;
 
   21 import java.awt.Color;
 
   22 import java.awt.Component;
 
   23 import java.awt.Cursor;
 
   24 import java.awt.Dimension;
 
   26 import java.awt.Graphics;
 
   27 import java.beans.PropertyChangeEvent;
 
   28 import java.beans.PropertyChangeListener;
 
   29 import java.beans.PropertyChangeSupport;
 
   30 import java.text.DateFormat;
 
   31 import java.text.SimpleDateFormat;
 
   32 import java.util.ArrayList;
 
   33 import java.util.Collections;
 
   34 import java.util.Date;
 
   35 import java.util.HashMap;
 
   36 import java.util.List;
 
   38 import javax.swing.JLabel;
 
   39 import javax.swing.JPanel;
 
   40 import org.openide.util.NbBundle;
 
   42 import javax.swing.JTable;
 
   43 import javax.swing.ListSelectionModel;
 
   44 import javax.swing.SwingConstants;
 
   45 import javax.swing.event.ListSelectionEvent;
 
   46 import javax.swing.event.ListSelectionListener;
 
   47 import javax.swing.event.TableModelEvent;
 
   48 import javax.swing.event.TableModelListener;
 
   49 import javax.swing.table.AbstractTableModel;
 
   50 import javax.swing.table.DefaultTableCellRenderer;
 
   51 import javax.swing.table.TableCellRenderer;
 
   55 import java.util.logging.Level;
 
   61 class IngestMessagePanel 
extends JPanel implements TableModelListener {
 
   63     private final MessageTableModel tableModel;
 
   64     private MessageTableRenderer renderer;
 
   65     private final IngestMessageMainPanel mainPanel;
 
   66     private static final Color ERROR_COLOR = 
new Color(255, 90, 90);
 
   67     private volatile int lastRowSelected = -1;
 
   68     private volatile long totalMessages = 0;
 
   69     private static final Logger logger = Logger.getLogger(IngestMessagePanel.class.getName());
 
   70     private static final PropertyChangeSupport messagePcs = 
new PropertyChangeSupport(IngestMessagePanel.class);
 
   71     static final String TOTAL_NUM_MESSAGES_CHANGED = 
"TOTAL_NUM_MESSAGES_CHANGED"; 
 
   72     static final String MESSAGES_BOX_CLEARED = 
"MESSAGES_BOX_CLEARED"; 
 
   73     static final String TOTAL_NUM_NEW_MESSAGES_CHANGED = 
"TOTAL_NUM_NEW_MESSAGES_CHANGED"; 
 
   76     public IngestMessagePanel(IngestMessageMainPanel mainPanel) {
 
   77         this.mainPanel = mainPanel;
 
   78         tableModel = 
new MessageTableModel();
 
   80         customizeComponents();
 
   83     public void markAllSeen() {
 
   84         tableModel.markAllSeen();
 
   87     int getLastRowSelected() {
 
   88         return this.lastRowSelected;
 
   91     synchronized IngestMessageGroup getSelectedMessage() {
 
   92         if (lastRowSelected < 0) {
 
   96         return tableModel.getMessageGroup(lastRowSelected);
 
   99     synchronized IngestMessageGroup getMessageGroup(
int rowNumber) {
 
  100         return tableModel.getMessageGroup(rowNumber);
 
  103     synchronized static void addPropertyChangeSupportListener(PropertyChangeListener l) {
 
  104         messagePcs.addPropertyChangeListener(l);
 
  112     @SuppressWarnings(
"unchecked")
 
  114     private 
void initComponents() {
 
  116         jScrollPane1 = 
new javax.swing.JScrollPane();
 
  117         messageTable = 
new javax.swing.JTable();
 
  118         controlPanel = 
new javax.swing.JPanel();
 
  119         sortByLabel = 
new javax.swing.JLabel();
 
  120         sortByComboBox = 
new javax.swing.JComboBox<String>();
 
  121         totalMessagesNameLabel = 
new javax.swing.JLabel();
 
  122         totalMessagesNameVal = 
new javax.swing.JLabel();
 
  123         totalUniqueMessagesNameLabel = 
new javax.swing.JLabel();
 
  124         totalUniqueMessagesNameVal = 
new javax.swing.JLabel();
 
  128         jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
 
  129         jScrollPane1.setOpaque(
false);
 
  130         jScrollPane1.setPreferredSize(
new java.awt.Dimension(32767, 32767));
 
  132         messageTable.setBackground(
new java.awt.Color(221, 221, 235));
 
  133         messageTable.setFont(messageTable.getFont().deriveFont(Font.PLAIN, 12));
 
  134         messageTable.setModel(tableModel);
 
  135         messageTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
 
  136         messageTable.setAutoscrolls(
false);
 
  137         messageTable.setCursor(
new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
 
  138         messageTable.setGridColor(
new java.awt.Color(204, 204, 204));
 
  139         messageTable.setOpaque(
false);
 
  140         messageTable.setSelectionForeground(
new java.awt.Color(0, 0, 0));
 
  141         messageTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
 
  142         messageTable.setShowHorizontalLines(
false);
 
  143         messageTable.setShowVerticalLines(
false);
 
  144         messageTable.getTableHeader().setReorderingAllowed(
false);
 
  145         jScrollPane1.setViewportView(messageTable);
 
  147         sortByLabel.setText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.sortByLabel.text")); 
 
  149         sortByComboBox.setModel(
new javax.swing.DefaultComboBoxModel<String>(
new String[] {
 
  150                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.sortByComboBox.model.time"),
 
  151                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.sortByComboBox.model.priority") })); 
 
  152         sortByComboBox.setToolTipText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.sortByComboBox.toolTipText")); 
 
  153         sortByComboBox.addActionListener(
new java.awt.event.ActionListener() {
 
  154             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  155                 sortByComboBoxActionPerformed(evt);
 
  159         totalMessagesNameLabel.setText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.totalMessagesNameLabel.text")); 
 
  161         totalMessagesNameVal.setText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.totalMessagesNameVal.text")); 
 
  163         totalUniqueMessagesNameLabel.setText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.totalUniqueMessagesNameLabel.text")); 
 
  165         totalUniqueMessagesNameVal.setText(
org.openide.util.NbBundle.getMessage(IngestMessagePanel.class, 
"IngestMessagePanel.totalUniqueMessagesNameVal.text")); 
 
  167         javax.swing.GroupLayout controlPanelLayout = 
new javax.swing.GroupLayout(controlPanel);
 
  168         controlPanel.setLayout(controlPanelLayout);
 
  169         controlPanelLayout.setHorizontalGroup(
 
  170             controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  171             .addGroup(controlPanelLayout.createSequentialGroup()
 
  173                 .addComponent(sortByLabel)
 
  174                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  175                 .addComponent(sortByComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  176                 .addGap(101, 101, 101)
 
  177                 .addComponent(totalMessagesNameLabel)
 
  178                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  179                 .addComponent(totalMessagesNameVal, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
 
  181                 .addComponent(totalUniqueMessagesNameLabel)
 
  182                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  183                 .addComponent(totalUniqueMessagesNameVal, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
 
  186         controlPanelLayout.setVerticalGroup(
 
  187             controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  188             .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  189                 .addComponent(sortByComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  190                 .addComponent(sortByLabel)
 
  191                 .addComponent(totalUniqueMessagesNameLabel)
 
  192                 .addComponent(totalUniqueMessagesNameVal)
 
  193                 .addComponent(totalMessagesNameLabel)
 
  194                 .addComponent(totalMessagesNameVal))
 
  197         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  198         this.setLayout(layout);
 
  199         layout.setHorizontalGroup(
 
  200             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  201             .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  202             .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
 
  204         layout.setVerticalGroup(
 
  205             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  206             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 
  207                 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
 
  209                 .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  213     private void sortByComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  214         synchronized (
this) {
 
  215             if (sortByComboBox.getSelectedIndex() == 0) {
 
  216                 tableModel.reSort(
true);
 
  218                 tableModel.reSort(
false);
 
  223     private javax.swing.JPanel controlPanel;
 
  224     private javax.swing.JScrollPane jScrollPane1;
 
  225     private javax.swing.JTable messageTable;
 
  226     private javax.swing.JComboBox<String> sortByComboBox;
 
  227     private javax.swing.JLabel sortByLabel;
 
  228     private javax.swing.JLabel totalMessagesNameLabel;
 
  229     private javax.swing.JLabel totalMessagesNameVal;
 
  230     private javax.swing.JLabel totalUniqueMessagesNameLabel;
 
  231     private javax.swing.JLabel totalUniqueMessagesNameVal;
 
  234     private void customizeComponents() {
 
  235         mainPanel.setOpaque(
true);
 
  236         jScrollPane1.setOpaque(
true);
 
  237         messageTable.setOpaque(
false);
 
  239         jScrollPane1.setWheelScrollingEnabled(
true);
 
  241         messageTable.setAutoscrolls(
false);
 
  242         messageTable.setShowHorizontalLines(
false);
 
  243         messageTable.setShowVerticalLines(
false);
 
  245         messageTable.getParent().setBackground(messageTable.getBackground());
 
  247         renderer = 
new MessageTableRenderer();
 
  248         int numCols = messageTable.getColumnCount();
 
  251         for (
int i = 0; i < numCols; ++i) {
 
  252             messageTable.getColumnModel().getColumn(i).setCellRenderer(renderer);
 
  255         messageTable.setCellSelectionEnabled(
false);
 
  256         messageTable.setColumnSelectionAllowed(
false);
 
  257         messageTable.setRowSelectionAllowed(
true);
 
  258         messageTable.getSelectionModel().addListSelectionListener(
new MessageVisitedSelection());
 
  261         tableModel.addTableModelListener(
this);
 
  265     public void paint(Graphics g) {
 
  269         setTableSize(messageTable.getParent().getSize());
 
  273     public void setPreferredSize(Dimension dmnsn) {
 
  274         super.setPreferredSize(dmnsn);
 
  275         setTableSize(messageTable.getParent().getSize());
 
  278     void setTableSize(Dimension d) {
 
  279         double[] columnWidths = 
new double[]{0.20, 0.08, 0.08, 0.49, 0.15};
 
  280         int numCols = messageTable.getColumnCount();
 
  281         for (
int i = 0; i < numCols; ++i) {
 
  282             messageTable.getColumnModel().getColumn(i).setPreferredWidth((
int)(d.width * columnWidths[i]));
 
  286     public synchronized void addMessage(IngestMessage m) {
 
  287         tableModel.addMessage(m);
 
  291         final int newMsgUnreadUnique = tableModel.getNumberUnreadGroups();
 
  294             messagePcs.firePropertyChange(TOTAL_NUM_MESSAGES_CHANGED, 0, newMsgUnreadUnique);
 
  296         catch (Exception e) {
 
  297             logger.log(Level.SEVERE, 
"IngestMessagePanel listener threw exception", e); 
 
  298             MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(), 
"IngestMessagePanel.moduleErr"),
 
  299                                           NbBundle.getMessage(
this.getClass(),
 
  300                                                               "IngestMessagePanel.moduleErr.errListenUpdates.text"),
 
  301                                           MessageNotifyUtil.MessageType.ERROR);
 
  305         this.totalMessagesNameVal.setText(Long.toString(totalMessages));
 
  306         final int totalMessagesUnique = tableModel.getNumberGroups();
 
  307         this.totalUniqueMessagesNameVal.setText(Integer.toString(totalMessagesUnique));
 
  310     public synchronized void clearMessages() {
 
  311         final int origMsgGroups = tableModel.getNumberUnreadGroups();
 
  313         tableModel.clearMessages();
 
  314         totalMessagesNameVal.setText(
"-");
 
  315         totalUniqueMessagesNameVal.setText(
"-");
 
  318             messagePcs.firePropertyChange(MESSAGES_BOX_CLEARED, origMsgGroups, 0);
 
  320         catch (Exception e) {
 
  321             logger.log(Level.SEVERE, 
"IngestMessagePanel listener threw exception", e); 
 
  322             MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(), 
"IngestMessagePanel.moduleErr"),
 
  323                                           NbBundle.getMessage(
this.getClass(),
 
  324                                                               "IngestMessagePanel.moduleErr.errListenUpdates.text"),
 
  325                                           MessageNotifyUtil.MessageType.ERROR);
 
  329      public synchronized int getMessagesCount() {
 
  330          return tableModel.getNumberMessages();
 
  333     private synchronized void setVisited(
int rowNumber) {
 
  334         final int origMsgGroups = tableModel.getNumberUnreadGroups();
 
  335         tableModel.setVisited(rowNumber);
 
  336         lastRowSelected = rowNumber;
 
  339             messagePcs.firePropertyChange(TOOL_TIP_TEXT_KEY, origMsgGroups, tableModel.getNumberUnreadGroups());
 
  341         catch (Exception e) {
 
  342             logger.log(Level.SEVERE, 
"IngestMessagePanel listener threw exception", e); 
 
  343             MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(), 
"IngestMessagePanel.moduleErr"),
 
  344                                           NbBundle.getMessage(
this.getClass(),
 
  345                                                               "IngestMessagePanel.moduleErr.errListenUpdates.text"),
 
  346                                           MessageNotifyUtil.MessageType.ERROR);
 
  351     public void tableChanged(TableModelEvent e) {
 
  352         int newMessages = tableModel.getNumberNewMessages();
 
  355             messagePcs.firePropertyChange(
new PropertyChangeEvent(tableModel, TOTAL_NUM_NEW_MESSAGES_CHANGED, -1, newMessages));
 
  357         catch (Exception ee) {
 
  358             logger.log(Level.SEVERE, 
"IngestMessagePanel listener threw exception", ee); 
 
  359             MessageNotifyUtil.Notify.show(NbBundle.getMessage(
this.getClass(), 
"IngestMessagePanel.moduleErr"),
 
  360                                           NbBundle.getMessage(
this.getClass(),
 
  361                                                               "IngestMessagePanel.moduleErr.errListenUpdates.text"),
 
  362                                           MessageNotifyUtil.MessageType.ERROR);
 
  369                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.MsgTableMod.colNames.module"),
 
  370                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.MsgTableMod.colNames.num"),
 
  371                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.MsgTableMod.colNames.new"),
 
  372                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.MsgTableMod.colNames.subject"),
 
  373                 NbBundle.getMessage(this.getClass(), 
"IngestMessagePanel.MsgTableMod.colNames.timestamp")};
 
  376         private final Map<String, Map<String, List<IngestMessageGroup>>> 
groupings = 
new HashMap<>();
 
  383             return columnNames.length;
 
  392             for (TableEntry entry : messageData) {
 
  393                 entry.hasBeenSeen(
true);
 
  395             fireTableChanged(
new TableModelEvent(
this));
 
  400             for (TableEntry entry : messageData) {
 
  401                 if (!entry.hasBeenSeen()) {
 
  409             return messageData.size();
 
  414             for (TableEntry e : messageData) {
 
  415                 total += e.messageGroup.getCount();
 
  422             for (TableEntry e : messageData) {
 
  423                 if (!e.hasBeenVisited) {
 
  424                     total += e.messageGroup.getCount();
 
  432             for (TableEntry e : messageData) {
 
  433                 if (!e.hasBeenVisited) {
 
  442             return columnNames[column];
 
  446         public synchronized Object 
getValueAt(
int rowIndex, 
int columnIndex) {
 
  449             int numMessages = messageData.size();
 
  450             if (rowIndex > messageData.size() - 1 ||
 
  451                     columnIndex > columnNames.length - 1) {
 
  454                 logger.log(Level.WARNING, 
"Requested inbox message at" + rowIndex, 
", only have " + numMessages); 
 
  457             TableEntry entry = messageData.get(rowIndex);
 
  459             switch (columnIndex) {
 
  461                     ret = entry.messageGroup.getSource();
 
  464                     ret = entry.messageGroup.getCount();
 
  467                     ret = !entry.hasBeenSeen();
 
  470                     ret = entry.messageGroup.getSubject();
 
  473                     ret = entry.messageGroup.getDatePosted();
 
  476                     logger.log(Level.SEVERE, 
"Invalid table column index: {0}", columnIndex); 
 
  495             for (TableEntry e : messageData) {
 
  496                 if (e.messageGroup.getUniqueKey().equals(uniqueKey)) {
 
  509             IngestMessageGroup messageGroup = null;
 
  512                 if (!groupings.containsKey(moduleName)) {
 
  513                     groupings.put(moduleName, 
new HashMap<String, List<IngestMessageGroup>>());                    
 
  515                 final Map<String, List<IngestMessageGroup>> groups = groupings.get(moduleName);                
 
  518                 List<IngestMessageGroup> uniqGroups = groups.get(uniqueness);
 
  519                 if (uniqGroups == null) {
 
  521                     uniqGroups = 
new ArrayList<>();
 
  522                     messageGroup = 
new IngestMessageGroup(m);
 
  523                     uniqGroups.add(messageGroup);
 
  524                     groups.put(uniqueness, uniqGroups);
 
  526                     final int uniqueGroupsCount = uniqGroups.size();
 
  527                     if (uniqueGroupsCount > MESSAGE_GROUP_THRESH) {
 
  529                         messageGroup = uniqGroups.get(0);
 
  530                         for (
int i = 1; i < uniqueGroupsCount; ++i) {
 
  531                             messageGroup.addAll(uniqGroups.get(i));
 
  539                         uniqGroups.add(messageGroup);
 
  544                             messageData.remove(toRemove);
 
  546                             this.fireTableRowsDeleted(toRemove, toRemove);
 
  549                     } 
else if (uniqueGroupsCount == 1) {
 
  550                         IngestMessageGroup first = uniqGroups.get(0);
 
  552                         if (first.getCount() > 1) {
 
  555                             messageGroup = first;
 
  560                                 messageData.remove(toRemove);
 
  562                                 this.fireTableRowsDeleted(toRemove, toRemove);
 
  568                             messageGroup = 
new IngestMessageGroup(m);
 
  569                             uniqGroups.add(messageGroup);
 
  575                         messageGroup = 
new IngestMessageGroup(m);
 
  576                         uniqGroups.add(messageGroup);
 
  583                 messageGroup = 
new IngestMessageGroup(m);
 
  587             messageData.add(
new TableEntry(messageGroup));
 
  588             int newRowIndex = messageData.size() -1;
 
  589             fireTableRowsInserted(newRowIndex, newRowIndex);
 
  592             if (chronoSort == 
false) {
 
  593                 Collections.sort(messageData);
 
  594                 fireTableDataChanged();
 
  601             fireTableDataChanged();
 
  605             messageData.get(rowNumber).hasBeenVisited(
true);
 
  607             fireTableCellUpdated(rowNumber, 2);
 
  612             for (TableEntry e : messageData) {
 
  613                 if (!e.hasBeenVisited) {
 
  614                     e.hasBeenVisited(
true);
 
  615                     fireTableCellUpdated(row, 2);
 
  622             if (rowNumber < messageData.size()) {
 
  623                 return messageData.get(rowNumber).hasBeenVisited();
 
  630             if (rowNumber < messageData.size()) {
 
  631                 return messageData.get(rowNumber).messageGroup.getMessageType();
 
  638             if (rowNumber < messageData.size()) {
 
  639                 return messageData.get(rowNumber).messageGroup;
 
  645         public synchronized void reSort(
boolean chronoLogical) {
 
  646             if (chronoSort == chronoLogical) {
 
  650             chronoSort = chronoLogical;
 
  651             Collections.sort(messageData);
 
  652             fireTableDataChanged();
 
  655         class TableEntry 
implements Comparable<TableEntry> {
 
  657             IngestMessageGroup messageGroup;
 
  658             boolean hasBeenVisited = 
false;
 
  659             boolean hasBeenSeen = 
false;
 
  661             public boolean hasBeenVisited() {
 
  662                 return hasBeenVisited;
 
  665             public void hasBeenVisited(
boolean visited) {
 
  666                 hasBeenVisited = visited;
 
  669             public boolean hasBeenSeen() {
 
  673             public void hasBeenSeen(
boolean seen) {
 
  677             TableEntry(IngestMessageGroup messageGroup) {
 
  678                 this.messageGroup = messageGroup;
 
  682             public int compareTo(TableEntry o) {
 
  683                 if (chronoSort == 
true) {
 
  684                     return this.messageGroup.getDatePosted().compareTo(o.messageGroup.getDatePosted());
 
  686                     return messageGroup.getCount() - o.messageGroup.getCount();
 
  694     static class IngestMessageGroup {
 
  696         static final Color VERY_HIGH_PRI_COLOR = 
new Color(164, 164, 202); 
 
  697         static final Color HIGH_PRI_COLOR = 
new Color(180, 180, 211);
 
  698         static final Color MED_PRI_COLOR = 
new Color(199, 199, 222);
 
  699         static final Color LOW_PRI_COLOR = 
new Color(221, 221, 235);
 
  700         private final List<IngestMessage> messages;
 
  702         IngestMessageGroup(IngestMessage message) {
 
  703             messages = 
new ArrayList<>();
 
  704             messages.add(message);
 
  707         private List<IngestMessage> getMessages() {
 
  711         synchronized void add(IngestMessage message) {
 
  712             messages.add(message);
 
  716         synchronized void addAll(IngestMessageGroup group) {
 
  717             for (IngestMessage m : group.getMessages()) {
 
  722         synchronized int getCount() {
 
  723             return messages.size();
 
  726        synchronized String getDetails() {
 
  727             StringBuilder b = 
new StringBuilder(
"");
 
  728             for (IngestMessage m : messages) {
 
  729                 String details = m.getDetails();
 
  730                 if (details == null || details.equals(
"")) {
 
  745         synchronized Color getColor() {
 
  746             int count = messages.size();
 
  748                 return VERY_HIGH_PRI_COLOR;
 
  749             } 
else if (count < 5) {
 
  750                 return HIGH_PRI_COLOR;
 
  751             } 
else if (count < 15) {
 
  752                 return MED_PRI_COLOR;
 
  754                 return LOW_PRI_COLOR;
 
  763         synchronized Date getDatePosted() {
 
  764             return messages.get(messages.size() - 1).getDatePosted();
 
  771         synchronized String getSubject() {
 
  772             return messages.get(0).getSubject();
 
  778         synchronized String getUniqueKey() {
 
  779             return messages.get(0).getUniqueKey();
 
  785         synchronized String getSource() {
 
  786             return messages.get(0).getSource();
 
  792         synchronized BlackboardArtifact getData() {
 
  793             return messages.get(0).getData();
 
  799         synchronized IngestMessage.MessageType getMessageType() {
 
  800             return messages.get(0).getMessageType();
 
  822             if (value instanceof Boolean) {
 
  823                 return booleanRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
  824             } 
else if (value instanceof Date) {
 
  825                 return dateRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
  827                 return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
  837         private final String 
bulletChar = 
new String(Character.toChars(0x2022));
 
  842             super.setForeground(table.getSelectionForeground());
 
  843             super.setBackground(table.getSelectionBackground());
 
  846             if (value instanceof Boolean) {
 
  847                 boolVal = ((Boolean)value);
 
  849                 throw new RuntimeException(NbBundle.getMessage(
this.getClass(),
 
  850                                                                "IngestMessagePanel.BooleanRenderer.exception.nonBoolVal.msg"));
 
  853             String aValue = boolVal ? bulletChar : 
"";
 
  855             JLabel cell = (JLabel)super.getTableCellRendererComponent(table, aValue, isSelected, hasFocus, row, column);
 
  858             cell.setHorizontalAlignment(SwingConstants.CENTER);
 
  861             cell.setFont(cell.getFont().deriveFont(Font.PLAIN, 16));
 
  863             final IngestMessageGroup messageGroup = tableModel.getMessageGroup(row);
 
  864             if (messageGroup != null) {
 
  867                     cell.setBackground(ERROR_COLOR);
 
  869                     cell.setBackground(Color.orange);
 
  872                     cell.setBackground(messageGroup.getColor());
 
  887                 JTable table, Object value,
 
  888                 boolean isSelected, 
boolean hasFocus,
 
  889                 int row, 
int column) {
 
  891             Component cell = super.getTableCellRendererComponent(
 
  892                     table, value, 
false, 
false, row, column);
 
  894             Font visitedFont = cell.getFont().deriveFont(Font.PLAIN, 12);
 
  895             Font notVisitedFont = cell.getFont().deriveFont(Font.BOLD, 12);
 
  898                 String subject = (String)value;
 
  899                 setToolTipText(subject);
 
  900                 if (tableModel.isVisited(row)) {
 
  901                     cell.setFont(visitedFont);
 
  903                     cell.setFont(notVisitedFont);
 
  907             final IngestMessageGroup messageGroup = tableModel.getMessageGroup(row);
 
  908             if (messageGroup != null) {
 
  911                     cell.setBackground(ERROR_COLOR);
 
  913                     cell.setBackground(Color.orange);
 
  916                     cell.setBackground(messageGroup.getColor());
 
  928             super.setForeground(table.getSelectionForeground());
 
  929             super.setBackground(table.getSelectionBackground());
 
  931             Object aValue = value;
 
  932             if (value instanceof Date) {
 
  933                 Date date = (Date)value;
 
  934                 DateFormat df = 
new SimpleDateFormat(
"HH:mm:ss");
 
  935                 aValue = df.format(date);
 
  937                 throw new RuntimeException(NbBundle.getMessage(
this.getClass(),
 
  938                                                                "IngestMessagePanel.DateRenderer.exception.nonDateVal.text"));
 
  941             Component cell =  super.getTableCellRendererComponent(table, aValue, isSelected, hasFocus, row, column);
 
  943             final IngestMessageGroup messageGroup = tableModel.getMessageGroup(row);
 
  944             if (messageGroup != null) {
 
  947                     cell.setBackground(ERROR_COLOR);
 
  949                     cell.setBackground(Color.orange);
 
  952                     cell.setBackground(messageGroup.getColor());
 
  967             ListSelectionModel selModel = (ListSelectionModel) e.getSource();
 
  968             if (selModel.isSelectionEmpty() || selModel.getValueIsAdjusting()) {
 
  972             final int minIndex = selModel.getMinSelectionIndex();
 
  973             final int maxIndex = selModel.getMaxSelectionIndex();
 
  975             for (
int i = minIndex; i <= maxIndex; i++) {
 
  976                 if (selModel.isSelectedIndex(i)) {
 
  981             selModel.clearSelection();
 
  982             if (selected != -1) {
 
  983                 setVisited(selected);
 
  984                 messageTable.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 
  986                 IngestMessageGroup m = getMessageGroup(selected);
 
  988                     String details = m.getDetails();
 
  989                     if (details != null && !details.equals(
"")) {
 
  990                         mainPanel.showDetails(selected);
 
  993                 messageTable.setCursor(null);
 
synchronized int getRowCount()
 
synchronized int getTableEntryIndex(String uniqueKey)
 
final TableCellRenderer defaultRenderer
 
synchronized IngestMessageGroup getMessageGroup(int rowNumber)
 
Class<?> getColumnClass(int c)
 
boolean isCellEditable(int rowIndex, int columnIndex)
 
synchronized int getNumberNewMessages()
 
MessageType getMessageType()
 
synchronized void markAllSeen()
 
static final int MESSAGE_GROUP_THRESH
 
String getColumnName(int column)
 
final Map< String, Map< String, List< IngestMessageGroup > > > groupings
 
synchronized int getNumberUnreadMessages()
 
final String[] columnNames
 
final TableCellRenderer dateRenderer
 
synchronized int getNumberUnreadGroups()
 
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
 
void valueChanged(ListSelectionEvent e)
 
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
 
synchronized int getNumberGroups()
 
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
 
synchronized void setVisitedAll()
 
void setRowSelected(int rowSelected)
 
synchronized void addMessage(IngestMessage m)
 
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
 
synchronized void clearMessages()
 
synchronized int getNumberMessages()
 
synchronized boolean isVisited(int rowNumber)
 
final TableCellRenderer booleanRenderer
 
synchronized MessageType getMessageType(int rowNumber)
 
final List< TableEntry > messageData
 
synchronized Object getValueAt(int rowIndex, int columnIndex)
 
synchronized void setVisited(int rowNumber)
 
static Logger getLogger(String name)
 
synchronized void reSort(boolean chronoLogical)