// ImportTransactionDialog package org.javamoney.examples.ez.money.gui.dialog; import static org.javamoney.examples.ez.common.utility.ButtonHelper.buildButton; import static org.javamoney.examples.ez.common.utility.I18NHelper.getSharedProperty; import static org.javamoney.examples.ez.money.utility.DialogHelper.inform; import static org.javamoney.examples.ez.money.utility.TransactionDateHelper.isInRange; import static org.javamoney.examples.ez.money.utility.TransactionHelper.getCorrespondingTransferReference; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Collection; import javax.swing.JMenuItem; import javax.swing.JTabbedPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.javamoney.examples.ez.money.IconKeys; import org.javamoney.examples.ez.money.gui.GUIConstants; import org.javamoney.examples.ez.money.gui.table.ImportDuplicateTable; import org.javamoney.examples.ez.money.gui.table.ImportTransactionTable; import org.javamoney.examples.ez.money.model.dynamic.transaction.ImportTransaction; import org.javamoney.examples.ez.money.model.persisted.account.Account; import org.javamoney.examples.ez.money.model.persisted.transaction.Transaction; import org.javamoney.examples.ez.common.gui.DialogHeader; import org.javamoney.examples.ez.common.gui.Panel; import org.javamoney.examples.ez.common.gui.PopupMenu; import org.javamoney.examples.ez.common.gui.ScrollPane; import org.javamoney.examples.ez.common.utility.I18NHelper; /** * This class provides a dialog for choosing transactions to import. */ public final class ImportTransactionDialog extends ApplicationDialog { /** * Constructs a new dialog for choosing transactions to import. * * @param account The account to import the transactions into. * @param collection The transactions to import. */ public ImportTransactionDialog(Account account, Collection<ImportTransaction> collection) { super(800, 600); setAccount(account); setDuplicates(new ImportDuplicateTable()); setTable(new ImportTransactionTable()); setTransactions(collection); buildPanel(); // Add listeners. getDuplicates().addMouseListener(createPopupMenuForDuplicates()); getDuplicates().addMouseListener(new MouseHandler()); getTable().addMouseListener(createPopupMenu()); getTable().getSelectionModel().addListSelectionListener(new SelectionHandler()); } /** * This method returns the collection of transactions to import or null if the * dialog was canceled. * * @return The collection of transactions to import or null if the dialog was * canceled. */ public Collection<ImportTransaction> showDialog() { ProcessWorker processWorker = new ProcessWorker(); Collection<ImportTransaction> transactions = getTransactions(); if(transactions.size() != 0) { // Compute possible duplicates as a process. processWorker.showDialog(); if(processWorker.wasAccepted() == true) { // Display all the available transactions. getTable().display(); if(getTable().getRowCount() != 0) { getTable().selectRow(0); } runDialog(); } if(wasAccepted() != true || transactions.size() == 0) { transactions = null; } } else { inform(getProperty("no_transactions.title"), getProperty("no_transactions.description")); transactions = null; } return transactions; } ////////////////////////////////////////////////////////////////////////////// // Start of private methods. ////////////////////////////////////////////////////////////////////////////// private void buildPanel() { Panel panel = getContentPane(); // Build panel. panel.setFill(GridBagConstraints.BOTH); panel.add(createDialogHeader(), 0, 0, 1, 1, 100, 0); panel.add(createTablePanel(), 0, 1, 1, 1, 0, 50); panel.addEmptyCellAt(0, 2); panel.add(createDuplicatesPanel(), 0, 3, 1, 1, 0, 50); panel.add(createOKCancelButtonPanel(new ActionHandler()), 0, 4, 1, 1, 0, 0); } private static DialogHeader createDialogHeader() { String description = getProperty("header.description"); String title = getProperty("header.title"); return new DialogHeader(title, description, IconKeys.DIALOG_IMPORT.getIcon()); } private Panel createDuplicatesPanel() { Panel panel = new Panel(); ScrollPane scrollPane = new ScrollPane(getDuplicates()); JTabbedPane tabs = new JTabbedPane(); // Build scroll pane. scrollPane.setBackground(GUIConstants.COLOR_BACKGROUND_FILL); // Build tab. tabs.addTab(getProperty("duplicates"), scrollPane); // Build panel. panel.setFill(GridBagConstraints.BOTH); panel.add(tabs, 0, 0, 1, 1, 100, 100); panel.setInsets(new Insets(5, 5, 0, 5)); return panel; } private Panel createImportPanel() { Panel panel = new Panel(); String account = "<html><b>" + getAccount().getIdentifier() + "</b></html>"; // Build panel. panel.setAnchor(GridBagConstraints.EAST); panel.addEmptyCellAt(0, 0); panel.add(getProperty("account") + ": ", 0, 1, 1, 1, 0, 100); panel.setAnchor(GridBagConstraints.WEST); panel.add(account, 1, 1, 1, 1, 100, 0); panel.addEmptyCellAt(0, 2); return panel; } private static JMenuItem createMenuItem(String command, ActionHandler handler) { JMenuItem item = new JMenuItem(); // Build items. buildButton(item, command, handler); return item; } private PopupMenu createPopupMenu() { PopupMenu menu = new PopupMenu(); ActionHandler handler = new ActionHandler(); // Add items to menu. menu.add(createMenuItem(ACTION_SELECT_ALL, handler)); menu.addSeparator(); menu.add(createMenuItem(ACTION_SELECT_NON_DUPLICATES, handler)); return menu; } private PopupMenu createPopupMenuForDuplicates() { PopupMenu menu = new PopupMenu(); ActionHandler handler = new ActionHandler(); // Add items to menu. menu.add(createMenuItem(ACTION_RECONCILED, handler)); menu.add(createMenuItem(ACTION_PENDING, handler)); return menu; } private Panel createTablePanel() { Panel panel = new Panel(); ScrollPane scrollPane = new ScrollPane(getTable()); // Build scroll pane. scrollPane.setBackground(GUIConstants.COLOR_BACKGROUND_FILL); // Build panel. panel.setFill(GridBagConstraints.BOTH); panel.add(createImportPanel(), 0, 0, 1, 1, 100, 0); panel.add(scrollPane, 0, 1, 1, 1, 0, 100); panel.setInsets(new Insets(5, 5, 0, 5)); return panel; } private Account getAccount() { return itsAccount; } private ImportDuplicateTable getDuplicates() { return itsDuplicates; } private static String getProperty(String key) { return I18NHelper.getProperty("ImportTransactionDialog." + key); } private ImportTransactionTable getTable() { return itsTable; } private Collection<ImportTransaction> getTransactions() { return itsTransactions; } private static boolean hasPossibleDuplicate(Transaction trans, Transaction iTrans) { boolean result = false; // A possible duplicate is one that occurred within 7 days (+/-) and has the // same amount. if(isInRange(iTrans, trans.getDate(), 7) == true) { if(trans.getAmount() == iTrans.getAmount()) { result = true; } } return result; } private void selectAll() { for(ImportTransaction trans : getTable().getList()) { trans.setIsSelected(true); } getTable().repaint(); } private void selectNonDuplicates() { for(ImportTransaction trans : getTable().getList()) { trans.setIsSelected(trans.hasDuplicates() == false); } getTable().repaint(); } private void setAccount(Account account) { itsAccount = account; } private void setDuplicates(ImportDuplicateTable table) { itsDuplicates = table; } private void setTable(ImportTransactionTable table) { itsTable = table; } private void setReconciled(boolean reconciled) { for(int row : getDuplicates().getSelectedRows()) { Transaction trans = getDuplicates().get(row); Transaction transfer = getCorrespondingTransferReference(trans, getAccount()); trans.setIsReconciled(reconciled); // Apply to transfer if applicable. if(transfer != null) { transfer.setIsReconciled(reconciled); } } getDuplicates().repaint(); } private void setTransactions(Collection<ImportTransaction> collection) { itsTransactions = collection; } ////////////////////////////////////////////////////////////////////////////// // Start of inner classes. ////////////////////////////////////////////////////////////////////////////// private class ActionHandler implements ActionListener { public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if(command.equals(ACTION_PENDING) == true) { setReconciled(false); } else if(command.equals(ACTION_RECONCILED) == true) { setReconciled(true); } else if(command.equals(ACTION_SELECT_ALL) == true) { selectAll(); } else if(command.equals(ACTION_SELECT_NON_DUPLICATES) == true) { selectNonDuplicates(); } else { setAccepted(command.equals(ACTION_OK)); dispose(); } } } private class ProcessWorker extends ProcessDialog { protected ProcessWorker() { super(ImportTransactionDialog.getProperty("processing"), getTransactions().size()); } @Override protected void doProcess() { for(ImportTransaction iTrans : getTransactions()) { // Put the transactions into the table. getTable().add(iTrans); for(Transaction trans : getAccount().getTransactions()) { if(hasPossibleDuplicate(trans, iTrans.getTransaction()) == true) { iTrans.getDuplicates().add(trans); } // Check to see if the user canceled the process. if(canProcess() == false) { break; } } iTrans.setIsSelected(iTrans.hasDuplicates() == false); setValue(getValue() + 1); // Check to see if the user canceled the process. if(canProcess() == false) { break; } } signalProcessIsDone(); } } private class MouseHandler extends MouseAdapter { @Override public void mouseClicked(MouseEvent event) { if(event.getButton() == MouseEvent.BUTTON1 && event.getClickCount() == 2) { Transaction trans = getDuplicates().getSelectedElement(); if(trans != null) { int column = getDuplicates().getIndexForColumn(getTable().getColumnIndexAtX(event.getX())); if(column == ImportDuplicateTable.RECONCILED_COLUMN) { setReconciled(!trans.isReconciled()); } } } } } private class SelectionHandler implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { if(event.getValueIsAdjusting() == false && getTable().getSelectedRow() != -1) { ImportTransaction iTrans = getTable().getSelectedElement(); getDuplicates().clear(); for(Transaction trans : iTrans.getDuplicates()) { getDuplicates().add(trans); } getDuplicates().display(); } } } ////////////////////////////////////////////////////////////////////////////// // Start of class members. ////////////////////////////////////////////////////////////////////////////// private Account itsAccount; private ImportDuplicateTable itsDuplicates; private ImportTransactionTable itsTable; private Collection<ImportTransaction> itsTransactions; private static final String ACTION_PENDING = getSharedProperty("mark_pending"); private static final String ACTION_RECONCILED = getSharedProperty("mark_reconciled"); private static final String ACTION_SELECT_ALL = getProperty("select_all"); private static final String ACTION_SELECT_NON_DUPLICATES = getProperty("select_non_duplicates"); }