biz.wolschon.finance.jgnucash.panels.WritableTransactionsPanel.java Source code

Java tutorial

Introduction

Here is the source code for biz.wolschon.finance.jgnucash.panels.WritableTransactionsPanel.java

Source

/**
 * WritableTransactionsPanel.java
 * created: 21.09.2008 07:49:55
 * (c) 2008 by <a href="http://Wolschon.biz">Wolschon Softwaredesign und Beratung</a>
 * This file is part of jgnucashLib-V1 by Marcus Wolschon <a href="mailto:Marcus@Wolscon.biz">Marcus@Wolscon.biz</a>.
 * You can purchase support for a sensible hourly rate or
 * a commercial license of this file (unless modified by others) by contacting him directly.
 *
 *  jgnucashLib-V1 is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  jgnucashLib-V1 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with jgnucashLib-V1.  If not, see <http://www.gnu.org/licenses/>.
 *
 ***********************************
 * Editing this file:
 *  -For consistent code-quality this file should be checked with the
 *   checkstyle-ruleset enclosed in this project.
 *  -After the design of this file has settled it should get it's own
 *   JUnit-Test that shall be executed regularly. It is best to write
 *   the test-case BEFORE writing this class and to run it on every build
 *   as a regression-test.
 */
package biz.wolschon.finance.jgnucash.panels;

//other imports

import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTable;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.java.plugin.PluginManager;
import org.java.plugin.registry.Extension;
import org.java.plugin.registry.ExtensionPoint;
import org.java.plugin.registry.PluginDescriptor;

import biz.wolschon.fileformats.gnucash.GnucashAccount;
import biz.wolschon.fileformats.gnucash.GnucashTransactionSplit;
import biz.wolschon.fileformats.gnucash.GnucashWritableTransactionSplit;
import biz.wolschon.finance.jgnucash.models.GnucashAccountTransactionsTableModel;
import biz.wolschon.finance.jgnucash.models.GnucashTransactionSplitsTableModel;
import biz.wolschon.finance.jgnucash.plugin.TransactionMenuAction;
import biz.wolschon.finance.jgnucash.swingModels.GnucashSimpleAccountTransactionsTableModel;

//automatically created propertyChangeListener-Support
//import java.beans.PropertyChangeListener;
//import java.beans.PropertyChangeSupport;

/**
 * (c) 2008 by <a href="http://Wolschon.biz>Wolschon Softwaredesign und Beratung</a>.<br/>
 * Project: jgnucashLib-V1<br/>
 * WritableTransactionsPanel.java<br/>
 * created: 21.09.2008 07:49:55 <br/>
 *<br/><br/>
 * <b>Variant of TransactionsPanel that allows editing the transactions.</b>
 * @author <a href="mailto:Marcus@Wolschon.biz">Marcus Wolschon</a>
 */
public class WritableTransactionsPanel extends TransactionsPanel {
    /**
     * Our logger for debug- and error-output.
     */
    static final Log LOGGER = LogFactory.getLog(WritableTransactionsPanel.class);

    /**
     * (c) 2008 by <a href="http://Wolschon.biz>Wolschon Softwaredesign und Beratung</a>.<br/>
     * Project: jgnucashLib-GPL<br/>
     * TransactionMenuActionMenuAction<br/>
     * created: 12.11.2008 <br/>
     *<br/><br/>
     * <b>Have a plugin react to it's menu-point in the context-menu.</b>
     * @author  <a href="mailto:Marcus@Wolschon.biz">fox</a>
     */
    public class TransactionMenuActionMenuAction implements ActionListener {
        /**
         * The plugin.
         */
        private final Extension ext;

        /**
         * The name of the plugin.
         */
        private final String pluginName;

        /**
         * @param aWritableTransactionsPanel
         * @param aExt the plugin to execute
         * @param aPluginName the name to display
         */
        public TransactionMenuActionMenuAction(final Extension aExt, final String aPluginName) {
            ext = aExt;
            pluginName = aPluginName;
        }

