// BudgetPanel package org.javamoney.examples.ez.money.gui.dialog.preferences; import static org.javamoney.examples.ez.common.utility.BorderHelper.createTitledBorder; 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.ApplicationProperties.UI_CURRENCY_FORMAT; import static org.javamoney.examples.ez.money.ApplicationProperties.UI_DATE_FORMAT; import static org.javamoney.examples.ez.money.model.DataManager.getIncome; import java.awt.GridBagConstraints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Date; import javax.swing.AbstractButton; import javax.swing.JTextField; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import org.javamoney.examples.ez.money.model.persisted.category.Category; import org.javamoney.examples.ez.money.utility.TransactionDateHelper; import org.javamoney.examples.ez.common.gui.CheckBox; 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 managing the expense's budget. */ final class BudgetPanel extends Panel { /** * Constructs a new preferences panel. * * @param chooser The chooser that contains the categories. */ protected BudgetPanel(PreferencesDataElementChooser chooser) { setAmountField(new JTextField()); setChooser(chooser); createButtons(); // Build panel. setFill(GridBagConstraints.BOTH); add(createInfoPanel(), 0, 0, 1, 1, 100, 100); // Initialize the panel with the selected budget. displayBudgetInfo(); // Add listeners. getAmountField().addFocusListener(new FocusHandler()); getAmountField().addKeyListener(new KeyHandler()); getChooser().addTreeSelectionListener(new SelectionHandler()); new ClipboardMenuController(getAmountField()); } /** * This method updates this panel's collection. */ protected void updateView() { getChooser().selectFirst(); } ////////////////////////////////////////////////////////////////////////////// // Start of private methods. ////////////////////////////////////////////////////////////////////////////// private void createButtons() { ActionHandler handler = new ActionHandler(); itsButtons = new AbstractButton[3]; getButtons()[DATE] = new Link(); getButtons()[ENABLE] = new CheckBox(); getButtons()[ROLLOVER] = new CheckBox(); // Build check boxes. buildButton(getButtons()[DATE], "", handler); buildButton(getButtons()[ENABLE], getProperty("enable"), handler); buildButton(getButtons()[ROLLOVER], getProperty("rollover"), handler); } private Panel createInfoPanel() { Panel panel = new Panel(); // Build field. getAmountField().setDocument(new TextConstrainer(13, "0123456789,.")); getAmountField().setHorizontalAlignment(JTextField.TRAILING); // Build panel. panel.setAnchor(GridBagConstraints.WEST); panel.add(getButtons()[ENABLE], 0, 0, 1, 1, 0, 50); panel.add(getButtons()[ROLLOVER], 0, 1, 1, 1, 0, 50); panel.add(getButtons()[DATE], 1, 1, 2, 1, 0, 0); panel.setAnchor(GridBagConstraints.EAST); panel.add(getProperty("budget") + ": ", 2, 0, 1, 1, 100, 0); panel.setFill(GridBagConstraints.HORIZONTAL); panel.add(getAmountField(), 3, 0, 1, 1, 0, 0); // Aesthetic spacers. panel.addEmptyCellAt(3, 1, 15); panel.addEmptyCellAt(4, 1); panel.setBorder(createTitledBorder(getSharedProperty("more_options"))); return panel; } private void displayBudgetInfo() { Category category = (Category)getChooser().getSelectedElement(); String amount = ""; Date date = new Date(); boolean canBeBudgeted = false; boolean hasRollover = false; boolean isBudgeted = false; if(category != null) { canBeBudgeted = category.canBeBudgeted(); if(canBeBudgeted == true && category.isBudgeted() == true) { amount = UI_CURRENCY_FORMAT.format(Math.abs(category.getBudget())); date = category.getRolloverStartDate(); hasRollover = category.hasRolloverBudget(); isBudgeted = true; } } // Display budget data. getButtons()[DATE].setEnabled(hasRollover); getButtons()[DATE].setText(UI_DATE_FORMAT.format(date)); getButtons()[ENABLE].setEnabled(canBeBudgeted); getButtons()[ENABLE].setSelected(isBudgeted); getButtons()[ROLLOVER].setEnabled(isBudgeted); getButtons()[ROLLOVER].setSelected(hasRollover); getAmountField().setEnabled(isBudgeted); getAmountField().setText(amount); } private JTextField getAmountField() { return itsAmountField; } private AbstractButton[] getButtons() { return itsButtons; } private PreferencesDataElementChooser getChooser() { return itsChooser; } private static String getProperty(String key) { return I18NHelper.getProperty("BudgetPanel." + key); } private void setAmountField(JTextField textField) { itsAmountField = textField; } private void setBudget() { Category category = (Category)getChooser().getSelectedElement(); int amount = Math.abs(category.getBudget()); try { amount = (int)UI_CURRENCY_FORMAT.parse(getAmountField().getText()); } catch(Exception exception) { // Ignored. } // Budgets for income categories are negative behind the scenes and positive // in the UI so the sign needs to be flipped. if(getChooser().getCollection() == getIncome()) { amount = -amount; } category.setBudget(amount); } private void setChooser(PreferencesDataElementChooser chooser) { itsChooser = chooser; } private void setIsBudgeted() { Category category = (Category)getChooser().getSelectedElement(); category.setIsBudgeted(!category.isBudgeted()); displayBudgetInfo(); } private void setRolloverBudget() { Category category = (Category)getChooser().getSelectedElement(); category.setHasRolloverBudget(!category.hasRolloverBudget()); displayBudgetInfo(); } private void setRolloverStartDate() { Category category = (Category)getChooser().getSelectedElement(); Date date = TransactionDateHelper.showDateDialog(category.getRolloverStartDate()); if(date != null) { category.setRolloverStartDate(date); getButtons()[DATE].setText(UI_DATE_FORMAT.format(date)); } } ////////////////////////////////////////////////////////////////////////////// // Start of inner classes. ////////////////////////////////////////////////////////////////////////////// private class ActionHandler implements ActionListener { public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if(source == getButtons()[DATE]) { setRolloverStartDate(); } else if(source == getButtons()[ENABLE]) { setIsBudgeted(); } else if(source == getButtons()[ROLLOVER]) { setRolloverBudget(); } } } private class FocusHandler extends FocusAdapter { @Override public void focusLost(FocusEvent event) { Category category = (Category)getChooser().getSelectedElement(); getAmountField().setText(UI_CURRENCY_FORMAT.format(Math.abs(category.getBudget()))); } } private class KeyHandler extends KeyAdapter { @Override public void keyReleased(KeyEvent event) { setBudget(); } } private class SelectionHandler implements TreeSelectionListener { public void valueChanged(TreeSelectionEvent event) { displayBudgetInfo(); } } ////////////////////////////////////////////////////////////////////////////// // Start of class members. ////////////////////////////////////////////////////////////////////////////// private JTextField itsAmountField; private AbstractButton[] itsButtons; private PreferencesDataElementChooser itsChooser; private static final int DATE = 0; private static final int ENABLE = 1; private static final int ROLLOVER = 2; }