biz.wolschon.finance.jgnucash.accountProperties.AccountProperties.java Source code

Java tutorial

Introduction

Here is the source code for biz.wolschon.finance.jgnucash.accountProperties.AccountProperties.java

Source

/**
 * AccountProperties.java
 * created: 19.06.2009
 * (c) 2008 by <a href="http://Wolschon.biz">Wolschon Softwaredesign und Beratung</a>
 * This file is part of jgnucashLib-GPL 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-GPL 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-GPL 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.accountProperties;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import biz.wolschon.fileformats.gnucash.GnucashAccount;
import biz.wolschon.fileformats.gnucash.GnucashWritableAccount;
import biz.wolschon.finance.jgnucash.actions.AccountAction;

import com.l2fprod.common.propertysheet.DefaultProperty;
import com.l2fprod.common.propertysheet.Property;
import com.l2fprod.common.propertysheet.PropertySheetPanel;
import com.l2fprod.common.propertysheet.PropertySheetTableModel;

/**
 * (c) 2009 by <a href="http://Wolschon.biz>Wolschon Softwaredesign und Beratung</a>.<br/>
 * Project: jgnucashLib-GPL<br/>
 * AccountProperties<br/>
 * created: 19.06.2009 <br/>
 *<br/><br/>
 * <b>Action to open an the properties of an account in a new tab.</b>
 * @author  <a href="mailto:Marcus@Wolschon.biz">Marcus Wolschon</a>
 */
public class AccountProperties implements AccountAction, ClipboardOwner {

    /**
     * Our logger for debug- and error-output.
     */
    private static final Log LOGGER = LogFactory.getLog(AccountProperties.class);

    /**
     * The account we open.
     */
    private GnucashWritableAccount myAccount;

    /**
     * @see #getValue(String)
     */
    private final Map<String, Object> myAddedTags = new HashMap<String, Object>();