        /**
         * {@inheritDoc}
         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
         */
        @Override
        public void actionPerformed(final ActionEvent aE) {
            try {
                JTable table = WritableTransactionsPanel.this.getTransactionTable();
                GnucashSimpleAccountTransactionsTableModel model = (GnucashSimpleAccountTransactionsTableModel) table
                        .getModel();
                int[] selectedRows = table.getSelectedRows();
                Collection<GnucashWritableTransactionSplit> transactions = new ArrayList<GnucashWritableTransactionSplit>(
                        selectedRows.length);
                for (int i : selectedRows) {
                    transactions.add((GnucashWritableTransactionSplit) model.getTransactionSplit(i));
                }

                // Activate plug-in that declares extension.
                getPluginManager().activatePlugin(ext.getDeclaringPluginDescriptor().getId());
                // Get plug-in class loader.
                ClassLoader classLoader = getPluginManager()
                        .getPluginClassLoader(ext.getDeclaringPluginDescriptor());
                // Load Tool class.
                Class toolCls = classLoader.loadClass(ext.getParameter("class").valueAsString());
                // Create Tool instance.
                Object o = toolCls.newInstance();
                if (!(o instanceof TransactionMenuAction)) {
                    LOG.log(Level.SEVERE,
                            "Plugin '" + pluginName + "' does not implement TransactionMenuAction-interface.");
                    JOptionPane.showMessageDialog(WritableTransactionsPanel.this, "Error",
                            "Plugin '" + pluginName + "' does not implement v-interface.",
                            JOptionPane.ERROR_MESSAGE);
                    return;

                }
                TransactionMenuAction action = (TransactionMenuAction) o;
                try {
                    WritableTransactionsPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                    action.handleSelectedTransactions(transactions);
                } catch (Exception e1) {
                    LOG.log(Level.SEVERE, "MenuAction via Plugin '" + pluginName + "' failed.", e1);
                    JOptionPane.showMessageDialog(
                            WritableTransactionsPanel.this, "Error", "MenuAction via Plugin '" + pluginName
                                    + "' failed.\n" + "[" + e1.getClass().getName() + "]: " + e1.getMessage(),
                            JOptionPane.ERROR_MESSAGE);
                } finally {
                    WritableTransactionsPanel.this.setCursor(Cursor.getDefaultCursor());
                }
            } catch (Exception e1) {
                LOGGER.error("Could not activate requested import-plugin '" + pluginName + "'.", e1);
                JOptionPane.showMessageDialog(
                        WritableTransactionsPanel.this, "Error", "Could not activate requested MenuAction-plugin '"
                                + pluginName + "'.\n" + "[" + e1.getClass().getName() + "]: " + e1.getMessage(),
                        JOptionPane.ERROR_MESSAGE);
            }

        }

    }

    /**
     * the context-menu for the transactionTable.
     */
    private JPopupMenu myContextMenu;

    /**
     * The main-entry-point to our plugin-api.
     * May be null to disable plugins.
     */
    private PluginManager pluginManager = null;

    /**
     * The descriptor for our top-level application-plugin.
     * May be null to disable plugins.
     */
    private PluginDescriptor pluginDescriptor = null;

    /**
     *
     */
    public WritableTransactionsPanel() {
        super();
    }

    /**
     * @param aPluginDescriptor for extensing the context-menu with plugins.
     * @param aPluginManager for extensing the context-menu with plugins.
     *
     */
    public WritableTransactionsPanel(final PluginManager aPluginManager, final PluginDescriptor aPluginDescriptor) {
        super();
        setPluginManager(aPluginManager);
        setPluginDescriptor(aPluginDescriptor);
    }

    /**
     * @param account if null, an empty table will be shown.
     */
    public WritableTransactionsPanel(final GnucashAccount account) {
        super();
        setAccount(account);
    }

    /**
     * Automatically created logger for debug and error-output.
     */
    private static final Logger LOG = Logger.getLogger(WritableTransactionsPanel.class.getName());

    /**
     * The panel to show a single transaction.
     */
    private ShowWritableTransactionPanel mySingleWritableTransactionPanel;

    /**
     * Just an overridden ToString to return this classe's name
     * and hashCode.
     * @return className and hashCode
     */
    @Override
    public String toString() {
        return "WritableTransactionsPanel@" + hashCode();
    }

    /**
     * Give an account who's transactions to display.
     * @param account if null, an empty table will be shown.
     */
    @Override
    public void setAccount(final GnucashAccount account) {

        if (account == null) {
            setModel(new GnucashAccountTransactionsTableModel());
        } else {
            setModel(new GnucashAccountTransactionsTableModel(account));
        }
    }

    /**
     * Instead of displaying the transactions of an account,
     * display the given (ordered) list of transactions.
     * @param aTransactionList
     */
    public void setDisplayedTransactions(final List<GnucashTransactionSplit> aTransactionList) {
        setModel(new GnucashTransactionSplitsTableModel(aTransactionList));
    }

    /**
     * This method initializes ShowTransactionPanel.
     *
     * @return javax.swing.JPanel
     */

    @Override
    protected ShowTransactionPanel getSingleTransactionPanel() {
        return getSingleWritableTransactionPanel();
    }

