【问题标题】:How to include currency symbol for the converted currencies?如何包含转换货币的货币符号?
【发布时间】:2021-09-27 17:14:14
【问题描述】:

我尝试在以下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 Amount"));
    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)。美元货币符号出现在所有转换结果中,即使它们与美元不同。

我尝试为货币对创建 if 子句,例如 if(new CurrencyPair(Currency.USD, Currency.USD)),但这不是一个好的代码行。

我想实现一个解决方案,让任何转换结果都有自己的货币。

【问题讨论】:

  • 如果您需要其他货币符号,您需要先传递另一个 Locale,然后再传递 Locale.US。对于 Locale.US,货币是(并且可能永远是)美元。
  • 或者,您可以让您的enum Currency 具有格式化方法,然后使用from 值进行格式化。这避免了一些半骇人听闻的“选择给我这种货币的语言环境”的代码(将来可能会改变并给出不同的结果)。

标签: java eclipse currency converters


【解决方案1】:

怎么样:

enum Currency {

    USD("United States Dollar", Locale.US),
    GBP("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));

我在此解决方案/格式中看到一个(小)问题,即在上述国家/地区的数字格式不一致。 (千位/小数点分隔符将随应用的语言环境而变化)

编辑:

..甚至更糟/更丑陋:一些国家/地区在其货币符号前加上其他国家/地区。


更好的方法:

  1. 使用 Currency.symbol:

    enum Currency {
    
      USD("United States Dollar", "$"),
      GBP("Great Britain Pound", "£"),
      AUD("Australian Dollar", "AUD"),
      EUR("Euro", "€");
    
      private final String symbol;
     ...
    
  2. 引入&lt;Currency, DecimalFormat&gt;的(静态)EnumMap并预填充:

    private static final Map<Currency, DecimalFormat> SYMBOL2FMT
        = new EnumMap<>(Currency.class) {{
        for (Currency c : Currency.values()) {
            put(c, new DecimalFormat("###,###.### " + c.getSymbol()));
        }
    }};
    
  3. 将其绑定在一起:

     // Convert ...
     BigDecimal conversion = convertCurrency(amountInputText);
     // fetch (to) symbol
     Currency toCurrency = ((Currency) toOptions.getSelectedItem());
     convertText.setText(SYMBOL2FMT.get(toCurrency).format(conversion));
    

【讨论】:

  • 感谢@xerx593 的帮助!我解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 2014-08-28
  • 2019-02-23
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多