// Form
package org.javamoney.examples.ez.money.gui.view.register;
import static org.javamoney.examples.ez.common.CommonConstants.IS_MAC;
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.KeywordKeys.NOT_CATEGORIZED;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.CANCEL;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.DATE_PICKER;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.EDIT;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.ENTER;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.NEW;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.NEXT;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.PENDING;
import static org.javamoney.examples.ez.money.gui.view.register.FormButtonKeys.SPLIT;
import static org.javamoney.examples.ez.money.gui.view.register.FormFieldKeys.AMOUNT;
import static org.javamoney.examples.ez.money.gui.view.register.FormFieldKeys.CHECK_NUMBER;
import static org.javamoney.examples.ez.money.gui.view.register.FormFieldKeys.DATE;
import static org.javamoney.examples.ez.money.gui.view.register.FormFieldKeys.NOTES;
import static org.javamoney.examples.ez.money.model.DataManager.getAccounts;
import static org.javamoney.examples.ez.money.model.DataManager.getExpenses;
import static org.javamoney.examples.ez.money.model.DataManager.getIncome;
import static org.javamoney.examples.ez.money.model.DataManager.getPayees;
import static org.javamoney.examples.ez.money.model.dynamic.transaction.TransactionTypeKeys.EXPENSE;
import static org.javamoney.examples.ez.money.model.dynamic.transaction.TransactionTypeKeys.INCOME;
import static org.javamoney.examples.ez.money.model.dynamic.transaction.TransactionTypeKeys.TRANSFER;
import static org.javamoney.examples.ez.money.model.persisted.transaction.Transaction.MAX_PAYEE_LENGTH;
import static org.javamoney.examples.ez.money.utility.EditorHelper.createAmountFieldEditor;
import static org.javamoney.examples.ez.money.utility.EditorHelper.createCheckNumberFieldEditor;
import static org.javamoney.examples.ez.money.utility.EditorHelper.createDateFieldEditor;
import static org.javamoney.examples.ez.money.utility.EditorHelper.createNotesFieldEditor;
import java.awt.GridBagConstraints;
import java.awt.event.ActionListener;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import org.javamoney.examples.ez.money.IconKeys;
import org.javamoney.examples.ez.money.gui.chooser.ElementComboBoxChooser;
import org.javamoney.examples.ez.money.model.DataCollection;
import org.javamoney.examples.ez.money.model.dynamic.transaction.TransactionTypeKeys;
import org.javamoney.examples.ez.common.gui.Link;
import org.javamoney.examples.ez.common.gui.Panel;
import org.javamoney.examples.ez.common.utility.ClipboardMenuController;
import org.javamoney.examples.ez.common.utility.I18NHelper;
import org.javamoney.examples.ez.common.utility.TextConstrainer;
/**
* This class facilitates management of all the elements that make up the
* transaction form.
*/
final
class
Form
extends Panel
{
/**
* Constructs a new form customized for the specified transaction type.
*
* @param type The transaction type.
* @param handler The listener to be notified when action events occur.
*/
protected
Form(TransactionTypeKeys type, ActionListener handler)
{
setType(type);
setPayFromChooser(new ElementComboBoxChooser(getPayFromCollection()));
setPayToChooser(new ElementComboBoxChooser(getPayToCollection()));
createButtons(handler);
createFields();
buildPanel();
if(getType() != TRANSFER)
{
getPayFromChooser().setEditable(true);
getPayFromChooser().getTextField().setDocument(new TextConstrainer(MAX_PAYEE_LENGTH));
// Add listeners.
new AutoCompleteHandler(this);
new ClipboardMenuController(getPayFromChooser().getTextField());
}
// Add listeners.
for(JTextField field : getFields())
{
new ClipboardMenuController(field);
}
new FormDateHandler(this);
new FormTraversalHandler(this);
}
/**
* This method clears all the editable fields in the form.
*/
protected
void
clearFields()
{
for(JTextField field : getFields())
{
field.setText("");
}
if(getType() != TRANSFER)
{
getPayFromChooser().clearSelection();
setPayToIsSplit(false);
}
}
/**
* This method enables or disables the elements of the from depending of the
* specified value.
*
* @param value true or false.
*/
protected
void
enableForm(boolean value)
{
// Enable buttons.
for(AbstractButton button : getButtons())
{
button.setEnabled(value);
}
// Enable fields.
for(JTextField field : getFields())
{
field.setEnabled(value);
}
// Enable choosers.
getPayToChooser().setEnabled(value);
getPayFromChooser().setEnabled(value);
// Set defaults.
getButton(NEW).setEnabled(true);
// Splits are only for non-transfers.
if(value == true && getType() == TRANSFER)
{
getButton(SPLIT).setEnabled(false);
}
}
/**
* This method returns the form button for the specified key.
*
* @param key The button's key.
*
* @return The form button for the specified key.
*/
protected
AbstractButton
getButton(FormButtonKeys key)
{
return getButtons()[key.ordinal()];
}
/**
* This method returns the form field for the specified key.
*
* @param key The field's key.
*
* @return The form field for the specified key.
*/
protected
JTextField
getField(FormFieldKeys key)
{
return getFields()[key.ordinal()];
}
/**
* This method returns where the money is being paid from, either an account
* or payee.
*
* @return Where the money is being paid from, either an account or payee.
*/
protected
String
getPayFrom()
{
return getPayFromChooser().getSelectedItem();
}
/**
* This method returns the chooser for selecting where the money is being paid
* from, either an account or payee.
*
* @return The chooser for selecting where the money is being paid from.
*/
protected
ElementComboBoxChooser
getPayFromChooser()
{
return itsPayFromChooser;
}
/**
* This method returns the where the money is being paid to, either an account
* or category.
*
* @return Where the money is being paid to, either an account or category.
*/
protected
String
getPayTo()
{
String payTo = getPayToChooser().getSelectedItem();
if(payTo.equals(NOT_CATEGORIZED.toString()) == true)
{
payTo = "";
}
return payTo;
}
/**
* This method returns the chooser for selecting where the money is being paid
* to, either an account or category.
*
* @return The chooser for selecting where the money is being paid to.
*/
protected
ElementComboBoxChooser
getPayToChooser()
{
return itsPayToChooser;
}
/**
* This method returns the transaction type.
*
* @return The transaction type.
*/
protected
TransactionTypeKeys
getType()
{
return itsType;
}
/**
* This method sets whether or not the transaction is being paid out to
* multiple categories.
* <p>
* <b>Note:</b> This should only apply to categories and not accounts.
*
* @param isSplit true or false.
*/
protected
void
setPayToIsSplit(boolean isSplit)
{
if(isSplit == true)
{
getPayToChooser().removeAllItems();
getPayToChooser().addItem(getProperty("split"));
}
else
{
getPayToChooser().displayElements(getPayToCollection());
getPayToChooser().addNotCategorizedOption();
getPayToChooser().setSelectedIndex(0);
}
}
//////////////////////////////////////////////////////////////////////////////
// Start of private methods.
//////////////////////////////////////////////////////////////////////////////
private
void
buildPanel()
{
String category = null;
String gap = ": ";
String payee = null;
// Get correct category text.
if(getType() == TRANSFER)
{
category = getSharedProperty("to") + gap;
}
else
{
category = getSharedProperty("category") + gap;
}
// Get correct payee text.
if(getType() == EXPENSE)
{
payee = getSharedProperty("to") + gap;
}
else
{
payee = getSharedProperty("from") + gap;
}
// Build panel.
setFill(GridBagConstraints.HORIZONTAL);
add(getButton(NEXT), 6, 0, 1, 1, 0, 20);
add(getButton(NEW), 0, 1, 1, 1, 0, 0);
add(getField(DATE), 5, 1, 1, 1, 0, 20);
add(getButton(DATE_PICKER), 6, 1, 1, 1, 0, 0);
add(getButton(EDIT), 7, 2, 1, 1, 0, 20);
add(getButton(SPLIT), 3, 3, 1, 1, 0, 20);
add(getButton(ENTER), 7, 3, 1, 1, 0, 0);
add(getButton(CANCEL), 7, 5, 1, 1, 0, 20);
setAnchor(GridBagConstraints.EAST);
setFill(GridBagConstraints.NONE);
add(payee, 1, 2, 1, 1, 0, 0);
add(category, 1, 3, 1, 1, 0, 0);
add(getSharedProperty("notes") + gap, 1, 5, 1, 1, 0, 0);
add(getSharedProperty("check_number") + gap, 4, 0, 1, 1, 0, 0);
add(getSharedProperty("date") + gap, 4, 1, 1, 1, 0, 0);
add(getSharedProperty("amount") + gap, 4, 2, 1, 1, 0, 0);
setFill(GridBagConstraints.HORIZONTAL);
add(getPayFromChooser(), 2, 2, 2, 1, 0, 0);
add(getPayToChooser(), 2, 3, 1, 1, 100, 0);
add(getField(NOTES), 2, 5, 2, 1, 0, 0);
add(getField(CHECK_NUMBER), 5, 0, 1, 1, 0, 0);
add(getField(AMOUNT), 5, 2, 1, 1, 0, 0);
add(getButton(PENDING), 5, 3, 1, 1, 0, 0);
// Aesthetic spacers.
addEmptyCellAt(1, 6, 10);
addEmptyCellAt(4, 4, 12);
addEmptyCellAt(5, 5, 17);
}
private
JButton
createButton(FormButtonKeys key, String tip, ActionListener listener)
{
JButton button = new JButton();
// Build Button.
buildButton(button, key.getText(), listener, "", tip);
if(IS_MAC == false)
{
button.setMnemonic(key.getText().charAt(0));
}
return button;
}
private
void
createButtons(ActionListener handler)
{
itsButtons = new AbstractButton[8];
getButtons()[CANCEL.ordinal()] = createButton(CANCEL, null, handler);
getButtons()[EDIT.ordinal()] = createButton(EDIT, null, handler);
getButtons()[ENTER.ordinal()] = createButton(ENTER, null, handler);
getButtons()[DATE_PICKER.ordinal()] = createLink(IconKeys.DATE, getSharedProperty("date_tip"), handler);
getButtons()[NEW.ordinal()] = createButton(NEW, null, handler);
getButtons()[NEXT.ordinal()] = createLink(IconKeys.FORM_NEXT_CHECK, getProperty("next_tip"), handler);
getButtons()[PENDING.ordinal()] = new JCheckBox(PENDING.getText());
getButtons()[SPLIT.ordinal()] = createButton(SPLIT, null, handler);
}
private
void
createFields()
{
itsFields = new JTextField[4];
getFields()[AMOUNT.ordinal()] = createAmountFieldEditor();
getFields()[CHECK_NUMBER.ordinal()] = createCheckNumberFieldEditor();
getFields()[DATE.ordinal()] = createDateFieldEditor();
getFields()[NOTES.ordinal()] = createNotesFieldEditor();
}
private
Link
createLink(IconKeys icon, String tip, ActionListener listener)
{
Link link = new Link();
// Build link.
buildButton(link, "", icon.getIcon(), listener, "", tip);
return link;
}
private
AbstractButton[]
getButtons()
{
return itsButtons;
}
private
JTextField[]
getFields()
{
return itsFields;
}
private
DataCollection
getPayFromCollection()
{
return (getType() == TRANSFER) ? getAccounts() : getPayees();
}
private
DataCollection
getPayToCollection()
{
DataCollection collection = getExpenses();
if(getType() == INCOME)
{
collection = getIncome();
}
else if(getType() == TRANSFER)
{
collection = getAccounts();
}
return collection;
}
private
static
String
getProperty(String key)
{
return I18NHelper.getProperty("Form." + key);
}
private
void
setPayFromChooser(ElementComboBoxChooser chooser)
{
itsPayFromChooser = chooser;
}
private
void
setPayToChooser(ElementComboBoxChooser chooser)
{
itsPayToChooser = chooser;
}
private
void
setType(TransactionTypeKeys type)
{
itsType = type;
}
//////////////////////////////////////////////////////////////////////////////
// Start of class members.
//////////////////////////////////////////////////////////////////////////////
private AbstractButton[] itsButtons;
private JTextField[] itsFields;
private ElementComboBoxChooser itsPayFromChooser;
private ElementComboBoxChooser itsPayToChooser;
private TransactionTypeKeys itsType;
}