    /**
     * This method initializes ShowTransactionPanel.
     *
     * @return javax.swing.JPanel
     */
    protected ShowTransactionPanel getSingleWritableTransactionPanel() {
        if (mySingleWritableTransactionPanel == null) {
            mySingleWritableTransactionPanel = new ShowWritableTransactionPanel();
            mySingleWritableTransactionPanel.setSplitActions(getSplitActions());
        }
        return mySingleWritableTransactionPanel;
    }
    //
    //    //------------------------ support for propertyChangeListeners ------------------
    //
    //    /**
    //     * support for firing PropertyChangeEvents.
    //     * (gets initialized only if we really have listeners)
    //     */
    //    private volatile PropertyChangeSupport myPropertyChange = null;
    //
    //    /**
    //     * Returned value may be null if we never had listeners.
    //     * @return Our support for firing PropertyChangeEvents
    //     */
    //    protected PropertyChangeSupport getPropertyChangeSupport() {
    //        return myPropertyChange;
    //    }
    //
    //    /**
    //     * Add a PropertyChangeListener to the listener list.
    //     * The listener is registered for all properties.
    //     *
    //     * @param listener  The PropertyChangeListener to be added
    //     */
    //    public final void addPropertyChangeListener(
    //                                                final PropertyChangeListener listener) {
    //        if (myPropertyChange == null) {
    //            myPropertyChange = new PropertyChangeSupport(this);
    //        }
    //        myPropertyChange.addPropertyChangeListener(listener);
    //    }
    //
    //    /**
    //     * Add a PropertyChangeListener for a specific property.  The listener
    //     * will be invoked only when a call on firePropertyChange names that
    //     * specific property.
    //     *
    //     * @param propertyName  The name of the property to listen on.
    //     * @param listener  The PropertyChangeListener to be added
    //     */
    //    public final void addPropertyChangeListener(
    //                                                final String propertyName,
    //                                                final PropertyChangeListener listener) {
    //        if (myPropertyChange == null) {
    //            myPropertyChange = new PropertyChangeSupport(this);
    //        }
    //        myPropertyChange.addPropertyChangeListener(propertyName, listener);
    //    }
    //
    //    /**
    //     * Remove a PropertyChangeListener for a specific property.
    //     *
    //     * @param propertyName  The name of the property that was listened on.
    //     * @param listener  The PropertyChangeListener to be removed
    //     */
    //    public final void removePropertyChangeListener(
    //                                                   final String propertyName,
    //                                                   final PropertyChangeListener listener) {
    //        if (myPropertyChange != null) {
    //            myPropertyChange.removePropertyChangeListener(propertyName,
    //                    listener);
    //        }
    //    }
    //
    //    /**
    //     * Remove a PropertyChangeListener from the listener list.
    //     * This removes a PropertyChangeListener that was registered
    //     * for all properties.
    //     *
    //     * @param listener  The PropertyChangeListener to be removed
    //     */
    //    public synchronized void removePropertyChangeListener(
    //                                                          final PropertyChangeListener listener) {
    //        if (myPropertyChange != null) {
    //            myPropertyChange.removePropertyChangeListener(listener);
    //        }
    //    }
    //
    //    //-------------------------------------------------------

    /**
     * {@inheritDoc}
     * @see biz.wolschon.finance.jgnucash.panels.TransactionsPanel#getTransactionTable()
     */
    @Override
    protected JTable getTransactionTable() {
        JTable transactionTable = super.getTransactionTable();
        transactionTable.add(getTransactionTableContextMenu());
        return transactionTable;
    }

    /**
     * @return the context-menu for the transactionTable.
     * @see #getTransactionTable()
     */
    private Component getTransactionTableContextMenu() {
        if (myContextMenu == null) {
            myContextMenu = new JPopupMenu();

            PluginManager manager = getPluginManager();
            // if we are configured for the plugin-api
            if (manager != null) {
                ExtensionPoint toolExtPoint = manager.getRegistry().getExtensionPoint(getPluginDescriptor().getId(),
                        "TransactionMenuAction");
                for (Iterator<Extension> it = toolExtPoint.getConnectedExtensions().iterator(); it.hasNext();) {
                    Extension ext = it.next();
                    String pluginName = "unknown";

                    try {
                        pluginName = ext.getParameter("name").valueAsString();
                        JMenuItem newMenuItem = new JMenuItem();
                        newMenuItem.putClientProperty("extension", ext);
                        newMenuItem.setText(pluginName);
                        newMenuItem.addActionListener(new TransactionMenuActionMenuAction(ext, pluginName));
                        myContextMenu.add(newMenuItem);
                    } catch (Exception e) {
                        LOG.log(Level.SEVERE, "cannot load TransactionMenuAction-Plugin '" + pluginName + "'", e);
                        JOptionPane.showMessageDialog(this, "Error",
                                "Cannot load TransactionMenuAction-Plugin '" + pluginName + "'",
                                JOptionPane.ERROR_MESSAGE);
                    }
                }
            }

        }
        return myContextMenu;
    }

    /**
     * The main-entry-point to our plugin-api.
     * (may be null to disable plugins.)
     * @return the pluginManager
     */
    public PluginManager getPluginManager() {
        return pluginManager;
    }

    /**
     * The main-entry-point to our plugin-api.
     * (may be null to disable plugins.)
     * @param aPluginManager the pluginManager to set
     */
    public void setPluginManager(final PluginManager aPluginManager) {
        pluginManager = aPluginManager;
    }

    /**
     * The descriptor for our top-level application-plugin.
     * (may be null to disable plugins.)
     * @return the pluginDescriptor
     */
    public PluginDescriptor getPluginDescriptor() {
        return pluginDescriptor;
    }

    /**
     * The descriptor for our top-level application-plugin.
     * (may be null to disable plugins.)
     * @param aPluginDescriptor the pluginDescriptor to set
     */
    public void setPluginDescriptor(final PluginDescriptor aPluginDescriptor) {
        pluginDescriptor = aPluginDescriptor;
    }

}