    /**
     * @see #addPropertyChangeListener(PropertyChangeListener)
     */
    private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);

    /**
     * The JPanel with the slot-values.
     */
    private JPanel mySettingsPanel;

    /**
     * The Panel with the controls to add a custom attribute.
     */
    private JPanel myAddCustomAttrPanel;

    /**
     * The text-field to enter the name of a new custom attribute.
     * @see #myAddCustomAttrPanel
     */
    private JTextField myCustomAttributeName;

    /**
     * The text-field to enter the value of a new custom attribute.
     * @see #myAddCustomAttrPanel
     */
    private JTextField myCustomAttributeValue;

    /**
     * The button to add a new custom attribute.
     */
    private JButton myAddCustomAttributeButton;

    /**
     * The PropertySheet with the custom attributes.
     */
    private PropertySheetPanel myPropertySheet;

    /**
     * The panel with the close-button.
     */
    private JPanel myButtonsPanel;

    /**
     * The frame we show everything in.
     */
    private JFrame myFrame;

    /**
     * The button to close the frame.
     */
    private JButton myCloseButton;

    /**
     * Popup-menu on properties.
     */
    private JPopupMenu myPropertyMenu;

    /**
     * The menu-item in the {@link #myPropertyMenu} to remove a custom attribute.
     */
    private JMenuItem myRemoveMenuItem;

    /**
     * Initialize.
     */
    public AccountProperties() {
        this.putValue(Action.NAME, "Account Properties...");
        this.putValue(Action.LONG_DESCRIPTION, "Show the properties of an account.");
        this.putValue(Action.SHORT_DESCRIPTION, "Show the properties of an account.");
    }

    /**
     * @param anAccount the account to show.
     */
    public AccountProperties(final GnucashAccount anAccount) {
        this();
        setAccount(anAccount);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setAccount(final GnucashAccount anAccount) {
        myAccount = (GnucashWritableAccount) anAccount;
        if (myAccount != null) {
            LOGGER.debug("setAccount(" + myAccount.getName() + ")");
            updateCustomAttributesPanel();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addPropertyChangeListener(final PropertyChangeListener aListener) {
        myPropertyChangeSupport.addPropertyChangeListener(aListener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object getValue(final String aKey) {
        return myAddedTags.get(aKey);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isEnabled() {
        return myAccount != null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void putValue(final String aKey, final Object aValue) {
        myAddedTags.put(aKey, aValue);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removePropertyChangeListener(final PropertyChangeListener aListener) {
        myPropertyChangeSupport.removePropertyChangeListener(aListener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setEnabled(final boolean aB) {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed(final ActionEvent aE) {
        JPanel newPanel = new JPanel(new GridLayout(2, 2));

        newPanel.add(new JLabel("GUID:"));
        final JTextField disabledIDInput = new JTextField(myAccount.getId());
        final JPopupMenu accountIDPopupMenu = createAccountIDPopupMenu();
        disabledIDInput.setEditable(false);
        disabledIDInput.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(final MouseEvent arg0) {
                if (arg0.isPopupTrigger()) {
                    accountIDPopupMenu.show(disabledIDInput, arg0.getX(), arg0.getY());
                }
            }

            @Override
            public void mousePressed(final MouseEvent arg0) {
                if (arg0.isPopupTrigger()) {
                    accountIDPopupMenu.show(disabledIDInput, arg0.getX(), arg0.getY());
                }
            }

        });
        newPanel.add(disabledIDInput);

        newPanel.add(new JLabel("name:"));
        final JTextField nameInput = new JTextField(myAccount.getName());
        nameInput.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent aE) {
                myAccount.setName(nameInput.getText());
            }

        });
        newPanel.add(nameInput);

        myFrame = new JFrame(myAccount.getName());
        myFrame.getContentPane().setLayout(new BorderLayout());
        myFrame.getContentPane().add(newPanel, BorderLayout.NORTH);
        myFrame.getContentPane().add(getButtonsPanel(), BorderLayout.SOUTH);

        myFrame.getContentPane().add(getMySettingsPanel(), BorderLayout.CENTER);
        myFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        myFrame.pack();
        myFrame.setVisible(true);
    }

    private JPopupMenu createAccountIDPopupMenu() {
        final JPopupMenu accountIDPopupMenu = new JPopupMenu();
        JMenuItem copyAccountIDMenuItem = new JMenuItem("copy");
        copyAccountIDMenuItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent arg0) {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                clipboard.setContents(new StringSelection(myAccount.getId()), AccountProperties.this);
            }
        });
        accountIDPopupMenu.add(copyAccountIDMenuItem);
        return accountIDPopupMenu;
    }

    /**
     * @return The panel with the close-button.
     */
    private JPanel getButtonsPanel() {
        if (myButtonsPanel == null) {
            myButtonsPanel = new JPanel(new BorderLayout());
            myButtonsPanel.add(getCloseButton(), BorderLayout.CENTER);
        }
        return myButtonsPanel;
    }

    /**
     * @return the close-button
     */
    private JButton getCloseButton() {
        if (myCloseButton == null) {
            myCloseButton = new JButton("close");
            myCloseButton.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(final ActionEvent aE) {
                    myFrame.setVisible(false);
                }

            });
        }
        return myCloseButton;
    }

    /**
     * @return a panel to edit the settings of this section
     */
    private JPanel getMySettingsPanel() {
        if (mySettingsPanel == null) {
            mySettingsPanel = new JPanel();

            mySettingsPanel.setLayout(new BorderLayout());
            myPropertySheet = new PropertySheetPanel();
            myPropertySheet.setToolBarVisible(true);
            myPropertySheet.setSorting(false);
            myPropertySheet.setMode(PropertySheetPanel.VIEW_AS_CATEGORIES);
            myPropertySheet.setDescriptionVisible(true);

            myPropertySheet.addPropertySheetChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(final PropertyChangeEvent aEvt) {
                    Object property = aEvt.getSource();
                    if (property instanceof DefaultProperty) {
                        DefaultProperty prop = (DefaultProperty) property;
                        try {
                            myAccount.setUserDefinedAttribute(prop.getName(), prop.getValue().toString());
                        } catch (Exception e) {
                            LOGGER.error("error in writing userDefinedAttribute", e);
                        }
                    }
                }

            });
            myPropertySheet.getTable().addMouseListener(new MouseAdapter() {

                /** show popup if mouseReleased is a popupTrigger on this platform.
                 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
                 */
                @Override
                public void mouseReleased(final MouseEvent aE) {
                    if (aE.isPopupTrigger()) {
                        JPopupMenu menu = getPropertyPopup();
                        menu.show(myPropertySheet, aE.getX(), aE.getY());
                    }
                    super.mouseClicked(aE);
                }

                /** show popup if mousePressed is a popupTrigger on this platform.
                 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
                 */
                @Override
                public void mousePressed(final MouseEvent aE) {
                    if (aE.isPopupTrigger()) {
                        JPopupMenu menu = getPropertyPopup();
                        menu.show(myPropertySheet, aE.getX(), aE.getY());
                    }
                    super.mouseClicked(aE);
                }

            });
            //
            updateCustomAttributesPanel();
            //        for (ConfigurationSetting setting : getConfigSection().getSettings()) {
            //            MyProperty myProperty = new MyProperty(setting);
            //            myProperty.addPropertyChangeListener(savingPropertyChangeListener);
            //            propertySheet.addProperty(myProperty);
            //        }
            mySettingsPanel.add(new JLabel("custom attributes:"), BorderLayout.NORTH);
            mySettingsPanel.add(myPropertySheet, BorderLayout.CENTER);
            mySettingsPanel.add(getAddCustomAttrPanel(), BorderLayout.SOUTH);

            //        MyPropertyEditorFactory propertyEditorFactory = new MyPropertyEditorFactory();
            //        propertySheet.setEditorFactory(propertyEditorFactory);
            //        propertySheet.setRendererFactory(propertyEditorFactory);

        }
        return mySettingsPanel;
    }

    /**
     * Update the PropertySheet.
     */
    private void updateCustomAttributesPanel() {
        if (myPropertySheet == null) {
            LOGGER.debug("updateCustomAttributesPanel() myPropertySheet is null");
            return;
        }
        Property[] properties = myPropertySheet.getProperties();
        if (properties != null) {
            LOGGER.debug("updateCustomAttributesPanel() " + properties.length + " attributes to remove from panel");
            for (Property property : properties) {
                myPropertySheet.removeProperty(property);
            }
        } else {
            LOGGER.debug("updateCustomAttributesPanel() " + "no attributes to remove from panel");
        }

        Collection<String> keys = myAccount.getUserDefinedAttributeKeys();
        LOGGER.debug("updateCustomAttributesPanel() #UserDefinedAttributeKeys=" + keys.size());
        for (String key : keys) {
            DefaultProperty property = new DefaultProperty();
            property.setName(key);
            property.setDisplayName(key);
            property.setEditable(true);
            //property.setCategory("");
            property.setType(String.class);
            property.setValue(myAccount.getUserDefinedAttribute(key));
            myPropertySheet.addProperty(property);
        }
        // remove the dummy-slots created in GnucashObjectImpl (cannot save empty xml-slots-entity)
        if (myPropertySheet.getProperties().length > 0
                && myPropertySheet.getProperties()[0].getName().equals("dummy")) {
            myPropertySheet.removeProperty(myPropertySheet.getProperties()[0]);
        }
    }

    /**
     * @return The Panel with the controls to add a custom attribute.
     */
    private JPanel getAddCustomAttrPanel() {
        if (myAddCustomAttrPanel == null) {
            final int rowCount = 3;
            myAddCustomAttrPanel = new JPanel(new GridLayout(rowCount, 2));
            myAddCustomAttrPanel.add(new JLabel("Name:"));
            myAddCustomAttrPanel.add(getCustomAttributeName());
            myAddCustomAttrPanel.add(new JLabel("Value:"));
            myAddCustomAttrPanel.add(getCustomAttributeValue());
            myAddCustomAttrPanel.add(new JLabel(""));
            myAddCustomAttrPanel.add(getAddCustomAttributeButton());
        }
        return myAddCustomAttrPanel;
    }

    /**
     * @return The text-field to enter the name of a new custom attribute.
     */
    private JTextField getCustomAttributeName() {
        if (myCustomAttributeName == null) {
            myCustomAttributeName = new JTextField();
        }
        return myCustomAttributeName;
    }

    /**
     * @return The text-field to enter the value of a new custom attribute.
     */
    private JTextField getCustomAttributeValue() {
        if (myCustomAttributeValue == null) {
            myCustomAttributeValue = new JTextField();
        }
        return myCustomAttributeValue;
    }

    /**
     * @return the button to add a new custom attribute.
     */
    private JButton getAddCustomAttributeButton() {
        if (myAddCustomAttributeButton == null) {
            myAddCustomAttributeButton = new JButton("add");
            myAddCustomAttributeButton.setEnabled(myAccount instanceof GnucashWritableAccount);
            myAddCustomAttributeButton.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(final ActionEvent aE) {
                    try {
                        LOGGER.debug("adding user-defined attribute '" + getCustomAttributeName().getText()
                                + "' to '" + getCustomAttributeValue().getText() + "'");
                        (myAccount).setUserDefinedAttribute(getCustomAttributeName().getText(),
                                getCustomAttributeValue().getText());
                        updateCustomAttributesPanel();
                    } catch (Exception e) {
                        LOGGER.error("error in updateCustomAttributesPanel", e);
                    }
                }

            });
        }
        return myAddCustomAttributeButton;
    }

    /**
     * @return Popup-menu on properties.
     */
    protected JPopupMenu getPropertyPopup() {
        if (myPropertyMenu == null) {
            myPropertyMenu = new JPopupMenu();
            myPropertyMenu.add(getRemoveMenuItem());
        }
        return myPropertyMenu;
    }

    /**
     * @return The menu-item in the {@link #myPropertyMenu} to remove a custom attribute.
     */
    private JMenuItem getRemoveMenuItem() {
        if (myRemoveMenuItem == null) {
            myRemoveMenuItem = new JMenuItem("remove");
            myRemoveMenuItem.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(final ActionEvent aE) {
                    int selectedRow = myPropertySheet.getTable().getSelectedRow();
                    PropertySheetTableModel model = ((PropertySheetTableModel) myPropertySheet.getTable()
                            .getModel());
                    LOGGER.debug("selected for deletion: #" + selectedRow + " of " + model.getProperties().length);
                    Property property = model.getProperties()[selectedRow - 1];
                    LOGGER.debug("selected for deletion: " + property.getName());
                    model.removeProperty(property);
                }

            });
        }
        return myRemoveMenuItem;
    }

    /* (non-Javadoc)
     * @see java.awt.datatransfer.ClipboardOwner#lostOwnership(java.awt.datatransfer.Clipboard, java.awt.datatransfer.Transferable)
     */
    @Override
    public void lostOwnership(final Clipboard arg0, final Transferable arg1) {
        // ignored
    }
}