我尝试在以下link中更新Java货币转换器应用程序。 这是代码
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Main extends JPanel {
enum Currency {
USD("United States Dollar"),
GBR("Great Britain Pound"),
AUD("Australian Dollar"),
EUR("Euro");
private String description;
Currency(String description) {
this.description = description;
}
@Override public String toString() {
return this.name() + " - " + this.description;
}
}
class CurrencyPair {
private final Currency from;
private final Currency to;
public CurrencyPair(Currency from, Currency to) {
this.from = from;
this.to = to;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CurrencyPair that = (CurrencyPair) o;
if (from != that.from) return false;
return to == that.to;
}
@Override public int hashCode() {
int result = from.hashCode();
result = 31 * result + to.hashCode();
return result;
}
}
private final Map<CurrencyPair, BigDecimal> exchangeRates = new HashMap<CurrencyPair, BigDecimal>() {{
put(new CurrencyPair(Main.Currency.USD, Main.Currency.USD), BigDecimal.valueOf(1));
put(new CurrencyPair(Main.Currency.AUD, Main.Currency.AUD), BigDecimal.valueOf(1));
put(new CurrencyPair(Main.Currency.EUR, Main.Currency.EUR), BigDecimal.valueOf(1));
put(new CurrencyPair(Main.Currency.GBR, Main.Currency.GBR), BigDecimal.valueOf(1));
put(new CurrencyPair(Main.Currency.USD, Main.Currency.GBR), BigDecimal.valueOf(0.75));
put(new CurrencyPair(Main.Currency.USD, Main.Currency.AUD), BigDecimal.valueOf(1.33));
put(new CurrencyPair(Main.Currency.USD, Main.Currency.EUR), BigDecimal.valueOf(0.89));
put(new CurrencyPair(Main.Currency.EUR, Main.Currency.USD), BigDecimal.valueOf(1.12));
put(new CurrencyPair(Main.Currency.EUR, Main.Currency.AUD), BigDecimal.valueOf(1.49));
put(new CurrencyPair(Main.Currency.EUR, Main.Currency.GBR), BigDecimal.valueOf(0.85));
put(new CurrencyPair(Main.Currency.AUD, Main.Currency.USD), BigDecimal.valueOf(0.74));
put(new CurrencyPair(Main.Currency.AUD, Main.Currency.EUR), BigDecimal.valueOf(0.67));
put(new CurrencyPair(Main.Currency.AUD, Main.Currency.GBR), BigDecimal.valueOf(0.57));
put(new CurrencyPair(Main.Currency.GBR, Main.Currency.USD), BigDecimal.valueOf(1.33));
put(new CurrencyPair(Main.Currency.GBR, Main.Currency.EUR), BigDecimal.valueOf(1.18));
put(new CurrencyPair(Main.Currency.GBR, Main.Currency.AUD), BigDecimal.valueOf(1.76));
}};
public Main() {
super(new FlowLayout(FlowLayout.LEADING));
// Amount
JTextField amountInput = new JTextField(20);
JPanel amount = new JPanel();
amount.add(amountInput);
amount.setBorder(BorderFactory.createTitledBorder("Enter Ammount"));
add(amount, BorderLayout.CENTER);
// From
JPanel from = new JPanel();
JComboBox fromOptions = new JComboBox(Currency.values());
from.add(fromOptions);
from.setBorder(BorderFactory.createTitledBorder("Select currency"));
add(from, BorderLayout.CENTER);
// To
JComboBox toOptions = new JComboBox(Currency.values());
JPanel to = new JPanel();
to.add(toOptions);
to.setBorder(BorderFactory.createTitledBorder("Convert to"));
add(to, BorderLayout.CENTER);
// Convert Action
JLabel convertText = new JLabel();
JButton convertCmd = new JButton("Convert");
convertCmd.addActionListener(convertAction(amountInput, fromOptions, toOptions, convertText));
JPanel convert = new JPanel();
convert.add(convertCmd);
convert.add(convertText);
add(convert);
}
private ActionListener convertAction(
final JTextField amountInput,
final JComboBox fromOptions,
final JComboBox toOptions,
final JLabel convertText) {
return new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO: Needs proper validation
String amountInputText = amountInput.getText();
if ("".equals(amountInputText)) { return; }
// Convert
BigDecimal conversion = convertCurrency(amountInputText);
convertText.setText(NumberFormat
.getCurrencyInstance(Locale.US)
.format(conversion));
}
private BigDecimal convertCurrency(String amountInputText) {
// TODO: Needs proper rounding and precision setting
CurrencyPair currencyPair = new CurrencyPair(
(Currency) fromOptions.getSelectedItem(),
(Currency) toOptions.getSelectedItem());
BigDecimal rate = exchangeRates.get(currencyPair);
BigDecimal amount = new BigDecimal(amountInputText);
return amount.multiply(rate);
}
};
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new Main());
frame.setTitle("Currency Thing");
frame.setSize(500, 500);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
主要问题是.getCurrencyInstance(Locale.US)
。 USD货币符号出现在所有转换后的结果中,即使它们不同于USD。
我试图为货币对创建if
子句,例如if(new CurrencyPair(Currency.USD, Currency.USD))
,但这不是一个好的代码行。
我想实现一个解决方案,使任何转换结果都具有自己的货币。
答案 0 :(得分:0)
怎么样:
enum Currency {
USD("United States Dollar", Locale.US),
GBR("Great Britain Pound", Locale.UK),
AUD("Australian Dollar", new Locale("en", "AUS")),
EUR("Euro", /*here little complicated*/ Locale.FRANCE);
private final Locale locale;
private final String description;
Currency(String description, Locale locale) {
this.description = description;
this.locale = locale;
}
@Override public String toString() {
return this.name() + " - " + this.description;
//... getters
}
..通过“语言环境”字段扩展货币。 (或者String currency;
)
然后获取并使用它:
// Convert
BigDecimal conversion = convertCurrency(amountInputText);
// fetch (to) locale
Locale locale = ((Currency) toOptions.getSelectedItem()).getLocale();
// ... & apply
convertText.setText(NumberFormat
.getCurrencyInstance(locale)
.format(conversion));
我看到此解决方案/格式的一个(小)问题,在提到的国家/地区,数字格式不一致。 (千位/十进制分隔符将随应用的语言环境而变化)
编辑:
..甚至更糟/更糟:某些国家/地区将其货币符号预先添加到其他国家/地区中。
更好的方法:
带有Currency.symbol:
enum Currency {
USD("United States Dollar", "$"),
GBR("Great Britain Pound", "£"),
AUD("Australian Dollar", "AUD"),
EUR("Euro", "€");
private final String symbol;
...
引入<Currency, DecimalFormat>
的(静态)EnumMap并预先填写:
private static final Map<Currency, DecimalFormat> SYMBOL2FMT
= new EnumMap<>(Currency.class) {{
for (Currency c : Currency.values()) {
put(c, new DecimalFormat("###,###.### " + c.getSymbol()));
}
}};
将其绑定在一起:
// Convert ...
BigDecimal conversion = convertCurrency(amountInputText);
// fetch (to) symbol
Currency toCurrency = ((Currency) toOptions.getSelectedItem());
convertText.setText(SYMBOL2FMT.get(toCurrency).format(conversion));