// ComparisonView package org.javamoney.examples.ez.money.gui.view.home; import static org.javamoney.examples.ez.common.utility.BorderHelper.createTitledBorder; import static org.javamoney.examples.ez.common.utility.DateHelper.getStartOfCurrentMonth; 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.IconKeys.PIE_CHART_BLUE; import static org.javamoney.examples.ez.money.IconKeys.PIE_CHART_BLUE_LEGEND; import static org.javamoney.examples.ez.money.IconKeys.PIE_CHART_GRAY; import static org.javamoney.examples.ez.money.IconKeys.PIE_CHART_RED; import static org.javamoney.examples.ez.money.IconKeys.PIE_CHART_RED_LEGEND; import static org.javamoney.examples.ez.money.model.DataManager.getAccounts; import static org.javamoney.examples.ez.money.utility.TransactionDateHelper.isOnOrAfter; import java.awt.Color; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.Image; import java.awt.geom.Arc2D; import javax.swing.JLabel; import org.javamoney.examples.ez.money.locale.PercentFormat; import org.javamoney.examples.ez.money.model.DataElement; 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.money.utility.TransactionHelper; import org.javamoney.examples.ez.common.gui.Panel; import org.javamoney.examples.ez.common.utility.I18NHelper; /** * This class provides a very basic comparison view of expenses versus income * for the current month. */ public final class ComparisonView extends Panel { /** * */ private static final long serialVersionUID = 1810428160527929576L; /** * Constructs a new comparison view. */ public ComparisonView() { setTotals(new double[2]); createLabels(); buildPanel(); } /** * This method renders the view specific data to its canvas. * * @param graphics The graphics context to render to. */ @Override public void paint(Graphics graphics) { super.paint(graphics); double total = getTotals()[MONTH_EXPENSE] + getTotals()[MONTH_INCOME]; int height = 174; int width = height; int xCoord = 200; int yCoord = 15; if(total != 0.0) { int arc = (int)(360 * (getTotals()[MONTH_EXPENSE] / total)); // Fill the pie as income, and then paint the expenses. graphics.setClip(new Arc2D.Double(xCoord, yCoord, width, height, 0, 360, Arc2D.PIE)); graphics.drawImage(INCOME, xCoord, yCoord, null); graphics.setClip(new Arc2D.Double(xCoord, yCoord, width, height, 0, arc, Arc2D.PIE)); graphics.drawImage(EXPENSE, xCoord, yCoord, null); } else { String str = getProperty("no_data"); int strWidth = getFontMetrics(getFont()).stringWidth(str); // Clear previous paints. graphics.setColor(getBackground()); graphics.fillArc(xCoord, yCoord, width, height, 0, 360); graphics.setClip(new Arc2D.Double(xCoord, yCoord, width, height, 0, 360, Arc2D.PIE)); graphics.drawImage(NO_DATA, xCoord, yCoord, null); // Center the text. xCoord += width / 2 - (strWidth / 2); yCoord += height / 2; graphics.setColor(Color.BLACK); graphics.drawString(str, xCoord, yCoord); } } /** * This method updates the view. */ public void updateView() { resetTotals(); // Iterate the accounts and total up the transactions. for(DataElement element : getAccounts().getCollection()) { Account account = (Account)element; if(account.isActive() == true) { for(Transaction trans : account.getTransactions()) { addToTotals(trans); } } } updateLabels(); repaint(); } ////////////////////////////////////////////////////////////////////////////// // Start of private methods. ////////////////////////////////////////////////////////////////////////////// private void addToTotals(Transaction trans) { if(TransactionHelper.isTransfer(trans) == false) { double amount = Math.abs(trans.getAmount().getNumber().doubleValue()); int monthIndex = MONTH_EXPENSE; if(TransactionHelper.isIncome(trans) == true) { monthIndex = MONTH_INCOME; } if(isOnOrAfter(trans, getStartOfCurrentMonth()) == true) { getTotals()[monthIndex] += amount; } } } private void buildPanel() { int height = 12; // Build panel. // This spacer is to ensure sufficient height for the pie chart. addEmptyRowsAt(0, 0, height); setAnchor(GridBagConstraints.SOUTHWEST); add(createLegendPanel(), 1, 0, 1, height, 100, 100); setBorder(createTitledBorder(getProperty("comparison"), false)); } private void createLabels() { itsLabels = new JLabel[2]; for(int len = 0; len < getLabels().length; ++len) { getLabels()[len] = new JLabel(); } } private Panel createLegendPanel() { Panel panel = new Panel(); String gap = ": "; // Build panel. panel.setAnchor(GridBagConstraints.EAST); panel.add(getSharedProperty("income") + gap, 0, 0, 1, 1, 0, 50); panel.addEmptyCellAt(2, 1); panel.add(getSharedProperty("expenses") + gap, 0, 2, 1, 1, 0, 50); panel.addEmptyCellAt(2, 3); panel.setAnchor(GridBagConstraints.CENTER); panel.add(PIE_CHART_BLUE_LEGEND.getIcon(), 1, 0, 1, 1, 0, 0); panel.add(PIE_CHART_RED_LEGEND.getIcon(), 1, 2, 1, 1, 0, 0); panel.setAnchor(GridBagConstraints.WEST); panel.add(getLabels()[MONTH_INCOME], 3, 0, 1, 1, 100, 0); panel.addEmptyCellAt(3, 1, 8); panel.add(getLabels()[MONTH_EXPENSE], 3, 2, 1, 1, 0, 0); panel.setBorder(createTitledBorder(getSharedProperty("legend"), false)); return panel; } private JLabel[] getLabels() { return itsLabels; } private static String getProperty(String key) { return I18NHelper.getProperty("ComparisonView." + key); } private double[] getTotals() { return itsTotals; } private void resetTotals() { for(int len = 0; len < getTotals().length; ++len) { getTotals()[len] = 0.0; } } private void setTotals(double[] array) { itsTotals = array; } private void updateLabels() { double total = getTotals()[MONTH_EXPENSE] + getTotals()[MONTH_INCOME]; if(total != 0.0) { PercentFormat pFormat = new PercentFormat(); double expensePercent = getTotals()[MONTH_EXPENSE] / total; double incomePercent = getTotals()[MONTH_INCOME] / total; getLabels()[MONTH_EXPENSE].setText(pFormat.format(expensePercent)); getLabels()[MONTH_EXPENSE].setToolTipText(UI_CURRENCY_FORMAT.format(getTotals()[MONTH_EXPENSE])); getLabels()[MONTH_INCOME].setText(pFormat.format(incomePercent)); getLabels()[MONTH_INCOME].setToolTipText(UI_CURRENCY_FORMAT.format(getTotals()[MONTH_INCOME])); } else { getLabels()[MONTH_EXPENSE].setText(""); getLabels()[MONTH_EXPENSE].setToolTipText(null); getLabels()[MONTH_INCOME].setText(""); getLabels()[MONTH_INCOME].setToolTipText(null); } } ////////////////////////////////////////////////////////////////////////////// // Start of class members. ////////////////////////////////////////////////////////////////////////////// private JLabel[] itsLabels; private double[] itsTotals; private static final int MONTH_EXPENSE = 0; private static final int MONTH_INCOME = 1; private static final Image EXPENSE = PIE_CHART_RED.getIcon().getImage(); private static final Image INCOME = PIE_CHART_BLUE.getIcon().getImage(); private static final Image NO_DATA = PIE_CHART_GRAY.getIcon().getImage(); }