Coverage Report - com.nilhcem.fakesmtp.gui.tab.MailsListPane
 
Classes in this File Line Coverage Branch Coverage Complexity
MailsListPane
0%
0/45
0%
0/10
2.231
MailsListPane$1
0%
0/2
N/A
2.231
MailsListPane$2
0%
0/2
N/A
2.231
MailsListPane$3
0%
0/23
0%
0/14
2.231
MailsListPane$4
0%
0/3
N/A
2.231
MailsListPane$5
0%
0/9
0%
0/2
2.231
 
 1  
 package com.nilhcem.fakesmtp.gui.tab;
 2  
 
 3  
 import com.nilhcem.fakesmtp.core.ArgsHandler;
 4  
 import com.nilhcem.fakesmtp.core.Configuration;
 5  
 import com.nilhcem.fakesmtp.core.I18n;
 6  
 import com.nilhcem.fakesmtp.gui.info.ClearAllButton;
 7  
 import com.nilhcem.fakesmtp.model.EmailModel;
 8  
 import com.nilhcem.fakesmtp.model.UIModel;
 9  
 import com.nilhcem.fakesmtp.server.MailSaver;
 10  
 import org.slf4j.Logger;
 11  
 import org.slf4j.LoggerFactory;
 12  
 
 13  
 import javax.mail.internet.MimeUtility;
 14  
 import javax.swing.JOptionPane;
 15  
 import javax.swing.JScrollPane;
 16  
 import javax.swing.JTable;
 17  
 import javax.swing.table.DefaultTableModel;
 18  
 import java.awt.Desktop;
 19  
 import java.awt.Rectangle;
 20  
 import java.awt.event.ComponentAdapter;
 21  
 import java.awt.event.ComponentEvent;
 22  
 import java.awt.event.MouseEvent;
 23  
 import java.awt.event.MouseListener;
 24  
 import java.io.File;
 25  
 import java.io.IOException;
 26  
 import java.io.UnsupportedEncodingException;
 27  
 import java.text.SimpleDateFormat;
 28  
 import java.util.Observable;
 29  
 import java.util.Observer;
 30  
 
 31  
 /**
 32  
  * Scrolled table where will be displayed every received email (one line for each email).
 33  
  * <p>
 34  
  * The user can double-click on any row to see the selected email.
 35  
  * </p>
 36  
  *
 37  
  * @author Nilhcem
 38  
  * @since 1.0
 39  
  */
 40  0
 public final class MailsListPane implements Observer {
 41  
 
 42  0
         private int nbElements = 0;
 43  0
         private Desktop desktop = null;
 44  0
         private static final Logger LOGGER = LoggerFactory.getLogger(MailsListPane.class);
 45  0
         private final I18n i18n = I18n.INSTANCE;
 46  0
         private final JScrollPane mailsListPane = new JScrollPane();
 47  0
         private final SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss a");
 48  0
         private final int[] widths = new int[] {85, 140, 140}; // widths of columns in tab
 49  
 
 50  
         /**
 51  
          * Table with non-editable cells.
 52  
          */
 53  0
         private final JTable table = new JTable() {
 54  
                 private static final long serialVersionUID = 6332956458868628779L;
 55  
 
 56  
                 @Override
 57  
                 public boolean isCellEditable(int row, int column) {
 58  0
                         return false;
 59  
                 }
 60  
         };
 61  
 
 62  
         /**
 63  
          * Table model with non-editable cells.
 64  
          */
 65  0
         private final DefaultTableModel model = new DefaultTableModel() {
 66  
                 private static final long serialVersionUID = -6716294637919469299L;
 67  
 
 68  
                 public boolean isCellEditable(int rowIndex, int mColIndex) {
 69  0
                         return false;
 70  
                 }
 71  
         };
 72  
 
 73  
         /**
 74  
          * Creates the table and sets its cells as non editable.
 75  
          * <p>
 76  
          * Adds some mouse events on the table, to display emails, when a user clicks on
 77  
          * a specific row.<br>
 78  
          * If the email can't be found, an error message will be displayed.<br>
 79  
          * The table will reset the size of its column every time the size of the table changed
 80  
          * (for example when the user maximizes the window).
 81  
          * </p>
 82  
          */
 83  0
         public MailsListPane() {
 84  
                 // Init desktop (Java 6 Desktop API)
 85  0
                 if (Desktop.isDesktopSupported()) {
 86  0
                         desktop = Desktop.getDesktop();
 87  
                 }
 88  
 
 89  0
                 if (!ArgsHandler.INSTANCE.memoryModeEnabled()) {
 90  0
                         table.addMouseListener(new MouseListener() {
 91  
                                 @Override
 92  
                                 public void mouseReleased(MouseEvent e) {
 93  0
                                 }
 94  
 
 95  
                                 @Override
 96  
                                 public void mousePressed(MouseEvent e) {
 97  0
                                 }
 98  
 
 99  
                                 @Override
 100  
                                 public void mouseExited(MouseEvent e) {
 101  0
                                 }
 102  
 
 103  
                                 @Override
 104  
                                 public void mouseEntered(MouseEvent e) {
 105  0
                                 }
 106  
 
 107  
                                 @Override
 108  
                                 public void mouseClicked(MouseEvent e) {
 109  
 
 110  0
                                         String emlViewer = ArgsHandler.INSTANCE.getEmlViewer();
 111  
 
 112  0
                                         if (e.getClickCount() == 2 && (emlViewer != null || desktop != null)) {
 113  0
                                                 File file = null;
 114  0
                                                 JTable target = (JTable) e.getSource();
 115  0
                                                 String fileName = UIModel.INSTANCE.getListMailsMap().get(target.getSelectedRow());
 116  0
                                                 if (fileName == null) {
 117  0
                                                         LOGGER.error("Can't find any associated email for row #{}", target.getSelectedRow());
 118  
                                                 } else {
 119  0
                                                         file = new File(fileName);
 120  
                                                 }
 121  
 
 122  0
                                                 if (file != null && file.exists()) {
 123  
                                                         try {
 124  0
                                                                 if (emlViewer != null) {
 125  0
                                                                         Runtime.getRuntime().exec(emlViewer + " " + file.getAbsolutePath());
 126  
                                                                 } else {
 127  0
                                                                         desktop.open(file);
 128  
                                                                 }
 129  0
                                                         } catch (IOException ioe) {
 130  0
                                                                 LOGGER.error("", ioe);
 131  0
                                                                 displayError(String.format(i18n.get("mailslist.err.open"), file.getAbsolutePath()));
 132  0
                                                         }
 133  
                                                 } else {
 134  0
                                                         displayError(String.format(i18n.get("mailslist.err.find"), file.getAbsolutePath()));
 135  
                                                 }
 136  
                                         }
 137  0
                                 }
 138  
                         });
 139  
         }
 140  
 
 141  
                 // Auto scroll tab to bottom when a new element is inserted
 142  0
                 table.addComponentListener(new ComponentAdapter() {
 143  
                         public void componentResized(ComponentEvent e) {
 144  0
                                 table.scrollRectToVisible(new Rectangle(table.getCellRect(nbElements, 0, true)));
 145  0
                         }
 146  
                 });
 147  
 
 148  0
                 model.addColumn(i18n.get("mailslist.col.received"));
 149  0
                 model.addColumn(i18n.get("mailslist.col.from"));
 150  0
                 model.addColumn(i18n.get("mailslist.col.to"));
 151  0
                 model.addColumn(i18n.get("mailslist.col.subject"));
 152  0
                 table.setModel(model);
 153  
 
 154  0
                 mailsListPane.addComponentListener(new ComponentAdapter() {
 155  
                         public void componentResized(ComponentEvent e) {
 156  
                                 // When the width of a column is changed, only the columns to the left and right of the margin change
 157  0
                                 table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
 158  
 
 159  
                                 // Set width for each column
 160  0
                                 int total = 0;
 161  0
                                 int length = widths.length;
 162  0
                                 for (int i = 0; i < length; i++) {
 163  0
                                         table.getColumnModel().getColumn(i).setPreferredWidth(widths[i]);
 164  0
                                         total += widths[i];
 165  
                                 }
 166  0
                                 table.getColumnModel().getColumn(length).setPreferredWidth(table.getWidth() - total);
 167  0
                         }
 168  
                 });
 169  0
                 mailsListPane.getViewport().add(table, null);
 170  0
         }
 171  
 
 172  
         /**
 173  
          * Returns the JScrollPane object.
 174  
          *
 175  
          * @return the JScrollPane object.
 176  
          */
 177  
         public JScrollPane get() {
 178  0
                 return mailsListPane;
 179  
         }
 180  
 
 181  
         /**
 182  
          * Updates the content of the table.
 183  
          * <p>
 184  
          * This method will be called by an observable element.
 185  
      * </p>
 186  
          * <ul>
 187  
          *   <li>If the observable is a {@link MailSaver} object, a new row will be added
 188  
          *   to the table, and the {@link UIModel} will be updated;</li>
 189  
          *   <li>If the observable is a {@link ClearAllButton} object, all the cells
 190  
          *   of the table will be removed, and the {@link UIModel} will be updated.</li>
 191  
          * </ul>
 192  
          *
 193  
          * @param o the observable element which will notify this class.
 194  
          * @param arg optional parameters (an {@code EmailModel} object, for the case of
 195  
          * a {@code MailSaver} observable) containing all the information about the email.
 196  
          */
 197  
         @Override
 198  
         public void update(Observable o, Object arg) {
 199  0
                 if (o instanceof MailSaver) {
 200  0
                         EmailModel email = (EmailModel) arg;
 201  
                         String subject;
 202  
                         try {
 203  0
                                 subject = MimeUtility.decodeText(email.getSubject());
 204  0
                         } catch (UnsupportedEncodingException e) {
 205  0
                                 LOGGER.error("", e);
 206  0
                                 subject = email.getSubject();
 207  0
                         }
 208  
 
 209  0
                         model.addRow(new Object[] {dateFormat.format(email.getReceivedDate()), email.getFrom(), email.getTo(), subject});
 210  0
                         UIModel.INSTANCE.getListMailsMap().put(nbElements++, email.getFilePath());
 211  0
                 } else if (o instanceof ClearAllButton) {
 212  
                         // Delete information from the map
 213  0
                         UIModel.INSTANCE.getListMailsMap().clear();
 214  
 
 215  
                         // Remove elements from the list
 216  
                         try {
 217  0
                                 while (nbElements > 0) {
 218  0
                                         model.removeRow(--nbElements);
 219  
                                 }
 220  0
                         } catch (ArrayIndexOutOfBoundsException e) {
 221  0
                                 LOGGER.error("", e);
 222  0
                         }
 223  
                 }
 224  0
         }
 225  
 
 226  
         /**
 227  
          * Displays a message dialog containing the error specified in parameter.
 228  
          *
 229  
          * @param error a String representing an error message to display.
 230  
          */
 231  
         private void displayError(String error) {
 232  0
                 JOptionPane.showMessageDialog(mailsListPane.getParent(), error,
 233  0
                         String.format(i18n.get("mailslist.err.title"), Configuration.INSTANCE.get("application.name")),
 234  
                         JOptionPane.ERROR_MESSAGE);
 235  0
         }
 236  
 }