/*
* [CurrCon.java]
*
* Summary: Currency converter Applet. Displays amount in any international currency.
*
* Copyright: (c) 2001-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.8+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2001-03-08 initial
* 1.1 2001-03-20 use Exch objects for initialisation.
* 1.2 2001-12-20 catch missing params
* 1.3 2002-03-07 error message for unrecognised currency,
* bad amount.
* update exchange rates
* fix bug so now all Applets don't necessarily share same country.
* 1.4 2002-03-27 list of exchanges comes in serialised form, easier to update daily without
* a recompile.
* 1.5 2002-04-01 guess favoured currency.
* avoids using Currency class which requires JDK 1.4
* 1.6 2002-04-24 hashtable for country lookup.
* show=cCN$A, only create widgets needed.
* display symbol
* 1.7 2002-05-14 display large numbers in millions.
* widths made public for com.mindprod.htmlmacros.CurrCon
* 1.8 2003-11-01 get Bank of Canada Feed. Automatically delete countries without data
* today.
* 1.9 2004-07-07 remove rounding for 7 M style display since format has it built-in.
* 2.0 2005-06-13 add Trillions, Show millions and billions to one decimal point.
* name all colours
* 2.1 2005-07-16 set up with standard bat files.
* ensure compiled under 1.1 under all circumstances
* 2.2 2005-08-11 convert non-displaying currency signs to general currency.
* 2.3 2006-01-01
* 2.4 2006-02-16 change colour scheme. Currency code not so brazen.
* 2.5 2006-03-04 reformat with IntelliJ. add Javadoc.
* 2.6 2007-01-29
* 2.7 2008-01-29
* 2.8 2008-01-29 get version number is sync with currConAux
* 2.9 2008-01-30 safer code for Applet instance interaction
* 3.0 2008-01-31 locks and other means to deal with interApplet fibrillation.
* 3.1 2008-01-31 volatile and yield to help smooth interApplet fibrillation.
* 3.2 2008-01-31 avoid shared variable to smooth interApplet fibrillation.
* 3.3 2008-02-01 use threads and invokeLater to avoid freezes on Linux
* 3.4 2008-02-15 lower price.
* 3.5 2008-09-19 allow commas in parameter amount values.
* 3.6 2010-02-04 new colours to match mindprod style sheet. wider currency code selector to hold KRW
* 3.7 2010-05-31 add P code that acts like A, but gives precise value.
* 3.8 2010-06-02 ensure P code prices update when currency changed elsewhere on the page.
* 3.9 2010-12-04 compress resource. use pure arrays to avoid generics trouble.
* 4.0 2011-01-21 new format for BOC files, no longer need boccodes.csv
* 4.1 2011-01-26 switch to iso currency codes, allow multi-char currency symbols. Allow accents in currency names.
* Flip from JDK 1.1 to 1.5
* 4.2 2011-02-19 now supports Windows/IE variable resolution.
* 4.3 2011-05-07 adjust to new Boc Format, URLs and filenames.
* 4.4 2011-05-18 adjust to new format of Boc exchange rates. Simplify by eliminating currconaux directory.
* 4.5 2011-12-29 adjust to new format from Bank of Canada.
*/
/*
TODO
- use java.util.Currency instead of our own currency tables.
- autoresizing Applets.
- L code for large amount field that is left exact.
- allow commas/dots in amount field.
- store currency preference in cookie..
- automatic update of exchange rates.
- sort by country name, also currency abbr.
- way to let user know how up to date exchange rates are.
- bigger box for bigger value.
- optional amount display
- smart width, drop decimal points and commas if room tight. Drop show country if room tight.
- use smaller font.
possible futures n = name of currency, user may change.
Applet width and height must be big enough to contain
all the pieces you include.
c=50 C=30 N=120 $=10 A=70 P=100
c$A is width 130, cN is width 170, $A is width 80, c$AN is 250, $AN is 200
$AC is 110
</applet>
*/
package com.mindprod.currcon;
import com.mindprod.common18.EIO;
import com.mindprod.common18.ST;
import com.mindprod.common18.VersionCheck;
import com.mindprod.fastcat.FastCat;
import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import java.awt.Container;
import java.awt.Font;
import java.awt.Label;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.ObjectInputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Locale;
import static java.lang.System.*;
/**
* Currency converter Applet. Displays amount in any international currency.
*
* Uses Applet tags like this:
* <applet archive="currcon.jar" code="CurrCon.class"
* width="130" height="20" alt="1000.00 CAD"
* >
* <param name="currency" value="CAD">
* <param name="amount" value="1000.00">
* <param name="show" value="c$A">
* </applet>
*
* <applet archive="currcon.jar" code="CurrCon.class"
* width="130" height="20" alt="1000.00 CAD"
* >
* <param name="currency" value="CAD">
* <param name="amount" value="1000.00">
* always with . and no commas or $ despite locale.
* max $999,999.99
* <param name="show" value="c$A">
* possible letters:
* c = 3-letter code, user may change
* C = 3-letter code, user may not change, tracks changes elsewhere.
* N = name of the currency, user may not change.
* $ = lead currency symbol on value.
* A = amount, converted to selected currency. user may not change.
* P = precise amount. No abbreviations.
* If there is a show value A present, then currency and amount params must be
* present.
*
* any combinations and orders are possible, though you would not likely
* have both c and C. It makes no sense to have $ without V.
*
* The key trick is Broadcaster that uses AppletContext.getApplets to find all the other
* instances of CurrCon on the same page, and notify them of the change of Currency.
*
* @author Roedy Green, Canadian Mind Products
* @version 4.5 2011-12-29 adjust to new format from Bank of Canada.
* @since 2001-03-08
*/
public final class CurrCon extends JApplet
{
// When CurrCon was written, all instances of the Applet on a page ran on a single thread.
// Now each instance gets its own thread.
private static final int FIRST_COPYRIGHT_YEAR = 2001;
/**
* undisplayed copyright notice
*/
private static final String EMBEDDED_COPYRIGHT =
"Copyright: (c) 2001-2017 Roedy Green, Canadian Mind Products, http://mindprod.com";
private static final String RELEASE_DATE = "2011-12-29";
/**
* embedded version string.
*/
private static final String VERSION_STRING = "4.5";
/**
* true if want extra debugging output on console.
* If you turn on debugging, turn on instance parm is com.mindprod.htmlmacros.macro.CurrCon
*/
static boolean DEBUGGING = false;
/**
* table to lookup country and get the current it uses. shared by all Applets
*/
private static HashMap countryToCurr;
/**
* list of the daily exchange rates for various currencies. shared by all Applets
*/
private static Exch[] exchs;
static
{
// should happen once, only one and before any init method runs.
fetchCurrencyInfo();
}
/**
* helps format the amount display , for 0 to 3 decimal places DecimalFormat is not thread Safe. That should not
* matter since all Applets run on the same thread, but just in case... Actual display is Locale dependent, e.g.
* comma or decimal point. Not thread safe so we make them non-static.
*/
private final DecimalFormat[] df = {
new DecimalFormat( "###,###,##0" ),
new DecimalFormat( "#,###,##0.0" ),
new DecimalFormat( "###,##0.00" ),
new DecimalFormat( "###,##0.000" ), };
/**
* which instance on the page are we, unique string
*/
private String instance = "unknown";
/**
* font we use mostly. Dialog has good support for currency symbols, except Indian Rupee sign.
*/
private Font mainFont;
/**
* listener for user to select a different currency
*/
private ItemListener theItemListener;
/**
* allow user to select which 3-letter currency to use.
*/
private JComboBox currCodeSelect;
/**
* Display the converted amount.
*/
private JLabel compactAmountDisplay;
/**
* display of 3 letter code
*/
private JLabel currencyCodeDisplay;
/**
* display the name of the currency in words, e..g. Canadian dollars
*/
private JLabel currenceNameDisplay;
/**
* used to display errors
*/
private JLabel invalidDisplay;
/**
* Display the converted amount precisely, without abbreviations
*/
private JLabel preciseAmountDisplay;
/**
* 3-letter iso currency code for base currency, one described in the Applet tag.
*/
private String baseCurrencyAbbr;
/**
* 3-letter ISO currency code. The user's preferred code based on his country setting. Does not change as selects
* different codes.
*/
private String userCurrencyAbbr;
/**
* true once this instance of the Applet is ready to go
*/
private boolean ready = false;
/**
* do we put a lead $ on value
*/
private boolean showSymbols = false;
/**
* The amount we want to display in the base currency
*/
private double baseAmount = 0;
/**
* actual height of applet, may be higher than we requested on